linux-arm-msm.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/25] drm/msm/dpu: wide planes support
@ 2022-02-09 17:24 Dmitry Baryshkov
  2022-02-09 17:24 ` [PATCH 01/25] drm/msm/dpu: rip out master " Dmitry Baryshkov
                   ` (25 more replies)
  0 siblings, 26 replies; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:24 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

It took me a way longer to finish than I expected. And more patches that
I initially hoped. This patchset brings in multirect usage to support
using two SSPP rectangles for a single plane. Virtual planes support is
omitted from this pull request, it will come later.

Dmitry Baryshkov (25):
  drm/msm/dpu: rip out master planes support
  drm/msm/dpu: do not limit the zpos property
  drm/msm/dpu: add support for SSPP allocation to RM
  drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
  drm/msm/dpu: move pipe_hw to dpu_plane_state
  drm/msm/dpu: inline dpu_plane_get_ctl_flush
  drm/msm/dpu: drop dpu_plane_pipe function
  drm/msm/dpu: get rid of cached flush_mask
  drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic
  drm/msm/dpu: introduce struct dpu_sw_pipe
  drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
  drm/msm/dpu: inline _dpu_plane_set_scanout
  drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
  drm/msm/dpu: move stride programming to
    dpu_hw_sspp_setup_sourceaddress
  drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg
  drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout
  drm/msm/dpu: drop src_split and multirect check from
    dpu_crtc_atomic_check
  drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
  drm/msm/dpu: don't use unsupported blend stages
  drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
  drm/msm/dpu: simplify dpu_plane_validate_src()
  drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe
    and dpu_format
  drm/msm/dpu: rework dpu_plane_atomic_check() and
    dpu_plane_sspp_atomic_update()
  drm/msm/dpu: populate SmartDMA features in hw catalog
  drm/msm/dpu: add support for wide planes

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c      | 355 +++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h      |   1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c   |   4 -
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    |  10 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c    |  78 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h    |  35 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c   | 136 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h   |  88 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c       |  21 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h       |   1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c     | 813 +++++++++---------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h     |  42 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c        |  81 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h        |   6 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h     |  19 +-
 15 files changed, 827 insertions(+), 863 deletions(-)

-- 
2.34.1


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

* [PATCH 01/25] drm/msm/dpu: rip out master planes support
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
@ 2022-02-09 17:24 ` Dmitry Baryshkov
  2022-04-27  1:28   ` Abhinav Kumar
  2022-02-09 17:24 ` [PATCH 02/25] drm/msm/dpu: do not limit the zpos property Dmitry Baryshkov
                   ` (24 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:24 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Master/virtual planes were used for multirect support. In preparation to
reworking DPU planes, drop support for master planes (which was not used
anyway).

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c    | 11 +---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c |  3 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  4 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c     |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 72 ++++-----------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   | 13 +---
 6 files changed, 18 insertions(+), 87 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index e7c9fe1a250f..7318bd45637a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1138,17 +1138,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	}
 
 	for (i = 1; i < SSPP_MAX; i++) {
-		if (pipe_staged[i]) {
+		if (pipe_staged[i])
 			dpu_plane_clear_multirect(pipe_staged[i]);
-
-			if (is_dpu_plane_virtual(pipe_staged[i]->plane)) {
-				DPU_ERROR(
-					"r1 only virt plane:%d not supported\n",
-					pipe_staged[i]->plane->base.id);
-				rc  = -EINVAL;
-				goto end;
-			}
-		}
 	}
 
 	z_pos = -1;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 09cdc3576653..8714ee767346 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -783,8 +783,7 @@ static const struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp,
 }
 
 struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
-		void __iomem *addr, struct dpu_mdss_cfg *catalog,
-		bool is_virtual_pipe)
+		void __iomem *addr, struct dpu_mdss_cfg *catalog)
 {
 	struct dpu_hw_pipe *hw_pipe;
 	const struct dpu_sspp_cfg *cfg;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 92b071b78fdb..1b18de957500 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -394,11 +394,9 @@ struct dpu_kms;
  * @idx:  Pipe index for which driver object is required
  * @addr: Mapped register io address of MDP
  * @catalog : Pointer to mdss catalog data
- * @is_virtual_pipe: is this pipe virtual pipe
  */
 struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
-		void __iomem *addr, struct dpu_mdss_cfg *catalog,
-		bool is_virtual_pipe);
+		void __iomem *addr, struct dpu_mdss_cfg *catalog);
 
 /**
  * dpu_hw_sspp_destroy(): Destroys SSPP driver context
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 47fe11a84a77..4d2b75f3bc89 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -738,7 +738,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
 			  catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR));
 
 		plane = dpu_plane_init(dev, catalog->sspp[i].id, type,
-				       (1UL << max_crtc_count) - 1, 0);
+				       (1UL << max_crtc_count) - 1);
 		if (IS_ERR(plane)) {
 			DPU_ERROR("dpu_plane_init failed\n");
 			ret = PTR_ERR(plane);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ca75089c9d61..3fcc964dec0a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -89,7 +89,7 @@ enum dpu_plane_qos {
 /*
  * struct dpu_plane - local dpu plane structure
  * @aspace: address space pointer
- * @mplane_list: List of multirect planes of the same pipe
+ * @csc_ptr: Points to dpu_csc_cfg structure to use for current
  * @catalog: Points to dpu catalog structure
  * @revalidate: force revalidation of all the plane properties
  */
@@ -104,8 +104,6 @@ struct dpu_plane {
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
-	bool is_virtual;
-	struct list_head mplane_list;
 	struct dpu_mdss_cfg *catalog;
 };
 
@@ -223,7 +221,7 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_pipe_cfg
 static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
 		const struct dpu_format *fmt, u32 src_width)
 {
-	struct dpu_plane *pdpu, *tmp;
+	struct dpu_plane *pdpu;
 	struct dpu_plane_state *pstate;
 	u32 fixed_buff_size;
 	u32 total_fl;
@@ -237,19 +235,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
 	pstate = to_dpu_plane_state(plane->state);
 	fixed_buff_size = pdpu->catalog->caps->pixel_ram_size;
 
-	list_for_each_entry(tmp, &pdpu->mplane_list, mplane_list) {
-		u32 tmp_width;
-
-		if (!tmp->base.state->visible)
-			continue;
-		tmp_width = drm_rect_width(&tmp->base.state->src) >> 16;
-		DPU_DEBUG("plane%d/%d src_width:%d/%d\n",
-				pdpu->base.base.id, tmp->base.base.id,
-				src_width,
-				tmp_width);
-		src_width = max_t(u32, src_width,
-				  tmp_width);
-	}
+	/* FIXME: in multirect case account for the src_width of all the planes */
 
 	if (fmt->fetch_planes == DPU_PLANE_PSEUDO_PLANAR) {
 		if (fmt->chroma_sample == DPU_CHROMA_420) {
@@ -848,13 +834,8 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 	}
 
 done:
-	if (dpu_plane[R0]->is_virtual) {
-		pstate[R0]->multirect_index = DPU_SSPP_RECT_1;
-		pstate[R1]->multirect_index = DPU_SSPP_RECT_0;
-	} else {
-		pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
-		pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
-	}
+	pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
+	pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
 
 	DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
 		pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
@@ -1213,19 +1194,13 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
 {
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct drm_plane_state *state = plane->state;
 	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
 
-	trace_dpu_plane_disable(DRMID(plane), is_dpu_plane_virtual(plane),
+	trace_dpu_plane_disable(DRMID(plane), false,
 				pstate->multirect_mode);
 
 	pstate->pending = true;
-
-	if (is_dpu_plane_virtual(plane) &&
-			pdpu->pipe_hw && pdpu->pipe_hw->ops.setup_multirect)
-		pdpu->pipe_hw->ops.setup_multirect(pdpu->pipe_hw,
-				DPU_SSPP_RECT_SOLO, DPU_SSPP_MULTIRECT_NONE);
 }
 
 static void dpu_plane_atomic_update(struct drm_plane *plane,
@@ -1444,17 +1419,12 @@ enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane)
 	return plane ? to_dpu_plane(plane)->pipe : SSPP_NONE;
 }
 
-bool is_dpu_plane_virtual(struct drm_plane *plane)
-{
-	return plane ? to_dpu_plane(plane)->is_virtual : false;
-}
-
 /* initialize plane */
 struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		uint32_t pipe, enum drm_plane_type type,
-		unsigned long possible_crtcs, u32 master_plane_id)
+		unsigned long possible_crtcs)
 {
-	struct drm_plane *plane = NULL, *master_plane = NULL;
+	struct drm_plane *plane = NULL;
 	const uint32_t *format_list;
 	struct dpu_plane *pdpu;
 	struct msm_drm_private *priv = dev->dev_private;
@@ -1474,18 +1444,9 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	/* cache local stuff for later */
 	plane = &pdpu->base;
 	pdpu->pipe = pipe;
-	pdpu->is_virtual = (master_plane_id != 0);
-	INIT_LIST_HEAD(&pdpu->mplane_list);
-	master_plane = drm_plane_find(dev, NULL, master_plane_id);
-	if (master_plane) {
-		struct dpu_plane *mpdpu = to_dpu_plane(master_plane);
-
-		list_add_tail(&pdpu->mplane_list, &mpdpu->mplane_list);
-	}
 
 	/* initialize underlying h/w driver */
-	pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog,
-							master_plane_id != 0);
+	pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog);
 	if (IS_ERR(pdpu->pipe_hw)) {
 		DPU_ERROR("[%u]SSPP init failed\n", pipe);
 		ret = PTR_ERR(pdpu->pipe_hw);
@@ -1495,14 +1456,8 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		goto clean_sspp;
 	}
 
-	if (pdpu->is_virtual) {
-		format_list = pdpu->pipe_hw->cap->sblk->virt_format_list;
-		num_formats = pdpu->pipe_hw->cap->sblk->virt_num_formats;
-	}
-	else {
-		format_list = pdpu->pipe_hw->cap->sblk->format_list;
-		num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
-	}
+	format_list = pdpu->pipe_hw->cap->sblk->format_list;
+	num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
 
 	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
 				format_list, num_formats,
@@ -1543,15 +1498,14 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 
 	mutex_init(&pdpu->lock);
 
-	DPU_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", plane->name,
-					pipe, plane->base.id, master_plane_id);
+	DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name,
+					pipe, plane->base.id);
 	return plane;
 
 clean_sspp:
 	if (pdpu && pdpu->pipe_hw)
 		dpu_hw_sspp_destroy(pdpu->pipe_hw);
 clean_plane:
-	list_del(&pdpu->mplane_list);
 	kfree(pdpu);
 	return ERR_PTR(ret);
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 9d51dad5c6a5..d2f60810434e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -59,14 +59,6 @@ struct dpu_multirect_plane_states {
  */
 enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
 
-/**
- * is_dpu_plane_virtual - check for virtual plane
- * @plane: Pointer to DRM plane object
- * returns: true - if the plane is virtual
- *          false - if the plane is primary
- */
-bool is_dpu_plane_virtual(struct drm_plane *plane);
-
 /**
  * dpu_plane_get_ctl_flush - get control flush mask
  * @plane:   Pointer to DRM plane object
@@ -94,14 +86,11 @@ void dpu_plane_set_error(struct drm_plane *plane, bool error);
  * @pipe:  dpu hardware pipe identifier
  * @type:  Plane type - PRIMARY/OVERLAY/CURSOR
  * @possible_crtcs: bitmask of crtc that can be attached to the given pipe
- * @master_plane_id: primary plane id of a multirect pipe. 0 value passed for
- *                   a regular plane initialization. A non-zero primary plane
- *                   id will be passed for a virtual pipe initialization.
  *
  */
 struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		uint32_t pipe, enum drm_plane_type type,
-		unsigned long possible_crtcs, u32 master_plane_id);
+		unsigned long possible_crtcs);
 
 /**
  * dpu_plane_validate_multirecti_v2 - validate the multirect planes
-- 
2.34.1


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

* [PATCH 02/25] drm/msm/dpu: do not limit the zpos property
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
  2022-02-09 17:24 ` [PATCH 01/25] drm/msm/dpu: rip out master " Dmitry Baryshkov
@ 2022-02-09 17:24 ` Dmitry Baryshkov
  2022-04-27  1:32   ` Abhinav Kumar
  2022-02-09 17:24 ` [PATCH 03/25] drm/msm/dpu: add support for SSPP allocation to RM Dmitry Baryshkov
                   ` (23 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:24 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Stop limiting zpos property values, we use normalized_zpos anyway. And
nothing stops userspace from assigning several planes to a single zpos
(it is a userspace bug, but the kernel is forgiving about it).

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 10 +---------
 1 file changed, 1 insertion(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 3fcc964dec0a..c04c3be16d85 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1429,7 +1429,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	struct dpu_plane *pdpu;
 	struct msm_drm_private *priv = dev->dev_private;
 	struct dpu_kms *kms = to_dpu_kms(priv->kms);
-	int zpos_max = DPU_ZPOS_MAX;
 	uint32_t num_formats;
 	int ret = -EINVAL;
 
@@ -1467,14 +1466,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 
 	pdpu->catalog = kms->catalog;
 
-	if (kms->catalog->mixer_count &&
-		kms->catalog->mixer[0].sblk->maxblendstages) {
-		zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
-		if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
-			zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
-	}
-
-	ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
+	ret = drm_plane_create_zpos_property(plane, 0, 0, DPU_ZPOS_MAX);
 	if (ret)
 		DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
 
-- 
2.34.1


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

* [PATCH 03/25] drm/msm/dpu: add support for SSPP allocation to RM
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
  2022-02-09 17:24 ` [PATCH 01/25] drm/msm/dpu: rip out master " Dmitry Baryshkov
  2022-02-09 17:24 ` [PATCH 02/25] drm/msm/dpu: do not limit the zpos property Dmitry Baryshkov
@ 2022-02-09 17:24 ` Dmitry Baryshkov
  2022-04-27  2:06   ` Abhinav Kumar
  2022-02-09 17:24 ` [PATCH 04/25] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c Dmitry Baryshkov
                   ` (22 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:24 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Add support for handling and allocting SSPP blocks through the resource
manager. Handling code is not converted to use it though.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 10 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h     |  1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 18 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c      | 81 +++++++++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h      |  6 ++
 5 files changed, 104 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 1b18de957500..f805c30643b1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -388,6 +388,16 @@ struct dpu_hw_pipe {
 };
 
 struct dpu_kms;
+/**
+ * to_dpu_hw_pipe - convert base object dpu_hw_base to container
+ * @hw: Pointer to base hardware block
+ * return: Pointer to hardware block container
+ */
+static inline struct dpu_hw_pipe *to_dpu_hw_pipe(struct dpu_hw_blk *hw)
+{
+	return container_of(hw, struct dpu_hw_pipe, base);
+}
+
 /**
  * dpu_hw_sspp_init - initializes the sspp hw driver object.
  * Should be called once before accessing every pipe.
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 2d385b4b7f5e..824495ad2392 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -146,6 +146,7 @@ struct dpu_global_state {
 	uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
 	uint32_t intf_to_enc_id[INTF_MAX - INTF_0];
 	uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
+	uint32_t pipe_to_plane_id[SSPP_MAX - SSPP_NONE];
 };
 
 struct dpu_global_state
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index c04c3be16d85..146dbccd79cd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1235,8 +1235,6 @@ static void dpu_plane_destroy(struct drm_plane *plane)
 		/* this will destroy the states as well */
 		drm_plane_cleanup(plane);
 
-		dpu_hw_sspp_destroy(pdpu->pipe_hw);
-
 		kfree(pdpu);
 	}
 }
@@ -1445,14 +1443,13 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	pdpu->pipe = pipe;
 
 	/* initialize underlying h/w driver */
-	pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog);
-	if (IS_ERR(pdpu->pipe_hw)) {
-		DPU_ERROR("[%u]SSPP init failed\n", pipe);
-		ret = PTR_ERR(pdpu->pipe_hw);
+	if (!kms->rm.sspp_blks[pipe - SSPP_NONE])
 		goto clean_plane;
-	} else if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
+	pdpu->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
+
+	if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
 		DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
-		goto clean_sspp;
+		goto clean_plane;
 	}
 
 	format_list = pdpu->pipe_hw->cap->sblk->format_list;
@@ -1462,7 +1459,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 				format_list, num_formats,
 				supported_format_modifiers, type, NULL);
 	if (ret)
-		goto clean_sspp;
+		goto clean_plane;
 
 	pdpu->catalog = kms->catalog;
 
@@ -1494,9 +1491,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 					pipe, plane->base.id);
 	return plane;
 
-clean_sspp:
-	if (pdpu && pdpu->pipe_hw)
-		dpu_hw_sspp_destroy(pdpu->pipe_hw);
 clean_plane:
 	kfree(pdpu);
 	return ERR_PTR(ret);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index f9c83d6e427a..21c9e513f1f6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -8,6 +8,7 @@
 #include "dpu_hw_lm.h"
 #include "dpu_hw_ctl.h"
 #include "dpu_hw_pingpong.h"
+#include "dpu_hw_sspp.h"
 #include "dpu_hw_intf.h"
 #include "dpu_hw_dspp.h"
 #include "dpu_hw_merge3d.h"
@@ -35,6 +36,14 @@ int dpu_rm_destroy(struct dpu_rm *rm)
 {
 	int i;
 
+	for (i = 0; i < ARRAY_SIZE(rm->sspp_blks); i++) {
+		struct dpu_hw_pipe *hw;
+
+		if (rm->sspp_blks[i]) {
+			hw = to_dpu_hw_pipe(rm->sspp_blks[i]);
+			dpu_hw_sspp_destroy(hw);
+		}
+	}
 	for (i = 0; i < ARRAY_SIZE(rm->pingpong_blks); i++) {
 		struct dpu_hw_pingpong *hw;
 
@@ -166,6 +175,24 @@ int dpu_rm_init(struct dpu_rm *rm,
 		rm->pingpong_blks[pp->id - PINGPONG_0] = &hw->base;
 	}
 
+	for (i = 0; i < cat->sspp_count; i++) {
+		struct dpu_hw_pipe *hw;
+		const struct dpu_sspp_cfg *sspp = &cat->sspp[i];
+
+		if (sspp->id <= SSPP_NONE || sspp->id >= SSPP_MAX) {
+			DPU_ERROR("skip sspp %d with invalid id\n", sspp->id);
+			continue;
+		}
+		hw = dpu_hw_sspp_init(sspp->id, mmio, cat);
+		if (IS_ERR_OR_NULL(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed sspp object creation: err %d\n",
+				rc);
+			goto fail;
+		}
+		rm->sspp_blks[sspp->id - SSPP_NONE] = &hw->base;
+	}
+
 	for (i = 0; i < cat->intf_count; i++) {
 		struct dpu_hw_intf *hw;
 		const struct dpu_intf_cfg *intf = &cat->intf[i];
@@ -660,3 +687,57 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
 
 	return num_blks;
 }
+
+enum dpu_sspp dpu_rm_get_sspp(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t plane_id, bool yuv, bool scale)
+{
+	int i;
+	enum dpu_sspp pipe = SSPP_NONE;
+	struct dpu_hw_pipe *pipe_hw;
+	bool retry = false;
+
+retry_loop:
+	for (i = 0; i < ARRAY_SIZE(rm->sspp_blks) && pipe == SSPP_NONE; i++) {
+		if (!rm->sspp_blks[i])
+			continue;
+		if (reserved_by_other(global_state->pipe_to_plane_id, i, plane_id))
+			continue;
+
+		pipe_hw = to_dpu_hw_pipe(rm->sspp_blks[i]);
+
+		/* skip incompatible planes */
+		if (scale && !(pipe_hw->cap->features & DPU_SSPP_SCALER))
+			continue;
+
+		if (yuv && (!(pipe_hw->cap->features & DPU_SSPP_SCALER) ||
+			    !(pipe_hw->cap->features & DPU_SSPP_CSC_ANY)))
+			continue;
+
+		/* For non-yuv, non-scaled planes try to find simple (DMA)
+		 * plane, fallback to VIG on a second try.
+		 *
+		 * This way we'd leave VIG pipes to be later used for YUV formats.
+		 */
+
+		if (!scale && !yuv && !retry &&
+		    (pipe_hw->cap->features & (DPU_SSPP_SCALER | DPU_SSPP_CSC_ANY)))
+			continue;
+
+		pipe = i + SSPP_NONE;
+	};
+
+	if (!scale && !yuv && !retry && pipe == SSPP_NONE) {
+		retry = true;
+		goto retry_loop;
+	}
+
+	if (pipe != SSPP_NONE)
+		global_state->pipe_to_plane_id[pipe - SSPP_NONE] = plane_id;
+
+	return pipe;
+}
+
+void dpu_rm_release_sspp(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t plane_id)
+{
+	_dpu_rm_clear_mapping(global_state->pipe_to_plane_id,
+			ARRAY_SIZE(global_state->pipe_to_plane_id), plane_id);
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 1f12c8d5b8aa..b759fe39f6d6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -16,6 +16,7 @@ struct dpu_global_state;
 /**
  * struct dpu_rm - DPU dynamic hardware resource manager
  * @pingpong_blks: array of pingpong hardware resources
+ * @sspp_blks: array of sspp hardware resources
  * @mixer_blks: array of layer mixer hardware resources
  * @ctl_blks: array of ctl hardware resources
  * @intf_blks: array of intf hardware resources
@@ -25,6 +26,7 @@ struct dpu_global_state;
  */
 struct dpu_rm {
 	struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
+	struct dpu_hw_blk *sspp_blks[SSPP_MAX - SSPP_NONE];
 	struct dpu_hw_blk *mixer_blks[LM_MAX - LM_0];
 	struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0];
 	struct dpu_hw_blk *intf_blks[INTF_MAX - INTF_0];
@@ -88,5 +90,9 @@ void dpu_rm_release(struct dpu_global_state *global_state,
 int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
 	struct dpu_global_state *global_state, uint32_t enc_id,
 	enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size);
+
+enum dpu_sspp dpu_rm_get_sspp(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t plane_id, bool yuv, bool scale);
+void dpu_rm_release_sspp(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t plane_id);
+
 #endif /* __DPU_RM_H__ */
 
-- 
2.34.1


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

* [PATCH 04/25] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (2 preceding siblings ...)
  2022-02-09 17:24 ` [PATCH 03/25] drm/msm/dpu: add support for SSPP allocation to RM Dmitry Baryshkov
@ 2022-02-09 17:24 ` Dmitry Baryshkov
  2022-05-03 21:34   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 05/25] drm/msm/dpu: move pipe_hw to dpu_plane_state Dmitry Baryshkov
                   ` (21 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:24 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

As SSPP blocks are now visible through dpu_kms->rm.sspp_blocks, move
SSPP debugfs creation from dpu_plane to dpu_kms.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c     | 19 +++++++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 16 ----------------
 3 files changed, 19 insertions(+), 17 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index f805c30643b1..674f311f99b4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -415,7 +415,6 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
  */
 void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx);
 
-void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root);
 int _dpu_hw_sspp_init_debugfs(struct dpu_hw_pipe *hw_pipe, struct dpu_kms *kms, struct dentry *entry);
 
 #endif /*_DPU_HW_SSPP_H */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 4d2b75f3bc89..8196b11fe2f3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -259,6 +259,25 @@ void dpu_debugfs_create_regset32(const char *name, umode_t mode,
 	debugfs_create_file(name, mode, parent, regset, &dpu_fops_regset32);
 }
 
+static void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root)
+{
+	struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
+	int i;
+
+	if (IS_ERR(entry))
+		return;
+
+	for (i = SSPP_NONE; i < SSPP_MAX; i++) {
+		struct dpu_hw_pipe *pipe_hw;
+
+		if (!dpu_kms->rm.sspp_blks[i - SSPP_NONE])
+			continue;
+
+		pipe_hw = to_dpu_hw_pipe(dpu_kms->rm.sspp_blks[i - SSPP_NONE]);
+		_dpu_hw_sspp_init_debugfs(pipe_hw, dpu_kms, entry);
+	}
+}
+
 static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
 {
 	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 146dbccd79cd..37742f74a7bf 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1359,22 +1359,6 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
 	_dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL);
 	pm_runtime_put_sync(&dpu_kms->pdev->dev);
 }
-
-/* SSPP live inside dpu_plane private data only. Enumerate them here. */
-void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root)
-{
-	struct drm_plane *plane;
-	struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
-
-	if (IS_ERR(entry))
-		return;
-
-	drm_for_each_plane(plane, dpu_kms->dev) {
-		struct dpu_plane *pdpu = to_dpu_plane(plane);
-
-		_dpu_hw_sspp_init_debugfs(pdpu->pipe_hw, dpu_kms, entry);
-	}
-}
 #endif
 
 static bool dpu_plane_format_mod_supported(struct drm_plane *plane,
-- 
2.34.1


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

* [PATCH 05/25] drm/msm/dpu: move pipe_hw to dpu_plane_state
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (3 preceding siblings ...)
  2022-02-09 17:24 ` [PATCH 04/25] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-03 22:32   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 06/25] drm/msm/dpu: inline dpu_plane_get_ctl_flush Dmitry Baryshkov
                   ` (20 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

In preparation to adding fully virtualized planes, move struct
dpu_hw_pipe instance from struct dpu_plane to struct dpu_plane_state, as
it will become a part of state (allocated during atomic check) rather
than part of a plane (allocated during boot).

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 104 ++++++++++++----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   2 +
 2 files changed, 58 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 37742f74a7bf..0247ff8a67a2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -100,7 +100,6 @@ struct dpu_plane {
 
 	enum dpu_sspp pipe;
 
-	struct dpu_hw_pipe *pipe_hw;
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
@@ -300,6 +299,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 		struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	const struct dpu_format *fmt = NULL;
 	u64 qos_lut;
 	u32 total_fl = 0, lut_usage;
@@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 			fmt ? (char *)&fmt->base.pixel_format : NULL,
 			pdpu->is_rt_pipe, total_fl, qos_lut);
 
-	pdpu->pipe_hw->ops.setup_creq_lut(pdpu->pipe_hw, qos_lut);
+	pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
 }
 
 /**
@@ -343,6 +343,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
 		struct drm_framebuffer *fb)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	const struct dpu_format *fmt = NULL;
 	u32 danger_lut, safe_lut;
 
@@ -382,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
 		danger_lut,
 		safe_lut);
 
-	pdpu->pipe_hw->ops.setup_danger_safe_lut(pdpu->pipe_hw,
+	pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
 			danger_lut, safe_lut);
 }
 
@@ -396,14 +397,15 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 	bool enable, u32 flags)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
 
 	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
 	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
-		pipe_qos_cfg.creq_vblank = pdpu->pipe_hw->cap->sblk->creq_vblank;
+		pipe_qos_cfg.creq_vblank = pstate->pipe_hw->cap->sblk->creq_vblank;
 		pipe_qos_cfg.danger_vblank =
-				pdpu->pipe_hw->cap->sblk->danger_vblank;
+				pstate->pipe_hw->cap->sblk->danger_vblank;
 		pipe_qos_cfg.vblank_en = enable;
 	}
 
@@ -429,7 +431,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 		pipe_qos_cfg.danger_vblank,
 		pdpu->is_rt_pipe);
 
-	pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,
+	pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
 			&pipe_qos_cfg);
 }
 
@@ -443,18 +445,19 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 		struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_vbif_set_ot_params ot_params;
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
 	memset(&ot_params, 0, sizeof(ot_params));
-	ot_params.xin_id = pdpu->pipe_hw->cap->xin_id;
-	ot_params.num = pdpu->pipe_hw->idx - SSPP_NONE;
+	ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
+	ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
 	ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
 	ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
 	ot_params.is_wfd = !pdpu->is_rt_pipe;
 	ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
 	ot_params.vbif_idx = VBIF_RT;
-	ot_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
+	ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
 	ot_params.rd = true;
 
 	dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
@@ -467,14 +470,15 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_vbif_set_qos_params qos_params;
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
 	memset(&qos_params, 0, sizeof(qos_params));
 	qos_params.vbif_idx = VBIF_RT;
-	qos_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
-	qos_params.xin_id = pdpu->pipe_hw->cap->xin_id;
-	qos_params.num = pdpu->pipe_hw->idx - SSPP_VIG0;
+	qos_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
+	qos_params.xin_id = pstate->pipe_hw->cap->xin_id;
+	qos_params.num = pstate->pipe_hw->idx - SSPP_VIG0;
 	qos_params.is_rt = pdpu->is_rt_pipe;
 
 	DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, clk_ctrl:%d\n",
@@ -501,11 +505,11 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
 	else if (ret)
 		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-	else if (pdpu->pipe_hw->ops.setup_sourceaddress) {
-		trace_dpu_plane_set_scanout(pdpu->pipe_hw->idx,
+	else if (pstate->pipe_hw->ops.setup_sourceaddress) {
+		trace_dpu_plane_set_scanout(pstate->pipe_hw->idx,
 					    &pipe_cfg->layout,
 					    pstate->multirect_index);
-		pdpu->pipe_hw->ops.setup_sourceaddress(pdpu->pipe_hw, pipe_cfg,
+		pstate->pipe_hw->ops.setup_sourceaddress(pstate->pipe_hw, pipe_cfg,
 						pstate->multirect_index);
 	}
 }
@@ -549,7 +553,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 			scale_cfg->src_height[i] /= chroma_subsmpl_v;
 		}
 
-		if (pdpu->pipe_hw->cap->features &
+		if (pstate->pipe_hw->cap->features &
 			BIT(DPU_SSPP_SCALER_QSEED4)) {
 			scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
 			scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
@@ -609,6 +613,7 @@ static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
 
 static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, const struct dpu_format *fmt)
 {
+	struct dpu_plane_state *pstate = to_dpu_plane_state(pdpu->base.state);
 	const struct dpu_csc_cfg *csc_ptr;
 
 	if (!pdpu) {
@@ -619,7 +624,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
 	if (!DPU_FORMAT_IS_YUV(fmt))
 		return NULL;
 
-	if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->pipe_hw->cap->features)
+	if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe_hw->cap->features)
 		csc_ptr = &dpu_csc10_YUV2RGB_601L;
 	else
 		csc_ptr = &dpu_csc_YUV2RGB_601L;
@@ -654,8 +659,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 			&scaler3_cfg, &pixel_ext, fmt,
 			info->hsub, info->vsub);
 
-	if (pdpu->pipe_hw->ops.setup_pe)
-		pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
+	if (pstate->pipe_hw->ops.setup_pe)
+		pstate->pipe_hw->ops.setup_pe(pstate->pipe_hw,
 				&pixel_ext);
 
 	/**
@@ -663,9 +668,9 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 	 * bypassed. Still we need to update alpha and bitwidth
 	 * ONLY for RECT0
 	 */
-	if (pdpu->pipe_hw->ops.setup_scaler &&
+	if (pstate->pipe_hw->ops.setup_scaler &&
 			pstate->multirect_index != DPU_SSPP_RECT_1)
-		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
+		pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
 				pipe_cfg,
 				&scaler3_cfg);
 }
@@ -694,8 +699,8 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
 
 	/* update sspp */
-	if (fmt && pdpu->pipe_hw->ops.setup_solidfill) {
-		pdpu->pipe_hw->ops.setup_solidfill(pdpu->pipe_hw,
+	if (fmt && pstate->pipe_hw->ops.setup_solidfill) {
+		pstate->pipe_hw->ops.setup_solidfill(pstate->pipe_hw,
 				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
 				pstate->multirect_index);
 
@@ -709,13 +714,13 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 		pipe_cfg.src_rect.y2 =
 			drm_rect_height(&pipe_cfg.dst_rect);
 
-		if (pdpu->pipe_hw->ops.setup_format)
-			pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw,
+		if (pstate->pipe_hw->ops.setup_format)
+			pstate->pipe_hw->ops.setup_format(pstate->pipe_hw,
 					fmt, DPU_SSPP_SOLID_FILL,
 					pstate->multirect_index);
 
-		if (pdpu->pipe_hw->ops.setup_rects)
-			pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
+		if (pstate->pipe_hw->ops.setup_rects)
+			pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
 					&pipe_cfg,
 					pstate->multirect_index);
 
@@ -953,10 +958,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 		crtc_state = drm_atomic_get_new_crtc_state(state,
 							   new_plane_state->crtc);
 
-	min_scale = FRAC_16_16(1, pdpu->pipe_hw->cap->sblk->maxupscale);
+	min_scale = FRAC_16_16(1, pstate->pipe_hw->cap->sblk->maxupscale);
 	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
 						  min_scale,
-						  pdpu->pipe_hw->cap->sblk->maxdwnscale << 16,
+						  pstate->pipe_hw->cap->sblk->maxdwnscale << 16,
 						  true, true);
 	if (ret) {
 		DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
@@ -982,8 +987,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
 
 	if (DPU_FORMAT_IS_YUV(fmt) &&
-		(!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
-		 !(pdpu->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
+		(!(pstate->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
+		 !(pstate->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
 		DPU_DEBUG_PLANE(pdpu,
 				"plane doesn't have scaler/csc for yuv\n");
 		return -EINVAL;
@@ -1044,12 +1049,12 @@ void dpu_plane_flush(struct drm_plane *plane)
 	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
 		/* force 100% alpha */
 		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
-	else if (pdpu->pipe_hw && pdpu->pipe_hw->ops.setup_csc) {
+	else if (pstate->pipe_hw && pstate->pipe_hw->ops.setup_csc) {
 		const struct dpu_format *fmt = to_dpu_format(msm_framebuffer_format(plane->state->fb));
 		const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, fmt);
 
 		if (csc_ptr)
-			pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, csc_ptr);
+			pstate->pipe_hw->ops.setup_csc(pstate->pipe_hw, csc_ptr);
 	}
 
 	/* flag h/w flush complete */
@@ -1116,21 +1121,21 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		return;
 	}
 
-	if (pdpu->pipe_hw->ops.setup_rects) {
-		pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
+	if (pstate->pipe_hw->ops.setup_rects) {
+		pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
 				&pipe_cfg,
 				pstate->multirect_index);
 	}
 
 	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
 
-	if (pdpu->pipe_hw->ops.setup_multirect)
-		pdpu->pipe_hw->ops.setup_multirect(
-				pdpu->pipe_hw,
+	if (pstate->pipe_hw->ops.setup_multirect)
+		pstate->pipe_hw->ops.setup_multirect(
+				pstate->pipe_hw,
 				pstate->multirect_index,
 				pstate->multirect_mode);
 
-	if (pdpu->pipe_hw->ops.setup_format) {
+	if (pstate->pipe_hw->ops.setup_format) {
 		unsigned int rotation;
 
 		src_flags = 0x0;
@@ -1147,10 +1152,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			src_flags |= DPU_SSPP_FLIP_UD;
 
 		/* update format */
-		pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw, fmt, src_flags,
+		pstate->pipe_hw->ops.setup_format(pstate->pipe_hw, fmt, src_flags,
 				pstate->multirect_index);
 
-		if (pdpu->pipe_hw->ops.setup_cdp) {
+		if (pstate->pipe_hw->ops.setup_cdp) {
 			struct dpu_hw_pipe_cdp_cfg cdp_cfg;
 
 			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
@@ -1164,7 +1169,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 					DPU_FORMAT_IS_TILE(fmt);
 			cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
 
-			pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, &cdp_cfg, pstate->multirect_index);
+			pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg, pstate->multirect_index);
 		}
 	}
 
@@ -1310,10 +1315,9 @@ static void dpu_plane_atomic_print_state(struct drm_printer *p,
 		const struct drm_plane_state *state)
 {
 	const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
-	const struct dpu_plane *pdpu = to_dpu_plane(state->plane);
 
 	drm_printf(p, "\tstage=%d\n", pstate->stage);
-	drm_printf(p, "\tsspp=%s\n", pdpu->pipe_hw->cap->name);
+	drm_printf(p, "\tsspp=%s\n", pstate->pipe_hw->cap->name);
 	drm_printf(p, "\tmultirect_mode=%s\n", dpu_get_multirect_mode(pstate->multirect_mode));
 	drm_printf(p, "\tmultirect_index=%s\n", dpu_get_multirect_index(pstate->multirect_index));
 }
@@ -1322,6 +1326,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu;
 	struct dpu_plane_state *pstate;
+	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
 
 	if (!plane) {
 		DPU_ERROR("invalid plane\n");
@@ -1343,6 +1348,8 @@ static void dpu_plane_reset(struct drm_plane *plane)
 		return;
 	}
 
+	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
+
 	__drm_atomic_helper_plane_reset(plane, &pstate->base);
 }
 
@@ -1411,6 +1418,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	struct dpu_plane *pdpu;
 	struct msm_drm_private *priv = dev->dev_private;
 	struct dpu_kms *kms = to_dpu_kms(priv->kms);
+	struct dpu_hw_pipe *pipe_hw;
 	uint32_t num_formats;
 	int ret = -EINVAL;
 
@@ -1429,15 +1437,15 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	/* initialize underlying h/w driver */
 	if (!kms->rm.sspp_blks[pipe - SSPP_NONE])
 		goto clean_plane;
-	pdpu->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
+	pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
 
-	if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
+	if (!pipe_hw->cap || !pipe_hw->cap->sblk) {
 		DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
 		goto clean_plane;
 	}
 
-	format_list = pdpu->pipe_hw->cap->sblk->format_list;
-	num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
+	format_list = pipe_hw->cap->sblk->format_list;
+	num_formats = pipe_hw->cap->sblk->num_formats;
 
 	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
 				format_list, num_formats,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index d2f60810434e..42b88b6bc9c2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -35,6 +35,8 @@ struct dpu_plane_state {
 	uint32_t multirect_mode;
 	bool pending;
 
+	struct dpu_hw_pipe *pipe_hw;
+
 	u64 plane_fetch_bw;
 	u64 plane_clk;
 };
-- 
2.34.1


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

* [PATCH 06/25] drm/msm/dpu: inline dpu_plane_get_ctl_flush
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (4 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 05/25] drm/msm/dpu: move pipe_hw to dpu_plane_state Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-03 22:55   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 07/25] drm/msm/dpu: drop dpu_plane_pipe function Dmitry Baryshkov
                   ` (19 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

There is no need to keep a separate function for calling into the ctl if
we already know all the details. Inline this function in the dpu_crtc.c

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 15 ++++++++-------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 12 ------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  9 ---------
 3 files changed, 8 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 7318bd45637a..5fc338ef3460 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -348,7 +348,6 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	struct dpu_format *format;
 	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
 
-	u32 flush_mask;
 	uint32_t stage_idx, lm_idx;
 	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
 	bool bg_alpha_enable = false;
@@ -356,6 +355,8 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 
 	memset(fetch_active, 0, sizeof(fetch_active));
 	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		enum dpu_sspp sspp_idx;
+
 		state = plane->state;
 		if (!state)
 			continue;
@@ -363,14 +364,14 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		pstate = to_dpu_plane_state(state);
 		fb = state->fb;
 
-		dpu_plane_get_ctl_flush(plane, ctl, &flush_mask);
-		set_bit(dpu_plane_pipe(plane), fetch_active);
+		sspp_idx = dpu_plane_pipe(plane);
+		set_bit(sspp_idx, fetch_active);
 
 		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
 				crtc->base.id,
 				pstate->stage,
 				plane->base.id,
-				dpu_plane_pipe(plane) - SSPP_VIG0,
+				sspp_idx - SSPP_VIG0,
 				state->fb ? state->fb->base.id : -1);
 
 		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
@@ -380,13 +381,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 
 		stage_idx = zpos_cnt[pstate->stage]++;
 		stage_cfg->stage[pstate->stage][stage_idx] =
-					dpu_plane_pipe(plane);
+					sspp_idx;
 		stage_cfg->multirect_index[pstate->stage][stage_idx] =
 					pstate->multirect_index;
 
 		trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
 					   state, pstate, stage_idx,
-					   dpu_plane_pipe(plane) - SSPP_VIG0,
+					   sspp_idx - SSPP_VIG0,
 					   format->base.pixel_format,
 					   fb ? fb->modifier : 0);
 
@@ -395,7 +396,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 			_dpu_crtc_setup_blend_cfg(mixer + lm_idx,
 						pstate, format);
 
-			mixer[lm_idx].flush_mask |= flush_mask;
+			mixer[lm_idx].flush_mask |= ctl->ops.get_bitmask_sspp(ctl, sspp_idx);
 
 			if (bg_alpha_enable && !format->alpha_enable)
 				mixer[lm_idx].mixer_op_mode = 0;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 0247ff8a67a2..ca194cd83cd0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -849,18 +849,6 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 	return 0;
 }
 
-/**
- * dpu_plane_get_ctl_flush - get control flush for the given plane
- * @plane: Pointer to drm plane structure
- * @ctl: Pointer to hardware control driver
- * @flush_sspp: Pointer to sspp flush control word
- */
-void dpu_plane_get_ctl_flush(struct drm_plane *plane, struct dpu_hw_ctl *ctl,
-		u32 *flush_sspp)
-{
-	*flush_sspp = ctl->ops.get_bitmask_sspp(ctl, dpu_plane_pipe(plane));
-}
-
 static int dpu_plane_prepare_fb(struct drm_plane *plane,
 		struct drm_plane_state *new_state)
 {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 42b88b6bc9c2..aa9478b475d4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -61,15 +61,6 @@ struct dpu_multirect_plane_states {
  */
 enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
 
-/**
- * dpu_plane_get_ctl_flush - get control flush mask
- * @plane:   Pointer to DRM plane object
- * @ctl: Pointer to control hardware
- * @flush_sspp: Pointer to sspp flush control word
- */
-void dpu_plane_get_ctl_flush(struct drm_plane *plane, struct dpu_hw_ctl *ctl,
-		u32 *flush_sspp);
-
 /**
  * dpu_plane_flush - final plane operations before commit flush
  * @plane: Pointer to drm plane structure
-- 
2.34.1


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

* [PATCH 07/25] drm/msm/dpu: drop dpu_plane_pipe function
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (5 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 06/25] drm/msm/dpu: inline dpu_plane_get_ctl_flush Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-03 23:04   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 08/25] drm/msm/dpu: get rid of cached flush_mask Dmitry Baryshkov
                   ` (18 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

There no more need for the dpu_plane_pipe() function, crtc code can
access pstate->pipe_hw.idx directly.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 4 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 5 -----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 7 -------
 3 files changed, 2 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 5fc338ef3460..d21791db6ab1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -364,7 +364,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		pstate = to_dpu_plane_state(state);
 		fb = state->fb;
 
-		sspp_idx = dpu_plane_pipe(plane);
+		sspp_idx = pstate->pipe_hw->idx;
 		set_bit(sspp_idx, fetch_active);
 
 		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
@@ -1112,7 +1112,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
 		pstates[cnt].drm_pstate = pstate;
 		pstates[cnt].stage = pstate->normalized_zpos;
-		pstates[cnt].pipe_id = dpu_plane_pipe(plane);
+		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe_hw->idx;
 
 		if (pipe_staged[pstates[cnt].pipe_id]) {
 			multirect_plane[multirect_count].r0 =
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ca194cd83cd0..d1f9b4bc10ac 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1391,11 +1391,6 @@ static const struct drm_plane_helper_funcs dpu_plane_helper_funcs = {
 		.atomic_update = dpu_plane_atomic_update,
 };
 
-enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane)
-{
-	return plane ? to_dpu_plane(plane)->pipe : SSPP_NONE;
-}
-
 /* initialize plane */
 struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		uint32_t pipe, enum drm_plane_type type,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index aa9478b475d4..d745cde4ea77 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -54,13 +54,6 @@ struct dpu_multirect_plane_states {
 #define to_dpu_plane_state(x) \
 	container_of(x, struct dpu_plane_state, base)
 
-/**
- * dpu_plane_pipe - return sspp identifier for the given plane
- * @plane:   Pointer to DRM plane object
- * Returns: sspp identifier of the given plane
- */
-enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
-
 /**
  * dpu_plane_flush - final plane operations before commit flush
  * @plane: Pointer to drm plane structure
-- 
2.34.1


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

* [PATCH 08/25] drm/msm/dpu: get rid of cached flush_mask
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (6 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 07/25] drm/msm/dpu: drop dpu_plane_pipe function Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-03 23:40   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 09/25] drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic Dmitry Baryshkov
                   ` (17 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Instead of querying the CTL for the flush mask (for SSPP, LM or DSPP),
storing the mask in the mixer configuration and then pushing the mask to
the CTL, tell CTL to cache the flush in place.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c   | 25 ++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h   |  1 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 78 +++++++++-------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 35 +++++++---
 4 files changed, 66 insertions(+), 73 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index d21791db6ab1..e6c33022d560 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -396,7 +396,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 			_dpu_crtc_setup_blend_cfg(mixer + lm_idx,
 						pstate, format);
 
-			mixer[lm_idx].flush_mask |= ctl->ops.get_bitmask_sspp(ctl, sspp_idx);
+			mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx);
 
 			if (bg_alpha_enable && !format->alpha_enable)
 				mixer[lm_idx].mixer_op_mode = 0;
@@ -430,7 +430,6 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
 
 	for (i = 0; i < cstate->num_mixers; i++) {
 		mixer[i].mixer_op_mode = 0;
-		mixer[i].flush_mask = 0;
 		if (mixer[i].lm_ctl->ops.clear_all_blendstages)
 			mixer[i].lm_ctl->ops.clear_all_blendstages(
 					mixer[i].lm_ctl);
@@ -447,17 +446,14 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
 
 		lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
 
-		mixer[i].flush_mask |= ctl->ops.get_bitmask_mixer(ctl,
-			mixer[i].hw_lm->idx);
-
 		/* stage config flush mask */
-		ctl->ops.update_pending_flush(ctl, mixer[i].flush_mask);
+		ctl->ops.update_pending_flush_mixer(ctl,
+			mixer[i].hw_lm->idx);
 
-		DRM_DEBUG_ATOMIC("lm %d, op_mode 0x%X, ctl %d, flush mask 0x%x\n",
+		DRM_DEBUG_ATOMIC("lm %d, op_mode 0x%X, ctl %d\n",
 			mixer[i].hw_lm->idx - LM_0,
 			mixer[i].mixer_op_mode,
-			ctl->idx - CTL_0,
-			mixer[i].flush_mask);
+			ctl->idx - CTL_0);
 
 		ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
 			&stage_cfg);
@@ -701,16 +697,9 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
 			dspp->ops.setup_pcc(dspp, &cfg);
 		}
 
-		mixer[i].flush_mask |= ctl->ops.get_bitmask_dspp(ctl,
-			mixer[i].hw_dspp->idx);
-
 		/* stage config flush mask */
-		ctl->ops.update_pending_flush(ctl, mixer[i].flush_mask);
-
-		DRM_DEBUG_ATOMIC("lm %d, ctl %d, flush mask 0x%x\n",
-			mixer[i].hw_lm->idx - DSPP_0,
-			ctl->idx - CTL_0,
-			mixer[i].flush_mask);
+		ctl->ops.update_pending_flush_dspp(ctl,
+			mixer[i].hw_dspp->idx);
 	}
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index b8785c394fcc..9f87fc32b1bb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -95,7 +95,6 @@ struct dpu_crtc_mixer {
 	struct dpu_hw_ctl *lm_ctl;
 	struct dpu_hw_dspp *hw_dspp;
 	u32 mixer_op_mode;
-	u32 flush_mask;
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 02da9ecf71f1..8dc59659bd18 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -139,92 +139,84 @@ static inline void dpu_hw_ctl_trigger_flush(struct dpu_hw_ctl *ctx)
 	DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
 }
 
-static uint32_t dpu_hw_ctl_get_bitmask_sspp(struct dpu_hw_ctl *ctx,
+static void dpu_hw_ctl_update_pending_flush_sspp(struct dpu_hw_ctl *ctx,
 	enum dpu_sspp sspp)
 {
-	uint32_t flushbits = 0;
-
 	switch (sspp) {
 	case SSPP_VIG0:
-		flushbits =  BIT(0);
+		ctx->pending_flush_mask |=  BIT(0);
 		break;
 	case SSPP_VIG1:
-		flushbits = BIT(1);
+		ctx->pending_flush_mask |= BIT(1);
 		break;
 	case SSPP_VIG2:
-		flushbits = BIT(2);
+		ctx->pending_flush_mask |= BIT(2);
 		break;
 	case SSPP_VIG3:
-		flushbits = BIT(18);
+		ctx->pending_flush_mask |= BIT(18);
 		break;
 	case SSPP_RGB0:
-		flushbits = BIT(3);
+		ctx->pending_flush_mask |= BIT(3);
 		break;
 	case SSPP_RGB1:
-		flushbits = BIT(4);
+		ctx->pending_flush_mask |= BIT(4);
 		break;
 	case SSPP_RGB2:
-		flushbits = BIT(5);
+		ctx->pending_flush_mask |= BIT(5);
 		break;
 	case SSPP_RGB3:
-		flushbits = BIT(19);
+		ctx->pending_flush_mask |= BIT(19);
 		break;
 	case SSPP_DMA0:
-		flushbits = BIT(11);
+		ctx->pending_flush_mask |= BIT(11);
 		break;
 	case SSPP_DMA1:
-		flushbits = BIT(12);
+		ctx->pending_flush_mask |= BIT(12);
 		break;
 	case SSPP_DMA2:
-		flushbits = BIT(24);
+		ctx->pending_flush_mask |= BIT(24);
 		break;
 	case SSPP_DMA3:
-		flushbits = BIT(25);
+		ctx->pending_flush_mask |= BIT(25);
 		break;
 	case SSPP_CURSOR0:
-		flushbits = BIT(22);
+		ctx->pending_flush_mask |= BIT(22);
 		break;
 	case SSPP_CURSOR1:
-		flushbits = BIT(23);
+		ctx->pending_flush_mask |= BIT(23);
 		break;
 	default:
 		break;
 	}
-
-	return flushbits;
 }
 
-static uint32_t dpu_hw_ctl_get_bitmask_mixer(struct dpu_hw_ctl *ctx,
+static void dpu_hw_ctl_update_pending_flush_mixer(struct dpu_hw_ctl *ctx,
 	enum dpu_lm lm)
 {
-	uint32_t flushbits = 0;
-
 	switch (lm) {
 	case LM_0:
-		flushbits = BIT(6);
+		ctx->pending_flush_mask |= BIT(6);
 		break;
 	case LM_1:
-		flushbits = BIT(7);
+		ctx->pending_flush_mask |= BIT(7);
 		break;
 	case LM_2:
-		flushbits = BIT(8);
+		ctx->pending_flush_mask |= BIT(8);
 		break;
 	case LM_3:
-		flushbits = BIT(9);
+		ctx->pending_flush_mask |= BIT(9);
 		break;
 	case LM_4:
-		flushbits = BIT(10);
+		ctx->pending_flush_mask |= BIT(10);
 		break;
 	case LM_5:
-		flushbits = BIT(20);
+		ctx->pending_flush_mask |= BIT(20);
 		break;
 	default:
-		return -EINVAL;
+		break;
 	}
 
-	flushbits |= CTL_FLUSH_MASK_CTL;
-
-	return flushbits;
+	ctx->pending_flush_mask |= CTL_FLUSH_MASK_CTL;
 }
 
 static void dpu_hw_ctl_update_pending_flush_intf(struct dpu_hw_ctl *ctx,
@@ -262,29 +254,25 @@ static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx,
 	ctx->pending_flush_mask |= BIT(MERGE_3D_IDX);
 }
 
-static uint32_t dpu_hw_ctl_get_bitmask_dspp(struct dpu_hw_ctl *ctx,
+static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
 	enum dpu_dspp dspp)
 {
-	uint32_t flushbits = 0;
-
 	switch (dspp) {
 	case DSPP_0:
-		flushbits = BIT(13);
+		ctx->pending_flush_mask |= BIT(13);
 		break;
 	case DSPP_1:
-		flushbits = BIT(14);
+		ctx->pending_flush_mask |= BIT(14);
 		break;
 	case DSPP_2:
-		flushbits = BIT(15);
+		ctx->pending_flush_mask |= BIT(15);
 		break;
 	case DSPP_3:
-		flushbits = BIT(21);
+		ctx->pending_flush_mask |= BIT(21);
 		break;
 	default:
-		return 0;
+		break;
 	}
-
-	return flushbits;
 }
 
 static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us)
@@ -592,9 +580,9 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
 	ops->wait_reset_status = dpu_hw_ctl_wait_reset_status;
 	ops->clear_all_blendstages = dpu_hw_ctl_clear_all_blendstages;
 	ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
-	ops->get_bitmask_sspp = dpu_hw_ctl_get_bitmask_sspp;
-	ops->get_bitmask_mixer = dpu_hw_ctl_get_bitmask_mixer;
-	ops->get_bitmask_dspp = dpu_hw_ctl_get_bitmask_dspp;
+	ops->update_pending_flush_sspp = dpu_hw_ctl_update_pending_flush_sspp;
+	ops->update_pending_flush_mixer = dpu_hw_ctl_update_pending_flush_mixer;
+	ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp;
 	if (cap & BIT(DPU_CTL_FETCH_ACTIVE))
 		ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active;
 };
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
index 806c171e5df2..84e8167c23a1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
@@ -110,6 +110,32 @@ struct dpu_hw_ctl_ops {
 	void (*update_pending_flush_merge_3d)(struct dpu_hw_ctl *ctx,
 		enum dpu_merge_3d blk);
 
+	/**
+	 * OR in the given flushbits to the cached pending_flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 * @blk       : SSPP block index
+	 */
+	void (*update_pending_flush_sspp)(struct dpu_hw_ctl *ctx,
+		enum dpu_sspp blk);
+
+	/**
+	 * OR in the given flushbits to the cached pending_flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 * @blk       : LM block index
+	 */
+	void (*update_pending_flush_mixer)(struct dpu_hw_ctl *ctx,
+		enum dpu_lm blk);
+
+	/**
+	 * OR in the given flushbits to the cached pending_flush_mask
+	 * No effect on hardware
+	 * @ctx       : ctl path ctx pointer
+	 * @blk       : DSPP block index
+	 */
+	void (*update_pending_flush_dspp)(struct dpu_hw_ctl *ctx,
+		enum dpu_dspp blk);
 	/**
 	 * Write the value of the pending_flush_mask to hardware
 	 * @ctx       : ctl path ctx pointer
@@ -144,15 +170,6 @@ struct dpu_hw_ctl_ops {
 	 */
 	int (*wait_reset_status)(struct dpu_hw_ctl *ctx);
 
-	uint32_t (*get_bitmask_sspp)(struct dpu_hw_ctl *ctx,
-		enum dpu_sspp blk);
-
-	uint32_t (*get_bitmask_mixer)(struct dpu_hw_ctl *ctx,
-		enum dpu_lm blk);
-
-	uint32_t (*get_bitmask_dspp)(struct dpu_hw_ctl *ctx,
-		enum dpu_dspp blk);
-
 	/**
 	 * Set all blend stages to disabled
 	 * @ctx       : ctl path ctx pointer
-- 
2.34.1


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

* [PATCH 09/25] drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (7 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 08/25] drm/msm/dpu: get rid of cached flush_mask Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-06 18:56   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe Dmitry Baryshkov
                   ` (16 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

The funcitons _dpu_crtc_blend_setup() and _dpu_crtc_blend_setup_mixer()
have an intertwined mixture of CTL and LM-related code. Split these two
functions into LM-specific and CTL-specific parts, making both code
paths clean and observable.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 101 +++++++++++++---------
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |  10 +--
 2 files changed, 63 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index e6c33022d560..ada7d5750536 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -336,27 +336,23 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
 	}
 }
 
-static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
-	struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer,
-	struct dpu_hw_stage_cfg *stage_cfg)
+static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc)
 {
+	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
+	struct dpu_crtc_mixer *mixer = cstate->mixers;
 	struct drm_plane *plane;
 	struct drm_framebuffer *fb;
 	struct drm_plane_state *state;
-	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
 	struct dpu_plane_state *pstate = NULL;
 	struct dpu_format *format;
-	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
-
+	int i;
 	uint32_t stage_idx, lm_idx;
-	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
 	bool bg_alpha_enable = false;
-	DECLARE_BITMAP(fetch_active, SSPP_MAX);
 
-	memset(fetch_active, 0, sizeof(fetch_active));
-	drm_atomic_crtc_for_each_plane(plane, crtc) {
-		enum dpu_sspp sspp_idx;
+	for (i = 0; i < cstate->num_mixers; i++)
+		mixer[i].mixer_op_mode = 0;
 
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
 		state = plane->state;
 		if (!state)
 			continue;
@@ -364,14 +360,10 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		pstate = to_dpu_plane_state(state);
 		fb = state->fb;
 
-		sspp_idx = pstate->pipe_hw->idx;
-		set_bit(sspp_idx, fetch_active);
-
-		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
+		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d fb %d\n",
 				crtc->base.id,
 				pstate->stage,
 				plane->base.id,
-				sspp_idx - SSPP_VIG0,
 				state->fb ? state->fb->base.id : -1);
 
 		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
@@ -379,15 +371,8 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
 			bg_alpha_enable = true;
 
-		stage_idx = zpos_cnt[pstate->stage]++;
-		stage_cfg->stage[pstate->stage][stage_idx] =
-					sspp_idx;
-		stage_cfg->multirect_index[pstate->stage][stage_idx] =
-					pstate->multirect_index;
-
 		trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
 					   state, pstate, stage_idx,
-					   sspp_idx - SSPP_VIG0,
 					   format->base.pixel_format,
 					   fb ? fb->modifier : 0);
 
@@ -396,8 +381,6 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 			_dpu_crtc_setup_blend_cfg(mixer + lm_idx,
 						pstate, format);
 
-			mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx);
-
 			if (bg_alpha_enable && !format->alpha_enable)
 				mixer[lm_idx].mixer_op_mode = 0;
 			else
@@ -406,17 +389,22 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		}
 	}
 
-	if (ctl->ops.set_active_pipes)
-		ctl->ops.set_active_pipes(ctl, fetch_active);
-
 	 _dpu_crtc_program_lm_output_roi(crtc);
+
+	for (i = 0; i < cstate->num_mixers; i++) {
+		struct dpu_hw_mixer *lm;
+
+		lm = mixer[i].hw_lm;
+
+		lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
+
+		DRM_DEBUG_ATOMIC("lm %d, op_mode 0x%X\n",
+			mixer[i].hw_lm->idx - LM_0,
+			mixer[i].mixer_op_mode);
+	}
 }
 
-/**
- * _dpu_crtc_blend_setup - configure crtc mixers
- * @crtc: Pointer to drm crtc structure
- */
-static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
+static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc)
 {
 	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
 	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
@@ -425,34 +413,62 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
 	struct dpu_hw_mixer *lm;
 	struct dpu_hw_stage_cfg stage_cfg;
 	int i;
+	struct drm_plane *plane;
+	struct drm_plane_state *state;
+	struct dpu_plane_state *pstate = NULL;
+
+	uint32_t stage_idx, lm_idx;
+	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
+	DECLARE_BITMAP(fetch_active, SSPP_MAX);
 
 	DRM_DEBUG_ATOMIC("%s\n", dpu_crtc->name);
 
-	for (i = 0; i < cstate->num_mixers; i++) {
-		mixer[i].mixer_op_mode = 0;
+	for (i = 0; i < cstate->num_mixers; i++)
 		if (mixer[i].lm_ctl->ops.clear_all_blendstages)
 			mixer[i].lm_ctl->ops.clear_all_blendstages(
 					mixer[i].lm_ctl);
-	}
 
 	/* initialize stage cfg */
 	memset(&stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg));
 
-	_dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer, &stage_cfg);
+	memset(fetch_active, 0, sizeof(fetch_active));
+	drm_atomic_crtc_for_each_plane(plane, crtc) {
+		enum dpu_sspp sspp_idx;
+
+		state = plane->state;
+		if (!state)
+			continue;
+
+		pstate = to_dpu_plane_state(state);
+
+		sspp_idx = pstate->pipe_hw->idx;
+		set_bit(sspp_idx, fetch_active);
+
+		stage_idx = zpos_cnt[pstate->stage]++;
+		stage_cfg.stage[pstate->stage][stage_idx] =
+					sspp_idx;
+		stage_cfg.multirect_index[pstate->stage][stage_idx] =
+					pstate->multirect_index;
+
+		/* blend config update */
+		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++)
+			mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx);
+	}
+
+	ctl = mixer->lm_ctl;
+	if (ctl->ops.set_active_pipes)
+		ctl->ops.set_active_pipes(ctl, fetch_active);
 
 	for (i = 0; i < cstate->num_mixers; i++) {
 		ctl = mixer[i].lm_ctl;
 		lm = mixer[i].hw_lm;
 
-		lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
-
 		/* stage config flush mask */
 		ctl->ops.update_pending_flush_mixer(ctl,
 			mixer[i].hw_lm->idx);
 
-		DRM_DEBUG_ATOMIC("lm %d, op_mode 0x%X, ctl %d\n",
+		DRM_DEBUG_ATOMIC("lm %d, ctl %d\n",
 			mixer[i].hw_lm->idx - LM_0,
-			mixer[i].mixer_op_mode,
 			ctl->idx - CTL_0);
 
 		ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
@@ -731,7 +747,8 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
 	if (unlikely(!cstate->num_mixers))
 		return;
 
-	_dpu_crtc_blend_setup(crtc);
+	_dpu_crtc_blend_setup_mixer(crtc);
+	_dpu_crtc_blend_setup_ctl(crtc);
 
 	_dpu_crtc_setup_cp_blocks(crtc);
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
index 54d74341e690..ecd2f371374d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -632,9 +632,9 @@ TRACE_EVENT(dpu_enc_phys_vid_irq_ctrl,
 TRACE_EVENT(dpu_crtc_setup_mixer,
 	TP_PROTO(uint32_t crtc_id, uint32_t plane_id,
 		 struct drm_plane_state *state, struct dpu_plane_state *pstate,
-		 uint32_t stage_idx, enum dpu_sspp sspp, uint32_t pixel_format,
+		 uint32_t stage_idx, uint32_t pixel_format,
 		 uint64_t modifier),
-	TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx, sspp,
+	TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
 		pixel_format, modifier),
 	TP_STRUCT__entry(
 		__field(	uint32_t,		crtc_id		)
@@ -644,7 +644,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
 		__field_struct(	struct drm_rect,	dst_rect	)
 		__field(	uint32_t,		stage_idx	)
 		__field(	enum dpu_stage,		stage		)
-		__field(	enum dpu_sspp,		sspp		)
 		__field(	uint32_t,		multirect_idx	)
 		__field(	uint32_t,		multirect_mode	)
 		__field(	uint32_t,		pixel_format	)
@@ -658,20 +657,19 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
 		__entry->dst_rect = drm_plane_state_dest(state);
 		__entry->stage_idx = stage_idx;
 		__entry->stage = pstate->stage;
-		__entry->sspp = sspp;
 		__entry->multirect_idx = pstate->multirect_index;
 		__entry->multirect_mode = pstate->multirect_mode;
 		__entry->pixel_format = pixel_format;
 		__entry->modifier = modifier;
 	),
 	TP_printk("crtc_id:%u plane_id:%u fb_id:%u src:" DRM_RECT_FP_FMT
-		  " dst:" DRM_RECT_FMT " stage_idx:%u stage:%d, sspp:%d "
+		  " dst:" DRM_RECT_FMT " stage_idx:%u stage:%d, "
 		  "multirect_index:%d multirect_mode:%u pix_format:%u "
 		  "modifier:%llu",
 		  __entry->crtc_id, __entry->plane_id, __entry->fb_id,
 		  DRM_RECT_FP_ARG(&__entry->src_rect),
 		  DRM_RECT_ARG(&__entry->dst_rect),
-		  __entry->stage_idx, __entry->stage, __entry->sspp,
+		  __entry->stage_idx, __entry->stage,
 		  __entry->multirect_idx, __entry->multirect_mode,
 		  __entry->pixel_format, __entry->modifier)
 );
-- 
2.34.1


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

* [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (8 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 09/25] drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-06 21:30   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 11/25] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks Dmitry Baryshkov
                   ` (15 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Wrap SSPP and multirect index/mode into a single structure that
represents software view on the pipe used.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c    |   8 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  16 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 136 ++++++++++----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   |   4 +-
 4 files changed, 86 insertions(+), 78 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index ada7d5750536..751c64012058 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -441,14 +441,14 @@ static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc)
 
 		pstate = to_dpu_plane_state(state);
 
-		sspp_idx = pstate->pipe_hw->idx;
+		sspp_idx = pstate->pipe.sspp->idx;
 		set_bit(sspp_idx, fetch_active);
 
 		stage_idx = zpos_cnt[pstate->stage]++;
 		stage_cfg.stage[pstate->stage][stage_idx] =
 					sspp_idx;
 		stage_cfg.multirect_index[pstate->stage][stage_idx] =
-					pstate->multirect_index;
+					pstate->pipe.multirect_index;
 
 		/* blend config update */
 		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++)
@@ -1118,7 +1118,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
 		pstates[cnt].drm_pstate = pstate;
 		pstates[cnt].stage = pstate->normalized_zpos;
-		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe_hw->idx;
+		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx;
 
 		if (pipe_staged[pstates[cnt].pipe_id]) {
 			multirect_plane[multirect_count].r0 =
@@ -1389,7 +1389,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
 			state->crtc_x, state->crtc_y, state->crtc_w,
 			state->crtc_h);
 		seq_printf(s, "\tmultirect: mode: %d index: %d\n",
-			pstate->multirect_mode, pstate->multirect_index);
+			pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
 
 		seq_puts(s, "\n");
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 674f311f99b4..0af2bc6e5df8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -159,15 +159,11 @@ struct dpu_hw_pixel_ext {
  * @src_rect:  src ROI, caller takes into account the different operations
  *             such as decimation, flip etc to program this field
  * @dest_rect: destination ROI.
- * @index:     index of the rectangle of SSPP
- * @mode:      parallel or time multiplex multirect mode
  */
 struct dpu_hw_pipe_cfg {
 	struct dpu_hw_fmt_layout layout;
 	struct drm_rect src_rect;
 	struct drm_rect dst_rect;
-	enum dpu_sspp_multirect_index index;
-	enum dpu_sspp_multirect_mode mode;
 };
 
 /**
@@ -218,6 +214,18 @@ struct dpu_hw_pipe_ts_cfg {
 	u64 time;
 };
 
+/**
+ * struct dpu_sw_pipe - software pipe description
+ * @sspp:      backing SSPP pipe
+ * @index:     index of the rectangle of SSPP
+ * @mode:      parallel or time multiplex multirect mode
+ */
+struct dpu_sw_pipe {
+	struct dpu_hw_pipe *sspp;
+	enum dpu_sspp_multirect_index multirect_index;
+	enum dpu_sspp_multirect_mode multirect_mode;
+};
+
 /**
  * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions
  * Caller must call the init function to get the pipe context for each pipe
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index d1f9b4bc10ac..51b5e8a3182b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -247,7 +247,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
 				((src_width + 32) * fmt->bpp);
 		}
 	} else {
-		if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
+		if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
 			total_fl = (fixed_buff_size / 2) * 2 /
 				((src_width + 32) * fmt->bpp);
 		} else {
@@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 			fmt ? (char *)&fmt->base.pixel_format : NULL,
 			pdpu->is_rt_pipe, total_fl, qos_lut);
 
-	pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
+	pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut);
 }
 
 /**
@@ -383,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
 		danger_lut,
 		safe_lut);
 
-	pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
+	pstate->pipe.sspp->ops.setup_danger_safe_lut(pstate->pipe.sspp,
 			danger_lut, safe_lut);
 }
 
@@ -403,9 +403,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
 	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
-		pipe_qos_cfg.creq_vblank = pstate->pipe_hw->cap->sblk->creq_vblank;
+		pipe_qos_cfg.creq_vblank = pstate->pipe.sspp->cap->sblk->creq_vblank;
 		pipe_qos_cfg.danger_vblank =
-				pstate->pipe_hw->cap->sblk->danger_vblank;
+				pstate->pipe.sspp->cap->sblk->danger_vblank;
 		pipe_qos_cfg.vblank_en = enable;
 	}
 
@@ -431,7 +431,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 		pipe_qos_cfg.danger_vblank,
 		pdpu->is_rt_pipe);
 
-	pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
+	pstate->pipe.sspp->ops.setup_qos_ctrl(pstate->pipe.sspp,
 			&pipe_qos_cfg);
 }
 
@@ -450,14 +450,14 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
 	memset(&ot_params, 0, sizeof(ot_params));
-	ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
-	ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
+	ot_params.xin_id = pstate->pipe.sspp->cap->xin_id;
+	ot_params.num = pstate->pipe.sspp->idx - SSPP_NONE;
 	ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
 	ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
 	ot_params.is_wfd = !pdpu->is_rt_pipe;
 	ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
 	ot_params.vbif_idx = VBIF_RT;
-	ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
+	ot_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
 	ot_params.rd = true;
 
 	dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
@@ -476,9 +476,9 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
 
 	memset(&qos_params, 0, sizeof(qos_params));
 	qos_params.vbif_idx = VBIF_RT;
-	qos_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
-	qos_params.xin_id = pstate->pipe_hw->cap->xin_id;
-	qos_params.num = pstate->pipe_hw->idx - SSPP_VIG0;
+	qos_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
+	qos_params.xin_id = pstate->pipe.sspp->cap->xin_id;
+	qos_params.num = pstate->pipe.sspp->idx - SSPP_VIG0;
 	qos_params.is_rt = pdpu->is_rt_pipe;
 
 	DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, clk_ctrl:%d\n",
@@ -505,12 +505,12 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
 	else if (ret)
 		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-	else if (pstate->pipe_hw->ops.setup_sourceaddress) {
-		trace_dpu_plane_set_scanout(pstate->pipe_hw->idx,
+	else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
+		trace_dpu_plane_set_scanout(pstate->pipe.sspp->idx,
 					    &pipe_cfg->layout,
-					    pstate->multirect_index);
-		pstate->pipe_hw->ops.setup_sourceaddress(pstate->pipe_hw, pipe_cfg,
-						pstate->multirect_index);
+					    pstate->pipe.multirect_index);
+		pstate->pipe.sspp->ops.setup_sourceaddress(pstate->pipe.sspp, pipe_cfg,
+						pstate->pipe.multirect_index);
 	}
 }
 
@@ -553,7 +553,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 			scale_cfg->src_height[i] /= chroma_subsmpl_v;
 		}
 
-		if (pstate->pipe_hw->cap->features &
+		if (pstate->pipe.sspp->cap->features &
 			BIT(DPU_SSPP_SCALER_QSEED4)) {
 			scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
 			scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
@@ -624,7 +624,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
 	if (!DPU_FORMAT_IS_YUV(fmt))
 		return NULL;
 
-	if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe_hw->cap->features)
+	if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe.sspp->cap->features)
 		csc_ptr = &dpu_csc10_YUV2RGB_601L;
 	else
 		csc_ptr = &dpu_csc_YUV2RGB_601L;
@@ -659,8 +659,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 			&scaler3_cfg, &pixel_ext, fmt,
 			info->hsub, info->vsub);
 
-	if (pstate->pipe_hw->ops.setup_pe)
-		pstate->pipe_hw->ops.setup_pe(pstate->pipe_hw,
+	if (pstate->pipe.sspp->ops.setup_pe)
+		pstate->pipe.sspp->ops.setup_pe(pstate->pipe.sspp,
 				&pixel_ext);
 
 	/**
@@ -668,9 +668,9 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 	 * bypassed. Still we need to update alpha and bitwidth
 	 * ONLY for RECT0
 	 */
-	if (pstate->pipe_hw->ops.setup_scaler &&
-			pstate->multirect_index != DPU_SSPP_RECT_1)
-		pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
+	if (pstate->pipe.sspp->ops.setup_scaler &&
+			pstate->pipe.multirect_index != DPU_SSPP_RECT_1)
+		pstate->pipe.sspp->ops.setup_scaler(pstate->pipe.sspp,
 				pipe_cfg,
 				&scaler3_cfg);
 }
@@ -699,10 +699,10 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
 
 	/* update sspp */
-	if (fmt && pstate->pipe_hw->ops.setup_solidfill) {
-		pstate->pipe_hw->ops.setup_solidfill(pstate->pipe_hw,
+	if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
+		pstate->pipe.sspp->ops.setup_solidfill(pstate->pipe.sspp,
 				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
-				pstate->multirect_index);
+				pstate->pipe.multirect_index);
 
 		/* override scaler/decimation if solid fill */
 		pipe_cfg.dst_rect = pstate->base.dst;
@@ -714,15 +714,15 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 		pipe_cfg.src_rect.y2 =
 			drm_rect_height(&pipe_cfg.dst_rect);
 
-		if (pstate->pipe_hw->ops.setup_format)
-			pstate->pipe_hw->ops.setup_format(pstate->pipe_hw,
+		if (pstate->pipe.sspp->ops.setup_format)
+			pstate->pipe.sspp->ops.setup_format(pstate->pipe.sspp,
 					fmt, DPU_SSPP_SOLID_FILL,
-					pstate->multirect_index);
+					pstate->pipe.multirect_index);
 
-		if (pstate->pipe_hw->ops.setup_rects)
-			pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
+		if (pstate->pipe.sspp->ops.setup_rects)
+			pstate->pipe.sspp->ops.setup_rects(pstate->pipe.sspp,
 					&pipe_cfg,
-					pstate->multirect_index);
+					pstate->pipe.multirect_index);
 
 		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
 	}
@@ -734,8 +734,8 @@ void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state)
 {
 	struct dpu_plane_state *pstate = to_dpu_plane_state(drm_state);
 
-	pstate->multirect_index = DPU_SSPP_RECT_SOLO;
-	pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+	pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
+	pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
 }
 
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
@@ -817,8 +817,8 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 
 	/* Prefer PARALLEL FETCH Mode over TIME_MX Mode */
 	if (parallel_fetch_qualified) {
-		pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
-		pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+		pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+		pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
 
 		goto done;
 	}
@@ -828,8 +828,8 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 
 	if (dst[R1].y1 >= dst[R0].y2 + buffer_lines ||
 	    dst[R0].y1 >= dst[R1].y2 + buffer_lines) {
-		pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
-		pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
+		pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
+		pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
 	} else {
 		DPU_ERROR(
 			"No multirect mode possible for the planes (%d - %d)\n",
@@ -839,13 +839,13 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 	}
 
 done:
-	pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
-	pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
+	pstate[R0]->pipe.multirect_index = DPU_SSPP_RECT_0;
+	pstate[R1]->pipe.multirect_index = DPU_SSPP_RECT_1;
 
 	DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
-		pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
+		pstate[R0]->pipe.multirect_mode, pstate[R0]->pipe.multirect_index);
 	DPU_DEBUG_PLANE(dpu_plane[R1], "R1: %d - %d\n",
-		pstate[R1]->multirect_mode, pstate[R1]->multirect_index);
+		pstate[R1]->pipe.multirect_mode, pstate[R1]->pipe.multirect_index);
 	return 0;
 }
 
@@ -937,6 +937,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	int ret = 0, min_scale;
 	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;
 	const struct drm_crtc_state *crtc_state = NULL;
 	const struct dpu_format *fmt;
 	struct drm_rect src, dst, fb_rect = { 0 };
@@ -946,10 +947,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 		crtc_state = drm_atomic_get_new_crtc_state(state,
 							   new_plane_state->crtc);
 
-	min_scale = FRAC_16_16(1, pstate->pipe_hw->cap->sblk->maxupscale);
+	min_scale = FRAC_16_16(1, pipe->sspp->cap->sblk->maxupscale);
 	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
 						  min_scale,
-						  pstate->pipe_hw->cap->sblk->maxdwnscale << 16,
+						  pipe->sspp->cap->sblk->maxdwnscale << 16,
 						  true, true);
 	if (ret) {
 		DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
@@ -975,8 +976,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
 
 	if (DPU_FORMAT_IS_YUV(fmt) &&
-		(!(pstate->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
-		 !(pstate->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
+		(!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
+		 !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
 		DPU_DEBUG_PLANE(pdpu,
 				"plane doesn't have scaler/csc for yuv\n");
 		return -EINVAL;
@@ -1037,12 +1038,12 @@ void dpu_plane_flush(struct drm_plane *plane)
 	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
 		/* force 100% alpha */
 		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
-	else if (pstate->pipe_hw && pstate->pipe_hw->ops.setup_csc) {
+	else if (pstate->pipe.sspp && pstate->pipe.sspp->ops.setup_csc) {
 		const struct dpu_format *fmt = to_dpu_format(msm_framebuffer_format(plane->state->fb));
 		const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, fmt);
 
 		if (csc_ptr)
-			pstate->pipe_hw->ops.setup_csc(pstate->pipe_hw, csc_ptr);
+			pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, csc_ptr);
 	}
 
 	/* flag h/w flush complete */
@@ -1072,6 +1073,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct drm_plane_state *state = plane->state;
 	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
+	struct dpu_sw_pipe *pipe = &pstate->pipe;
 	struct drm_crtc *crtc = state->crtc;
 	struct drm_framebuffer *fb = state->fb;
 	bool is_rt_pipe, update_qos_remap;
@@ -1109,21 +1111,21 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		return;
 	}
 
-	if (pstate->pipe_hw->ops.setup_rects) {
-		pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
+	if (pipe->sspp->ops.setup_rects) {
+		pipe->sspp->ops.setup_rects(pipe->sspp,
 				&pipe_cfg,
-				pstate->multirect_index);
+				pipe->multirect_index);
 	}
 
 	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
 
-	if (pstate->pipe_hw->ops.setup_multirect)
-		pstate->pipe_hw->ops.setup_multirect(
-				pstate->pipe_hw,
-				pstate->multirect_index,
-				pstate->multirect_mode);
+	if (pipe->sspp->ops.setup_multirect)
+		pipe->sspp->ops.setup_multirect(
+				pipe->sspp,
+				pipe->multirect_index,
+				pipe->multirect_mode);
 
-	if (pstate->pipe_hw->ops.setup_format) {
+	if (pipe->sspp->ops.setup_format) {
 		unsigned int rotation;
 
 		src_flags = 0x0;
@@ -1140,10 +1142,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			src_flags |= DPU_SSPP_FLIP_UD;
 
 		/* update format */
-		pstate->pipe_hw->ops.setup_format(pstate->pipe_hw, fmt, src_flags,
-				pstate->multirect_index);
+		pipe->sspp->ops.setup_format(pipe->sspp, fmt, src_flags,
+				pipe->multirect_index);
 
-		if (pstate->pipe_hw->ops.setup_cdp) {
+		if (pipe->sspp->ops.setup_cdp) {
 			struct dpu_hw_pipe_cdp_cfg cdp_cfg;
 
 			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
@@ -1157,7 +1159,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 					DPU_FORMAT_IS_TILE(fmt);
 			cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
 
-			pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg, pstate->multirect_index);
+			pipe->sspp->ops.setup_cdp(pipe->sspp, &cdp_cfg, pipe->multirect_index);
 		}
 	}
 
@@ -1191,7 +1193,7 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
 	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
 
 	trace_dpu_plane_disable(DRMID(plane), false,
-				pstate->multirect_mode);
+				pstate->pipe.multirect_mode);
 
 	pstate->pending = true;
 }
@@ -1305,9 +1307,9 @@ static void dpu_plane_atomic_print_state(struct drm_printer *p,
 	const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
 
 	drm_printf(p, "\tstage=%d\n", pstate->stage);
-	drm_printf(p, "\tsspp=%s\n", pstate->pipe_hw->cap->name);
-	drm_printf(p, "\tmultirect_mode=%s\n", dpu_get_multirect_mode(pstate->multirect_mode));
-	drm_printf(p, "\tmultirect_index=%s\n", dpu_get_multirect_index(pstate->multirect_index));
+	drm_printf(p, "\tsspp=%s\n", pstate->pipe.sspp->cap->name);
+	drm_printf(p, "\tmultirect_mode=%s\n", dpu_get_multirect_mode(pstate->pipe.multirect_mode));
+	drm_printf(p, "\tmultirect_index=%s\n", dpu_get_multirect_index(pstate->pipe.multirect_index));
 }
 
 static void dpu_plane_reset(struct drm_plane *plane)
@@ -1336,7 +1338,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
 		return;
 	}
 
-	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
+	pstate->pipe.sspp = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
 
 	__drm_atomic_helper_plane_reset(plane, &pstate->base);
 }
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index d745cde4ea77..b6fd6f856d6a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -31,11 +31,9 @@ struct dpu_plane_state {
 	struct msm_gem_address_space *aspace;
 	enum dpu_stage stage;
 	bool needs_qos_remap;
-	uint32_t multirect_index;
-	uint32_t multirect_mode;
 	bool pending;
 
-	struct dpu_hw_pipe *pipe_hw;
+	struct dpu_sw_pipe pipe;
 
 	u64 plane_fetch_bw;
 	u64 plane_clk;
-- 
2.34.1


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

* [PATCH 11/25] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (9 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-06 22:24   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 12/25] drm/msm/dpu: inline _dpu_plane_set_scanout Dmitry Baryshkov
                   ` (14 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Where feasible, use dpu_sw_pipe rather than a combo of dpu_hw_pipe and
multirect_index/_mode arguments.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 59 ++++++++++----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 46 ++++++---------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 62 +++++++++------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  9 ++-
 4 files changed, 77 insertions(+), 99 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 8714ee767346..d8120168f974 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -168,17 +168,16 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
 	return rc;
 }
 
-static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
-		enum dpu_sspp_multirect_index index,
-		enum dpu_sspp_multirect_mode mode)
+static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe)
 {
+	struct dpu_hw_pipe *ctx = pipe->sspp;
 	u32 mode_mask;
 	u32 idx;
 
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
 		return;
 
-	if (index == DPU_SSPP_RECT_SOLO) {
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
 		/**
 		 * if rect index is RECT_SOLO, we cannot expect a
 		 * virtual plane sharing the same SSPP id. So we go
@@ -187,8 +186,8 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
 		mode_mask = 0;
 	} else {
 		mode_mask = DPU_REG_READ(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx);
-		mode_mask |= index;
-		if (mode == DPU_SSPP_MULTIRECT_TIME_MX)
+		mode_mask |= pipe->multirect_index;
+		if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_TIME_MX)
 			mode_mask |= BIT(2);
 		else
 			mode_mask &= ~BIT(2);
@@ -239,10 +238,10 @@ static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx,
 /*
  * Setup source pixel format, flip,
  */
-static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
-		const struct dpu_format *fmt, u32 flags,
-		enum dpu_sspp_multirect_index rect_mode)
+static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe,
+		const struct dpu_format *fmt, u32 flags)
 {
+	struct dpu_hw_pipe *ctx = pipe->sspp;
 	struct dpu_hw_blk_reg_map *c;
 	u32 chroma_samp, unpack, src_format;
 	u32 opmode = 0;
@@ -253,7 +252,8 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx) || !fmt)
 		return;
 
-	if (rect_mode == DPU_SSPP_RECT_SOLO || rect_mode == DPU_SSPP_RECT_0) {
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+	    pipe->multirect_index == DPU_SSPP_RECT_0) {
 		op_mode_off = SSPP_SRC_OP_MODE;
 		unpack_pat_off = SSPP_SRC_UNPACK_PATTERN;
 		format_off = SSPP_SRC_FORMAT;
@@ -443,10 +443,10 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
 /*
  * dpu_hw_sspp_setup_rects()
  */
-static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_cfg *cfg,
-		enum dpu_sspp_multirect_index rect_index)
+static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
+		struct dpu_hw_pipe_cfg *cfg)
 {
+	struct dpu_hw_pipe *ctx = pipe->sspp;
 	struct dpu_hw_blk_reg_map *c;
 	u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
 	u32 src_size_off, src_xy_off, out_size_off, out_xy_off;
@@ -457,7 +457,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
 
 	c = &ctx->hw;
 
-	if (rect_index == DPU_SSPP_RECT_SOLO || rect_index == DPU_SSPP_RECT_0) {
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+	    pipe->multirect_index == DPU_SSPP_RECT_0) {
 		src_size_off = SSPP_SRC_SIZE;
 		src_xy_off = SSPP_SRC_XY;
 		out_size_off = SSPP_OUT_SIZE;
@@ -478,7 +479,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
 	dst_size = (drm_rect_height(&cfg->dst_rect) << 16) |
 		drm_rect_width(&cfg->dst_rect);
 
-	if (rect_index == DPU_SSPP_RECT_SOLO) {
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
 		ystride0 = (cfg->layout.plane_pitch[0]) |
 			(cfg->layout.plane_pitch[1] << 16);
 		ystride1 = (cfg->layout.plane_pitch[2]) |
@@ -487,7 +488,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
 		ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx);
 		ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx);
 
-		if (rect_index == DPU_SSPP_RECT_0) {
+		if (pipe->multirect_index == DPU_SSPP_RECT_0) {
 			ystride0 = (ystride0 & 0xFFFF0000) |
 				(cfg->layout.plane_pitch[0] & 0x0000FFFF);
 			ystride1 = (ystride1 & 0xFFFF0000)|
@@ -512,21 +513,21 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
 	DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
-static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_cfg *cfg,
-		enum dpu_sspp_multirect_index rect_mode)
+static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
+		struct dpu_hw_pipe_cfg *cfg)
 {
+	struct dpu_hw_pipe *ctx = pipe->sspp;
 	int i;
 	u32 idx;
 
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
 		return;
 
-	if (rect_mode == DPU_SSPP_RECT_SOLO) {
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
 		for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
 			DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4,
 					cfg->layout.plane_addr[i]);
-	} else if (rect_mode == DPU_SSPP_RECT_0) {
+	} else if (pipe->multirect_index == DPU_SSPP_RECT_0) {
 		DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx,
 				cfg->layout.plane_addr[0]);
 		DPU_REG_WRITE(&ctx->hw, SSPP_SRC2_ADDR + idx,
@@ -556,15 +557,16 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
 	dpu_hw_csc_setup(&ctx->hw, idx, data, csc10);
 }
 
-static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, enum
-		dpu_sspp_multirect_index rect_index)
+static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
 {
+	struct dpu_hw_pipe *ctx = pipe->sspp;
 	u32 idx;
 
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
 		return;
 
-	if (rect_index == DPU_SSPP_RECT_SOLO || rect_index == DPU_SSPP_RECT_0)
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+	    pipe->multirect_index == DPU_SSPP_RECT_0)
 		DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR + idx, color);
 	else
 		DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR_REC1 + idx,
@@ -626,10 +628,10 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe *ctx,
 	DPU_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL + idx, qos_ctrl);
 }
 
-static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_cdp_cfg *cfg,
-		enum dpu_sspp_multirect_index index)
+static void dpu_hw_sspp_setup_cdp(struct dpu_sw_pipe *pipe,
+		struct dpu_hw_pipe_cdp_cfg *cfg)
 {
+	struct dpu_hw_pipe *ctx = pipe->sspp;
 	u32 idx;
 	u32 cdp_cntl = 0;
 	u32 cdp_cntl_offset = 0;
@@ -640,7 +642,8 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
 		return;
 
-	if (index == DPU_SSPP_RECT_SOLO || index == DPU_SSPP_RECT_0)
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
+	    pipe->multirect_index == DPU_SSPP_RECT_0)
 		cdp_cntl_offset = SSPP_CDP_CNTL;
 	else
 		cdp_cntl_offset = SSPP_CDP_CNTL_REC1;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 0af2bc6e5df8..74171fb4e585 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -234,24 +234,20 @@ struct dpu_sw_pipe {
 struct dpu_hw_sspp_ops {
 	/**
 	 * setup_format - setup pixel format cropping rectangle, flip
-	 * @ctx: Pointer to pipe context
+	 * @pipe: Pointer to software pipe context
 	 * @cfg: Pointer to pipe config structure
 	 * @flags: Extra flags for format config
-	 * @index: rectangle index in multirect
 	 */
-	void (*setup_format)(struct dpu_hw_pipe *ctx,
-			const struct dpu_format *fmt, u32 flags,
-			enum dpu_sspp_multirect_index index);
+	void (*setup_format)(struct dpu_sw_pipe *pipe,
+			const struct dpu_format *fmt, u32 flags);
 
 	/**
 	 * setup_rects - setup pipe ROI rectangles
-	 * @ctx: Pointer to pipe context
+	 * @pipe: Pointer to software pipe context
 	 * @cfg: Pointer to pipe config structure
-	 * @index: rectangle index in multirect
 	 */
-	void (*setup_rects)(struct dpu_hw_pipe *ctx,
-			struct dpu_hw_pipe_cfg *cfg,
-			enum dpu_sspp_multirect_index index);
+	void (*setup_rects)(struct dpu_sw_pipe *pipe,
+			struct dpu_hw_pipe_cfg *cfg);
 
 	/**
 	 * setup_pe - setup pipe pixel extension
@@ -263,13 +259,11 @@ struct dpu_hw_sspp_ops {
 
 	/**
 	 * setup_sourceaddress - setup pipe source addresses
-	 * @ctx: Pointer to pipe context
+	 * @pipe: Pointer to software pipe context
 	 * @cfg: Pointer to pipe config structure
-	 * @index: rectangle index in multirect
 	 */
-	void (*setup_sourceaddress)(struct dpu_hw_pipe *ctx,
-			struct dpu_hw_pipe_cfg *cfg,
-			enum dpu_sspp_multirect_index index);
+	void (*setup_sourceaddress)(struct dpu_sw_pipe *ctx,
+			struct dpu_hw_pipe_cfg *cfg);
 
 	/**
 	 * setup_csc - setup color space coversion
@@ -280,24 +274,18 @@ struct dpu_hw_sspp_ops {
 
 	/**
 	 * setup_solidfill - enable/disable colorfill
-	 * @ctx: Pointer to pipe context
+	 * @pipe: Pointer to software pipe context
 	 * @const_color: Fill color value
 	 * @flags: Pipe flags
-	 * @index: rectangle index in multirect
 	 */
-	void (*setup_solidfill)(struct dpu_hw_pipe *ctx, u32 color,
-			enum dpu_sspp_multirect_index index);
+	void (*setup_solidfill)(struct dpu_sw_pipe *pipe, u32 color);
 
 	/**
 	 * setup_multirect - setup multirect configuration
-	 * @ctx: Pointer to pipe context
-	 * @index: rectangle index in multirect
-	 * @mode: parallel fetch / time multiplex multirect mode
+	 * @pipe: Pointer to software pipe context
 	 */
 
-	void (*setup_multirect)(struct dpu_hw_pipe *ctx,
-			enum dpu_sspp_multirect_index index,
-			enum dpu_sspp_multirect_mode mode);
+	void (*setup_multirect)(struct dpu_sw_pipe *pipe);
 
 	/**
 	 * setup_sharpening - setup sharpening
@@ -362,13 +350,11 @@ struct dpu_hw_sspp_ops {
 
 	/**
 	 * setup_cdp - setup client driven prefetch
-	 * @ctx: Pointer to pipe context
+	 * @pipe: Pointer to software pipe context
 	 * @cfg: Pointer to cdp configuration
-	 * @index: rectangle index in multirect
 	 */
-	void (*setup_cdp)(struct dpu_hw_pipe *ctx,
-			struct dpu_hw_pipe_cdp_cfg *cfg,
-			enum dpu_sspp_multirect_index index);
+	void (*setup_cdp)(struct dpu_sw_pipe *pipe,
+			struct dpu_hw_pipe_cdp_cfg *cfg);
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 51b5e8a3182b..d029ce806039 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -506,16 +506,13 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 	else if (ret)
 		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
 	else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
-		trace_dpu_plane_set_scanout(pstate->pipe.sspp->idx,
-					    &pipe_cfg->layout,
-					    pstate->pipe.multirect_index);
-		pstate->pipe.sspp->ops.setup_sourceaddress(pstate->pipe.sspp, pipe_cfg,
-						pstate->pipe.multirect_index);
+		trace_dpu_plane_set_scanout(&pstate->pipe,
+					    &pipe_cfg->layout);
+		pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, pipe_cfg);
 	}
 }
 
-static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
-		struct dpu_plane_state *pstate,
+static void _dpu_plane_setup_scaler3(struct dpu_hw_pipe *pipe_hw,
 		uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h,
 		struct dpu_hw_scaler3_cfg *scale_cfg,
 		struct dpu_hw_pixel_ext *pixel_ext,
@@ -553,7 +550,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 			scale_cfg->src_height[i] /= chroma_subsmpl_v;
 		}
 
-		if (pstate->pipe.sspp->cap->features &
+		if (pipe_hw->cap->features &
 			BIT(DPU_SSPP_SCALER_QSEED4)) {
 			scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
 			scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
@@ -637,11 +634,11 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
 	return csc_ptr;
 }
 
-static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
-		struct dpu_plane_state *pstate,
+static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe,
 		const struct dpu_format *fmt, bool color_fill,
 		struct dpu_hw_pipe_cfg *pipe_cfg)
 {
+	struct dpu_hw_pipe *pipe_hw = pipe->sspp;
 	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
 	struct dpu_hw_scaler3_cfg scaler3_cfg;
 	struct dpu_hw_pixel_ext pixel_ext;
@@ -651,7 +648,7 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 
 	/* don't chroma subsample if decimating */
 	/* update scaler. calculate default config for QSEED3 */
-	_dpu_plane_setup_scaler3(pdpu, pstate,
+	_dpu_plane_setup_scaler3(pipe_hw,
 			drm_rect_width(&pipe_cfg->src_rect),
 			drm_rect_height(&pipe_cfg->src_rect),
 			drm_rect_width(&pipe_cfg->dst_rect),
@@ -659,8 +656,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 			&scaler3_cfg, &pixel_ext, fmt,
 			info->hsub, info->vsub);
 
-	if (pstate->pipe.sspp->ops.setup_pe)
-		pstate->pipe.sspp->ops.setup_pe(pstate->pipe.sspp,
+	if (pipe_hw->ops.setup_pe)
+		pipe_hw->ops.setup_pe(pipe_hw,
 				&pixel_ext);
 
 	/**
@@ -668,9 +665,9 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 	 * bypassed. Still we need to update alpha and bitwidth
 	 * ONLY for RECT0
 	 */
-	if (pstate->pipe.sspp->ops.setup_scaler &&
-			pstate->pipe.multirect_index != DPU_SSPP_RECT_1)
-		pstate->pipe.sspp->ops.setup_scaler(pstate->pipe.sspp,
+	if (pipe_hw->ops.setup_scaler &&
+			pipe->multirect_index != DPU_SSPP_RECT_1)
+		pipe_hw->ops.setup_scaler(pipe_hw,
 				pipe_cfg,
 				&scaler3_cfg);
 }
@@ -700,9 +697,8 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 
 	/* update sspp */
 	if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
-		pstate->pipe.sspp->ops.setup_solidfill(pstate->pipe.sspp,
-				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
-				pstate->pipe.multirect_index);
+		pstate->pipe.sspp->ops.setup_solidfill(&pstate->pipe,
+				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24));
 
 		/* override scaler/decimation if solid fill */
 		pipe_cfg.dst_rect = pstate->base.dst;
@@ -715,16 +711,14 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 			drm_rect_height(&pipe_cfg.dst_rect);
 
 		if (pstate->pipe.sspp->ops.setup_format)
-			pstate->pipe.sspp->ops.setup_format(pstate->pipe.sspp,
-					fmt, DPU_SSPP_SOLID_FILL,
-					pstate->pipe.multirect_index);
+			pstate->pipe.sspp->ops.setup_format(&pstate->pipe,
+					fmt, DPU_SSPP_SOLID_FILL);
 
 		if (pstate->pipe.sspp->ops.setup_rects)
-			pstate->pipe.sspp->ops.setup_rects(pstate->pipe.sspp,
-					&pipe_cfg,
-					pstate->pipe.multirect_index);
+			pstate->pipe.sspp->ops.setup_rects(&pstate->pipe,
+					&pipe_cfg);
 
-		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
+		_dpu_plane_setup_scaler(&pstate->pipe, fmt, true, &pipe_cfg);
 	}
 
 	return 0;
@@ -1112,18 +1106,15 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	}
 
 	if (pipe->sspp->ops.setup_rects) {
-		pipe->sspp->ops.setup_rects(pipe->sspp,
-				&pipe_cfg,
-				pipe->multirect_index);
+		pipe->sspp->ops.setup_rects(pipe,
+				&pipe_cfg);
 	}
 
-	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
+	_dpu_plane_setup_scaler(pipe, fmt, false, &pipe_cfg);
 
 	if (pipe->sspp->ops.setup_multirect)
 		pipe->sspp->ops.setup_multirect(
-				pipe->sspp,
-				pipe->multirect_index,
-				pipe->multirect_mode);
+				pipe);
 
 	if (pipe->sspp->ops.setup_format) {
 		unsigned int rotation;
@@ -1142,8 +1133,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			src_flags |= DPU_SSPP_FLIP_UD;
 
 		/* update format */
-		pipe->sspp->ops.setup_format(pipe->sspp, fmt, src_flags,
-				pipe->multirect_index);
+		pipe->sspp->ops.setup_format(pipe, fmt, src_flags);
 
 		if (pipe->sspp->ops.setup_cdp) {
 			struct dpu_hw_pipe_cdp_cfg cdp_cfg;
@@ -1159,7 +1149,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 					DPU_FORMAT_IS_TILE(fmt);
 			cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
 
-			pipe->sspp->ops.setup_cdp(pipe->sspp, &cdp_cfg, pipe->multirect_index);
+			pipe->sspp->ops.setup_cdp(pipe, &cdp_cfg);
 		}
 	}
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
index ecd2f371374d..11b61f9777eb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -759,18 +759,17 @@ TRACE_EVENT(dpu_crtc_disable_frame_pending,
 );
 
 TRACE_EVENT(dpu_plane_set_scanout,
-	TP_PROTO(enum dpu_sspp index, struct dpu_hw_fmt_layout *layout,
-		 enum dpu_sspp_multirect_index multirect_index),
-	TP_ARGS(index, layout, multirect_index),
+	TP_PROTO(struct dpu_sw_pipe *pipe, struct dpu_hw_fmt_layout *layout),
+	TP_ARGS(pipe, layout),
 	TP_STRUCT__entry(
 		__field(	enum dpu_sspp,			index	)
 		__field_struct(	struct dpu_hw_fmt_layout,	layout	)
 		__field(	enum dpu_sspp_multirect_index,	multirect_index)
 	),
 	TP_fast_assign(
-		__entry->index = index;
+		__entry->index = pipe->sspp.idx;
 		__entry->layout = *layout;
-		__entry->multirect_index = multirect_index;
+		__entry->multirect_index = pipe->multirect_index;
 	),
 	TP_printk("index:%d layout:{%ux%u @ [%u/%u, %u/%u, %u/%u, %u/%u]} "
 		  "multirect_index:%d", __entry->index, __entry->layout.width,
-- 
2.34.1


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

* [PATCH 12/25] drm/msm/dpu: inline _dpu_plane_set_scanout
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (10 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 11/25] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-06 23:33   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 13/25] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3() Dmitry Baryshkov
                   ` (13 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

In preparation to reworking dpu_plane_sspp_atomic_update() inline the
_dpu_plane_set_scanout() function.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 41 ++++++++++-------------
 1 file changed, 18 insertions(+), 23 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index d029ce806039..3ce7dcc285e2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -490,28 +490,6 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
 	dpu_vbif_set_qos_remap(dpu_kms, &qos_params);
 }
 
-static void _dpu_plane_set_scanout(struct drm_plane *plane,
-		struct dpu_plane_state *pstate,
-		struct dpu_hw_pipe_cfg *pipe_cfg,
-		struct drm_framebuffer *fb)
-{
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
-	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
-	struct msm_gem_address_space *aspace = kms->base.aspace;
-	int ret;
-
-	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout);
-	if (ret == -EAGAIN)
-		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
-	else if (ret)
-		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-	else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
-		trace_dpu_plane_set_scanout(&pstate->pipe,
-					    &pipe_cfg->layout);
-		pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, pipe_cfg);
-	}
-}
-
 static void _dpu_plane_setup_scaler3(struct dpu_hw_pipe *pipe_hw,
 		uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h,
 		struct dpu_hw_scaler3_cfg *scale_cfg,
@@ -1074,10 +1052,27 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	const struct dpu_format *fmt =
 		to_dpu_format(msm_framebuffer_format(fb));
 	struct dpu_hw_pipe_cfg pipe_cfg;
+	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
+	struct msm_gem_address_space *aspace = kms->base.aspace;
+	bool update_src_addr = true;
+	int ret;
 
 	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
 
-	_dpu_plane_set_scanout(plane, pstate, &pipe_cfg, fb);
+	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg.layout);
+	if (ret == -EAGAIN) {
+		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
+		update_src_addr = false;
+	} else if (ret) {
+		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
+		update_src_addr = false;
+	}
+
+	if (update_src_addr &&
+	    pipe->sspp->ops.setup_sourceaddress) {
+		trace_dpu_plane_set_scanout(pipe, &pipe_cfg.layout);
+		pipe->sspp->ops.setup_sourceaddress(pipe, &pipe_cfg);
+	}
 
 	pstate->pending = true;
 
-- 
2.34.1


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

* [PATCH 13/25] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (11 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 12/25] drm/msm/dpu: inline _dpu_plane_set_scanout Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-09 22:30   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 14/25] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress Dmitry Baryshkov
                   ` (12 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

There is no need to pass full dpu_hw_pipe_cfg instance to
_dpu_hw_sspp_setup_scaler3, pass just struct dpu_format pointer.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 9 ++++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 7 +++----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 4 ++--
 3 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index d8120168f974..7194c14f87bc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -415,19 +415,18 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
 }
 
 static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_cfg *sspp,
-		void *scaler_cfg)
+		struct dpu_hw_scaler3_cfg *scaler3_cfg,
+		const struct dpu_format *format)
 {
 	u32 idx;
-	struct dpu_hw_scaler3_cfg *scaler3_cfg = scaler_cfg;
 
-	if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) || !sspp
+	if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx)
 		|| !scaler3_cfg)
 		return;
 
 	dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg, idx,
 			ctx->cap->sblk->scaler_blk.version,
-			sspp->layout.format);
+			format);
 }
 
 static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 74171fb4e585..eee8501ea80d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -334,13 +334,12 @@ struct dpu_hw_sspp_ops {
 
 	/**
 	 * setup_scaler - setup scaler
-	 * @ctx: Pointer to pipe context
-	 * @pipe_cfg: Pointer to pipe configuration
 	 * @scaler_cfg: Pointer to scaler configuration
+	 * @format: pixel format parameters
 	 */
 	void (*setup_scaler)(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_cfg *pipe_cfg,
-		void *scaler_cfg);
+		struct dpu_hw_scaler3_cfg *scaler3_cfg,
+		const struct dpu_format *format);
 
 	/**
 	 * get_scaler_ver - get scaler h/w version
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 3ce7dcc285e2..e9421fa2fb2e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -646,8 +646,8 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe,
 	if (pipe_hw->ops.setup_scaler &&
 			pipe->multirect_index != DPU_SSPP_RECT_1)
 		pipe_hw->ops.setup_scaler(pipe_hw,
-				pipe_cfg,
-				&scaler3_cfg);
+				&scaler3_cfg,
+				fmt);
 }
 
 /**
-- 
2.34.1


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

* [PATCH 14/25] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (12 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 13/25] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3() Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-13 18:50   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 15/25] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg Dmitry Baryshkov
                   ` (11 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Move stride programming to dpu_hw_sspp_setup_sourceaddress(), so that
dpu_hw_sspp_setup_rects() programs only source and destination
rectangles.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 57 +++++++++++----------
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 7194c14f87bc..2186506e6315 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -447,7 +447,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
 {
 	struct dpu_hw_pipe *ctx = pipe->sspp;
 	struct dpu_hw_blk_reg_map *c;
-	u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
+	u32 src_size, src_xy, dst_size, dst_xy;
 	u32 src_size_off, src_xy_off, out_size_off, out_xy_off;
 	u32 idx;
 
@@ -478,44 +478,18 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
 	dst_size = (drm_rect_height(&cfg->dst_rect) << 16) |
 		drm_rect_width(&cfg->dst_rect);
 
-	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
-		ystride0 = (cfg->layout.plane_pitch[0]) |
-			(cfg->layout.plane_pitch[1] << 16);
-		ystride1 = (cfg->layout.plane_pitch[2]) |
-			(cfg->layout.plane_pitch[3] << 16);
-	} else {
-		ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx);
-		ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx);
-
-		if (pipe->multirect_index == DPU_SSPP_RECT_0) {
-			ystride0 = (ystride0 & 0xFFFF0000) |
-				(cfg->layout.plane_pitch[0] & 0x0000FFFF);
-			ystride1 = (ystride1 & 0xFFFF0000)|
-				(cfg->layout.plane_pitch[2] & 0x0000FFFF);
-		} else {
-			ystride0 = (ystride0 & 0x0000FFFF) |
-				((cfg->layout.plane_pitch[0] << 16) &
-				 0xFFFF0000);
-			ystride1 = (ystride1 & 0x0000FFFF) |
-				((cfg->layout.plane_pitch[2] << 16) &
-				 0xFFFF0000);
-		}
-	}
-
 	/* rectangle register programming */
 	DPU_REG_WRITE(c, src_size_off + idx, src_size);
 	DPU_REG_WRITE(c, src_xy_off + idx, src_xy);
 	DPU_REG_WRITE(c, out_size_off + idx, dst_size);
 	DPU_REG_WRITE(c, out_xy_off + idx, dst_xy);
-
-	DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
-	DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
 static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
 		struct dpu_hw_pipe_cfg *cfg)
 {
 	struct dpu_hw_pipe *ctx = pipe->sspp;
+	u32 ystride0, ystride1;
 	int i;
 	u32 idx;
 
@@ -537,6 +511,33 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
 		DPU_REG_WRITE(&ctx->hw, SSPP_SRC3_ADDR + idx,
 				cfg->layout.plane_addr[2]);
 	}
+
+	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
+		ystride0 = (cfg->layout.plane_pitch[0]) |
+			(cfg->layout.plane_pitch[1] << 16);
+		ystride1 = (cfg->layout.plane_pitch[2]) |
+			(cfg->layout.plane_pitch[3] << 16);
+	} else {
+		ystride0 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx);
+		ystride1 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx);
+
+		if (pipe->multirect_index == DPU_SSPP_RECT_0) {
+			ystride0 = (ystride0 & 0xFFFF0000) |
+				(cfg->layout.plane_pitch[0] & 0x0000FFFF);
+			ystride1 = (ystride1 & 0xFFFF0000)|
+				(cfg->layout.plane_pitch[2] & 0x0000FFFF);
+		} else {
+			ystride0 = (ystride0 & 0x0000FFFF) |
+				((cfg->layout.plane_pitch[0] << 16) &
+				 0xFFFF0000);
+			ystride1 = (ystride1 & 0x0000FFFF) |
+				((cfg->layout.plane_pitch[2] << 16) &
+				 0xFFFF0000);
+		}
+	}
+
+	DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx, ystride0);
+	DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
 static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
-- 
2.34.1


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

* [PATCH 15/25] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (13 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 14/25] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-13 18:58   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 16/25] drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout Dmitry Baryshkov
                   ` (10 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Remove dpu_hw_fmt_layout instance from struct dpu_hw_fmt_layout, leaving
only src_rect and dst_rect.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 30 ++++++++++-----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  6 ++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  7 ++---
 3 files changed, 21 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 2186506e6315..df6698778b6d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -486,7 +486,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
 }
 
 static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
-		struct dpu_hw_pipe_cfg *cfg)
+		struct dpu_hw_fmt_layout *layout)
 {
 	struct dpu_hw_pipe *ctx = pipe->sspp;
 	u32 ystride0, ystride1;
@@ -497,41 +497,41 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
 		return;
 
 	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
-		for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
+		for (i = 0; i < ARRAY_SIZE(layout->plane_addr); i++)
 			DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4,
-					cfg->layout.plane_addr[i]);
+					layout->plane_addr[i]);
 	} else if (pipe->multirect_index == DPU_SSPP_RECT_0) {
 		DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx,
-				cfg->layout.plane_addr[0]);
+				layout->plane_addr[0]);
 		DPU_REG_WRITE(&ctx->hw, SSPP_SRC2_ADDR + idx,
-				cfg->layout.plane_addr[2]);
+				layout->plane_addr[2]);
 	} else {
 		DPU_REG_WRITE(&ctx->hw, SSPP_SRC1_ADDR + idx,
-				cfg->layout.plane_addr[0]);
+				layout->plane_addr[0]);
 		DPU_REG_WRITE(&ctx->hw, SSPP_SRC3_ADDR + idx,
-				cfg->layout.plane_addr[2]);
+				layout->plane_addr[2]);
 	}
 
 	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
-		ystride0 = (cfg->layout.plane_pitch[0]) |
-			(cfg->layout.plane_pitch[1] << 16);
-		ystride1 = (cfg->layout.plane_pitch[2]) |
-			(cfg->layout.plane_pitch[3] << 16);
+		ystride0 = (layout->plane_pitch[0]) |
+			(layout->plane_pitch[1] << 16);
+		ystride1 = (layout->plane_pitch[2]) |
+			(layout->plane_pitch[3] << 16);
 	} else {
 		ystride0 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx);
 		ystride1 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx);
 
 		if (pipe->multirect_index == DPU_SSPP_RECT_0) {
 			ystride0 = (ystride0 & 0xFFFF0000) |
-				(cfg->layout.plane_pitch[0] & 0x0000FFFF);
+				(layout->plane_pitch[0] & 0x0000FFFF);
 			ystride1 = (ystride1 & 0xFFFF0000)|
-				(cfg->layout.plane_pitch[2] & 0x0000FFFF);
+				(layout->plane_pitch[2] & 0x0000FFFF);
 		} else {
 			ystride0 = (ystride0 & 0x0000FFFF) |
-				((cfg->layout.plane_pitch[0] << 16) &
+				((layout->plane_pitch[0] << 16) &
 				 0xFFFF0000);
 			ystride1 = (ystride1 & 0x0000FFFF) |
-				((cfg->layout.plane_pitch[2] << 16) &
+				((layout->plane_pitch[2] << 16) &
 				 0xFFFF0000);
 		}
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index eee8501ea80d..93b60545ba98 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -155,13 +155,11 @@ struct dpu_hw_pixel_ext {
 
 /**
  * struct dpu_hw_pipe_cfg : Pipe description
- * @layout:    format layout information for programming buffer to hardware
  * @src_rect:  src ROI, caller takes into account the different operations
  *             such as decimation, flip etc to program this field
  * @dest_rect: destination ROI.
  */
 struct dpu_hw_pipe_cfg {
-	struct dpu_hw_fmt_layout layout;
 	struct drm_rect src_rect;
 	struct drm_rect dst_rect;
 };
@@ -260,10 +258,10 @@ struct dpu_hw_sspp_ops {
 	/**
 	 * setup_sourceaddress - setup pipe source addresses
 	 * @pipe: Pointer to software pipe context
-	 * @cfg: Pointer to pipe config structure
+	 * @layout: format layout information for programming buffer to hardware
 	 */
 	void (*setup_sourceaddress)(struct dpu_sw_pipe *ctx,
-			struct dpu_hw_pipe_cfg *cfg);
+			struct dpu_hw_fmt_layout *layout);
 
 	/**
 	 * setup_csc - setup color space coversion
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index e9421fa2fb2e..a521c0681af6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1052,6 +1052,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	const struct dpu_format *fmt =
 		to_dpu_format(msm_framebuffer_format(fb));
 	struct dpu_hw_pipe_cfg pipe_cfg;
+	struct dpu_hw_fmt_layout layout;
 	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
 	struct msm_gem_address_space *aspace = kms->base.aspace;
 	bool update_src_addr = true;
@@ -1059,7 +1060,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
 
-	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg.layout);
+	ret = dpu_format_populate_layout(aspace, fb, &layout);
 	if (ret == -EAGAIN) {
 		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
 		update_src_addr = false;
@@ -1070,8 +1071,8 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 	if (update_src_addr &&
 	    pipe->sspp->ops.setup_sourceaddress) {
-		trace_dpu_plane_set_scanout(pipe, &pipe_cfg.layout);
-		pipe->sspp->ops.setup_sourceaddress(pipe, &pipe_cfg);
+		trace_dpu_plane_set_scanout(pipe, &layout);
+		pipe->sspp->ops.setup_sourceaddress(pipe, &layout);
 	}
 
 	pstate->pending = true;
-- 
2.34.1


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

* [PATCH 16/25] drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (14 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 15/25] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-13 19:03   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 17/25] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check Dmitry Baryshkov
                   ` (9 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Since layout is not cached anymore, drop comparison against previous
layout and corresponding EAGAIN handling.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 4 ----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 5 +----
 2 files changed, 1 insertion(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
index 440ae93d7bd1..5c7d739143f0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
@@ -927,10 +927,6 @@ int dpu_format_populate_layout(
 	else
 		ret = _dpu_format_populate_addrs_linear(aspace, fb, layout);
 
-	/* check if anything changed */
-	if (!ret && !memcmp(plane_addr, layout->plane_addr, sizeof(plane_addr)))
-		ret = -EAGAIN;
-
 	return ret;
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index a521c0681af6..b2395f02f6d3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1061,10 +1061,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
 
 	ret = dpu_format_populate_layout(aspace, fb, &layout);
-	if (ret == -EAGAIN) {
-		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
-		update_src_addr = false;
-	} else if (ret) {
+	if (ret) {
 		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
 		update_src_addr = false;
 	}
-- 
2.34.1


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

* [PATCH 17/25] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (15 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 16/25] drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-26 22:59   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 18/25] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check() Dmitry Baryshkov
                   ` (8 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Neither source split nor multirect are properly supported at this
moment. Both of these checks depend on normalized_zpos being equal for
several planes (which is never the case for normalized zpos).
Drop these checks to simplify dpu_crtc_atomic_check(). The actual
support for either of these features is not removed from the backend
code (sspp, ctl, etc).

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 166 ++---------------------
 1 file changed, 12 insertions(+), 154 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 751c64012058..cbd0e50c2bd3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1046,13 +1046,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
 	drm_crtc_vblank_on(crtc);
 }
 
-struct plane_state {
-	struct dpu_plane_state *dpu_pstate;
-	const struct drm_plane_state *drm_pstate;
-	int stage;
-	u32 pipe_id;
-};
-
 static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		struct drm_atomic_state *state)
 {
@@ -1060,28 +1053,21 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 									  crtc);
 	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
 	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
-	struct plane_state *pstates;
 
 	const struct drm_plane_state *pstate;
 	struct drm_plane *plane;
 	struct drm_display_mode *mode;
 
-	int cnt = 0, rc = 0, mixer_width = 0, i, z_pos;
+	int rc = 0;
 
-	struct dpu_multirect_plane_states multirect_plane[DPU_STAGE_MAX * 2];
-	int multirect_count = 0;
-	const struct drm_plane_state *pipe_staged[SSPP_MAX];
-	int left_zpos_cnt = 0, right_zpos_cnt = 0;
 	struct drm_rect crtc_rect = { 0 };
 
-	pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
-
 	if (!crtc_state->enable || !crtc_state->active) {
 		DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n",
 				crtc->base.id, crtc_state->enable,
 				crtc_state->active);
 		memset(&cstate->new_perf, 0, sizeof(cstate->new_perf));
-		goto end;
+		return 0;
 	}
 
 	mode = &crtc_state->adjusted_mode;
@@ -1091,13 +1077,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	if (crtc_state->active_changed)
 		crtc_state->mode_changed = true;
 
-	memset(pipe_staged, 0, sizeof(pipe_staged));
-
-	if (cstate->num_mixers) {
-		mixer_width = mode->hdisplay / cstate->num_mixers;
-
+	if (cstate->num_mixers)
 		_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
-	}
 
 	crtc_rect.x2 = mode->hdisplay;
 	crtc_rect.y2 = mode->vdisplay;
@@ -1105,33 +1086,16 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	 /* get plane state for all drm planes associated with crtc state */
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
 		struct drm_rect dst, clip = crtc_rect;
+		int z_pos;
 
 		if (IS_ERR_OR_NULL(pstate)) {
 			rc = PTR_ERR(pstate);
 			DPU_ERROR("%s: failed to get plane%d state, %d\n",
 					dpu_crtc->name, plane->base.id, rc);
-			goto end;
-		}
-		if (cnt >= DPU_STAGE_MAX * 4)
-			continue;
-
-		pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
-		pstates[cnt].drm_pstate = pstate;
-		pstates[cnt].stage = pstate->normalized_zpos;
-		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx;
-
-		if (pipe_staged[pstates[cnt].pipe_id]) {
-			multirect_plane[multirect_count].r0 =
-				pipe_staged[pstates[cnt].pipe_id];
-			multirect_plane[multirect_count].r1 = pstate;
-			multirect_count++;
-
-			pipe_staged[pstates[cnt].pipe_id] = NULL;
-		} else {
-			pipe_staged[pstates[cnt].pipe_id] = pstate;
+			return rc;
 		}
 
-		cnt++;
+		dpu_plane_clear_multirect(pstate);
 
 		dst = drm_plane_state_dest(pstate);
 		if (!drm_rect_intersect(&clip, &dst)) {
@@ -1139,63 +1103,21 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 			DPU_ERROR("display: " DRM_RECT_FMT " plane: "
 				  DRM_RECT_FMT "\n", DRM_RECT_ARG(&crtc_rect),
 				  DRM_RECT_ARG(&dst));
-			rc = -E2BIG;
-			goto end;
+			return -E2BIG;
 		}
-	}
-
-	for (i = 1; i < SSPP_MAX; i++) {
-		if (pipe_staged[i])
-			dpu_plane_clear_multirect(pipe_staged[i]);
-	}
 
-	z_pos = -1;
-	for (i = 0; i < cnt; i++) {
-		/* reset counts at every new blend stage */
-		if (pstates[i].stage != z_pos) {
-			left_zpos_cnt = 0;
-			right_zpos_cnt = 0;
-			z_pos = pstates[i].stage;
-		}
+		z_pos = pstate->normalized_zpos;
 
 		/* verify z_pos setting before using it */
 		if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
 			DPU_ERROR("> %d plane stages assigned\n",
 					DPU_STAGE_MAX - DPU_STAGE_0);
-			rc = -EINVAL;
-			goto end;
-		} else if (pstates[i].drm_pstate->crtc_x < mixer_width) {
-			if (left_zpos_cnt == 2) {
-				DPU_ERROR("> 2 planes @ stage %d on left\n",
-					z_pos);
-				rc = -EINVAL;
-				goto end;
-			}
-			left_zpos_cnt++;
-
-		} else {
-			if (right_zpos_cnt == 2) {
-				DPU_ERROR("> 2 planes @ stage %d on right\n",
-					z_pos);
-				rc = -EINVAL;
-				goto end;
-			}
-			right_zpos_cnt++;
+			return -EINVAL;
 		}
 
-		pstates[i].dpu_pstate->stage = z_pos + DPU_STAGE_0;
+		to_dpu_plane_state(pstate)->stage = z_pos + DPU_STAGE_0;
 		DRM_DEBUG_ATOMIC("%s: zpos %d\n", dpu_crtc->name, z_pos);
-	}
 
-	for (i = 0; i < multirect_count; i++) {
-		if (dpu_plane_validate_multirect_v2(&multirect_plane[i])) {
-			DPU_ERROR(
-			"multirect validation failed for planes (%d - %d)\n",
-					multirect_plane[i].r0->plane->base.id,
-					multirect_plane[i].r1->plane->base.id);
-			rc = -EINVAL;
-			goto end;
-		}
 	}
 
 	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
@@ -1204,74 +1126,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	if (rc) {
 		DPU_ERROR("crtc%d failed performance check %d\n",
 				crtc->base.id, rc);
-		goto end;
-	}
-
-	/* validate source split:
-	 * use pstates sorted by stage to check planes on same stage
-	 * we assume that all pipes are in source split so its valid to compare
-	 * without taking into account left/right mixer placement
-	 */
-	for (i = 1; i < cnt; i++) {
-		struct plane_state *prv_pstate, *cur_pstate;
-		struct drm_rect left_rect, right_rect;
-		int32_t left_pid, right_pid;
-		int32_t stage;
-
-		prv_pstate = &pstates[i - 1];
-		cur_pstate = &pstates[i];
-		if (prv_pstate->stage != cur_pstate->stage)
-			continue;
-
-		stage = cur_pstate->stage;
-
-		left_pid = prv_pstate->dpu_pstate->base.plane->base.id;
-		left_rect = drm_plane_state_dest(prv_pstate->drm_pstate);
-
-		right_pid = cur_pstate->dpu_pstate->base.plane->base.id;
-		right_rect = drm_plane_state_dest(cur_pstate->drm_pstate);
-
-		if (right_rect.x1 < left_rect.x1) {
-			swap(left_pid, right_pid);
-			swap(left_rect, right_rect);
-		}
-
-		/**
-		 * - planes are enumerated in pipe-priority order such that
-		 *   planes with lower drm_id must be left-most in a shared
-		 *   blend-stage when using source split.
-		 * - planes in source split must be contiguous in width
-		 * - planes in source split must have same dest yoff and height
-		 */
-		if (right_pid < left_pid) {
-			DPU_ERROR(
-				"invalid src split cfg. priority mismatch. stage: %d left: %d right: %d\n",
-				stage, left_pid, right_pid);
-			rc = -EINVAL;
-			goto end;
-		} else if (right_rect.x1 != drm_rect_width(&left_rect)) {
-			DPU_ERROR("non-contiguous coordinates for src split. "
-				  "stage: %d left: " DRM_RECT_FMT " right: "
-				  DRM_RECT_FMT "\n", stage,
-				  DRM_RECT_ARG(&left_rect),
-				  DRM_RECT_ARG(&right_rect));
-			rc = -EINVAL;
-			goto end;
-		} else if (left_rect.y1 != right_rect.y1 ||
-			   drm_rect_height(&left_rect) != drm_rect_height(&right_rect)) {
-			DPU_ERROR("source split at stage: %d. invalid "
-				  "yoff/height: left: " DRM_RECT_FMT " right: "
-				  DRM_RECT_FMT "\n", stage,
-				  DRM_RECT_ARG(&left_rect),
-				  DRM_RECT_ARG(&right_rect));
-			rc = -EINVAL;
-			goto end;
-		}
+		return rc;
 	}
 
-end:
-	kfree(pstates);
-	return rc;
+	return 0;
 }
 
 int dpu_crtc_vblank(struct drm_crtc *crtc, bool en)
-- 
2.34.1


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

* [PATCH 18/25] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (16 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 17/25] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-27  0:14   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 19/25] drm/msm/dpu: don't use unsupported blend stages Dmitry Baryshkov
                   ` (7 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Remove plane checks/state updates from dpu_crtc_atomic_check(). The
belong to dpu_plane_atomic_check().

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 44 -----------------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 +++++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ----
 3 files changed, 10 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index cbd0e50c2bd3..fa279f0358d6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1054,14 +1054,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
 	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
 
-	const struct drm_plane_state *pstate;
-	struct drm_plane *plane;
 	struct drm_display_mode *mode;
 
 	int rc = 0;
 
-	struct drm_rect crtc_rect = { 0 };
-
 	if (!crtc_state->enable || !crtc_state->active) {
 		DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n",
 				crtc->base.id, crtc_state->enable,
@@ -1080,46 +1076,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	if (cstate->num_mixers)
 		_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
 
-	crtc_rect.x2 = mode->hdisplay;
-	crtc_rect.y2 = mode->vdisplay;
-
-	 /* get plane state for all drm planes associated with crtc state */
-	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
-		struct drm_rect dst, clip = crtc_rect;
-		int z_pos;
-
-		if (IS_ERR_OR_NULL(pstate)) {
-			rc = PTR_ERR(pstate);
-			DPU_ERROR("%s: failed to get plane%d state, %d\n",
-					dpu_crtc->name, plane->base.id, rc);
-			return rc;
-		}
-
-		dpu_plane_clear_multirect(pstate);
-
-		dst = drm_plane_state_dest(pstate);
-		if (!drm_rect_intersect(&clip, &dst)) {
-			DPU_ERROR("invalid vertical/horizontal destination\n");
-			DPU_ERROR("display: " DRM_RECT_FMT " plane: "
-				  DRM_RECT_FMT "\n", DRM_RECT_ARG(&crtc_rect),
-				  DRM_RECT_ARG(&dst));
-			return -E2BIG;
-		}
-
-		z_pos = pstate->normalized_zpos;
-
-		/* verify z_pos setting before using it */
-		if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
-			DPU_ERROR("> %d plane stages assigned\n",
-					DPU_STAGE_MAX - DPU_STAGE_0);
-			return -EINVAL;
-		}
-
-		to_dpu_plane_state(pstate)->stage = z_pos + DPU_STAGE_0;
-		DRM_DEBUG_ATOMIC("%s: zpos %d\n", dpu_crtc->name, z_pos);
-
-	}
-
 	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
 
 	rc = dpu_core_perf_crtc_check(crtc, crtc_state);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index b2395f02f6d3..637d164667e9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -702,14 +702,6 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 	return 0;
 }
 
-void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state)
-{
-	struct dpu_plane_state *pstate = to_dpu_plane_state(drm_state);
-
-	pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
-	pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
-}
-
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 {
 	struct dpu_plane_state *pstate[R_MAX];
@@ -931,6 +923,16 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	if (!new_plane_state->visible)
 		return 0;
 
+	pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
+	pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
+	pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
+	if (pstate->stage >= DPU_STAGE_MAX) {
+		DPU_ERROR("> %d plane stages assigned\n",
+				DPU_STAGE_MAX - DPU_STAGE_0);
+		return -EINVAL;
+	}
+
 	src.x1 = new_plane_state->src_x >> 16;
 	src.y1 = new_plane_state->src_y >> 16;
 	src.x2 = src.x1 + (new_plane_state->src_w >> 16);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index b6fd6f856d6a..e61c57b045ea 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -83,12 +83,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
  */
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane);
 
-/**
- * dpu_plane_clear_multirect - clear multirect bits for the given pipe
- * @drm_state: Pointer to DRM plane state
- */
-void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state);
-
 /**
  * dpu_plane_color_fill - enables color fill on plane
  * @plane:  Pointer to DRM plane object
-- 
2.34.1


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

* [PATCH 19/25] drm/msm/dpu: don't use unsupported blend stages
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (17 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 18/25] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check() Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-05-14  1:57   ` Abhinav Kumar
  2022-02-09 17:25 ` [PATCH 20/25] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state Dmitry Baryshkov
                   ` (6 subsequent siblings)
  25 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

The atomic_check compares blending stage with DPU_STAGE_MAX (maximum
amount of blending stages supported by the driver), however we should
compare it against .max_mixer_blendstages, the maximum blend stage
supported by the mixer.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 637d164667e9..952ff11162c0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -927,9 +927,9 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
 
 	pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
-	if (pstate->stage >= DPU_STAGE_MAX) {
+	if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
 		DPU_ERROR("> %d plane stages assigned\n",
-				DPU_STAGE_MAX - DPU_STAGE_0);
+				pdpu->catalog->caps->max_mixer_blendstages - DPU_STAGE_0);
 		return -EINVAL;
 	}
 
-- 
2.34.1


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

* [PATCH 20/25] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (18 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 19/25] drm/msm/dpu: don't use unsupported blend stages Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-02-09 17:25 ` [PATCH 21/25] drm/msm/dpu: simplify dpu_plane_validate_src() Dmitry Baryshkov
                   ` (5 subsequent siblings)
  25 siblings, 0 replies; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Now as all accesses to pipe_cfg and pstate have been cleaned, re-add
struct dpu_hw_pipe_cfg back to dpu_plane_state, so that
dpu_plane_atomic_check() and dpu_plane_atomic_update() do not have a
chance to disagree about src/dst rectangles (currently
dpu_plane_atomic_check() uses unclipped rectangles, while
dpu_plane_atomic_update() uses clipped rectangles calculated by
drm_atomic_helper_check_plane_state()).

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 62 ++++++++++-------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  1 +
 2 files changed, 28 insertions(+), 35 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 952ff11162c0..863aedcda66e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -904,7 +904,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	struct dpu_sw_pipe *pipe = &pstate->pipe;
 	const struct drm_crtc_state *crtc_state = NULL;
 	const struct dpu_format *fmt;
-	struct drm_rect src, dst, fb_rect = { 0 };
+	struct dpu_hw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+	struct drm_rect fb_rect = { 0 };
 	uint32_t min_src_size, max_linewidth;
 
 	if (new_plane_state->crtc)
@@ -933,12 +934,15 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 		return -EINVAL;
 	}
 
-	src.x1 = new_plane_state->src_x >> 16;
-	src.y1 = new_plane_state->src_y >> 16;
-	src.x2 = src.x1 + (new_plane_state->src_w >> 16);
-	src.y2 = src.y1 + (new_plane_state->src_h >> 16);
+	pipe_cfg->src_rect = new_plane_state->src;
 
-	dst = drm_plane_state_dest(new_plane_state);
+	/* state->src is 16.16, src_rect is not */
+	pipe_cfg->src_rect.x1 >>= 16;
+	pipe_cfg->src_rect.x2 >>= 16;
+	pipe_cfg->src_rect.y1 >>= 16;
+	pipe_cfg->src_rect.y2 >>= 16;
+
+	pipe_cfg->dst_rect = new_plane_state->dst;
 
 	fb_rect.x2 = new_plane_state->fb->width;
 	fb_rect.y2 = new_plane_state->fb->height;
@@ -957,30 +961,30 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 		return -EINVAL;
 
 	/* check src bounds */
-	} else if (!dpu_plane_validate_src(&src, &fb_rect, min_src_size)) {
+	} else if (!dpu_plane_validate_src(&pipe_cfg->src_rect, &fb_rect, min_src_size)) {
 		DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
-				DRM_RECT_ARG(&src));
+				DRM_RECT_ARG(&pipe_cfg->src_rect));
 		return -E2BIG;
 
 	/* valid yuv image */
 	} else if (DPU_FORMAT_IS_YUV(fmt) &&
-		   (src.x1 & 0x1 || src.y1 & 0x1 ||
-		    drm_rect_width(&src) & 0x1 ||
-		    drm_rect_height(&src) & 0x1)) {
+		   (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 ||
+		    drm_rect_width(&pipe_cfg->src_rect) & 0x1 ||
+		    drm_rect_height(&pipe_cfg->src_rect) & 0x1)) {
 		DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
-				DRM_RECT_ARG(&src));
+				DRM_RECT_ARG(&pipe_cfg->src_rect));
 		return -EINVAL;
 
 	/* min dst support */
-	} else if (drm_rect_width(&dst) < 0x1 || drm_rect_height(&dst) < 0x1) {
+	} else if (drm_rect_width(&pipe_cfg->dst_rect) < 0x1 || drm_rect_height(&pipe_cfg->dst_rect) < 0x1) {
 		DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
-				DRM_RECT_ARG(&dst));
+				DRM_RECT_ARG(&pipe_cfg->dst_rect));
 		return -EINVAL;
 
 	/* check decimated source width */
-	} else if (drm_rect_width(&src) > max_linewidth) {
+	} else if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
 		DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
-				DRM_RECT_ARG(&src), max_linewidth);
+				DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
 		return -E2BIG;
 	}
 
@@ -1053,15 +1057,13 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	bool is_rt_pipe, update_qos_remap;
 	const struct dpu_format *fmt =
 		to_dpu_format(msm_framebuffer_format(fb));
-	struct dpu_hw_pipe_cfg pipe_cfg;
+	struct dpu_hw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
 	struct dpu_hw_fmt_layout layout;
 	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
 	struct msm_gem_address_space *aspace = kms->base.aspace;
 	bool update_src_addr = true;
 	int ret;
 
-	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
-
 	ret = dpu_format_populate_layout(aspace, fb, &layout);
 	if (ret) {
 		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
@@ -1084,16 +1086,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			crtc->base.id, DRM_RECT_ARG(&state->dst),
 			(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
 
-	pipe_cfg.src_rect = state->src;
-
-	/* state->src is 16.16, src_rect is not */
-	pipe_cfg.src_rect.x1 >>= 16;
-	pipe_cfg.src_rect.x2 >>= 16;
-	pipe_cfg.src_rect.y1 >>= 16;
-	pipe_cfg.src_rect.y2 >>= 16;
-
-	pipe_cfg.dst_rect = state->dst;
-
 	/* override for color fill */
 	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
 		/* skip remaining processing on color fill */
@@ -1102,10 +1094,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 	if (pipe->sspp->ops.setup_rects) {
 		pipe->sspp->ops.setup_rects(pipe,
-				&pipe_cfg);
+				pipe_cfg);
 	}
 
-	_dpu_plane_setup_scaler(pipe, fmt, false, &pipe_cfg);
+	_dpu_plane_setup_scaler(pipe, fmt, false, pipe_cfg);
 
 	if (pipe->sspp->ops.setup_multirect)
 		pipe->sspp->ops.setup_multirect(
@@ -1148,12 +1140,12 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		}
 	}
 
-	_dpu_plane_set_qos_lut(plane, fb, &pipe_cfg);
+	_dpu_plane_set_qos_lut(plane, fb, &pstate->pipe_cfg);
 	_dpu_plane_set_danger_lut(plane, fb);
 
 	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
 		_dpu_plane_set_qos_ctrl(plane, true, DPU_PLANE_QOS_PANIC_CTRL);
-		_dpu_plane_set_ot_limit(plane, crtc, &pipe_cfg);
+		_dpu_plane_set_ot_limit(plane, crtc, &pstate->pipe_cfg);
 	}
 
 	update_qos_remap = (is_rt_pipe != pdpu->is_rt_pipe) ||
@@ -1167,9 +1159,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		_dpu_plane_set_qos_remap(plane);
 	}
 
-	_dpu_plane_calc_bw(plane, fb, &pipe_cfg);
+	_dpu_plane_calc_bw(plane, fb, &pstate->pipe_cfg);
 
-	_dpu_plane_calc_clk(plane, &pipe_cfg);
+	_dpu_plane_calc_clk(plane, &pstate->pipe_cfg);
 }
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index e61c57b045ea..69920c32cb9a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -34,6 +34,7 @@ struct dpu_plane_state {
 	bool pending;
 
 	struct dpu_sw_pipe pipe;
+	struct dpu_hw_pipe_cfg pipe_cfg;
 
 	u64 plane_fetch_bw;
 	u64 plane_clk;
-- 
2.34.1


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

* [PATCH 21/25] drm/msm/dpu: simplify dpu_plane_validate_src()
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (19 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 20/25] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-02-09 17:25 ` [PATCH 22/25] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format Dmitry Baryshkov
                   ` (4 subsequent siblings)
  25 siblings, 0 replies; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Since the driver uses clipped src coordinates, there is no need to check
against the fb coordinates. Remove corresponding checks and inline
dpu_plane_validate_src().

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 30 ++++++++---------------
 1 file changed, 10 insertions(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 863aedcda66e..37810948ffe6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -874,25 +874,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
 	msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace);
 }
 
-static bool dpu_plane_validate_src(struct drm_rect *src,
-				   struct drm_rect *fb_rect,
-				   uint32_t min_src_size)
-{
-	/* Ensure fb size is supported */
-	if (drm_rect_width(fb_rect) > MAX_IMG_WIDTH ||
-	    drm_rect_height(fb_rect) > MAX_IMG_HEIGHT)
-		return false;
-
-	/* Ensure src rect is above the minimum size */
-	if (drm_rect_width(src) < min_src_size ||
-	    drm_rect_height(src) < min_src_size)
-		return false;
-
-	/* Ensure src is fully encapsulated in fb */
-	return drm_rect_intersect(fb_rect, src) &&
-		drm_rect_equals(fb_rect, src);
-}
-
 static int dpu_plane_atomic_check(struct drm_plane *plane,
 				  struct drm_atomic_state *state)
 {
@@ -947,6 +928,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	fb_rect.x2 = new_plane_state->fb->width;
 	fb_rect.y2 = new_plane_state->fb->height;
 
+	/* Ensure fb size is supported */
+	if (drm_rect_width(&fb_rect) > MAX_IMG_WIDTH ||
+	    drm_rect_height(&fb_rect) > MAX_IMG_HEIGHT) {
+		DPU_DEBUG_PLANE(pdpu, "invalid framebuffer " DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&fb_rect));
+		return -E2BIG;
+	}
+
 	max_linewidth = pdpu->catalog->caps->max_linewidth;
 
 	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
@@ -961,7 +950,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 		return -EINVAL;
 
 	/* check src bounds */
-	} else if (!dpu_plane_validate_src(&pipe_cfg->src_rect, &fb_rect, min_src_size)) {
+	} else if (drm_rect_width(&pipe_cfg->src_rect) < min_src_size ||
+		   drm_rect_height(&pipe_cfg->src_rect) < min_src_size) {
 		DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
 				DRM_RECT_ARG(&pipe_cfg->src_rect));
 		return -E2BIG;
-- 
2.34.1


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

* [PATCH 22/25] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (20 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 21/25] drm/msm/dpu: simplify dpu_plane_validate_src() Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-02-09 17:25 ` [PATCH 23/25] drm/msm/dpu: rework dpu_plane_atomic_check() and dpu_plane_sspp_atomic_update() Dmitry Baryshkov
                   ` (3 subsequent siblings)
  25 siblings, 0 replies; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Rewrite dpu_plane's QoS related functions to take struct dpu_sw_pipe and
struct dpu_format as arguments rather than fetching them from the
pstate or drm_framebuffer.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 98 +++++++++++------------
 1 file changed, 47 insertions(+), 51 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 37810948ffe6..74b585f55b73 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -124,19 +124,18 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane)
 /**
  * _dpu_plane_calc_bw - calculate bandwidth required for a plane
  * @plane: Pointer to drm plane.
- * @fb:   Pointer to framebuffer associated with the given plane
+ * @fmt: Pointer to source buffer format
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated bandwidth in the plane state.
  * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest)
  * Prefill BW Equation: line src bytes * line_time
  */
 static void _dpu_plane_calc_bw(struct drm_plane *plane,
-	struct drm_framebuffer *fb,
+	const struct dpu_format *fmt,
 	struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane_state *pstate;
 	struct drm_display_mode *mode;
-	const struct dpu_format *fmt = NULL;
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 	int src_width, src_height, dst_height, fps;
 	u64 plane_prefill_bw;
@@ -148,8 +147,6 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
 	pstate = to_dpu_plane_state(plane->state);
 	mode = &plane->state->crtc->mode;
 
-	fmt = dpu_get_dpu_format_ext(fb->format->format, fb->modifier);
-
 	src_width = drm_rect_width(&pipe_cfg->src_rect);
 	src_height = drm_rect_height(&pipe_cfg->src_rect);
 	dst_height = drm_rect_height(&pipe_cfg->dst_rect);
@@ -213,25 +210,25 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_pipe_cfg
 /**
  * _dpu_plane_calc_fill_level - calculate fill level of the given source format
  * @plane:		Pointer to drm plane
+ * @pipe:		Pointer to software pipe
  * @fmt:		Pointer to source buffer format
  * @src_width:		width of source buffer
  * Return: fill level corresponding to the source buffer/format or 0 if error
  */
 static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
+		struct dpu_sw_pipe *pipe,
 		const struct dpu_format *fmt, u32 src_width)
 {
 	struct dpu_plane *pdpu;
-	struct dpu_plane_state *pstate;
 	u32 fixed_buff_size;
 	u32 total_fl;
 
-	if (!fmt || !plane->state || !src_width || !fmt->bpp) {
+	if (!fmt || !pipe || !src_width || !fmt->bpp) {
 		DPU_ERROR("invalid arguments\n");
 		return 0;
 	}
 
 	pdpu = to_dpu_plane(plane);
-	pstate = to_dpu_plane_state(plane->state);
 	fixed_buff_size = pdpu->catalog->caps->pixel_ram_size;
 
 	/* FIXME: in multirect case account for the src_width of all the planes */
@@ -247,7 +244,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
 				((src_width + 32) * fmt->bpp);
 		}
 	} else {
-		if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
+		if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
 			total_fl = (fixed_buff_size / 2) * 2 /
 				((src_width + 32) * fmt->bpp);
 		} else {
@@ -257,7 +254,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
 	}
 
 	DPU_DEBUG_PLANE(pdpu, "pnum:%d fmt: %4.4s w:%u fl:%u\n",
-			pdpu->pipe - SSPP_VIG0,
+			pipe->sspp->idx - SSPP_VIG0,
 			(char *)&fmt->base.pixel_format,
 			src_width, total_fl);
 
@@ -292,25 +289,22 @@ static u64 _dpu_plane_get_qos_lut(const struct dpu_qos_lut_tbl *tbl,
 /**
  * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
  * @plane:		Pointer to drm plane
- * @fb:			Pointer to framebuffer associated with the given plane
+ * @pipe:		Pointer to software pipe
+ * @fmt:		Pointer to source buffer format
  * @pipe_cfg:		Pointer to pipe configuration
  */
 static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
-		struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg *pipe_cfg)
+		struct dpu_sw_pipe *pipe,
+		const struct dpu_format *fmt, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
-	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-	const struct dpu_format *fmt = NULL;
 	u64 qos_lut;
 	u32 total_fl = 0, lut_usage;
 
 	if (!pdpu->is_rt_pipe) {
 		lut_usage = DPU_QOS_LUT_USAGE_NRT;
 	} else {
-		fmt = dpu_get_dpu_format_ext(
-				fb->format->format,
-				fb->modifier);
-		total_fl = _dpu_plane_calc_fill_level(plane, fmt,
+		total_fl = _dpu_plane_calc_fill_level(plane, pipe, fmt,
 				drm_rect_width(&pipe_cfg->src_rect));
 
 		if (fmt && DPU_FORMAT_IS_LINEAR(fmt))
@@ -322,7 +316,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 	qos_lut = _dpu_plane_get_qos_lut(
 			&pdpu->catalog->perf.qos_lut_tbl[lut_usage], total_fl);
 
-	trace_dpu_perf_set_qos_luts(pdpu->pipe - SSPP_VIG0,
+	trace_dpu_perf_set_qos_luts(pipe->sspp->idx - SSPP_VIG0,
 			(fmt) ? fmt->base.pixel_format : 0,
 			pdpu->is_rt_pipe, total_fl, qos_lut, lut_usage);
 
@@ -331,20 +325,20 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 			fmt ? (char *)&fmt->base.pixel_format : NULL,
 			pdpu->is_rt_pipe, total_fl, qos_lut);
 
-	pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut);
+	pipe->sspp->ops.setup_creq_lut(pipe->sspp, qos_lut);
 }
 
 /**
  * _dpu_plane_set_danger_lut - set danger/safe LUT of the given plane
  * @plane:		Pointer to drm plane
- * @fb:			Pointer to framebuffer associated with the given plane
+ * @pipe:		Pointer to software pipe
+ * @fmt:		Pointer to source buffer format
  */
 static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
-		struct drm_framebuffer *fb)
+		struct dpu_sw_pipe *pipe,
+		const struct dpu_format *fmt)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
-	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-	const struct dpu_format *fmt = NULL;
 	u32 danger_lut, safe_lut;
 
 	if (!pdpu->is_rt_pipe) {
@@ -353,10 +347,6 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
 		safe_lut = pdpu->catalog->perf.safe_lut_tbl
 				[DPU_QOS_LUT_USAGE_NRT];
 	} else {
-		fmt = dpu_get_dpu_format_ext(
-				fb->format->format,
-				fb->modifier);
-
 		if (fmt && DPU_FORMAT_IS_LINEAR(fmt)) {
 			danger_lut = pdpu->catalog->perf.danger_lut_tbl
 					[DPU_QOS_LUT_USAGE_LINEAR];
@@ -383,29 +373,30 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
 		danger_lut,
 		safe_lut);
 
-	pstate->pipe.sspp->ops.setup_danger_safe_lut(pstate->pipe.sspp,
+	pipe->sspp->ops.setup_danger_safe_lut(pipe->sspp,
 			danger_lut, safe_lut);
 }
 
 /**
  * _dpu_plane_set_qos_ctrl - set QoS control of the given plane
  * @plane:		Pointer to drm plane
+ * @pipe:		Pointer to software pipe
  * @enable:		true to enable QoS control
  * @flags:		QoS control mode (enum dpu_plane_qos)
  */
 static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
+		struct dpu_sw_pipe *pipe,
 	bool enable, u32 flags)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
-	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
 
 	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
 	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
-		pipe_qos_cfg.creq_vblank = pstate->pipe.sspp->cap->sblk->creq_vblank;
+		pipe_qos_cfg.creq_vblank = pipe->sspp->cap->sblk->creq_vblank;
 		pipe_qos_cfg.danger_vblank =
-				pstate->pipe.sspp->cap->sblk->danger_vblank;
+				pipe->sspp->cap->sblk->danger_vblank;
 		pipe_qos_cfg.vblank_en = enable;
 	}
 
@@ -431,33 +422,34 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 		pipe_qos_cfg.danger_vblank,
 		pdpu->is_rt_pipe);
 
-	pstate->pipe.sspp->ops.setup_qos_ctrl(pstate->pipe.sspp,
+	pipe->sspp->ops.setup_qos_ctrl(pipe->sspp,
 			&pipe_qos_cfg);
 }
 
 /**
  * _dpu_plane_set_ot_limit - set OT limit for the given plane
  * @plane:		Pointer to drm plane
+ * @pipe:		Pointer to software pipe
  * @crtc:		Pointer to drm crtc
  * @pipe_cfg:		Pointer to pipe configuration
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
+		struct dpu_sw_pipe *pipe,
 		struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
-	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_vbif_set_ot_params ot_params;
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
 	memset(&ot_params, 0, sizeof(ot_params));
-	ot_params.xin_id = pstate->pipe.sspp->cap->xin_id;
-	ot_params.num = pstate->pipe.sspp->idx - SSPP_NONE;
+	ot_params.xin_id = pipe->sspp->cap->xin_id;
+	ot_params.num = pipe->sspp->idx - SSPP_NONE;
 	ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
 	ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
 	ot_params.is_wfd = !pdpu->is_rt_pipe;
 	ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
 	ot_params.vbif_idx = VBIF_RT;
-	ot_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
+	ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
 	ot_params.rd = true;
 
 	dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
@@ -466,19 +458,20 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 /**
  * _dpu_plane_set_qos_remap - set vbif QoS for the given plane
  * @plane:		Pointer to drm plane
+ * @pipe:		Pointer to software pipe
  */
-static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
+static void _dpu_plane_set_qos_remap(struct drm_plane *plane,
+		struct dpu_sw_pipe *pipe)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
-	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_vbif_set_qos_params qos_params;
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
 	memset(&qos_params, 0, sizeof(qos_params));
 	qos_params.vbif_idx = VBIF_RT;
-	qos_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
-	qos_params.xin_id = pstate->pipe.sspp->cap->xin_id;
-	qos_params.num = pstate->pipe.sspp->idx - SSPP_VIG0;
+	qos_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
+	qos_params.xin_id = pipe->sspp->cap->xin_id;
+	qos_params.num = pipe->sspp->idx - SSPP_VIG0;
 	qos_params.is_rt = pdpu->is_rt_pipe;
 
 	DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, clk_ctrl:%d\n",
@@ -1069,7 +1062,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	pstate->pending = true;
 
 	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
-	_dpu_plane_set_qos_ctrl(plane, false, DPU_PLANE_QOS_PANIC_CTRL);
+	_dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
 
 	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
 			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
@@ -1130,12 +1123,12 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		}
 	}
 
-	_dpu_plane_set_qos_lut(plane, fb, &pstate->pipe_cfg);
-	_dpu_plane_set_danger_lut(plane, fb);
+	_dpu_plane_set_qos_lut(plane, pipe, fmt, &pstate->pipe_cfg);
+	_dpu_plane_set_danger_lut(plane, pipe, fmt);
 
 	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
-		_dpu_plane_set_qos_ctrl(plane, true, DPU_PLANE_QOS_PANIC_CTRL);
-		_dpu_plane_set_ot_limit(plane, crtc, &pstate->pipe_cfg);
+		_dpu_plane_set_qos_ctrl(plane, pipe, true, DPU_PLANE_QOS_PANIC_CTRL);
+		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pstate->pipe_cfg);
 	}
 
 	update_qos_remap = (is_rt_pipe != pdpu->is_rt_pipe) ||
@@ -1146,10 +1139,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			pdpu->is_rt_pipe = is_rt_pipe;
 		else if (pstate->needs_qos_remap)
 			pstate->needs_qos_remap = false;
-		_dpu_plane_set_qos_remap(plane);
+		_dpu_plane_set_qos_remap(plane, pipe);
 	}
 
-	_dpu_plane_calc_bw(plane, fb, &pstate->pipe_cfg);
+	_dpu_plane_calc_bw(plane, fmt, &pstate->pipe_cfg);
 
 	_dpu_plane_calc_clk(plane, &pstate->pipe_cfg);
 }
@@ -1186,11 +1179,13 @@ static void dpu_plane_atomic_update(struct drm_plane *plane,
 static void dpu_plane_destroy(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu = plane ? to_dpu_plane(plane) : NULL;
+	struct dpu_plane_state *pstate;
 
 	DPU_DEBUG_PLANE(pdpu, "\n");
 
 	if (pdpu) {
-		_dpu_plane_set_qos_ctrl(plane, false, DPU_PLANE_QOS_PANIC_CTRL);
+		pstate = to_dpu_plane_state(plane->state);
+		_dpu_plane_set_qos_ctrl(plane, &pstate->pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
 
 		mutex_destroy(&pdpu->lock);
 
@@ -1314,13 +1309,14 @@ static void dpu_plane_reset(struct drm_plane *plane)
 void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
 	if (!pdpu->is_rt_pipe)
 		return;
 
 	pm_runtime_get_sync(&dpu_kms->pdev->dev);
-	_dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL);
+	_dpu_plane_set_qos_ctrl(plane, &pstate->pipe, enable, DPU_PLANE_QOS_PANIC_CTRL);
 	pm_runtime_put_sync(&dpu_kms->pdev->dev);
 }
 #endif
-- 
2.34.1


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

* [PATCH 23/25] drm/msm/dpu: rework dpu_plane_atomic_check() and dpu_plane_sspp_atomic_update()
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (21 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 22/25] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-02-09 17:25 ` [PATCH 24/25] drm/msm/dpu: populate SmartDMA features in hw catalog Dmitry Baryshkov
                   ` (2 subsequent siblings)
  25 siblings, 0 replies; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Rewwork plane's atomic_check and atomic_update functions to clearly use
struct dpu_sw_pipe and struct dpu_hw_pipe_cfg. This is the last step towards
adding proper source split support.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 283 +++++++++++++---------
 1 file changed, 163 insertions(+), 120 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 74b585f55b73..623f67247c2d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -123,20 +123,19 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane)
 
 /**
  * _dpu_plane_calc_bw - calculate bandwidth required for a plane
- * @plane: Pointer to drm plane.
+ * @catalog: Points to dpu catalog structure
  * @fmt: Pointer to source buffer format
+ * @mode: Pointer to drm display mode
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated bandwidth in the plane state.
  * BW Equation: src_w * src_h * bpp * fps * (v_total / v_dest)
  * Prefill BW Equation: line src bytes * line_time
  */
-static void _dpu_plane_calc_bw(struct drm_plane *plane,
+static u64 _dpu_plane_calc_bw(const struct dpu_mdss_cfg *catalog,
 	const struct dpu_format *fmt,
+	const struct drm_display_mode *mode,
 	struct dpu_hw_pipe_cfg *pipe_cfg)
 {
-	struct dpu_plane_state *pstate;
-	struct drm_display_mode *mode;
-	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 	int src_width, src_height, dst_height, fps;
 	u64 plane_prefill_bw;
 	u64 plane_bw;
@@ -144,9 +143,6 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
 	u64 scale_factor;
 	int vbp, vpw, vfp;
 
-	pstate = to_dpu_plane_state(plane->state);
-	mode = &plane->state->crtc->mode;
-
 	src_width = drm_rect_width(&pipe_cfg->src_rect);
 	src_height = drm_rect_height(&pipe_cfg->src_rect);
 	dst_height = drm_rect_height(&pipe_cfg->dst_rect);
@@ -154,7 +150,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
 	vbp = mode->vtotal - mode->vsync_end;
 	vpw = mode->vsync_end - mode->vsync_start;
 	vfp = mode->vsync_start - mode->vdisplay;
-	hw_latency_lines =  dpu_kms->catalog->perf.min_prefill_lines;
+	hw_latency_lines =  catalog->perf.min_prefill_lines;
 	scale_factor = src_height > dst_height ?
 		mult_frac(src_height, 1, dst_height) : 1;
 
@@ -174,37 +170,36 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
 		do_div(plane_prefill_bw, hw_latency_lines);
 
 
-	pstate->plane_fetch_bw = max(plane_bw, plane_prefill_bw);
+	return max(plane_bw, plane_prefill_bw);
 }
 
 /**
  * _dpu_plane_calc_clk - calculate clock required for a plane
- * @plane: Pointer to drm plane.
+ * @mode: Pointer to drm display mode
  * @pipe_cfg: Pointer to pipe configuration
  * Result: Updates calculated clock in the plane state.
  * Clock equation: dst_w * v_total * fps * (src_h / dst_h)
  */
-static void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_pipe_cfg *pipe_cfg)
+static u64 _dpu_plane_calc_clk(const struct drm_display_mode *mode,
+		struct dpu_hw_pipe_cfg *pipe_cfg)
 {
-	struct dpu_plane_state *pstate;
-	struct drm_display_mode *mode;
 	int dst_width, src_height, dst_height, fps;
-
-	pstate = to_dpu_plane_state(plane->state);
-	mode = &plane->state->crtc->mode;
+	u64 plane_clk;
 
 	src_height = drm_rect_height(&pipe_cfg->src_rect);
 	dst_width = drm_rect_width(&pipe_cfg->dst_rect);
 	dst_height = drm_rect_height(&pipe_cfg->dst_rect);
 	fps = drm_mode_vrefresh(mode);
 
-	pstate->plane_clk =
+	plane_clk =
 		dst_width * mode->vtotal * fps;
 
 	if (src_height > dst_height) {
-		pstate->plane_clk *= src_height;
-		do_div(pstate->plane_clk, dst_height);
+		plane_clk *= src_height;
+		do_div(plane_clk, dst_height);
 	}
+
+	return plane_clk;
 }
 
 /**
@@ -429,13 +424,14 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 /**
  * _dpu_plane_set_ot_limit - set OT limit for the given plane
  * @plane:		Pointer to drm plane
+ * @mode:		Pointer to drm display mode
  * @pipe:		Pointer to software pipe
- * @crtc:		Pointer to drm crtc
  * @pipe_cfg:		Pointer to pipe configuration
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 		struct dpu_sw_pipe *pipe,
-		struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
+		struct dpu_hw_pipe_cfg *pipe_cfg,
+		const struct drm_display_mode *mode)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_vbif_set_ot_params ot_params;
@@ -447,7 +443,7 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 	ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
 	ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
 	ot_params.is_wfd = !pdpu->is_rt_pipe;
-	ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
+	ot_params.frame_rate = drm_mode_vrefresh(mode);
 	ot_params.vbif_idx = VBIF_RT;
 	ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
 	ot_params.rd = true;
@@ -867,6 +863,55 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
 	msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace);
 }
 
+static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
+		struct dpu_sw_pipe *pipe,
+		struct dpu_hw_pipe_cfg *pipe_cfg,
+		uint32_t max_linewidth,
+		const struct dpu_format *fmt)
+{
+	uint32_t min_src_size;
+
+	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
+
+	if (DPU_FORMAT_IS_YUV(fmt) &&
+		(!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
+		 !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
+		DPU_DEBUG_PLANE(pdpu,
+				"plane doesn't have scaler/csc for yuv\n");
+		return -EINVAL;
+
+	/* check src bounds */
+	} else if (drm_rect_width(&pipe_cfg->src_rect) < min_src_size ||
+		   drm_rect_height(&pipe_cfg->src_rect) < min_src_size) {
+		DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&pipe_cfg->src_rect));
+		return -E2BIG;
+
+	/* valid yuv image */
+	} else if (DPU_FORMAT_IS_YUV(fmt) &&
+		   (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 ||
+		    drm_rect_width(&pipe_cfg->src_rect) & 0x1 ||
+		    drm_rect_height(&pipe_cfg->src_rect) & 0x1)) {
+		DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&pipe_cfg->src_rect));
+		return -EINVAL;
+
+	/* min dst support */
+	} else if (drm_rect_width(&pipe_cfg->dst_rect) < 0x1 || drm_rect_height(&pipe_cfg->dst_rect) < 0x1) {
+		DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&pipe_cfg->dst_rect));
+		return -EINVAL;
+
+	/* check decimated source width */
+	} else if (drm_rect_width(&pipe_cfg->src_rect) > 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;
+	}
+
+	return 0;
+}
+
 static int dpu_plane_atomic_check(struct drm_plane *plane,
 				  struct drm_atomic_state *state)
 {
@@ -880,7 +925,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	const struct dpu_format *fmt;
 	struct dpu_hw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
 	struct drm_rect fb_rect = { 0 };
-	uint32_t min_src_size, max_linewidth;
+	uint32_t max_linewidth;
 
 	if (new_plane_state->crtc)
 		crtc_state = drm_atomic_get_new_crtc_state(state,
@@ -898,8 +943,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	if (!new_plane_state->visible)
 		return 0;
 
-	pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
-	pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+	pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+	pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
 
 	pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
 	if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
@@ -933,43 +978,9 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
 
-	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
-
-	if (DPU_FORMAT_IS_YUV(fmt) &&
-		(!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
-		 !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
-		DPU_DEBUG_PLANE(pdpu,
-				"plane doesn't have scaler/csc for yuv\n");
-		return -EINVAL;
-
-	/* check src bounds */
-	} else if (drm_rect_width(&pipe_cfg->src_rect) < min_src_size ||
-		   drm_rect_height(&pipe_cfg->src_rect) < min_src_size) {
-		DPU_DEBUG_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
-				DRM_RECT_ARG(&pipe_cfg->src_rect));
-		return -E2BIG;
-
-	/* valid yuv image */
-	} else if (DPU_FORMAT_IS_YUV(fmt) &&
-		   (pipe_cfg->src_rect.x1 & 0x1 || pipe_cfg->src_rect.y1 & 0x1 ||
-		    drm_rect_width(&pipe_cfg->src_rect) & 0x1 ||
-		    drm_rect_height(&pipe_cfg->src_rect) & 0x1)) {
-		DPU_DEBUG_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
-				DRM_RECT_ARG(&pipe_cfg->src_rect));
-		return -EINVAL;
-
-	/* min dst support */
-	} else if (drm_rect_width(&pipe_cfg->dst_rect) < 0x1 || drm_rect_height(&pipe_cfg->dst_rect) < 0x1) {
-		DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
-				DRM_RECT_ARG(&pipe_cfg->dst_rect));
-		return -EINVAL;
-
-	/* check decimated source width */
-	} else if (drm_rect_width(&pipe_cfg->src_rect) > 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;
-	}
+	ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, max_linewidth, fmt);
+	if (ret)
+		return ret;
 
 	pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
 
@@ -1028,51 +1039,18 @@ void dpu_plane_set_error(struct drm_plane *plane, bool error)
 	pdpu->is_error = error;
 }
 
-static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
+static void dpu_plane_atomic_update_pipe(
+		struct dpu_sw_pipe *pipe,
+		struct dpu_hw_pipe_cfg *pipe_cfg,
+		unsigned int plane_rotation,
+		struct dpu_hw_fmt_layout *layout,
+		const struct dpu_format *fmt,
+		const struct dpu_mdss_cfg *catalog)
 {
-	uint32_t src_flags;
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
-	struct drm_plane_state *state = plane->state;
-	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
-	struct dpu_sw_pipe *pipe = &pstate->pipe;
-	struct drm_crtc *crtc = state->crtc;
-	struct drm_framebuffer *fb = state->fb;
-	bool is_rt_pipe, update_qos_remap;
-	const struct dpu_format *fmt =
-		to_dpu_format(msm_framebuffer_format(fb));
-	struct dpu_hw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
-	struct dpu_hw_fmt_layout layout;
-	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
-	struct msm_gem_address_space *aspace = kms->base.aspace;
-	bool update_src_addr = true;
-	int ret;
-
-	ret = dpu_format_populate_layout(aspace, fb, &layout);
-	if (ret) {
-		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-		update_src_addr = false;
-	}
-
-	if (update_src_addr &&
+	if (layout &&
 	    pipe->sspp->ops.setup_sourceaddress) {
-		trace_dpu_plane_set_scanout(pipe, &layout);
-		pipe->sspp->ops.setup_sourceaddress(pipe, &layout);
-	}
-
-	pstate->pending = true;
-
-	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
-	_dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
-
-	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
-			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
-			crtc->base.id, DRM_RECT_ARG(&state->dst),
-			(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
-
-	/* override for color fill */
-	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
-		/* skip remaining processing on color fill */
-		return;
+		trace_dpu_plane_set_scanout(pipe, layout);
+		pipe->sspp->ops.setup_sourceaddress(pipe, layout);
 	}
 
 	if (pipe->sspp->ops.setup_rects) {
@@ -1088,10 +1066,11 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 	if (pipe->sspp->ops.setup_format) {
 		unsigned int rotation;
+		uint32_t src_flags;
 
 		src_flags = 0x0;
 
-		rotation = drm_rotation_simplify(state->rotation,
+		rotation = drm_rotation_simplify(plane_rotation,
 						 DRM_MODE_ROTATE_0 |
 						 DRM_MODE_REFLECT_X |
 						 DRM_MODE_REFLECT_Y);
@@ -1110,7 +1089,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
 
-			cdp_cfg.enable = pdpu->catalog->perf.cdp_cfg
+			cdp_cfg.enable = catalog->perf.cdp_cfg
 					[DPU_PERF_CDP_USAGE_RT].rd_enable;
 			cdp_cfg.ubwc_meta_enable =
 					DPU_FORMAT_IS_UBWC(fmt);
@@ -1122,29 +1101,93 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			pipe->sspp->ops.setup_cdp(pipe, &cdp_cfg);
 		}
 	}
+}
+
+static void dpu_plane_atomic_update_qos(
+		struct drm_plane *plane,
+		struct dpu_plane_state *pstate,
+		struct dpu_sw_pipe *pipe,
+		struct dpu_hw_pipe_cfg *pipe_cfg,
+		const struct dpu_format *fmt,
+		const struct drm_display_mode *mode,
+		bool is_rt_pipe
+		)
+{
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	bool update_qos_remap;
+
+	update_qos_remap = (is_rt_pipe != pdpu->is_rt_pipe) ||
+			pstate->needs_qos_remap;
+
+	if (is_rt_pipe != pdpu->is_rt_pipe)
+		pdpu->is_rt_pipe = is_rt_pipe;
+	if (pstate->needs_qos_remap)
+		pstate->needs_qos_remap = false;
 
-	_dpu_plane_set_qos_lut(plane, pipe, fmt, &pstate->pipe_cfg);
+	_dpu_plane_set_qos_lut(plane, pipe, fmt, pipe_cfg);
 	_dpu_plane_set_danger_lut(plane, pipe, fmt);
 
 	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
 		_dpu_plane_set_qos_ctrl(plane, pipe, true, DPU_PLANE_QOS_PANIC_CTRL);
-		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pstate->pipe_cfg);
+		_dpu_plane_set_ot_limit(plane, pipe, pipe_cfg, mode);
 	}
 
-	update_qos_remap = (is_rt_pipe != pdpu->is_rt_pipe) ||
-			pstate->needs_qos_remap;
-
-	if (update_qos_remap) {
-		if (is_rt_pipe != pdpu->is_rt_pipe)
-			pdpu->is_rt_pipe = is_rt_pipe;
-		else if (pstate->needs_qos_remap)
-			pstate->needs_qos_remap = false;
+	if (update_qos_remap)
 		_dpu_plane_set_qos_remap(plane, pipe);
+}
+
+static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
+{
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct drm_plane_state *state = plane->state;
+	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
+	struct dpu_sw_pipe *pipe = &pstate->pipe;
+	struct drm_crtc *crtc = state->crtc;
+	struct drm_framebuffer *fb = state->fb;
+	bool is_rt_pipe;
+	const struct dpu_format *fmt =
+		to_dpu_format(msm_framebuffer_format(fb));
+	struct dpu_hw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+	struct dpu_hw_fmt_layout layout;
+	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
+	struct msm_gem_address_space *aspace = kms->base.aspace;
+	bool update_src_addr = true;
+	int ret;
+
+	ret = dpu_format_populate_layout(aspace, fb, &layout);
+	if (ret) {
+		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
+		update_src_addr = false;
 	}
 
-	_dpu_plane_calc_bw(plane, fmt, &pstate->pipe_cfg);
+	pstate->pending = true;
+
+	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
+	_dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
+
+	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
+			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
+			crtc->base.id, DRM_RECT_ARG(&state->dst),
+			(char *)&fmt->base.pixel_format, DPU_FORMAT_IS_UBWC(fmt));
+
+	/* override for color fill */
+	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
+		/* skip remaining processing on color fill */
+		return;
+	}
+
+	dpu_plane_atomic_update_pipe(pipe, pipe_cfg,
+			state->rotation,
+			update_src_addr ? &layout : NULL,
+			fmt, pdpu->catalog);
+
+	dpu_plane_atomic_update_qos(plane, pstate,
+			pipe, pipe_cfg,
+			fmt, &crtc->mode, is_rt_pipe);
+
+	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, pipe_cfg);
 
-	_dpu_plane_calc_clk(plane, &pstate->pipe_cfg);
+	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, pipe_cfg);
 }
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
-- 
2.34.1


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

* [PATCH 24/25] drm/msm/dpu: populate SmartDMA features in hw catalog
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (22 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 23/25] drm/msm/dpu: rework dpu_plane_atomic_check() and dpu_plane_sspp_atomic_update() Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-02-09 17:25 ` [PATCH 25/25] drm/msm/dpu: add support for wide planes Dmitry Baryshkov
  2022-03-17  1:10 ` [PATCH 00/25] drm/msm/dpu: wide planes support Abhinav Kumar
  25 siblings, 0 replies; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Downstream driver uses dpu->caps->smart_dma_rev to update
sspp->cap->features with the bit corresponding to the supported SmartDMA
version. Upstream driver does not do this, resulting in SSPP subdriver
not enbaling setup_multirect callback. Add corresponding SmartDMA SSPP
feature bits to dpu hw catalog.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index aa75991903a6..3564eea29563 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -17,17 +17,21 @@
 	BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_EXCL_RECT))
 
 #define VIG_SDM845_MASK \
-	(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3))
+	(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3) |\
+	BIT(DPU_SSPP_SMART_DMA_V2))
 
 #define VIG_SC7180_MASK \
-	(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4))
+	(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED4) |\
+	BIT(DPU_SSPP_SMART_DMA_V2))
 
 #define VIG_SM8250_MASK \
-	(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE))
+	(VIG_MASK | BIT(DPU_SSPP_QOS_8LVL) | BIT(DPU_SSPP_SCALER_QSEED3LITE) |\
+	BIT(DPU_SSPP_SMART_DMA_V2))
 
 #define DMA_SDM845_MASK \
 	(BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\
 	BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\
+	BIT(DPU_SSPP_SMART_DMA_V2) |\
 	BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT))
 
 #define DMA_CURSOR_SDM845_MASK \
-- 
2.34.1


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

* [PATCH 25/25] drm/msm/dpu: add support for wide planes
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (23 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 24/25] drm/msm/dpu: populate SmartDMA features in hw catalog Dmitry Baryshkov
@ 2022-02-09 17:25 ` Dmitry Baryshkov
  2022-03-17  1:10 ` [PATCH 00/25] drm/msm/dpu: wide planes support Abhinav Kumar
  25 siblings, 0 replies; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-02-09 17:25 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Typically SSPP can support rectangle with width up to 2560. However it's
possible to use multirect feature and split source to use the SSPP to
output two consecutive rectangles. This commit brings in this capability
to support wider screen resolutions.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  |  35 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 194 ++++++++++++++++++----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   2 +
 3 files changed, 192 insertions(+), 39 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index fa279f0358d6..20ebac3028ec 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -418,7 +418,6 @@ static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc)
 	struct dpu_plane_state *pstate = NULL;
 
 	uint32_t stage_idx, lm_idx;
-	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
 	DECLARE_BITMAP(fetch_active, SSPP_MAX);
 
 	DRM_DEBUG_ATOMIC("%s\n", dpu_crtc->name);
@@ -434,6 +433,7 @@ static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc)
 	memset(fetch_active, 0, sizeof(fetch_active));
 	drm_atomic_crtc_for_each_plane(plane, crtc) {
 		enum dpu_sspp sspp_idx;
+		struct dpu_sw_pipe *pipe;
 
 		state = plane->state;
 		if (!state)
@@ -441,18 +441,37 @@ static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc)
 
 		pstate = to_dpu_plane_state(state);
 
-		sspp_idx = pstate->pipe.sspp->idx;
+		pipe = &pstate->pipe;
+		stage_idx = 0;
+
+		sspp_idx = pipe->sspp->idx;
 		set_bit(sspp_idx, fetch_active);
 
-		stage_idx = zpos_cnt[pstate->stage]++;
 		stage_cfg.stage[pstate->stage][stage_idx] =
 					sspp_idx;
 		stage_cfg.multirect_index[pstate->stage][stage_idx] =
-					pstate->pipe.multirect_index;
+					pipe->multirect_index;
 
 		/* blend config update */
 		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++)
 			mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx);
+
+		if (pstate->r_pipe.sspp) {
+			pipe = &pstate->r_pipe;
+			stage_idx = 1;
+
+			sspp_idx = pipe->sspp->idx;
+			set_bit(sspp_idx, fetch_active);
+
+			stage_cfg.stage[pstate->stage][stage_idx] =
+						sspp_idx;
+			stage_cfg.multirect_index[pstate->stage][stage_idx] =
+						pipe->multirect_index;
+
+			/* blend config update */
+			for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++)
+				mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx);
+		}
 	}
 
 	ctl = mixer->lm_ctl;
@@ -1202,8 +1221,16 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
 		seq_printf(s, "\tdst x:%4d dst_y:%4d dst_w:%4d dst_h:%4d\n",
 			state->crtc_x, state->crtc_y, state->crtc_w,
 			state->crtc_h);
+		seq_printf(s, "\tsspp: %d\n",
+			pstate->pipe.sspp->idx);
 		seq_printf(s, "\tmultirect: mode: %d index: %d\n",
 			pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
+		if (pstate->r_pipe.sspp) {
+			seq_printf(s, "\tsspp: %d\n",
+				pstate->r_pipe.sspp->idx);
+			seq_printf(s, "\tmultirect: mode: %d index: %d\n",
+				pstate->r_pipe.multirect_mode, pstate->r_pipe.multirect_index);
+		}
 
 		seq_puts(s, "\n");
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 623f67247c2d..2f88405ead80 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -575,9 +575,8 @@ static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
 	{ 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,},
 };
 
-static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, const struct dpu_format *fmt)
+static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe, const struct dpu_format *fmt)
 {
-	struct dpu_plane_state *pstate = to_dpu_plane_state(pdpu->base.state);
 	const struct dpu_csc_cfg *csc_ptr;
 
 	if (!pdpu) {
@@ -588,7 +587,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
 	if (!DPU_FORMAT_IS_YUV(fmt))
 		return NULL;
 
-	if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe.sspp->cap->features)
+	if (BIT(DPU_SSPP_CSC_10BIT) & pipe->sspp->cap->features)
 		csc_ptr = &dpu_csc10_YUV2RGB_601L;
 	else
 		csc_ptr = &dpu_csc_YUV2RGB_601L;
@@ -639,6 +638,27 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe,
 				fmt);
 }
 
+static void _dpu_plane_color_fill_pipe(struct dpu_sw_pipe *pipe,
+		struct dpu_hw_pipe_cfg *pipe_cfg,
+		const struct dpu_format *fmt,
+		u32 color)
+{
+	if (!pipe->sspp->ops.setup_solidfill)
+		return;
+
+	pipe->sspp->ops.setup_solidfill(pipe, color);
+
+	if (pipe->sspp->ops.setup_format)
+		pipe->sspp->ops.setup_format(pipe,
+				fmt, DPU_SSPP_SOLID_FILL);
+
+	if (pipe->sspp->ops.setup_rects)
+		pipe->sspp->ops.setup_rects(pipe,
+				pipe_cfg);
+
+	_dpu_plane_setup_scaler(pipe, fmt, true, pipe_cfg);
+}
+
 /**
  * _dpu_plane_color_fill - enables color fill on plane
  * @pdpu:   Pointer to DPU plane object
@@ -661,31 +681,39 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 	 * h/w only supports RGB variants
 	 */
 	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
+	if (!fmt)
+		return 0;
 
-	/* update sspp */
-	if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
-		pstate->pipe.sspp->ops.setup_solidfill(&pstate->pipe,
-				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24));
+	pipe_cfg.dst_rect = pstate->base.dst;
 
-		/* override scaler/decimation if solid fill */
-		pipe_cfg.dst_rect = pstate->base.dst;
+	pipe_cfg.src_rect.x1 = 0;
+	pipe_cfg.src_rect.y1 = 0;
+	pipe_cfg.src_rect.x2 =
+		drm_rect_width(&pipe_cfg.dst_rect);
+	pipe_cfg.src_rect.y2 =
+		drm_rect_height(&pipe_cfg.dst_rect);
 
-		pipe_cfg.src_rect.x1 = 0;
-		pipe_cfg.src_rect.y1 = 0;
+	/* update sspp */
+	if (pstate->r_pipe.sspp) {
+		/* split source */
+		pipe_cfg.dst_rect.x2 = (pipe_cfg.dst_rect.x1 + pipe_cfg.dst_rect.x2) >> 1;
 		pipe_cfg.src_rect.x2 =
 			drm_rect_width(&pipe_cfg.dst_rect);
-		pipe_cfg.src_rect.y2 =
-			drm_rect_height(&pipe_cfg.dst_rect);
 
-		if (pstate->pipe.sspp->ops.setup_format)
-			pstate->pipe.sspp->ops.setup_format(&pstate->pipe,
-					fmt, DPU_SSPP_SOLID_FILL);
+		_dpu_plane_color_fill_pipe(&pstate->pipe, &pipe_cfg, fmt,
+				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24));
 
-		if (pstate->pipe.sspp->ops.setup_rects)
-			pstate->pipe.sspp->ops.setup_rects(&pstate->pipe,
-					&pipe_cfg);
+		pipe_cfg.dst_rect.x1 = pipe_cfg.dst_rect.x2;
+		pipe_cfg.dst_rect.x2 = pstate->base.dst.x2;
+
+		pipe_cfg.src_rect.x2 =
+			drm_rect_width(&pipe_cfg.dst_rect);
 
-		_dpu_plane_setup_scaler(&pstate->pipe, fmt, true, &pipe_cfg);
+		_dpu_plane_color_fill_pipe(&pstate->r_pipe, &pipe_cfg, fmt,
+				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24));
+	} else {
+		_dpu_plane_color_fill_pipe(&pstate->pipe, &pipe_cfg, fmt,
+				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24));
 	}
 
 	return 0;
@@ -866,7 +894,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
 static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
 		struct dpu_sw_pipe *pipe,
 		struct dpu_hw_pipe_cfg *pipe_cfg,
-		uint32_t max_linewidth,
 		const struct dpu_format *fmt)
 {
 	uint32_t min_src_size;
@@ -901,12 +928,6 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
 		DPU_DEBUG_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
 				DRM_RECT_ARG(&pipe_cfg->dst_rect));
 		return -EINVAL;
-
-	/* check decimated source width */
-	} else if (drm_rect_width(&pipe_cfg->src_rect) > 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;
 	}
 
 	return 0;
@@ -921,9 +942,11 @@ static int dpu_plane_atomic_check(struct drm_plane *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;
+	struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
 	const struct drm_crtc_state *crtc_state = NULL;
 	const struct dpu_format *fmt;
 	struct dpu_hw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+	struct dpu_hw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
 	struct drm_rect fb_rect = { 0 };
 	uint32_t max_linewidth;
 
@@ -945,6 +968,9 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	pipe->multirect_index = DPU_SSPP_RECT_SOLO;
 	pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+	r_pipe->multirect_index = DPU_SSPP_RECT_SOLO;
+	r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+	r_pipe->sspp = NULL;
 
 	pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
 	if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
@@ -978,15 +1004,71 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
 
-	ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, max_linewidth, fmt);
+	if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) {
+		/* struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state); */
+
+		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;
+			/*
+			 * FIXME: it's not possible to check if sourcesplit is supported,
+			 * LMs is not assigned yet. It happens in dpu_encoder_virt_mode_set
+			 */
+		} else if (drm_rect_width(&pipe_cfg->src_rect) != drm_rect_width(&pipe_cfg->dst_rect) ||
+			   drm_rect_height(&pipe_cfg->src_rect) != drm_rect_height(&pipe_cfg->dst_rect) ||
+			   (!test_bit(DPU_SSPP_SMART_DMA_V1, &pipe->sspp->cap->features) &&
+			    !test_bit(DPU_SSPP_SMART_DMA_V2, &pipe->sspp->cap->features)) ||
+			   /* cstate->num_mixers < 2 ||
+			   !test_bit(DPU_MIXER_SOURCESPLIT, &cstate->mixers[0].hw_lm->cap->features) || */
+			   DPU_FORMAT_IS_YUV(fmt)) {
+			DPU_DEBUG_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u, can't use split source\n",
+					DRM_RECT_ARG(&pipe_cfg->src_rect), max_linewidth);
+			return -E2BIG;
+		}
+
+		/* Use multirect for wide plane. We do not support dynamic assignment of SSPPs, so we know the configuration. */
+		pipe->multirect_index = DPU_SSPP_RECT_0;
+		pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+
+		r_pipe->sspp = pipe->sspp;
+		r_pipe->multirect_index = DPU_SSPP_RECT_1;
+		r_pipe->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+
+		*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;
+	}
+
+	ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
 	if (ret)
 		return ret;
 
+	if (r_pipe->sspp) {
+		ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
+		if (ret)
+			return ret;
+	}
+
 	pstate->needs_qos_remap = drm_atomic_crtc_needs_modeset(crtc_state);
 
 	return 0;
 }
 
+static void dpu_plane_setup_csc(struct dpu_plane *pdpu,
+		struct dpu_sw_pipe *pipe,
+		const struct dpu_format *fmt)
+{
+	if (pipe->sspp && pipe->sspp->ops.setup_csc) {
+		const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, pipe, fmt);
+
+		if (csc_ptr)
+			pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
+	}
+}
+
 void dpu_plane_flush(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu;
@@ -1010,12 +1092,11 @@ void dpu_plane_flush(struct drm_plane *plane)
 	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
 		/* force 100% alpha */
 		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
-	else if (pstate->pipe.sspp && pstate->pipe.sspp->ops.setup_csc) {
+	else {
 		const struct dpu_format *fmt = to_dpu_format(msm_framebuffer_format(plane->state->fb));
-		const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, fmt);
 
-		if (csc_ptr)
-			pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, csc_ptr);
+		dpu_plane_setup_csc(pdpu, &pstate->pipe, fmt);
+		dpu_plane_setup_csc(pdpu, &pstate->r_pipe, fmt);
 	}
 
 	/* flag h/w flush complete */
@@ -1142,12 +1223,14 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	struct drm_plane_state *state = plane->state;
 	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
 	struct dpu_sw_pipe *pipe = &pstate->pipe;
+	struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
 	struct drm_crtc *crtc = state->crtc;
 	struct drm_framebuffer *fb = state->fb;
 	bool is_rt_pipe;
 	const struct dpu_format *fmt =
 		to_dpu_format(msm_framebuffer_format(fb));
 	struct dpu_hw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
+	struct dpu_hw_pipe_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
 	struct dpu_hw_fmt_layout layout;
 	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
 	struct msm_gem_address_space *aspace = kms->base.aspace;
@@ -1164,6 +1247,8 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
 	_dpu_plane_set_qos_ctrl(plane, pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
+	if (r_pipe->sspp)
+		_dpu_plane_set_qos_ctrl(plane, r_pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
 
 	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FP_FMT "->crtc%u " DRM_RECT_FMT
 			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_FP_ARG(&state->src),
@@ -1188,6 +1273,21 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, pipe_cfg);
 
 	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, pipe_cfg);
+
+	if (r_pipe->sspp) {
+		dpu_plane_atomic_update_pipe(r_pipe, r_pipe_cfg,
+				state->rotation,
+				update_src_addr ? &layout : NULL,
+				fmt, pdpu->catalog);
+
+		dpu_plane_atomic_update_qos(plane, pstate,
+				r_pipe, r_pipe_cfg,
+				fmt, &crtc->mode, is_rt_pipe);
+
+		pstate->plane_fetch_bw += _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, r_pipe_cfg);
+
+		pstate->plane_clk = max(pstate->plane_clk, _dpu_plane_calc_clk(&crtc->mode, r_pipe_cfg));
+	}
 }
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
@@ -1230,6 +1330,9 @@ static void dpu_plane_destroy(struct drm_plane *plane)
 		pstate = to_dpu_plane_state(plane->state);
 		_dpu_plane_set_qos_ctrl(plane, &pstate->pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
 
+		if (pstate->r_pipe.sspp)
+			_dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, false, DPU_PLANE_QOS_PANIC_CTRL);
+
 		mutex_destroy(&pdpu->lock);
 
 		/* this will destroy the states as well */
@@ -1310,11 +1413,26 @@ static void dpu_plane_atomic_print_state(struct drm_printer *p,
 		const struct drm_plane_state *state)
 {
 	const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
+	const struct dpu_sw_pipe *pipe = &pstate->pipe;
+	const struct dpu_hw_pipe_cfg *pipe_cfg = &pstate->pipe_cfg;
 
 	drm_printf(p, "\tstage=%d\n", pstate->stage);
-	drm_printf(p, "\tsspp=%s\n", pstate->pipe.sspp->cap->name);
-	drm_printf(p, "\tmultirect_mode=%s\n", dpu_get_multirect_mode(pstate->pipe.multirect_mode));
-	drm_printf(p, "\tmultirect_index=%s\n", dpu_get_multirect_index(pstate->pipe.multirect_index));
+
+	drm_printf(p, "\tsspp[0]=%s\n", pipe->sspp->cap->name);
+	drm_printf(p, "\tmultirect_mode[0]=%s\n", dpu_get_multirect_mode(pipe->multirect_mode));
+	drm_printf(p, "\tmultirect_index[0]=%s\n", dpu_get_multirect_index(pipe->multirect_index));
+	drm_printf(p, "\tsrc[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->src_rect));
+	drm_printf(p, "\tdst[0]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->dst_rect));
+
+	pipe = &pstate->r_pipe;
+	pipe_cfg = &pstate->r_pipe_cfg;
+	if (pipe->sspp) {
+		drm_printf(p, "\tsspp[1]=%s\n", pipe->sspp->cap->name);
+		drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(pipe->multirect_mode));
+		drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(pipe->multirect_index));
+		drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->src_rect));
+		drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&pipe_cfg->dst_rect));
+	}
 }
 
 static void dpu_plane_reset(struct drm_plane *plane)
@@ -1344,6 +1462,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
 	}
 
 	pstate->pipe.sspp = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
+	pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
+	pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
+	pstate->r_pipe.sspp = NULL;
 
 	__drm_atomic_helper_plane_reset(plane, &pstate->base);
 }
@@ -1360,6 +1482,8 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
 
 	pm_runtime_get_sync(&dpu_kms->pdev->dev);
 	_dpu_plane_set_qos_ctrl(plane, &pstate->pipe, enable, DPU_PLANE_QOS_PANIC_CTRL);
+	if (pstate->r_pipe.sspp)
+		_dpu_plane_set_qos_ctrl(plane, &pstate->r_pipe, enable, DPU_PLANE_QOS_PANIC_CTRL);
 	pm_runtime_put_sync(&dpu_kms->pdev->dev);
 }
 #endif
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 69920c32cb9a..2dd1986f69bc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -34,7 +34,9 @@ struct dpu_plane_state {
 	bool pending;
 
 	struct dpu_sw_pipe pipe;
+	struct dpu_sw_pipe r_pipe;
 	struct dpu_hw_pipe_cfg pipe_cfg;
+	struct dpu_hw_pipe_cfg r_pipe_cfg;
 
 	u64 plane_fetch_bw;
 	u64 plane_clk;
-- 
2.34.1


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

* Re: [PATCH 00/25] drm/msm/dpu: wide planes support
  2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
                   ` (24 preceding siblings ...)
  2022-02-09 17:25 ` [PATCH 25/25] drm/msm/dpu: add support for wide planes Dmitry Baryshkov
@ 2022-03-17  1:10 ` Abhinav Kumar
  2022-03-17  7:59   ` Dmitry Baryshkov
  25 siblings, 1 reply; 59+ messages in thread
From: Abhinav Kumar @ 2022-03-17  1:10 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

Hi Dmitry

I have reviewed the series , some patches completely , some of them 
especially the plane to sspp mapping is something i still need to check.

But I had one question on the design.

I thought we were going to have a boot param to control whether driver 
will internally use both rectangles for the layer so that in the future 
if compositors can do this splitting, we can use that instead of driver 
doing it ( keep boot param disabled ? ).

Thanks

Abhinav

On 2/9/2022 9:24 AM, Dmitry Baryshkov wrote:
> It took me a way longer to finish than I expected. And more patches that
> I initially hoped. This patchset brings in multirect usage to support
> using two SSPP rectangles for a single plane. Virtual planes support is
> omitted from this pull request, it will come later.
> 
> Dmitry Baryshkov (25):
>    drm/msm/dpu: rip out master planes support
>    drm/msm/dpu: do not limit the zpos property
>    drm/msm/dpu: add support for SSPP allocation to RM
>    drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
>    drm/msm/dpu: move pipe_hw to dpu_plane_state
>    drm/msm/dpu: inline dpu_plane_get_ctl_flush
>    drm/msm/dpu: drop dpu_plane_pipe function
>    drm/msm/dpu: get rid of cached flush_mask
>    drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic
>    drm/msm/dpu: introduce struct dpu_sw_pipe
>    drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
>    drm/msm/dpu: inline _dpu_plane_set_scanout
>    drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
>    drm/msm/dpu: move stride programming to
>      dpu_hw_sspp_setup_sourceaddress
>    drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg
>    drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout
>    drm/msm/dpu: drop src_split and multirect check from
>      dpu_crtc_atomic_check
>    drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
>    drm/msm/dpu: don't use unsupported blend stages
>    drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
>    drm/msm/dpu: simplify dpu_plane_validate_src()
>    drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe
>      and dpu_format
>    drm/msm/dpu: rework dpu_plane_atomic_check() and
>      dpu_plane_sspp_atomic_update()
>    drm/msm/dpu: populate SmartDMA features in hw catalog
>    drm/msm/dpu: add support for wide planes
> 
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c      | 355 +++-----
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h      |   1 -
>   drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c   |   4 -
>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    |  10 +-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c    |  78 +-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h    |  35 +-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c   | 136 +--
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h   |  88 +-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c       |  21 +-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h       |   1 +
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c     | 813 +++++++++---------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h     |  42 +-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c        |  81 ++
>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h        |   6 +
>   drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h     |  19 +-
>   15 files changed, 827 insertions(+), 863 deletions(-)
> 

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

* Re: [PATCH 00/25] drm/msm/dpu: wide planes support
  2022-03-17  1:10 ` [PATCH 00/25] drm/msm/dpu: wide planes support Abhinav Kumar
@ 2022-03-17  7:59   ` Dmitry Baryshkov
  0 siblings, 0 replies; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-03-17  7:59 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

On 17/03/2022 04:10, Abhinav Kumar wrote:
> Hi Dmitry
> 
> I have reviewed the series , some patches completely , some of them 
> especially the plane to sspp mapping is something i still need to check.
> 
> But I had one question on the design.
> 
> I thought we were going to have a boot param to control whether driver 
> will internally use both rectangles for the layer so that in the future 
> if compositors can do this splitting, we can use that instead of driver 
> doing it ( keep boot param disabled ? ).

No need to for this patch series. If your composer allocates smaller 
planes, then the driver won't do a thing. For the proper multirect there 
will be a boot param (at least initially) and then you can work on the 
custom properties, etc.

> 
> Thanks
> 
> Abhinav
> 
> On 2/9/2022 9:24 AM, Dmitry Baryshkov wrote:
>> It took me a way longer to finish than I expected. And more patches that
>> I initially hoped. This patchset brings in multirect usage to support
>> using two SSPP rectangles for a single plane. Virtual planes support is
>> omitted from this pull request, it will come later.
>>
>> Dmitry Baryshkov (25):
>>    drm/msm/dpu: rip out master planes support
>>    drm/msm/dpu: do not limit the zpos property
>>    drm/msm/dpu: add support for SSPP allocation to RM
>>    drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
>>    drm/msm/dpu: move pipe_hw to dpu_plane_state
>>    drm/msm/dpu: inline dpu_plane_get_ctl_flush
>>    drm/msm/dpu: drop dpu_plane_pipe function
>>    drm/msm/dpu: get rid of cached flush_mask
>>    drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic
>>    drm/msm/dpu: introduce struct dpu_sw_pipe
>>    drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
>>    drm/msm/dpu: inline _dpu_plane_set_scanout
>>    drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
>>    drm/msm/dpu: move stride programming to
>>      dpu_hw_sspp_setup_sourceaddress
>>    drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg
>>    drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout
>>    drm/msm/dpu: drop src_split and multirect check from
>>      dpu_crtc_atomic_check
>>    drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
>>    drm/msm/dpu: don't use unsupported blend stages
>>    drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
>>    drm/msm/dpu: simplify dpu_plane_validate_src()
>>    drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe
>>      and dpu_format
>>    drm/msm/dpu: rework dpu_plane_atomic_check() and
>>      dpu_plane_sspp_atomic_update()
>>    drm/msm/dpu: populate SmartDMA features in hw catalog
>>    drm/msm/dpu: add support for wide planes
>>
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c      | 355 +++-----
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h      |   1 -
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c   |   4 -
>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    |  10 +-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c    |  78 +-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h    |  35 +-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c   | 136 +--
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h   |  88 +-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c       |  21 +-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h       |   1 +
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c     | 813 +++++++++---------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h     |  42 +-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c        |  81 ++
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h        |   6 +
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h     |  19 +-
>>   15 files changed, 827 insertions(+), 863 deletions(-)
>>


-- 
With best wishes
Dmitry

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

* Re: [PATCH 01/25] drm/msm/dpu: rip out master planes support
  2022-02-09 17:24 ` [PATCH 01/25] drm/msm/dpu: rip out master " Dmitry Baryshkov
@ 2022-04-27  1:28   ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-04-27  1:28 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:24 AM, Dmitry Baryshkov wrote:
> Master/virtual planes were used for multirect support. In preparation to
> reworking DPU planes, drop support for master planes (which was not used
> anyway).
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Agreed, master planes were unused today anyway.
hence,
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c    | 11 +---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c |  3 +-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  4 +-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c     |  2 +-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 72 ++++-----------------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   | 13 +---
>   6 files changed, 18 insertions(+), 87 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index e7c9fe1a250f..7318bd45637a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1138,17 +1138,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   	}
>   
>   	for (i = 1; i < SSPP_MAX; i++) {
> -		if (pipe_staged[i]) {
> +		if (pipe_staged[i])
>   			dpu_plane_clear_multirect(pipe_staged[i]);
> -
> -			if (is_dpu_plane_virtual(pipe_staged[i]->plane)) {
> -				DPU_ERROR(
> -					"r1 only virt plane:%d not supported\n",
> -					pipe_staged[i]->plane->base.id);
> -				rc  = -EINVAL;
> -				goto end;
> -			}
> -		}
>   	}
>   
>   	z_pos = -1;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> index 09cdc3576653..8714ee767346 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -783,8 +783,7 @@ static const struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp,
>   }
>   
>   struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
> -		void __iomem *addr, struct dpu_mdss_cfg *catalog,
> -		bool is_virtual_pipe)
> +		void __iomem *addr, struct dpu_mdss_cfg *catalog)
>   {
>   	struct dpu_hw_pipe *hw_pipe;
>   	const struct dpu_sspp_cfg *cfg;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> index 92b071b78fdb..1b18de957500 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -394,11 +394,9 @@ struct dpu_kms;
>    * @idx:  Pipe index for which driver object is required
>    * @addr: Mapped register io address of MDP
>    * @catalog : Pointer to mdss catalog data
> - * @is_virtual_pipe: is this pipe virtual pipe
>    */
>   struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
> -		void __iomem *addr, struct dpu_mdss_cfg *catalog,
> -		bool is_virtual_pipe);
> +		void __iomem *addr, struct dpu_mdss_cfg *catalog);
>   
>   /**
>    * dpu_hw_sspp_destroy(): Destroys SSPP driver context
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index 47fe11a84a77..4d2b75f3bc89 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -738,7 +738,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
>   			  catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR));
>   
>   		plane = dpu_plane_init(dev, catalog->sspp[i].id, type,
> -				       (1UL << max_crtc_count) - 1, 0);
> +				       (1UL << max_crtc_count) - 1);
>   		if (IS_ERR(plane)) {
>   			DPU_ERROR("dpu_plane_init failed\n");
>   			ret = PTR_ERR(plane);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index ca75089c9d61..3fcc964dec0a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -89,7 +89,7 @@ enum dpu_plane_qos {
>   /*
>    * struct dpu_plane - local dpu plane structure
>    * @aspace: address space pointer
> - * @mplane_list: List of multirect planes of the same pipe
> + * @csc_ptr: Points to dpu_csc_cfg structure to use for current
>    * @catalog: Points to dpu catalog structure
>    * @revalidate: force revalidation of all the plane properties
>    */
> @@ -104,8 +104,6 @@ struct dpu_plane {
>   	uint32_t color_fill;
>   	bool is_error;
>   	bool is_rt_pipe;
> -	bool is_virtual;
> -	struct list_head mplane_list;
>   	struct dpu_mdss_cfg *catalog;
>   };
>   
> @@ -223,7 +221,7 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_pipe_cfg
>   static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
>   		const struct dpu_format *fmt, u32 src_width)
>   {
> -	struct dpu_plane *pdpu, *tmp;
> +	struct dpu_plane *pdpu;
>   	struct dpu_plane_state *pstate;
>   	u32 fixed_buff_size;
>   	u32 total_fl;
> @@ -237,19 +235,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
>   	pstate = to_dpu_plane_state(plane->state);
>   	fixed_buff_size = pdpu->catalog->caps->pixel_ram_size;
>   
> -	list_for_each_entry(tmp, &pdpu->mplane_list, mplane_list) {
> -		u32 tmp_width;
> -
> -		if (!tmp->base.state->visible)
> -			continue;
> -		tmp_width = drm_rect_width(&tmp->base.state->src) >> 16;
> -		DPU_DEBUG("plane%d/%d src_width:%d/%d\n",
> -				pdpu->base.base.id, tmp->base.base.id,
> -				src_width,
> -				tmp_width);
> -		src_width = max_t(u32, src_width,
> -				  tmp_width);
> -	}
> +	/* FIXME: in multirect case account for the src_width of all the planes */
>   
>   	if (fmt->fetch_planes == DPU_PLANE_PSEUDO_PLANAR) {
>   		if (fmt->chroma_sample == DPU_CHROMA_420) {
> @@ -848,13 +834,8 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
>   	}
>   
>   done:
> -	if (dpu_plane[R0]->is_virtual) {
> -		pstate[R0]->multirect_index = DPU_SSPP_RECT_1;
> -		pstate[R1]->multirect_index = DPU_SSPP_RECT_0;
> -	} else {
> -		pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
> -		pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
> -	}
> +	pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
> +	pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
>   
>   	DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
>   		pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
> @@ -1213,19 +1194,13 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   
>   static void _dpu_plane_atomic_disable(struct drm_plane *plane)
>   {
> -	struct dpu_plane *pdpu = to_dpu_plane(plane);
>   	struct drm_plane_state *state = plane->state;
>   	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>   
> -	trace_dpu_plane_disable(DRMID(plane), is_dpu_plane_virtual(plane),
> +	trace_dpu_plane_disable(DRMID(plane), false,
>   				pstate->multirect_mode);
>   
>   	pstate->pending = true;
> -
> -	if (is_dpu_plane_virtual(plane) &&
> -			pdpu->pipe_hw && pdpu->pipe_hw->ops.setup_multirect)
> -		pdpu->pipe_hw->ops.setup_multirect(pdpu->pipe_hw,
> -				DPU_SSPP_RECT_SOLO, DPU_SSPP_MULTIRECT_NONE);
>   }
>   
>   static void dpu_plane_atomic_update(struct drm_plane *plane,
> @@ -1444,17 +1419,12 @@ enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane)
>   	return plane ? to_dpu_plane(plane)->pipe : SSPP_NONE;
>   }
>   
> -bool is_dpu_plane_virtual(struct drm_plane *plane)
> -{
> -	return plane ? to_dpu_plane(plane)->is_virtual : false;
> -}
> -
>   /* initialize plane */
>   struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   		uint32_t pipe, enum drm_plane_type type,
> -		unsigned long possible_crtcs, u32 master_plane_id)
> +		unsigned long possible_crtcs)
>   {
> -	struct drm_plane *plane = NULL, *master_plane = NULL;
> +	struct drm_plane *plane = NULL;
>   	const uint32_t *format_list;
>   	struct dpu_plane *pdpu;
>   	struct msm_drm_private *priv = dev->dev_private;
> @@ -1474,18 +1444,9 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   	/* cache local stuff for later */
>   	plane = &pdpu->base;
>   	pdpu->pipe = pipe;
> -	pdpu->is_virtual = (master_plane_id != 0);
> -	INIT_LIST_HEAD(&pdpu->mplane_list);
> -	master_plane = drm_plane_find(dev, NULL, master_plane_id);
> -	if (master_plane) {
> -		struct dpu_plane *mpdpu = to_dpu_plane(master_plane);
> -
> -		list_add_tail(&pdpu->mplane_list, &mpdpu->mplane_list);
> -	}
>   
>   	/* initialize underlying h/w driver */
> -	pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog,
> -							master_plane_id != 0);
> +	pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog);
>   	if (IS_ERR(pdpu->pipe_hw)) {
>   		DPU_ERROR("[%u]SSPP init failed\n", pipe);
>   		ret = PTR_ERR(pdpu->pipe_hw);
> @@ -1495,14 +1456,8 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   		goto clean_sspp;
>   	}
>   
> -	if (pdpu->is_virtual) {
> -		format_list = pdpu->pipe_hw->cap->sblk->virt_format_list;
> -		num_formats = pdpu->pipe_hw->cap->sblk->virt_num_formats;
> -	}
> -	else {
> -		format_list = pdpu->pipe_hw->cap->sblk->format_list;
> -		num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
> -	}
> +	format_list = pdpu->pipe_hw->cap->sblk->format_list;
> +	num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
>   
>   	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
>   				format_list, num_formats,
> @@ -1543,15 +1498,14 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   
>   	mutex_init(&pdpu->lock);
>   
> -	DPU_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", plane->name,
> -					pipe, plane->base.id, master_plane_id);
> +	DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name,
> +					pipe, plane->base.id);
>   	return plane;
>   
>   clean_sspp:
>   	if (pdpu && pdpu->pipe_hw)
>   		dpu_hw_sspp_destroy(pdpu->pipe_hw);
>   clean_plane:
> -	list_del(&pdpu->mplane_list);
>   	kfree(pdpu);
>   	return ERR_PTR(ret);
>   }
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> index 9d51dad5c6a5..d2f60810434e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -59,14 +59,6 @@ struct dpu_multirect_plane_states {
>    */
>   enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
>   
> -/**
> - * is_dpu_plane_virtual - check for virtual plane
> - * @plane: Pointer to DRM plane object
> - * returns: true - if the plane is virtual
> - *          false - if the plane is primary
> - */
> -bool is_dpu_plane_virtual(struct drm_plane *plane);
> -
>   /**
>    * dpu_plane_get_ctl_flush - get control flush mask
>    * @plane:   Pointer to DRM plane object
> @@ -94,14 +86,11 @@ void dpu_plane_set_error(struct drm_plane *plane, bool error);
>    * @pipe:  dpu hardware pipe identifier
>    * @type:  Plane type - PRIMARY/OVERLAY/CURSOR
>    * @possible_crtcs: bitmask of crtc that can be attached to the given pipe
> - * @master_plane_id: primary plane id of a multirect pipe. 0 value passed for
> - *                   a regular plane initialization. A non-zero primary plane
> - *                   id will be passed for a virtual pipe initialization.
>    *
>    */
>   struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   		uint32_t pipe, enum drm_plane_type type,
> -		unsigned long possible_crtcs, u32 master_plane_id);
> +		unsigned long possible_crtcs);
>   
>   /**
>    * dpu_plane_validate_multirecti_v2 - validate the multirect planes

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

* Re: [PATCH 02/25] drm/msm/dpu: do not limit the zpos property
  2022-02-09 17:24 ` [PATCH 02/25] drm/msm/dpu: do not limit the zpos property Dmitry Baryshkov
@ 2022-04-27  1:32   ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-04-27  1:32 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:24 AM, Dmitry Baryshkov wrote:
> Stop limiting zpos property values, we use normalized_zpos anyway. And
> nothing stops userspace from assigning several planes to a single zpos
> (it is a userspace bug, but the kernel is forgiving about it).
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 10 +---------
>   1 file changed, 1 insertion(+), 9 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 3fcc964dec0a..c04c3be16d85 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1429,7 +1429,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   	struct dpu_plane *pdpu;
>   	struct msm_drm_private *priv = dev->dev_private;
>   	struct dpu_kms *kms = to_dpu_kms(priv->kms);
> -	int zpos_max = DPU_ZPOS_MAX;
>   	uint32_t num_formats;
>   	int ret = -EINVAL;
>   
> @@ -1467,14 +1466,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   
>   	pdpu->catalog = kms->catalog;
>   
> -	if (kms->catalog->mixer_count &&
> -		kms->catalog->mixer[0].sblk->maxblendstages) {
> -		zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
> -		if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
> -			zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
> -	}
> -
> -	ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
> +	ret = drm_plane_create_zpos_property(plane, 0, 0, DPU_ZPOS_MAX);
>   	if (ret)
>   		DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
>   

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

* Re: [PATCH 03/25] drm/msm/dpu: add support for SSPP allocation to RM
  2022-02-09 17:24 ` [PATCH 03/25] drm/msm/dpu: add support for SSPP allocation to RM Dmitry Baryshkov
@ 2022-04-27  2:06   ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-04-27  2:06 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:24 AM, Dmitry Baryshkov wrote:
> Add support for handling and allocting SSPP blocks through the resource
> manager. Handling code is not converted to use it though.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 10 +++
>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h     |  1 +
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 18 ++---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c      | 81 +++++++++++++++++++++
>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h      |  6 ++
>   5 files changed, 104 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> index 1b18de957500..f805c30643b1 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -388,6 +388,16 @@ struct dpu_hw_pipe {
>   };
>   
>   struct dpu_kms;
> +/**
> + * to_dpu_hw_pipe - convert base object dpu_hw_base to container
> + * @hw: Pointer to base hardware block
> + * return: Pointer to hardware block container
> + */
> +static inline struct dpu_hw_pipe *to_dpu_hw_pipe(struct dpu_hw_blk *hw)
> +{
> +	return container_of(hw, struct dpu_hw_pipe, base);
> +}
> +
>   /**
>    * dpu_hw_sspp_init - initializes the sspp hw driver object.
>    * Should be called once before accessing every pipe.
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> index 2d385b4b7f5e..824495ad2392 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
> @@ -146,6 +146,7 @@ struct dpu_global_state {
>   	uint32_t ctl_to_enc_id[CTL_MAX - CTL_0];
>   	uint32_t intf_to_enc_id[INTF_MAX - INTF_0];
>   	uint32_t dspp_to_enc_id[DSPP_MAX - DSPP_0];
> +	uint32_t pipe_to_plane_id[SSPP_MAX - SSPP_NONE];
>   };
>   
>   struct dpu_global_state
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index c04c3be16d85..146dbccd79cd 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1235,8 +1235,6 @@ static void dpu_plane_destroy(struct drm_plane *plane)
>   		/* this will destroy the states as well */
>   		drm_plane_cleanup(plane);
>   
> -		dpu_hw_sspp_destroy(pdpu->pipe_hw);
> -
>   		kfree(pdpu);
>   	}
>   }
> @@ -1445,14 +1443,13 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   	pdpu->pipe = pipe;
>   
>   	/* initialize underlying h/w driver */
> -	pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog);
> -	if (IS_ERR(pdpu->pipe_hw)) {
> -		DPU_ERROR("[%u]SSPP init failed\n", pipe);
> -		ret = PTR_ERR(pdpu->pipe_hw);
> +	if (!kms->rm.sspp_blks[pipe - SSPP_NONE])
>   		goto clean_plane;
> -	} else if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
> +	pdpu->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
> +
> +	if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
>   		DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
> -		goto clean_sspp;
> +		goto clean_plane;
>   	}
>   
>   	format_list = pdpu->pipe_hw->cap->sblk->format_list;
> @@ -1462,7 +1459,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   				format_list, num_formats,
>   				supported_format_modifiers, type, NULL);
>   	if (ret)
> -		goto clean_sspp;
> +		goto clean_plane;
>   
>   	pdpu->catalog = kms->catalog;
>   
> @@ -1494,9 +1491,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   					pipe, plane->base.id);
>   	return plane;
>   
> -clean_sspp:
> -	if (pdpu && pdpu->pipe_hw)
> -		dpu_hw_sspp_destroy(pdpu->pipe_hw);
>   clean_plane:
>   	kfree(pdpu);
>   	return ERR_PTR(ret);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> index f9c83d6e427a..21c9e513f1f6 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> @@ -8,6 +8,7 @@
>   #include "dpu_hw_lm.h"
>   #include "dpu_hw_ctl.h"
>   #include "dpu_hw_pingpong.h"
> +#include "dpu_hw_sspp.h"
>   #include "dpu_hw_intf.h"
>   #include "dpu_hw_dspp.h"
>   #include "dpu_hw_merge3d.h"
> @@ -35,6 +36,14 @@ int dpu_rm_destroy(struct dpu_rm *rm)
>   {
>   	int i;
>   
> +	for (i = 0; i < ARRAY_SIZE(rm->sspp_blks); i++) {
> +		struct dpu_hw_pipe *hw;
> +
> +		if (rm->sspp_blks[i]) {
> +			hw = to_dpu_hw_pipe(rm->sspp_blks[i]);
> +			dpu_hw_sspp_destroy(hw);
> +		}
> +	}
>   	for (i = 0; i < ARRAY_SIZE(rm->pingpong_blks); i++) {
>   		struct dpu_hw_pingpong *hw;
>   
> @@ -166,6 +175,24 @@ int dpu_rm_init(struct dpu_rm *rm,
>   		rm->pingpong_blks[pp->id - PINGPONG_0] = &hw->base;
>   	}
>   
> +	for (i = 0; i < cat->sspp_count; i++) {
> +		struct dpu_hw_pipe *hw;
> +		const struct dpu_sspp_cfg *sspp = &cat->sspp[i];
> +
> +		if (sspp->id <= SSPP_NONE || sspp->id >= SSPP_MAX) {
> +			DPU_ERROR("skip sspp %d with invalid id\n", sspp->id);
> +			continue;
> +		}
> +		hw = dpu_hw_sspp_init(sspp->id, mmio, cat);
> +		if (IS_ERR_OR_NULL(hw)) {
> +			rc = PTR_ERR(hw);
> +			DPU_ERROR("failed sspp object creation: err %d\n",
> +				rc);
> +			goto fail;
> +		}
> +		rm->sspp_blks[sspp->id - SSPP_NONE] = &hw->base;
> +	}
> +
>   	for (i = 0; i < cat->intf_count; i++) {
>   		struct dpu_hw_intf *hw;
>   		const struct dpu_intf_cfg *intf = &cat->intf[i];
> @@ -660,3 +687,57 @@ int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
>   
>   	return num_blks;
>   }
> +
> +enum dpu_sspp dpu_rm_get_sspp(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t plane_id, bool yuv, bool scale)
> +{

Right now we have only yuv and scale as requirements for the incoming 
plane. But these requirements can expand.

Do you think a enum req_mask will be a good addition here?
You can start with having 2 masks for YUV and Scale but atleast that way 
its expandable cleanly rather than just increasing function parameters here.


> +	int i;
> +	enum dpu_sspp pipe = SSPP_NONE;
> +	struct dpu_hw_pipe *pipe_hw;
> +	bool retry = false;
> +
> +retry_loop:
> +	for (i = 0; i < ARRAY_SIZE(rm->sspp_blks) && pipe == SSPP_NONE; i++) {
> +		if (!rm->sspp_blks[i])
> +			continue;
> +		if (reserved_by_other(global_state->pipe_to_plane_id, i, plane_id))
> +			continue;
> +
> +		pipe_hw = to_dpu_hw_pipe(rm->sspp_blks[i]);
> +
> +		/* skip incompatible planes */
> +		if (scale && !(pipe_hw->cap->features & DPU_SSPP_SCALER))
> +			continue;
> +
> +		if (yuv && (!(pipe_hw->cap->features & DPU_SSPP_SCALER) ||
> +			    !(pipe_hw->cap->features & DPU_SSPP_CSC_ANY)))
> +			continue;
> +
> +		/* For non-yuv, non-scaled planes try to find simple (DMA)
> +		 * plane, fallback to VIG on a second try.
> +		 *
> +		 * This way we'd leave VIG pipes to be later used for YUV formats.
> +		 */
> +

this strategy should work. I just think we need to validate this quite a 
bit with some real world cases such as video playback with UI layers, 
opening and closing video players, browsers etc.

I am yet to review the usage of this in the next patches, but yes if 
even this wont kick in for small layers, we are protected.


> +		if (!scale && !yuv && !retry &&
> +		    (pipe_hw->cap->features & (DPU_SSPP_SCALER | DPU_SSPP_CSC_ANY)))
> +			continue;
> +
> +		pipe = i + SSPP_NONE;
> +	};
> +
> +	if (!scale && !yuv && !retry && pipe == SSPP_NONE) {
> +		retry = true;
> +		goto retry_loop;
> +	}
> +
> +	if (pipe != SSPP_NONE)
> +		global_state->pipe_to_plane_id[pipe - SSPP_NONE] = plane_id;
> +
> +	return pipe;
> +}
> +
> +void dpu_rm_release_sspp(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t plane_id)
> +{
> +	_dpu_rm_clear_mapping(global_state->pipe_to_plane_id,
> +			ARRAY_SIZE(global_state->pipe_to_plane_id), plane_id);
> +}
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
> index 1f12c8d5b8aa..b759fe39f6d6 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
> @@ -16,6 +16,7 @@ struct dpu_global_state;
>   /**
>    * struct dpu_rm - DPU dynamic hardware resource manager
>    * @pingpong_blks: array of pingpong hardware resources
> + * @sspp_blks: array of sspp hardware resources
>    * @mixer_blks: array of layer mixer hardware resources
>    * @ctl_blks: array of ctl hardware resources
>    * @intf_blks: array of intf hardware resources
> @@ -25,6 +26,7 @@ struct dpu_global_state;
>    */
>   struct dpu_rm {
>   	struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
> +	struct dpu_hw_blk *sspp_blks[SSPP_MAX - SSPP_NONE];
>   	struct dpu_hw_blk *mixer_blks[LM_MAX - LM_0];
>   	struct dpu_hw_blk *ctl_blks[CTL_MAX - CTL_0];
>   	struct dpu_hw_blk *intf_blks[INTF_MAX - INTF_0];
> @@ -88,5 +90,9 @@ void dpu_rm_release(struct dpu_global_state *global_state,
>   int dpu_rm_get_assigned_resources(struct dpu_rm *rm,
>   	struct dpu_global_state *global_state, uint32_t enc_id,
>   	enum dpu_hw_blk_type type, struct dpu_hw_blk **blks, int blks_size);
> +
> +enum dpu_sspp dpu_rm_get_sspp(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t plane_id, bool yuv, bool scale);
> +void dpu_rm_release_sspp(struct dpu_rm *rm, struct dpu_global_state *global_state, uint32_t plane_id);
> +
>   #endif /* __DPU_RM_H__ */
>   

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

* Re: [PATCH 04/25] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
  2022-02-09 17:24 ` [PATCH 04/25] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c Dmitry Baryshkov
@ 2022-05-03 21:34   ` Abhinav Kumar
  2022-05-03 22:11     ` Dmitry Baryshkov
  0 siblings, 1 reply; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-03 21:34 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:24 AM, Dmitry Baryshkov wrote:
> As SSPP blocks are now visible through dpu_kms->rm.sspp_blocks, move
> SSPP debugfs creation from dpu_plane to dpu_kms.
> 

Change is fine by itself, but is it really needed?
Wouldnt it be better to keep dpu_debugfs_sspp_init in dpu_plane.c?

> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  1 -
>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c     | 19 +++++++++++++++++++
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 16 ----------------
>   3 files changed, 19 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> index f805c30643b1..674f311f99b4 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -415,7 +415,6 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
>    */
>   void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx);
>   
> -void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root);
>   int _dpu_hw_sspp_init_debugfs(struct dpu_hw_pipe *hw_pipe, struct dpu_kms *kms, struct dentry *entry);
>   
>   #endif /*_DPU_HW_SSPP_H */
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index 4d2b75f3bc89..8196b11fe2f3 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -259,6 +259,25 @@ void dpu_debugfs_create_regset32(const char *name, umode_t mode,
>   	debugfs_create_file(name, mode, parent, regset, &dpu_fops_regset32);
>   }
>   
> +static void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root)
> +{
> +	struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
> +	int i;
> +
> +	if (IS_ERR(entry))
> +		return;
> +
> +	for (i = SSPP_NONE; i < SSPP_MAX; i++) {
> +		struct dpu_hw_pipe *pipe_hw;
> +
> +		if (!dpu_kms->rm.sspp_blks[i - SSPP_NONE])
> +			continue;
> +
> +		pipe_hw = to_dpu_hw_pipe(dpu_kms->rm.sspp_blks[i - SSPP_NONE]);
> +		_dpu_hw_sspp_init_debugfs(pipe_hw, dpu_kms, entry);
> +	}
> +}
> +
>   static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
>   {
>   	struct dpu_kms *dpu_kms = to_dpu_kms(kms);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 146dbccd79cd..37742f74a7bf 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1359,22 +1359,6 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
>   	_dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL);
>   	pm_runtime_put_sync(&dpu_kms->pdev->dev);
>   }
> -
> -/* SSPP live inside dpu_plane private data only. Enumerate them here. */
> -void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root)
> -{
> -	struct drm_plane *plane;
> -	struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
> -
> -	if (IS_ERR(entry))
> -		return;
> -
> -	drm_for_each_plane(plane, dpu_kms->dev) {
> -		struct dpu_plane *pdpu = to_dpu_plane(plane);
> -
> -		_dpu_hw_sspp_init_debugfs(pdpu->pipe_hw, dpu_kms, entry);
> -	}
> -}
>   #endif
>   
>   static bool dpu_plane_format_mod_supported(struct drm_plane *plane,

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

* Re: [PATCH 04/25] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
  2022-05-03 21:34   ` Abhinav Kumar
@ 2022-05-03 22:11     ` Dmitry Baryshkov
  2022-05-03 22:34       ` Abhinav Kumar
  0 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-05-03 22:11 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

On 04/05/2022 00:34, Abhinav Kumar wrote:
> 
> 
> On 2/9/2022 9:24 AM, Dmitry Baryshkov wrote:
>> As SSPP blocks are now visible through dpu_kms->rm.sspp_blocks, move
>> SSPP debugfs creation from dpu_plane to dpu_kms.
>>
> 
> Change is fine by itself, but is it really needed?
> Wouldnt it be better to keep dpu_debugfs_sspp_init in dpu_plane.c?

No. We are going to break the dependency between planes and SSPPs at 
some point. Let's move the debugfs functions to the generic location.

> 
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  1 -
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c     | 19 +++++++++++++++++++
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 16 ----------------
>>   3 files changed, 19 insertions(+), 17 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>> index f805c30643b1..674f311f99b4 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>> @@ -415,7 +415,6 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp 
>> idx,
>>    */
>>   void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx);
>> -void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
>> *debugfs_root);
>>   int _dpu_hw_sspp_init_debugfs(struct dpu_hw_pipe *hw_pipe, struct 
>> dpu_kms *kms, struct dentry *entry);
>>   #endif /*_DPU_HW_SSPP_H */
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>> index 4d2b75f3bc89..8196b11fe2f3 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>> @@ -259,6 +259,25 @@ void dpu_debugfs_create_regset32(const char 
>> *name, umode_t mode,
>>       debugfs_create_file(name, mode, parent, regset, 
>> &dpu_fops_regset32);
>>   }
>> +static void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct 
>> dentry *debugfs_root)
>> +{
>> +    struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
>> +    int i;
>> +
>> +    if (IS_ERR(entry))
>> +        return;
>> +
>> +    for (i = SSPP_NONE; i < SSPP_MAX; i++) {
>> +        struct dpu_hw_pipe *pipe_hw;
>> +
>> +        if (!dpu_kms->rm.sspp_blks[i - SSPP_NONE])
>> +            continue;
>> +
>> +        pipe_hw = to_dpu_hw_pipe(dpu_kms->rm.sspp_blks[i - SSPP_NONE]);
>> +        _dpu_hw_sspp_init_debugfs(pipe_hw, dpu_kms, entry);
>> +    }
>> +}
>> +
>>   static int dpu_kms_debugfs_init(struct msm_kms *kms, struct 
>> drm_minor *minor)
>>   {
>>       struct dpu_kms *dpu_kms = to_dpu_kms(kms);
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 146dbccd79cd..37742f74a7bf 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -1359,22 +1359,6 @@ void dpu_plane_danger_signal_ctrl(struct 
>> drm_plane *plane, bool enable)
>>       _dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL);
>>       pm_runtime_put_sync(&dpu_kms->pdev->dev);
>>   }
>> -
>> -/* SSPP live inside dpu_plane private data only. Enumerate them here. */
>> -void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
>> *debugfs_root)
>> -{
>> -    struct drm_plane *plane;
>> -    struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
>> -
>> -    if (IS_ERR(entry))
>> -        return;
>> -
>> -    drm_for_each_plane(plane, dpu_kms->dev) {
>> -        struct dpu_plane *pdpu = to_dpu_plane(plane);
>> -
>> -        _dpu_hw_sspp_init_debugfs(pdpu->pipe_hw, dpu_kms, entry);
>> -    }
>> -}
>>   #endif
>>   static bool dpu_plane_format_mod_supported(struct drm_plane *plane,


-- 
With best wishes
Dmitry

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

* Re: [PATCH 05/25] drm/msm/dpu: move pipe_hw to dpu_plane_state
  2022-02-09 17:25 ` [PATCH 05/25] drm/msm/dpu: move pipe_hw to dpu_plane_state Dmitry Baryshkov
@ 2022-05-03 22:32   ` Abhinav Kumar
  2022-05-14  6:37     ` Dmitry Baryshkov
  0 siblings, 1 reply; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-03 22:32 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> In preparation to adding fully virtualized planes, move struct
> dpu_hw_pipe instance from struct dpu_plane to struct dpu_plane_state, as
> it will become a part of state (allocated during atomic check) rather
> than part of a plane (allocated during boot).
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 104 ++++++++++++----------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   2 +
>   2 files changed, 58 insertions(+), 48 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 37742f74a7bf..0247ff8a67a2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -100,7 +100,6 @@ struct dpu_plane {
>   
>   	enum dpu_sspp pipe;
>   
> -	struct dpu_hw_pipe *pipe_hw;
>   	uint32_t color_fill;
>   	bool is_error;
>   	bool is_rt_pipe;
> @@ -300,6 +299,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
>   		struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg *pipe_cfg)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
> +	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>   	const struct dpu_format *fmt = NULL;
>   	u64 qos_lut;
>   	u32 total_fl = 0, lut_usage;
> @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
>   			fmt ? (char *)&fmt->base.pixel_format : NULL,
>   			pdpu->is_rt_pipe, total_fl, qos_lut);
>   
> -	pdpu->pipe_hw->ops.setup_creq_lut(pdpu->pipe_hw, qos_lut);
> +	pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
>   }
>   
>   /**
> @@ -343,6 +343,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
>   		struct drm_framebuffer *fb)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
> +	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>   	const struct dpu_format *fmt = NULL;
>   	u32 danger_lut, safe_lut;
>   
> @@ -382,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
>   		danger_lut,
>   		safe_lut);
>   
> -	pdpu->pipe_hw->ops.setup_danger_safe_lut(pdpu->pipe_hw,
> +	pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
>   			danger_lut, safe_lut);
>   }
>   
> @@ -396,14 +397,15 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>   	bool enable, u32 flags)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
> +	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>   	struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>   
>   	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>   
>   	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
> -		pipe_qos_cfg.creq_vblank = pdpu->pipe_hw->cap->sblk->creq_vblank;
> +		pipe_qos_cfg.creq_vblank = pstate->pipe_hw->cap->sblk->creq_vblank;
>   		pipe_qos_cfg.danger_vblank =
> -				pdpu->pipe_hw->cap->sblk->danger_vblank;
> +				pstate->pipe_hw->cap->sblk->danger_vblank;
>   		pipe_qos_cfg.vblank_en = enable;
>   	}
>   
> @@ -429,7 +431,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>   		pipe_qos_cfg.danger_vblank,
>   		pdpu->is_rt_pipe);
>   
> -	pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,
> +	pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
>   			&pipe_qos_cfg);
>   }
>   
> @@ -443,18 +445,19 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
>   		struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
> +	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>   	struct dpu_vbif_set_ot_params ot_params;
>   	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>   
>   	memset(&ot_params, 0, sizeof(ot_params));
> -	ot_params.xin_id = pdpu->pipe_hw->cap->xin_id;
> -	ot_params.num = pdpu->pipe_hw->idx - SSPP_NONE;
> +	ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
> +	ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
>   	ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
>   	ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
>   	ot_params.is_wfd = !pdpu->is_rt_pipe;
>   	ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
>   	ot_params.vbif_idx = VBIF_RT;
> -	ot_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
> +	ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>   	ot_params.rd = true;
>   
>   	dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
> @@ -467,14 +470,15 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
>   static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
> +	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>   	struct dpu_vbif_set_qos_params qos_params;
>   	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>   
>   	memset(&qos_params, 0, sizeof(qos_params));
>   	qos_params.vbif_idx = VBIF_RT;
> -	qos_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
> -	qos_params.xin_id = pdpu->pipe_hw->cap->xin_id;
> -	qos_params.num = pdpu->pipe_hw->idx - SSPP_VIG0;
> +	qos_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
> +	qos_params.xin_id = pstate->pipe_hw->cap->xin_id;
> +	qos_params.num = pstate->pipe_hw->idx - SSPP_VIG0;
>   	qos_params.is_rt = pdpu->is_rt_pipe;
>   
>   	DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, clk_ctrl:%d\n",
> @@ -501,11 +505,11 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
>   		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
>   	else if (ret)
>   		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> -	else if (pdpu->pipe_hw->ops.setup_sourceaddress) {
> -		trace_dpu_plane_set_scanout(pdpu->pipe_hw->idx,
> +	else if (pstate->pipe_hw->ops.setup_sourceaddress) {
> +		trace_dpu_plane_set_scanout(pstate->pipe_hw->idx,
>   					    &pipe_cfg->layout,
>   					    pstate->multirect_index);
> -		pdpu->pipe_hw->ops.setup_sourceaddress(pdpu->pipe_hw, pipe_cfg,
> +		pstate->pipe_hw->ops.setup_sourceaddress(pstate->pipe_hw, pipe_cfg,
>   						pstate->multirect_index);
>   	}
>   }
> @@ -549,7 +553,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
>   			scale_cfg->src_height[i] /= chroma_subsmpl_v;
>   		}
>   
> -		if (pdpu->pipe_hw->cap->features &
> +		if (pstate->pipe_hw->cap->features &
>   			BIT(DPU_SSPP_SCALER_QSEED4)) {
>   			scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
>   			scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
> @@ -609,6 +613,7 @@ static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
>   
>   static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, const struct dpu_format *fmt)
>   {
> +	struct dpu_plane_state *pstate = to_dpu_plane_state(pdpu->base.state);
>   	const struct dpu_csc_cfg *csc_ptr;
>   
>   	if (!pdpu) {
> @@ -619,7 +624,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
>   	if (!DPU_FORMAT_IS_YUV(fmt))
>   		return NULL;
>   
> -	if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->pipe_hw->cap->features)
> +	if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe_hw->cap->features)
>   		csc_ptr = &dpu_csc10_YUV2RGB_601L;
>   	else
>   		csc_ptr = &dpu_csc_YUV2RGB_601L;
> @@ -654,8 +659,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>   			&scaler3_cfg, &pixel_ext, fmt,
>   			info->hsub, info->vsub);
>   
> -	if (pdpu->pipe_hw->ops.setup_pe)
> -		pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
> +	if (pstate->pipe_hw->ops.setup_pe)
> +		pstate->pipe_hw->ops.setup_pe(pstate->pipe_hw,
>   				&pixel_ext);
>   
>   	/**
> @@ -663,9 +668,9 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>   	 * bypassed. Still we need to update alpha and bitwidth
>   	 * ONLY for RECT0
>   	 */
> -	if (pdpu->pipe_hw->ops.setup_scaler &&
> +	if (pstate->pipe_hw->ops.setup_scaler &&
>   			pstate->multirect_index != DPU_SSPP_RECT_1)
> -		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
> +		pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
>   				pipe_cfg,
>   				&scaler3_cfg);
>   }
> @@ -694,8 +699,8 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>   
>   	/* update sspp */
> -	if (fmt && pdpu->pipe_hw->ops.setup_solidfill) {
> -		pdpu->pipe_hw->ops.setup_solidfill(pdpu->pipe_hw,
> +	if (fmt && pstate->pipe_hw->ops.setup_solidfill) {
> +		pstate->pipe_hw->ops.setup_solidfill(pstate->pipe_hw,
>   				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
>   				pstate->multirect_index);
>   
> @@ -709,13 +714,13 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   		pipe_cfg.src_rect.y2 =
>   			drm_rect_height(&pipe_cfg.dst_rect);
>   
> -		if (pdpu->pipe_hw->ops.setup_format)
> -			pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw,
> +		if (pstate->pipe_hw->ops.setup_format)
> +			pstate->pipe_hw->ops.setup_format(pstate->pipe_hw,
>   					fmt, DPU_SSPP_SOLID_FILL,
>   					pstate->multirect_index);
>   
> -		if (pdpu->pipe_hw->ops.setup_rects)
> -			pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
> +		if (pstate->pipe_hw->ops.setup_rects)
> +			pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>   					&pipe_cfg,
>   					pstate->multirect_index);
>   
> @@ -953,10 +958,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   		crtc_state = drm_atomic_get_new_crtc_state(state,
>   							   new_plane_state->crtc);
>   
> -	min_scale = FRAC_16_16(1, pdpu->pipe_hw->cap->sblk->maxupscale);
> +	min_scale = FRAC_16_16(1, pstate->pipe_hw->cap->sblk->maxupscale);
>   	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
>   						  min_scale,
> -						  pdpu->pipe_hw->cap->sblk->maxdwnscale << 16,
> +						  pstate->pipe_hw->cap->sblk->maxdwnscale << 16,
>   						  true, true);
>   	if (ret) {
>   		DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
> @@ -982,8 +987,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>   
>   	if (DPU_FORMAT_IS_YUV(fmt) &&
> -		(!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
> -		 !(pdpu->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
> +		(!(pstate->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
> +		 !(pstate->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
>   		DPU_DEBUG_PLANE(pdpu,
>   				"plane doesn't have scaler/csc for yuv\n");
>   		return -EINVAL;
> @@ -1044,12 +1049,12 @@ void dpu_plane_flush(struct drm_plane *plane)
>   	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
>   		/* force 100% alpha */
>   		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
> -	else if (pdpu->pipe_hw && pdpu->pipe_hw->ops.setup_csc) {
> +	else if (pstate->pipe_hw && pstate->pipe_hw->ops.setup_csc) {
>   		const struct dpu_format *fmt = to_dpu_format(msm_framebuffer_format(plane->state->fb));
>   		const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, fmt);
>   
>   		if (csc_ptr)
> -			pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, csc_ptr);
> +			pstate->pipe_hw->ops.setup_csc(pstate->pipe_hw, csc_ptr);
>   	}
>   
>   	/* flag h/w flush complete */
> @@ -1116,21 +1121,21 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   		return;
>   	}
>   
> -	if (pdpu->pipe_hw->ops.setup_rects) {
> -		pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
> +	if (pstate->pipe_hw->ops.setup_rects) {
> +		pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>   				&pipe_cfg,
>   				pstate->multirect_index);
>   	}
>   
>   	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
>   
> -	if (pdpu->pipe_hw->ops.setup_multirect)
> -		pdpu->pipe_hw->ops.setup_multirect(
> -				pdpu->pipe_hw,
> +	if (pstate->pipe_hw->ops.setup_multirect)
> +		pstate->pipe_hw->ops.setup_multirect(
> +				pstate->pipe_hw,
>   				pstate->multirect_index,
>   				pstate->multirect_mode);
>   
> -	if (pdpu->pipe_hw->ops.setup_format) {
> +	if (pstate->pipe_hw->ops.setup_format) {
>   		unsigned int rotation;
>   
>   		src_flags = 0x0;
> @@ -1147,10 +1152,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   			src_flags |= DPU_SSPP_FLIP_UD;
>   
>   		/* update format */
> -		pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw, fmt, src_flags,
> +		pstate->pipe_hw->ops.setup_format(pstate->pipe_hw, fmt, src_flags,
>   				pstate->multirect_index);
>   
> -		if (pdpu->pipe_hw->ops.setup_cdp) {
> +		if (pstate->pipe_hw->ops.setup_cdp) {
>   			struct dpu_hw_pipe_cdp_cfg cdp_cfg;
>   
>   			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
> @@ -1164,7 +1169,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   					DPU_FORMAT_IS_TILE(fmt);
>   			cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
>   
> -			pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, &cdp_cfg, pstate->multirect_index);
> +			pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg, pstate->multirect_index);
>   		}
>   	}
>   
> @@ -1310,10 +1315,9 @@ static void dpu_plane_atomic_print_state(struct drm_printer *p,
>   		const struct drm_plane_state *state)
>   {
>   	const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
> -	const struct dpu_plane *pdpu = to_dpu_plane(state->plane);
>   
>   	drm_printf(p, "\tstage=%d\n", pstate->stage);
> -	drm_printf(p, "\tsspp=%s\n", pdpu->pipe_hw->cap->name);
> +	drm_printf(p, "\tsspp=%s\n", pstate->pipe_hw->cap->name);
>   	drm_printf(p, "\tmultirect_mode=%s\n", dpu_get_multirect_mode(pstate->multirect_mode));
>   	drm_printf(p, "\tmultirect_index=%s\n", dpu_get_multirect_index(pstate->multirect_index));
>   }
> @@ -1322,6 +1326,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
>   {
>   	struct dpu_plane *pdpu;
>   	struct dpu_plane_state *pstate;
> +	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
>   
>   	if (!plane) {
>   		DPU_ERROR("invalid plane\n");
> @@ -1343,6 +1348,8 @@ static void dpu_plane_reset(struct drm_plane *plane)
>   		return;
>   	}
>   
> +	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
> +
>   	__drm_atomic_helper_plane_reset(plane, &pstate->base);
>   }
>   
> @@ -1411,6 +1418,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   	struct dpu_plane *pdpu;
>   	struct msm_drm_private *priv = dev->dev_private;
>   	struct dpu_kms *kms = to_dpu_kms(priv->kms);
> +	struct dpu_hw_pipe *pipe_hw;
>   	uint32_t num_formats;
>   	int ret = -EINVAL;
>   
> @@ -1429,15 +1437,15 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   	/* initialize underlying h/w driver */
>   	if (!kms->rm.sspp_blks[pipe - SSPP_NONE])
>   		goto clean_plane;
> -	pdpu->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
> +	pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
>   
> -	if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
> +	if (!pipe_hw->cap || !pipe_hw->cap->sblk) {
>   		DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
>   		goto clean_plane;
>   	}
>   
> -	format_list = pdpu->pipe_hw->cap->sblk->format_list;
> -	num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
> +	format_list = pipe_hw->cap->sblk->format_list;
> +	num_formats = pipe_hw->cap->sblk->num_formats;
>   
>   	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
>   				format_list, num_formats,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> index d2f60810434e..42b88b6bc9c2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -35,6 +35,8 @@ struct dpu_plane_state {
>   	uint32_t multirect_mode;
>   	bool pending;
>   
> +	struct dpu_hw_pipe *pipe_hw;

now that pipe_hw has been made part of the dpu_plane_state, it means
that it can also change with atomic state.

In this change, I can see you update this only in dpu_plane_reset() 
which will be invoked during the drm_mode_config_reset().

Should this pipe_hw assignment be moved to the dpu_plane_atomic_update() 
function?

> +
>   	u64 plane_fetch_bw;
>   	u64 plane_clk;
>   };

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

* Re: [PATCH 04/25] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
  2022-05-03 22:11     ` Dmitry Baryshkov
@ 2022-05-03 22:34       ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-03 22:34 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 5/3/2022 3:11 PM, Dmitry Baryshkov wrote:
> On 04/05/2022 00:34, Abhinav Kumar wrote:
>>
>>
>> On 2/9/2022 9:24 AM, Dmitry Baryshkov wrote:
>>> As SSPP blocks are now visible through dpu_kms->rm.sspp_blocks, move
>>> SSPP debugfs creation from dpu_plane to dpu_kms.
>>>
>>
>> Change is fine by itself, but is it really needed?
>> Wouldnt it be better to keep dpu_debugfs_sspp_init in dpu_plane.c?
> 
> No. We are going to break the dependency between planes and SSPPs at 
> some point. Let's move the debugfs functions to the generic location.
> 

Alright, keeping that dependency-break in mind,

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  1 -
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c     | 19 +++++++++++++++++++
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 16 ----------------
>>>   3 files changed, 19 insertions(+), 17 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>>> index f805c30643b1..674f311f99b4 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>>> @@ -415,7 +415,6 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum 
>>> dpu_sspp idx,
>>>    */
>>>   void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx);
>>> -void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
>>> *debugfs_root);
>>>   int _dpu_hw_sspp_init_debugfs(struct dpu_hw_pipe *hw_pipe, struct 
>>> dpu_kms *kms, struct dentry *entry);
>>>   #endif /*_DPU_HW_SSPP_H */
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>>> index 4d2b75f3bc89..8196b11fe2f3 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
>>> @@ -259,6 +259,25 @@ void dpu_debugfs_create_regset32(const char 
>>> *name, umode_t mode,
>>>       debugfs_create_file(name, mode, parent, regset, 
>>> &dpu_fops_regset32);
>>>   }
>>> +static void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct 
>>> dentry *debugfs_root)
>>> +{
>>> +    struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
>>> +    int i;
>>> +
>>> +    if (IS_ERR(entry))
>>> +        return;
>>> +
>>> +    for (i = SSPP_NONE; i < SSPP_MAX; i++) {
>>> +        struct dpu_hw_pipe *pipe_hw;
>>> +
>>> +        if (!dpu_kms->rm.sspp_blks[i - SSPP_NONE])
>>> +            continue;
>>> +
>>> +        pipe_hw = to_dpu_hw_pipe(dpu_kms->rm.sspp_blks[i - SSPP_NONE]);
>>> +        _dpu_hw_sspp_init_debugfs(pipe_hw, dpu_kms, entry);
>>> +    }
>>> +}
>>> +
>>>   static int dpu_kms_debugfs_init(struct msm_kms *kms, struct 
>>> drm_minor *minor)
>>>   {
>>>       struct dpu_kms *dpu_kms = to_dpu_kms(kms);
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> index 146dbccd79cd..37742f74a7bf 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -1359,22 +1359,6 @@ void dpu_plane_danger_signal_ctrl(struct 
>>> drm_plane *plane, bool enable)
>>>       _dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL);
>>>       pm_runtime_put_sync(&dpu_kms->pdev->dev);
>>>   }
>>> -
>>> -/* SSPP live inside dpu_plane private data only. Enumerate them 
>>> here. */
>>> -void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry 
>>> *debugfs_root)
>>> -{
>>> -    struct drm_plane *plane;
>>> -    struct dentry *entry = debugfs_create_dir("sspp", debugfs_root);
>>> -
>>> -    if (IS_ERR(entry))
>>> -        return;
>>> -
>>> -    drm_for_each_plane(plane, dpu_kms->dev) {
>>> -        struct dpu_plane *pdpu = to_dpu_plane(plane);
>>> -
>>> -        _dpu_hw_sspp_init_debugfs(pdpu->pipe_hw, dpu_kms, entry);
>>> -    }
>>> -}
>>>   #endif
>>>   static bool dpu_plane_format_mod_supported(struct drm_plane *plane,
> 
> 

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

* Re: [PATCH 06/25] drm/msm/dpu: inline dpu_plane_get_ctl_flush
  2022-02-09 17:25 ` [PATCH 06/25] drm/msm/dpu: inline dpu_plane_get_ctl_flush Dmitry Baryshkov
@ 2022-05-03 22:55   ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-03 22:55 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> There is no need to keep a separate function for calling into the ctl if
> we already know all the details. Inline this function in the dpu_crtc.c
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 15 ++++++++-------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 12 ------------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  9 ---------
>   3 files changed, 8 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 7318bd45637a..5fc338ef3460 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -348,7 +348,6 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   	struct dpu_format *format;
>   	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>   
> -	u32 flush_mask;
>   	uint32_t stage_idx, lm_idx;
>   	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
>   	bool bg_alpha_enable = false;
> @@ -356,6 +355,8 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   
>   	memset(fetch_active, 0, sizeof(fetch_active));
>   	drm_atomic_crtc_for_each_plane(plane, crtc) {
> +		enum dpu_sspp sspp_idx;
> +
>   		state = plane->state;
>   		if (!state)
>   			continue;
> @@ -363,14 +364,14 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   		pstate = to_dpu_plane_state(state);
>   		fb = state->fb;
>   
> -		dpu_plane_get_ctl_flush(plane, ctl, &flush_mask);
> -		set_bit(dpu_plane_pipe(plane), fetch_active);
> +		sspp_idx = dpu_plane_pipe(plane);
> +		set_bit(sspp_idx, fetch_active);
>   
>   		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
>   				crtc->base.id,
>   				pstate->stage,
>   				plane->base.id,
> -				dpu_plane_pipe(plane) - SSPP_VIG0,
> +				sspp_idx - SSPP_VIG0,
>   				state->fb ? state->fb->base.id : -1);
>   
>   		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
> @@ -380,13 +381,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   
>   		stage_idx = zpos_cnt[pstate->stage]++;
>   		stage_cfg->stage[pstate->stage][stage_idx] =
> -					dpu_plane_pipe(plane);
> +					sspp_idx;
>   		stage_cfg->multirect_index[pstate->stage][stage_idx] =
>   					pstate->multirect_index;
>   
>   		trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
>   					   state, pstate, stage_idx,
> -					   dpu_plane_pipe(plane) - SSPP_VIG0,
> +					   sspp_idx - SSPP_VIG0,
>   					   format->base.pixel_format,
>   					   fb ? fb->modifier : 0);
>   
> @@ -395,7 +396,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   			_dpu_crtc_setup_blend_cfg(mixer + lm_idx,
>   						pstate, format);
>   
> -			mixer[lm_idx].flush_mask |= flush_mask;
> +			mixer[lm_idx].flush_mask |= ctl->ops.get_bitmask_sspp(ctl, sspp_idx);
>   
>   			if (bg_alpha_enable && !format->alpha_enable)
>   				mixer[lm_idx].mixer_op_mode = 0;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 0247ff8a67a2..ca194cd83cd0 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -849,18 +849,6 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
>   	return 0;
>   }
>   
> -/**
> - * dpu_plane_get_ctl_flush - get control flush for the given plane
> - * @plane: Pointer to drm plane structure
> - * @ctl: Pointer to hardware control driver
> - * @flush_sspp: Pointer to sspp flush control word
> - */
> -void dpu_plane_get_ctl_flush(struct drm_plane *plane, struct dpu_hw_ctl *ctl,
> -		u32 *flush_sspp)
> -{
> -	*flush_sspp = ctl->ops.get_bitmask_sspp(ctl, dpu_plane_pipe(plane));
> -}
> -
>   static int dpu_plane_prepare_fb(struct drm_plane *plane,
>   		struct drm_plane_state *new_state)
>   {
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> index 42b88b6bc9c2..aa9478b475d4 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -61,15 +61,6 @@ struct dpu_multirect_plane_states {
>    */
>   enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
>   
> -/**
> - * dpu_plane_get_ctl_flush - get control flush mask
> - * @plane:   Pointer to DRM plane object
> - * @ctl: Pointer to control hardware
> - * @flush_sspp: Pointer to sspp flush control word
> - */
> -void dpu_plane_get_ctl_flush(struct drm_plane *plane, struct dpu_hw_ctl *ctl,
> -		u32 *flush_sspp);
> -
>   /**
>    * dpu_plane_flush - final plane operations before commit flush
>    * @plane: Pointer to drm plane structure

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

* Re: [PATCH 07/25] drm/msm/dpu: drop dpu_plane_pipe function
  2022-02-09 17:25 ` [PATCH 07/25] drm/msm/dpu: drop dpu_plane_pipe function Dmitry Baryshkov
@ 2022-05-03 23:04   ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-03 23:04 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> There no more need for the dpu_plane_pipe() function, crtc code can
> access pstate->pipe_hw.idx directly.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Perhaps this can be squashed with the previous change.

Otherwise,

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 4 ++--
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 5 -----
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 7 -------
>   3 files changed, 2 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 5fc338ef3460..d21791db6ab1 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -364,7 +364,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   		pstate = to_dpu_plane_state(state);
>   		fb = state->fb;
>   
> -		sspp_idx = dpu_plane_pipe(plane);
> +		sspp_idx = pstate->pipe_hw->idx;
>   		set_bit(sspp_idx, fetch_active);
>   
>   		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
> @@ -1112,7 +1112,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   		pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
>   		pstates[cnt].drm_pstate = pstate;
>   		pstates[cnt].stage = pstate->normalized_zpos;
> -		pstates[cnt].pipe_id = dpu_plane_pipe(plane);
> +		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe_hw->idx;
>   
>   		if (pipe_staged[pstates[cnt].pipe_id]) {
>   			multirect_plane[multirect_count].r0 =
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index ca194cd83cd0..d1f9b4bc10ac 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1391,11 +1391,6 @@ static const struct drm_plane_helper_funcs dpu_plane_helper_funcs = {
>   		.atomic_update = dpu_plane_atomic_update,
>   };
>   
> -enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane)
> -{
> -	return plane ? to_dpu_plane(plane)->pipe : SSPP_NONE;
> -}
> -
>   /* initialize plane */
>   struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   		uint32_t pipe, enum drm_plane_type type,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> index aa9478b475d4..d745cde4ea77 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -54,13 +54,6 @@ struct dpu_multirect_plane_states {
>   #define to_dpu_plane_state(x) \
>   	container_of(x, struct dpu_plane_state, base)
>   
> -/**
> - * dpu_plane_pipe - return sspp identifier for the given plane
> - * @plane:   Pointer to DRM plane object
> - * Returns: sspp identifier of the given plane
> - */
> -enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
> -
>   /**
>    * dpu_plane_flush - final plane operations before commit flush
>    * @plane: Pointer to drm plane structure

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

* Re: [PATCH 08/25] drm/msm/dpu: get rid of cached flush_mask
  2022-02-09 17:25 ` [PATCH 08/25] drm/msm/dpu: get rid of cached flush_mask Dmitry Baryshkov
@ 2022-05-03 23:40   ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-03 23:40 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> Instead of querying the CTL for the flush mask (for SSPP, LM or DSPP),
> storing the mask in the mixer configuration and then pushing the mask to
> the CTL, tell CTL to cache the flush in place.
> 

This follows the pattern of other update_pending_flush_*** ops which we 
have so this is fine.

This change can go in independent of this series. no need to wait.

Apart from a minor comments nit below,

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c   | 25 ++-----
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h   |  1 -
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 78 +++++++++-------------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 35 +++++++---
>   4 files changed, 66 insertions(+), 73 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index d21791db6ab1..e6c33022d560 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -396,7 +396,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   			_dpu_crtc_setup_blend_cfg(mixer + lm_idx,
>   						pstate, format);
>   
> -			mixer[lm_idx].flush_mask |= ctl->ops.get_bitmask_sspp(ctl, sspp_idx);
> +			mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx);
>   
>   			if (bg_alpha_enable && !format->alpha_enable)
>   				mixer[lm_idx].mixer_op_mode = 0;
> @@ -430,7 +430,6 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
>   
>   	for (i = 0; i < cstate->num_mixers; i++) {
>   		mixer[i].mixer_op_mode = 0;
> -		mixer[i].flush_mask = 0;
>   		if (mixer[i].lm_ctl->ops.clear_all_blendstages)
>   			mixer[i].lm_ctl->ops.clear_all_blendstages(
>   					mixer[i].lm_ctl);
> @@ -447,17 +446,14 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
>   
>   		lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
>   
> -		mixer[i].flush_mask |= ctl->ops.get_bitmask_mixer(ctl,
> -			mixer[i].hw_lm->idx);
> -
>   		/* stage config flush mask */
> -		ctl->ops.update_pending_flush(ctl, mixer[i].flush_mask);
> +		ctl->ops.update_pending_flush_mixer(ctl,
> +			mixer[i].hw_lm->idx);
>   
> -		DRM_DEBUG_ATOMIC("lm %d, op_mode 0x%X, ctl %d, flush mask 0x%x\n",
> +		DRM_DEBUG_ATOMIC("lm %d, op_mode 0x%X, ctl %d\n",
>   			mixer[i].hw_lm->idx - LM_0,
>   			mixer[i].mixer_op_mode,
> -			ctl->idx - CTL_0,
> -			mixer[i].flush_mask);
> +			ctl->idx - CTL_0);
>   
>   		ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
>   			&stage_cfg);
> @@ -701,16 +697,9 @@ static void _dpu_crtc_setup_cp_blocks(struct drm_crtc *crtc)
>   			dspp->ops.setup_pcc(dspp, &cfg);
>   		}
>   
> -		mixer[i].flush_mask |= ctl->ops.get_bitmask_dspp(ctl,
> -			mixer[i].hw_dspp->idx);
> -
>   		/* stage config flush mask */
> -		ctl->ops.update_pending_flush(ctl, mixer[i].flush_mask);
> -
> -		DRM_DEBUG_ATOMIC("lm %d, ctl %d, flush mask 0x%x\n",
> -			mixer[i].hw_lm->idx - DSPP_0,
> -			ctl->idx - CTL_0,
> -			mixer[i].flush_mask);
> +		ctl->ops.update_pending_flush_dspp(ctl,
> +			mixer[i].hw_dspp->idx);
>   	}
>   }
>   
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> index b8785c394fcc..9f87fc32b1bb 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
> @@ -95,7 +95,6 @@ struct dpu_crtc_mixer {
>   	struct dpu_hw_ctl *lm_ctl;
>   	struct dpu_hw_dspp *hw_dspp;
>   	u32 mixer_op_mode;
> -	u32 flush_mask;
>   };
>   
>   /**
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> index 02da9ecf71f1..8dc59659bd18 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> @@ -139,92 +139,84 @@ static inline void dpu_hw_ctl_trigger_flush(struct dpu_hw_ctl *ctx)
>   	DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
>   }
>   
> -static uint32_t dpu_hw_ctl_get_bitmask_sspp(struct dpu_hw_ctl *ctx,
> +static void dpu_hw_ctl_update_pending_flush_sspp(struct dpu_hw_ctl *ctx,
>   	enum dpu_sspp sspp)
>   {
> -	uint32_t flushbits = 0;
> -
>   	switch (sspp) {
>   	case SSPP_VIG0:
> -		flushbits =  BIT(0);
> +		ctx->pending_flush_mask |=  BIT(0);
>   		break;
>   	case SSPP_VIG1:
> -		flushbits = BIT(1);
> +		ctx->pending_flush_mask |= BIT(1);
>   		break;
>   	case SSPP_VIG2:
> -		flushbits = BIT(2);
> +		ctx->pending_flush_mask |= BIT(2);
>   		break;
>   	case SSPP_VIG3:
> -		flushbits = BIT(18);
> +		ctx->pending_flush_mask |= BIT(18);
>   		break;
>   	case SSPP_RGB0:
> -		flushbits = BIT(3);
> +		ctx->pending_flush_mask |= BIT(3);
>   		break;
>   	case SSPP_RGB1:
> -		flushbits = BIT(4);
> +		ctx->pending_flush_mask |= BIT(4);
>   		break;
>   	case SSPP_RGB2:
> -		flushbits = BIT(5);
> +		ctx->pending_flush_mask |= BIT(5);
>   		break;
>   	case SSPP_RGB3:
> -		flushbits = BIT(19);
> +		ctx->pending_flush_mask |= BIT(19);
>   		break;
>   	case SSPP_DMA0:
> -		flushbits = BIT(11);
> +		ctx->pending_flush_mask |= BIT(11);
>   		break;
>   	case SSPP_DMA1:
> -		flushbits = BIT(12);
> +		ctx->pending_flush_mask |= BIT(12);
>   		break;
>   	case SSPP_DMA2:
> -		flushbits = BIT(24);
> +		ctx->pending_flush_mask |= BIT(24);
>   		break;
>   	case SSPP_DMA3:
> -		flushbits = BIT(25);
> +		ctx->pending_flush_mask |= BIT(25);
>   		break;
>   	case SSPP_CURSOR0:
> -		flushbits = BIT(22);
> +		ctx->pending_flush_mask |= BIT(22);
>   		break;
>   	case SSPP_CURSOR1:
> -		flushbits = BIT(23);
> +		ctx->pending_flush_mask |= BIT(23);
>   		break;
>   	default:
>   		break;
>   	}
> -
> -	return flushbits;
>   }
>   
> -static uint32_t dpu_hw_ctl_get_bitmask_mixer(struct dpu_hw_ctl *ctx,
> +static void dpu_hw_ctl_update_pending_flush_mixer(struct dpu_hw_ctl *ctx,
>   	enum dpu_lm lm)
>   {
> -	uint32_t flushbits = 0;
> -
>   	switch (lm) {
>   	case LM_0:
> -		flushbits = BIT(6);
> +		ctx->pending_flush_mask |= BIT(6);
>   		break;
>   	case LM_1:
> -		flushbits = BIT(7);
> +		ctx->pending_flush_mask |= BIT(7);
>   		break;
>   	case LM_2:
> -		flushbits = BIT(8);
> +		ctx->pending_flush_mask |= BIT(8);
>   		break;
>   	case LM_3:
> -		flushbits = BIT(9);
> +		ctx->pending_flush_mask |= BIT(9);
>   		break;
>   	case LM_4:
> -		flushbits = BIT(10);
> +		ctx->pending_flush_mask |= BIT(10);
>   		break;
>   	case LM_5:
> -		flushbits = BIT(20);
> +		ctx->pending_flush_mask |= BIT(20);
>   		break;
>   	default:
> -		return -EINVAL;
> +		break;
>   	}
>   
> -	flushbits |= CTL_FLUSH_MASK_CTL;
> -
> -	return flushbits;
> +	ctx->pending_flush_mask |= CTL_FLUSH_MASK_CTL;
>   }
>   
>   static void dpu_hw_ctl_update_pending_flush_intf(struct dpu_hw_ctl *ctx,
> @@ -262,29 +254,25 @@ static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx,
>   	ctx->pending_flush_mask |= BIT(MERGE_3D_IDX);
>   }
>   
> -static uint32_t dpu_hw_ctl_get_bitmask_dspp(struct dpu_hw_ctl *ctx,
> +static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
>   	enum dpu_dspp dspp)
>   {
> -	uint32_t flushbits = 0;
> -
>   	switch (dspp) {
>   	case DSPP_0:
> -		flushbits = BIT(13);
> +		ctx->pending_flush_mask |= BIT(13);
>   		break;
>   	case DSPP_1:
> -		flushbits = BIT(14);
> +		ctx->pending_flush_mask |= BIT(14);
>   		break;
>   	case DSPP_2:
> -		flushbits = BIT(15);
> +		ctx->pending_flush_mask |= BIT(15);
>   		break;
>   	case DSPP_3:
> -		flushbits = BIT(21);
> +		ctx->pending_flush_mask |= BIT(21);
>   		break;
>   	default:
> -		return 0;
> +		break;
>   	}
> -
> -	return flushbits;
>   }
>   
>   static u32 dpu_hw_ctl_poll_reset_status(struct dpu_hw_ctl *ctx, u32 timeout_us)
> @@ -592,9 +580,9 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
>   	ops->wait_reset_status = dpu_hw_ctl_wait_reset_status;
>   	ops->clear_all_blendstages = dpu_hw_ctl_clear_all_blendstages;
>   	ops->setup_blendstage = dpu_hw_ctl_setup_blendstage;
> -	ops->get_bitmask_sspp = dpu_hw_ctl_get_bitmask_sspp;
> -	ops->get_bitmask_mixer = dpu_hw_ctl_get_bitmask_mixer;
> -	ops->get_bitmask_dspp = dpu_hw_ctl_get_bitmask_dspp;
> +	ops->update_pending_flush_sspp = dpu_hw_ctl_update_pending_flush_sspp;
> +	ops->update_pending_flush_mixer = dpu_hw_ctl_update_pending_flush_mixer;
> +	ops->update_pending_flush_dspp = dpu_hw_ctl_update_pending_flush_dspp;
>   	if (cap & BIT(DPU_CTL_FETCH_ACTIVE))
>   		ops->set_active_pipes = dpu_hw_ctl_set_fetch_pipe_active;
>   };
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
> index 806c171e5df2..84e8167c23a1 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
> @@ -110,6 +110,32 @@ struct dpu_hw_ctl_ops {
>   	void (*update_pending_flush_merge_3d)(struct dpu_hw_ctl *ctx,
>   		enum dpu_merge_3d blk);
>   
> +	/**
> +	 * OR in the given flushbits to the cached pending_flush_mask
> +	 * No effect on hardware
flush bits for SSPP

> +	 * @ctx       : ctl path ctx pointer
> +	 * @blk       : SSPP block index
> +	 */
> +	void (*update_pending_flush_sspp)(struct dpu_hw_ctl *ctx,
> +		enum dpu_sspp blk);
> +
> +	/**
> +	 * OR in the given flushbits to the cached pending_flush_mask
> +	 * No effect on hardware
> +	 * @ctx       : ctl path ctx pointer
> +	 * @blk       : LM block index
> +	 */
flush bits for blend stages
> +	void (*update_pending_flush_mixer)(struct dpu_hw_ctl *ctx,
> +		enum dpu_lm blk);
> +
> +	/**
> +	 * OR in the given flushbits to the cached pending_flush_mask
> +	 * No effect on hardware
flush bits for DSPP
> +	 * @ctx       : ctl path ctx pointer
> +	 * @blk       : DSPP block index
> +	 */
> +	void (*update_pending_flush_dspp)(struct dpu_hw_ctl *ctx,
> +		enum dpu_dspp blk);
>   	/**
>   	 * Write the value of the pending_flush_mask to hardware
>   	 * @ctx       : ctl path ctx pointer
> @@ -144,15 +170,6 @@ struct dpu_hw_ctl_ops {
>   	 */
>   	int (*wait_reset_status)(struct dpu_hw_ctl *ctx);
>   
> -	uint32_t (*get_bitmask_sspp)(struct dpu_hw_ctl *ctx,
> -		enum dpu_sspp blk);
> -
> -	uint32_t (*get_bitmask_mixer)(struct dpu_hw_ctl *ctx,
> -		enum dpu_lm blk);
> -
> -	uint32_t (*get_bitmask_dspp)(struct dpu_hw_ctl *ctx,
> -		enum dpu_dspp blk);
> -
>   	/**
>   	 * Set all blend stages to disabled
>   	 * @ctx       : ctl path ctx pointer

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

* Re: [PATCH 09/25] drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic
  2022-02-09 17:25 ` [PATCH 09/25] drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic Dmitry Baryshkov
@ 2022-05-06 18:56   ` Abhinav Kumar
  2022-05-06 20:14     ` Dmitry Baryshkov
  0 siblings, 1 reply; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-06 18:56 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> The funcitons _dpu_crtc_blend_setup() and _dpu_crtc_blend_setup_mixer()
> have an intertwined mixture of CTL and LM-related code. Split these two
> functions into LM-specific and CTL-specific parts, making both code
> paths clean and observable.
> 

I do see the intention of this change, but there are two things to 
consider here.

Let me know what you think of those:

1) Agreed that we are able to split it out but at what cost? We are 
repeating some of the loops such as

a) for (i = 0; i < cstate->num_mixers; i++) {
b) drm_atomic_crtc_for_each_plane(

2) The intertwining is "somewhat" logical here because we are 
programming the LMs for which we are staging the planes so it somewhat 
goes together

3) dropping sspp idx from this trace removes some useful informatio of 
which sspp is staged to which stage of blend

 >   		trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
 >   					   state, pstate, stage_idx,
 > -					   sspp_idx - SSPP_VIG0,
 >   					   format->base.pixel_format,
 >   					   fb ? fb->modifier : 0);


> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 101 +++++++++++++---------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |  10 +--
>   2 files changed, 63 insertions(+), 48 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index e6c33022d560..ada7d5750536 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -336,27 +336,23 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
>   	}
>   }
>   
> -static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> -	struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer,
> -	struct dpu_hw_stage_cfg *stage_cfg)
> +static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc)
>   {
> +	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
> +	struct dpu_crtc_mixer *mixer = cstate->mixers;
>   	struct drm_plane *plane;
>   	struct drm_framebuffer *fb;
>   	struct drm_plane_state *state;
> -	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
>   	struct dpu_plane_state *pstate = NULL;
>   	struct dpu_format *format;
> -	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
> -
> +	int i;
>   	uint32_t stage_idx, lm_idx;
> -	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
>   	bool bg_alpha_enable = false;
> -	DECLARE_BITMAP(fetch_active, SSPP_MAX);
>   
> -	memset(fetch_active, 0, sizeof(fetch_active));
> -	drm_atomic_crtc_for_each_plane(plane, crtc) {
> -		enum dpu_sspp sspp_idx;
> +	for (i = 0; i < cstate->num_mixers; i++)
> +		mixer[i].mixer_op_mode = 0;
>   
> +	drm_atomic_crtc_for_each_plane(plane, crtc) {
>   		state = plane->state;
>   		if (!state)
>   			continue;
> @@ -364,14 +360,10 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   		pstate = to_dpu_plane_state(state);
>   		fb = state->fb;
>   
> -		sspp_idx = pstate->pipe_hw->idx;
> -		set_bit(sspp_idx, fetch_active);
> -
> -		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
> +		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d fb %d\n",
>   				crtc->base.id,
>   				pstate->stage,
>   				plane->base.id,
> -				sspp_idx - SSPP_VIG0,
>   				state->fb ? state->fb->base.id : -1);
>   
>   		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
> @@ -379,15 +371,8 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   		if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
>   			bg_alpha_enable = true;
>   
> -		stage_idx = zpos_cnt[pstate->stage]++;
> -		stage_cfg->stage[pstate->stage][stage_idx] =
> -					sspp_idx;
> -		stage_cfg->multirect_index[pstate->stage][stage_idx] =
> -					pstate->multirect_index;
> -
>   		trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
>   					   state, pstate, stage_idx,
> -					   sspp_idx - SSPP_VIG0,
>   					   format->base.pixel_format,
>   					   fb ? fb->modifier : 0);
>   
> @@ -396,8 +381,6 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   			_dpu_crtc_setup_blend_cfg(mixer + lm_idx,
>   						pstate, format);
>   
> -			mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx);
> -
>   			if (bg_alpha_enable && !format->alpha_enable)
>   				mixer[lm_idx].mixer_op_mode = 0;
>   			else
> @@ -406,17 +389,22 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   		}
>   	}
>   
> -	if (ctl->ops.set_active_pipes)
> -		ctl->ops.set_active_pipes(ctl, fetch_active);
> -
>   	 _dpu_crtc_program_lm_output_roi(crtc);
> +
> +	for (i = 0; i < cstate->num_mixers; i++) {
> +		struct dpu_hw_mixer *lm;
> +
> +		lm = mixer[i].hw_lm;
> +
> +		lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
> +
> +		DRM_DEBUG_ATOMIC("lm %d, op_mode 0x%X\n",
> +			mixer[i].hw_lm->idx - LM_0,
> +			mixer[i].mixer_op_mode);
> +	}
>   }
>   
> -/**
> - * _dpu_crtc_blend_setup - configure crtc mixers
> - * @crtc: Pointer to drm crtc structure
> - */
> -static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
> +static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc)
>   {
>   	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
>   	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
> @@ -425,34 +413,62 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
>   	struct dpu_hw_mixer *lm;
>   	struct dpu_hw_stage_cfg stage_cfg;
>   	int i;
> +	struct drm_plane *plane;
> +	struct drm_plane_state *state;
> +	struct dpu_plane_state *pstate = NULL;
> +
> +	uint32_t stage_idx, lm_idx;
> +	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
> +	DECLARE_BITMAP(fetch_active, SSPP_MAX);
>   
>   	DRM_DEBUG_ATOMIC("%s\n", dpu_crtc->name);
>   
> -	for (i = 0; i < cstate->num_mixers; i++) {
> -		mixer[i].mixer_op_mode = 0;
> +	for (i = 0; i < cstate->num_mixers; i++)
>   		if (mixer[i].lm_ctl->ops.clear_all_blendstages)
>   			mixer[i].lm_ctl->ops.clear_all_blendstages(
>   					mixer[i].lm_ctl);
> -	}
>   
>   	/* initialize stage cfg */
>   	memset(&stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg));
>   
> -	_dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer, &stage_cfg);
> +	memset(fetch_active, 0, sizeof(fetch_active));
> +	drm_atomic_crtc_for_each_plane(plane, crtc) {
> +		enum dpu_sspp sspp_idx;
> +
> +		state = plane->state;
> +		if (!state)
> +			continue;
> +
> +		pstate = to_dpu_plane_state(state);
> +
> +		sspp_idx = pstate->pipe_hw->idx;
> +		set_bit(sspp_idx, fetch_active);
> +
> +		stage_idx = zpos_cnt[pstate->stage]++;
> +		stage_cfg.stage[pstate->stage][stage_idx] =
> +					sspp_idx;
> +		stage_cfg.multirect_index[pstate->stage][stage_idx] =
> +					pstate->multirect_index;
> +
> +		/* blend config update */
> +		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++)
> +			mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, sspp_idx);
> +	}
> +
> +	ctl = mixer->lm_ctl;
> +	if (ctl->ops.set_active_pipes)
> +		ctl->ops.set_active_pipes(ctl, fetch_active);
>   
>   	for (i = 0; i < cstate->num_mixers; i++) {
>   		ctl = mixer[i].lm_ctl;
>   		lm = mixer[i].hw_lm;
>   
> -		lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
> -
>   		/* stage config flush mask */
>   		ctl->ops.update_pending_flush_mixer(ctl,
>   			mixer[i].hw_lm->idx);
>   
> -		DRM_DEBUG_ATOMIC("lm %d, op_mode 0x%X, ctl %d\n",
> +		DRM_DEBUG_ATOMIC("lm %d, ctl %d\n",
>   			mixer[i].hw_lm->idx - LM_0,
> -			mixer[i].mixer_op_mode,
>   			ctl->idx - CTL_0);
>   
>   		ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
> @@ -731,7 +747,8 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc,
>   	if (unlikely(!cstate->num_mixers))
>   		return;
>   
> -	_dpu_crtc_blend_setup(crtc);
> +	_dpu_crtc_blend_setup_mixer(crtc);
> +	_dpu_crtc_blend_setup_ctl(crtc);
>   
>   	_dpu_crtc_setup_cp_blocks(crtc);
>   
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> index 54d74341e690..ecd2f371374d 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> @@ -632,9 +632,9 @@ TRACE_EVENT(dpu_enc_phys_vid_irq_ctrl,
>   TRACE_EVENT(dpu_crtc_setup_mixer,
>   	TP_PROTO(uint32_t crtc_id, uint32_t plane_id,
>   		 struct drm_plane_state *state, struct dpu_plane_state *pstate,
> -		 uint32_t stage_idx, enum dpu_sspp sspp, uint32_t pixel_format,
> +		 uint32_t stage_idx, uint32_t pixel_format,
>   		 uint64_t modifier),
> -	TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx, sspp,
> +	TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
>   		pixel_format, modifier),
>   	TP_STRUCT__entry(
>   		__field(	uint32_t,		crtc_id		)
> @@ -644,7 +644,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>   		__field_struct(	struct drm_rect,	dst_rect	)
>   		__field(	uint32_t,		stage_idx	)
>   		__field(	enum dpu_stage,		stage		)
> -		__field(	enum dpu_sspp,		sspp		)
>   		__field(	uint32_t,		multirect_idx	)
>   		__field(	uint32_t,		multirect_mode	)
>   		__field(	uint32_t,		pixel_format	)
> @@ -658,20 +657,19 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>   		__entry->dst_rect = drm_plane_state_dest(state);
>   		__entry->stage_idx = stage_idx;
>   		__entry->stage = pstate->stage;
> -		__entry->sspp = sspp;
>   		__entry->multirect_idx = pstate->multirect_index;
>   		__entry->multirect_mode = pstate->multirect_mode;
>   		__entry->pixel_format = pixel_format;
>   		__entry->modifier = modifier;
>   	),
>   	TP_printk("crtc_id:%u plane_id:%u fb_id:%u src:" DRM_RECT_FP_FMT
> -		  " dst:" DRM_RECT_FMT " stage_idx:%u stage:%d, sspp:%d "
> +		  " dst:" DRM_RECT_FMT " stage_idx:%u stage:%d, "
>   		  "multirect_index:%d multirect_mode:%u pix_format:%u "
>   		  "modifier:%llu",
>   		  __entry->crtc_id, __entry->plane_id, __entry->fb_id,
>   		  DRM_RECT_FP_ARG(&__entry->src_rect),
>   		  DRM_RECT_ARG(&__entry->dst_rect),
> -		  __entry->stage_idx, __entry->stage, __entry->sspp,
> +		  __entry->stage_idx, __entry->stage,
>   		  __entry->multirect_idx, __entry->multirect_mode,
>   		  __entry->pixel_format, __entry->modifier)
>   );

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

* Re: [PATCH 09/25] drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic
  2022-05-06 18:56   ` Abhinav Kumar
@ 2022-05-06 20:14     ` Dmitry Baryshkov
  0 siblings, 0 replies; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-05-06 20:14 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

On 06/05/2022 21:56, Abhinav Kumar wrote:
> 
> 
> On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
>> The funcitons _dpu_crtc_blend_setup() and _dpu_crtc_blend_setup_mixer()
>> have an intertwined mixture of CTL and LM-related code. Split these two
>> functions into LM-specific and CTL-specific parts, making both code
>> paths clean and observable.
>>
> 
> I do see the intention of this change, but there are two things to 
> consider here.
> 
> Let me know what you think of those:
> 
> 1) Agreed that we are able to split it out but at what cost? We are 
> repeating some of the loops such as
> 
> a) for (i = 0; i < cstate->num_mixers; i++) {
> b) drm_atomic_crtc_for_each_plane(

Maybe we should invert these loops, so that we'll through the planes and 
only then loop over the mixers.

> 
> 2) The intertwining is "somewhat" logical here because we are 
> programming the LMs for which we are staging the planes so it somewhat 
> goes together

I'll revisit this for v2. I'll move this towards the end of the series, 
so it would be more obvious if patch 25/25 is better with this change or 
w/o it.

> 
> 3) dropping sspp idx from this trace removes some useful informatio of 
> which sspp is staged to which stage of blend

I can add this back to the dpu_crtc_blend_setup_ctl

> 
>  >           trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
>  >                          state, pstate, stage_idx,
>  > -                       sspp_idx - SSPP_VIG0,
>  >                          format->base.pixel_format,
>  >                          fb ? fb->modifier : 0);
> 
> 
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 101 +++++++++++++---------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h |  10 +--
>>   2 files changed, 63 insertions(+), 48 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> index e6c33022d560..ada7d5750536 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> @@ -336,27 +336,23 @@ static void 
>> _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
>>       }
>>   }
>> -static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>> -    struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer,
>> -    struct dpu_hw_stage_cfg *stage_cfg)
>> +static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc)
>>   {
>> +    struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
>> +    struct dpu_crtc_mixer *mixer = cstate->mixers;
>>       struct drm_plane *plane;
>>       struct drm_framebuffer *fb;
>>       struct drm_plane_state *state;
>> -    struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
>>       struct dpu_plane_state *pstate = NULL;
>>       struct dpu_format *format;
>> -    struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>> -
>> +    int i;
>>       uint32_t stage_idx, lm_idx;
>> -    int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
>>       bool bg_alpha_enable = false;
>> -    DECLARE_BITMAP(fetch_active, SSPP_MAX);
>> -    memset(fetch_active, 0, sizeof(fetch_active));
>> -    drm_atomic_crtc_for_each_plane(plane, crtc) {
>> -        enum dpu_sspp sspp_idx;
>> +    for (i = 0; i < cstate->num_mixers; i++)
>> +        mixer[i].mixer_op_mode = 0;
>> +    drm_atomic_crtc_for_each_plane(plane, crtc) {
>>           state = plane->state;
>>           if (!state)
>>               continue;
>> @@ -364,14 +360,10 @@ static void _dpu_crtc_blend_setup_mixer(struct 
>> drm_crtc *crtc,
>>           pstate = to_dpu_plane_state(state);
>>           fb = state->fb;
>> -        sspp_idx = pstate->pipe_hw->idx;
>> -        set_bit(sspp_idx, fetch_active);
>> -
>> -        DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
>> +        DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d fb %d\n",
>>                   crtc->base.id,
>>                   pstate->stage,
>>                   plane->base.id,
>> -                sspp_idx - SSPP_VIG0,
>>                   state->fb ? state->fb->base.id : -1);
>>           format = 
>> to_dpu_format(msm_framebuffer_format(pstate->base.fb));
>> @@ -379,15 +371,8 @@ static void _dpu_crtc_blend_setup_mixer(struct 
>> drm_crtc *crtc,
>>           if (pstate->stage == DPU_STAGE_BASE && format->alpha_enable)
>>               bg_alpha_enable = true;
>> -        stage_idx = zpos_cnt[pstate->stage]++;
>> -        stage_cfg->stage[pstate->stage][stage_idx] =
>> -                    sspp_idx;
>> -        stage_cfg->multirect_index[pstate->stage][stage_idx] =
>> -                    pstate->multirect_index;
>> -
>>           trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
>>                          state, pstate, stage_idx,
>> -                       sspp_idx - SSPP_VIG0,
>>                          format->base.pixel_format,
>>                          fb ? fb->modifier : 0);
>> @@ -396,8 +381,6 @@ static void _dpu_crtc_blend_setup_mixer(struct 
>> drm_crtc *crtc,
>>               _dpu_crtc_setup_blend_cfg(mixer + lm_idx,
>>                           pstate, format);
>> -            
>> mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, 
>> sspp_idx);
>> -
>>               if (bg_alpha_enable && !format->alpha_enable)
>>                   mixer[lm_idx].mixer_op_mode = 0;
>>               else
>> @@ -406,17 +389,22 @@ static void _dpu_crtc_blend_setup_mixer(struct 
>> drm_crtc *crtc,
>>           }
>>       }
>> -    if (ctl->ops.set_active_pipes)
>> -        ctl->ops.set_active_pipes(ctl, fetch_active);
>> -
>>        _dpu_crtc_program_lm_output_roi(crtc);
>> +
>> +    for (i = 0; i < cstate->num_mixers; i++) {
>> +        struct dpu_hw_mixer *lm;
>> +
>> +        lm = mixer[i].hw_lm;
>> +
>> +        lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
>> +
>> +        DRM_DEBUG_ATOMIC("lm %d, op_mode 0x%X\n",
>> +            mixer[i].hw_lm->idx - LM_0,
>> +            mixer[i].mixer_op_mode);
>> +    }
>>   }
>> -/**
>> - * _dpu_crtc_blend_setup - configure crtc mixers
>> - * @crtc: Pointer to drm crtc structure
>> - */
>> -static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
>> +static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc)
>>   {
>>       struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
>>       struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc->state);
>> @@ -425,34 +413,62 @@ static void _dpu_crtc_blend_setup(struct 
>> drm_crtc *crtc)
>>       struct dpu_hw_mixer *lm;
>>       struct dpu_hw_stage_cfg stage_cfg;
>>       int i;
>> +    struct drm_plane *plane;
>> +    struct drm_plane_state *state;
>> +    struct dpu_plane_state *pstate = NULL;
>> +
>> +    uint32_t stage_idx, lm_idx;
>> +    int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
>> +    DECLARE_BITMAP(fetch_active, SSPP_MAX);
>>       DRM_DEBUG_ATOMIC("%s\n", dpu_crtc->name);
>> -    for (i = 0; i < cstate->num_mixers; i++) {
>> -        mixer[i].mixer_op_mode = 0;
>> +    for (i = 0; i < cstate->num_mixers; i++)
>>           if (mixer[i].lm_ctl->ops.clear_all_blendstages)
>>               mixer[i].lm_ctl->ops.clear_all_blendstages(
>>                       mixer[i].lm_ctl);
>> -    }
>>       /* initialize stage cfg */
>>       memset(&stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg));
>> -    _dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer, &stage_cfg);
>> +    memset(fetch_active, 0, sizeof(fetch_active));
>> +    drm_atomic_crtc_for_each_plane(plane, crtc) {
>> +        enum dpu_sspp sspp_idx;
>> +
>> +        state = plane->state;
>> +        if (!state)
>> +            continue;
>> +
>> +        pstate = to_dpu_plane_state(state);
>> +
>> +        sspp_idx = pstate->pipe_hw->idx;
>> +        set_bit(sspp_idx, fetch_active);
>> +
>> +        stage_idx = zpos_cnt[pstate->stage]++;
>> +        stage_cfg.stage[pstate->stage][stage_idx] =
>> +                    sspp_idx;
>> +        stage_cfg.multirect_index[pstate->stage][stage_idx] =
>> +                    pstate->multirect_index;
>> +
>> +        /* blend config update */
>> +        for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++)
>> +            
>> mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl, 
>> sspp_idx);
>> +    }
>> +
>> +    ctl = mixer->lm_ctl;
>> +    if (ctl->ops.set_active_pipes)
>> +        ctl->ops.set_active_pipes(ctl, fetch_active);
>>       for (i = 0; i < cstate->num_mixers; i++) {
>>           ctl = mixer[i].lm_ctl;
>>           lm = mixer[i].hw_lm;
>> -        lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
>> -
>>           /* stage config flush mask */
>>           ctl->ops.update_pending_flush_mixer(ctl,
>>               mixer[i].hw_lm->idx);
>> -        DRM_DEBUG_ATOMIC("lm %d, op_mode 0x%X, ctl %d\n",
>> +        DRM_DEBUG_ATOMIC("lm %d, ctl %d\n",
>>               mixer[i].hw_lm->idx - LM_0,
>> -            mixer[i].mixer_op_mode,
>>               ctl->idx - CTL_0);
>>           ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
>> @@ -731,7 +747,8 @@ static void dpu_crtc_atomic_begin(struct drm_crtc 
>> *crtc,
>>       if (unlikely(!cstate->num_mixers))
>>           return;
>> -    _dpu_crtc_blend_setup(crtc);
>> +    _dpu_crtc_blend_setup_mixer(crtc);
>> +    _dpu_crtc_blend_setup_ctl(crtc);
>>       _dpu_crtc_setup_cp_blocks(crtc);
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> index 54d74341e690..ecd2f371374d 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> @@ -632,9 +632,9 @@ TRACE_EVENT(dpu_enc_phys_vid_irq_ctrl,
>>   TRACE_EVENT(dpu_crtc_setup_mixer,
>>       TP_PROTO(uint32_t crtc_id, uint32_t plane_id,
>>            struct drm_plane_state *state, struct dpu_plane_state *pstate,
>> -         uint32_t stage_idx, enum dpu_sspp sspp, uint32_t pixel_format,
>> +         uint32_t stage_idx, uint32_t pixel_format,
>>            uint64_t modifier),
>> -    TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx, sspp,
>> +    TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
>>           pixel_format, modifier),
>>       TP_STRUCT__entry(
>>           __field(    uint32_t,        crtc_id        )
>> @@ -644,7 +644,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __field_struct(    struct drm_rect,    dst_rect    )
>>           __field(    uint32_t,        stage_idx    )
>>           __field(    enum dpu_stage,        stage        )
>> -        __field(    enum dpu_sspp,        sspp        )
>>           __field(    uint32_t,        multirect_idx    )
>>           __field(    uint32_t,        multirect_mode    )
>>           __field(    uint32_t,        pixel_format    )
>> @@ -658,20 +657,19 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __entry->dst_rect = drm_plane_state_dest(state);
>>           __entry->stage_idx = stage_idx;
>>           __entry->stage = pstate->stage;
>> -        __entry->sspp = sspp;
>>           __entry->multirect_idx = pstate->multirect_index;
>>           __entry->multirect_mode = pstate->multirect_mode;
>>           __entry->pixel_format = pixel_format;
>>           __entry->modifier = modifier;
>>       ),
>>       TP_printk("crtc_id:%u plane_id:%u fb_id:%u src:" DRM_RECT_FP_FMT
>> -          " dst:" DRM_RECT_FMT " stage_idx:%u stage:%d, sspp:%d "
>> +          " dst:" DRM_RECT_FMT " stage_idx:%u stage:%d, "
>>             "multirect_index:%d multirect_mode:%u pix_format:%u "
>>             "modifier:%llu",
>>             __entry->crtc_id, __entry->plane_id, __entry->fb_id,
>>             DRM_RECT_FP_ARG(&__entry->src_rect),
>>             DRM_RECT_ARG(&__entry->dst_rect),
>> -          __entry->stage_idx, __entry->stage, __entry->sspp,
>> +          __entry->stage_idx, __entry->stage,
>>             __entry->multirect_idx, __entry->multirect_mode,
>>             __entry->pixel_format, __entry->modifier)
>>   );


-- 
With best wishes
Dmitry

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

* Re: [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe
  2022-02-09 17:25 ` [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe Dmitry Baryshkov
@ 2022-05-06 21:30   ` Abhinav Kumar
  2022-05-06 21:39     ` Dmitry Baryshkov
  0 siblings, 1 reply; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-06 21:30 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> Wrap SSPP and multirect index/mode into a single structure that
> represents software view on the pipe used.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c    |   8 +-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  16 ++-
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 136 ++++++++++----------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   |   4 +-
>   4 files changed, 86 insertions(+), 78 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index ada7d5750536..751c64012058 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -441,14 +441,14 @@ static void _dpu_crtc_blend_setup_ctl(struct drm_crtc *crtc)
>   
>   		pstate = to_dpu_plane_state(state);
>   
> -		sspp_idx = pstate->pipe_hw->idx;
> +		sspp_idx = pstate->pipe.sspp->idx;
>   		set_bit(sspp_idx, fetch_active);
>   
>   		stage_idx = zpos_cnt[pstate->stage]++;
>   		stage_cfg.stage[pstate->stage][stage_idx] =
>   					sspp_idx;
>   		stage_cfg.multirect_index[pstate->stage][stage_idx] =
> -					pstate->multirect_index;
> +					pstate->pipe.multirect_index;
>   
>   		/* blend config update */
>   		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++)
> @@ -1118,7 +1118,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   		pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
>   		pstates[cnt].drm_pstate = pstate;
>   		pstates[cnt].stage = pstate->normalized_zpos;
> -		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe_hw->idx;
> +		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx;
>   
>   		if (pipe_staged[pstates[cnt].pipe_id]) {
>   			multirect_plane[multirect_count].r0 =
> @@ -1389,7 +1389,7 @@ static int _dpu_debugfs_status_show(struct seq_file *s, void *data)
>   			state->crtc_x, state->crtc_y, state->crtc_w,
>   			state->crtc_h);
>   		seq_printf(s, "\tmultirect: mode: %d index: %d\n",
> -			pstate->multirect_mode, pstate->multirect_index);
> +			pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
>   
>   		seq_puts(s, "\n");
>   	}
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> index 674f311f99b4..0af2bc6e5df8 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -159,15 +159,11 @@ struct dpu_hw_pixel_ext {
>    * @src_rect:  src ROI, caller takes into account the different operations
>    *             such as decimation, flip etc to program this field
>    * @dest_rect: destination ROI.
> - * @index:     index of the rectangle of SSPP
> - * @mode:      parallel or time multiplex multirect mode
>    */
>   struct dpu_hw_pipe_cfg {
>   	struct dpu_hw_fmt_layout layout;
>   	struct drm_rect src_rect;
>   	struct drm_rect dst_rect;
> -	enum dpu_sspp_multirect_index index;
> -	enum dpu_sspp_multirect_mode mode;
>   };
>   
>   /**
> @@ -218,6 +214,18 @@ struct dpu_hw_pipe_ts_cfg {
>   	u64 time;
>   };
>   
> +/**
> + * struct dpu_sw_pipe - software pipe description
> + * @sspp:      backing SSPP pipe
> + * @index:     index of the rectangle of SSPP
> + * @mode:      parallel or time multiplex multirect mode
> + */
> +struct dpu_sw_pipe {
> +	struct dpu_hw_pipe *sspp;
> +	enum dpu_sspp_multirect_index multirect_index;
> +	enum dpu_sspp_multirect_mode multirect_mode;
> +};
> +
>   /**
>    * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions
>    * Caller must call the init function to get the pipe context for each pipe
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index d1f9b4bc10ac..51b5e8a3182b 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -247,7 +247,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
>   				((src_width + 32) * fmt->bpp);
>   		}
>   	} else {
> -		if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
> +		if (pstate->pipe.multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
>   			total_fl = (fixed_buff_size / 2) * 2 /
>   				((src_width + 32) * fmt->bpp);
>   		} else {
> @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
>   			fmt ? (char *)&fmt->base.pixel_format : NULL,
>   			pdpu->is_rt_pipe, total_fl, qos_lut);
>   
> -	pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
> +	pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut);
>   }
>   
>   /**
> @@ -383,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
>   		danger_lut,
>   		safe_lut);
>   
> -	pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
> +	pstate->pipe.sspp->ops.setup_danger_safe_lut(pstate->pipe.sspp,
>   			danger_lut, safe_lut);
>   }
>   
> @@ -403,9 +403,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>   	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>   
>   	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
> -		pipe_qos_cfg.creq_vblank = pstate->pipe_hw->cap->sblk->creq_vblank;
> +		pipe_qos_cfg.creq_vblank = pstate->pipe.sspp->cap->sblk->creq_vblank;
>   		pipe_qos_cfg.danger_vblank =
> -				pstate->pipe_hw->cap->sblk->danger_vblank;
> +				pstate->pipe.sspp->cap->sblk->danger_vblank;
>   		pipe_qos_cfg.vblank_en = enable;
>   	}
>   
> @@ -431,7 +431,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>   		pipe_qos_cfg.danger_vblank,
>   		pdpu->is_rt_pipe);
>   
> -	pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
> +	pstate->pipe.sspp->ops.setup_qos_ctrl(pstate->pipe.sspp,
>   			&pipe_qos_cfg);
>   }
>   
> @@ -450,14 +450,14 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
>   	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>   
>   	memset(&ot_params, 0, sizeof(ot_params));
> -	ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
> -	ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
> +	ot_params.xin_id = pstate->pipe.sspp->cap->xin_id;
> +	ot_params.num = pstate->pipe.sspp->idx - SSPP_NONE;
>   	ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
>   	ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
>   	ot_params.is_wfd = !pdpu->is_rt_pipe;
>   	ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
>   	ot_params.vbif_idx = VBIF_RT;
> -	ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
> +	ot_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
>   	ot_params.rd = true;
>   
>   	dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
> @@ -476,9 +476,9 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
>   
>   	memset(&qos_params, 0, sizeof(qos_params));
>   	qos_params.vbif_idx = VBIF_RT;
> -	qos_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
> -	qos_params.xin_id = pstate->pipe_hw->cap->xin_id;
> -	qos_params.num = pstate->pipe_hw->idx - SSPP_VIG0;
> +	qos_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
> +	qos_params.xin_id = pstate->pipe.sspp->cap->xin_id;
> +	qos_params.num = pstate->pipe.sspp->idx - SSPP_VIG0;
>   	qos_params.is_rt = pdpu->is_rt_pipe;
>   
>   	DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, clk_ctrl:%d\n",
> @@ -505,12 +505,12 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
>   		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
>   	else if (ret)
>   		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> -	else if (pstate->pipe_hw->ops.setup_sourceaddress) {
> -		trace_dpu_plane_set_scanout(pstate->pipe_hw->idx,
> +	else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
> +		trace_dpu_plane_set_scanout(pstate->pipe.sspp->idx,
>   					    &pipe_cfg->layout,
> -					    pstate->multirect_index);
> -		pstate->pipe_hw->ops.setup_sourceaddress(pstate->pipe_hw, pipe_cfg,
> -						pstate->multirect_index);
> +					    pstate->pipe.multirect_index);
> +		pstate->pipe.sspp->ops.setup_sourceaddress(pstate->pipe.sspp, pipe_cfg,
> +						pstate->pipe.multirect_index);
>   	}
>   }
>   
> @@ -553,7 +553,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
>   			scale_cfg->src_height[i] /= chroma_subsmpl_v;
>   		}
>   
> -		if (pstate->pipe_hw->cap->features &
> +		if (pstate->pipe.sspp->cap->features &
>   			BIT(DPU_SSPP_SCALER_QSEED4)) {
>   			scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
>   			scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
> @@ -624,7 +624,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
>   	if (!DPU_FORMAT_IS_YUV(fmt))
>   		return NULL;
>   
> -	if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe_hw->cap->features)
> +	if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe.sspp->cap->features)
>   		csc_ptr = &dpu_csc10_YUV2RGB_601L;
>   	else
>   		csc_ptr = &dpu_csc_YUV2RGB_601L;
> @@ -659,8 +659,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>   			&scaler3_cfg, &pixel_ext, fmt,
>   			info->hsub, info->vsub);
>   
> -	if (pstate->pipe_hw->ops.setup_pe)
> -		pstate->pipe_hw->ops.setup_pe(pstate->pipe_hw,
> +	if (pstate->pipe.sspp->ops.setup_pe)
> +		pstate->pipe.sspp->ops.setup_pe(pstate->pipe.sspp,
>   				&pixel_ext);
>   
>   	/**
> @@ -668,9 +668,9 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>   	 * bypassed. Still we need to update alpha and bitwidth
>   	 * ONLY for RECT0
>   	 */
> -	if (pstate->pipe_hw->ops.setup_scaler &&
> -			pstate->multirect_index != DPU_SSPP_RECT_1)
> -		pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
> +	if (pstate->pipe.sspp->ops.setup_scaler &&
> +			pstate->pipe.multirect_index != DPU_SSPP_RECT_1)
> +		pstate->pipe.sspp->ops.setup_scaler(pstate->pipe.sspp,
>   				pipe_cfg,
>   				&scaler3_cfg);
>   }
> @@ -699,10 +699,10 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>   
>   	/* update sspp */
> -	if (fmt && pstate->pipe_hw->ops.setup_solidfill) {
> -		pstate->pipe_hw->ops.setup_solidfill(pstate->pipe_hw,
> +	if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
> +		pstate->pipe.sspp->ops.setup_solidfill(pstate->pipe.sspp,
>   				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
> -				pstate->multirect_index);
> +				pstate->pipe.multirect_index);
>   
>   		/* override scaler/decimation if solid fill */
>   		pipe_cfg.dst_rect = pstate->base.dst;
> @@ -714,15 +714,15 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   		pipe_cfg.src_rect.y2 =
>   			drm_rect_height(&pipe_cfg.dst_rect);
>   
> -		if (pstate->pipe_hw->ops.setup_format)
> -			pstate->pipe_hw->ops.setup_format(pstate->pipe_hw,
> +		if (pstate->pipe.sspp->ops.setup_format)
> +			pstate->pipe.sspp->ops.setup_format(pstate->pipe.sspp,
>   					fmt, DPU_SSPP_SOLID_FILL,
> -					pstate->multirect_index);
> +					pstate->pipe.multirect_index);
>   
> -		if (pstate->pipe_hw->ops.setup_rects)
> -			pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
> +		if (pstate->pipe.sspp->ops.setup_rects)
> +			pstate->pipe.sspp->ops.setup_rects(pstate->pipe.sspp,
>   					&pipe_cfg,
> -					pstate->multirect_index);
> +					pstate->pipe.multirect_index);
>   
>   		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
>   	}
> @@ -734,8 +734,8 @@ void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state)
>   {
>   	struct dpu_plane_state *pstate = to_dpu_plane_state(drm_state);
>   
> -	pstate->multirect_index = DPU_SSPP_RECT_SOLO;
> -	pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> +	pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
> +	pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
>   }
>   
>   int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
> @@ -817,8 +817,8 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
>   
>   	/* Prefer PARALLEL FETCH Mode over TIME_MX Mode */
>   	if (parallel_fetch_qualified) {
> -		pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
> -		pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
> +		pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
> +		pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>   
>   		goto done;
>   	}
> @@ -828,8 +828,8 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
>   
>   	if (dst[R1].y1 >= dst[R0].y2 + buffer_lines ||
>   	    dst[R0].y1 >= dst[R1].y2 + buffer_lines) {
> -		pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
> -		pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
> +		pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
> +		pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>   	} else {
>   		DPU_ERROR(
>   			"No multirect mode possible for the planes (%d - %d)\n",
> @@ -839,13 +839,13 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
>   	}
>   
>   done:
> -	pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
> -	pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
> +	pstate[R0]->pipe.multirect_index = DPU_SSPP_RECT_0;
> +	pstate[R1]->pipe.multirect_index = DPU_SSPP_RECT_1;
>   
>   	DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
> -		pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
> +		pstate[R0]->pipe.multirect_mode, pstate[R0]->pipe.multirect_index);
>   	DPU_DEBUG_PLANE(dpu_plane[R1], "R1: %d - %d\n",
> -		pstate[R1]->multirect_mode, pstate[R1]->multirect_index);
> +		pstate[R1]->pipe.multirect_mode, pstate[R1]->pipe.multirect_index);
>   	return 0;
>   }
>   
> @@ -937,6 +937,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	int ret = 0, min_scale;
>   	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;
>   	const struct drm_crtc_state *crtc_state = NULL;
>   	const struct dpu_format *fmt;
>   	struct drm_rect src, dst, fb_rect = { 0 };
> @@ -946,10 +947,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   		crtc_state = drm_atomic_get_new_crtc_state(state,
>   							   new_plane_state->crtc);
>   
> -	min_scale = FRAC_16_16(1, pstate->pipe_hw->cap->sblk->maxupscale);
> +	min_scale = FRAC_16_16(1, pipe->sspp->cap->sblk->maxupscale);
>   	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
>   						  min_scale,
> -						  pstate->pipe_hw->cap->sblk->maxdwnscale << 16,
> +						  pipe->sspp->cap->sblk->maxdwnscale << 16,
>   						  true, true);
>   	if (ret) {
>   		DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
> @@ -975,8 +976,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>   
>   	if (DPU_FORMAT_IS_YUV(fmt) &&
> -		(!(pstate->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
> -		 !(pstate->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
> +		(!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
> +		 !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
>   		DPU_DEBUG_PLANE(pdpu,
>   				"plane doesn't have scaler/csc for yuv\n");
>   		return -EINVAL;
> @@ -1037,12 +1038,12 @@ void dpu_plane_flush(struct drm_plane *plane)
>   	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
>   		/* force 100% alpha */
>   		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
> -	else if (pstate->pipe_hw && pstate->pipe_hw->ops.setup_csc) {
> +	else if (pstate->pipe.sspp && pstate->pipe.sspp->ops.setup_csc) {
>   		const struct dpu_format *fmt = to_dpu_format(msm_framebuffer_format(plane->state->fb));
>   		const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, fmt);
>   
>   		if (csc_ptr)
> -			pstate->pipe_hw->ops.setup_csc(pstate->pipe_hw, csc_ptr);
> +			pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, csc_ptr);
>   	}
>   
>   	/* flag h/w flush complete */
> @@ -1072,6 +1073,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
>   	struct drm_plane_state *state = plane->state;
>   	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
> +	struct dpu_sw_pipe *pipe = &pstate->pipe;
>   	struct drm_crtc *crtc = state->crtc;
>   	struct drm_framebuffer *fb = state->fb;
>   	bool is_rt_pipe, update_qos_remap;
> @@ -1109,21 +1111,21 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   		return;
>   	}
>   
> -	if (pstate->pipe_hw->ops.setup_rects) {
> -		pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
> +	if (pipe->sspp->ops.setup_rects) {
> +		pipe->sspp->ops.setup_rects(pipe->sspp,
>   				&pipe_cfg,
> -				pstate->multirect_index);
> +				pipe->multirect_index);
>   	}
>   
>   	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
>   
> -	if (pstate->pipe_hw->ops.setup_multirect)
> -		pstate->pipe_hw->ops.setup_multirect(
> -				pstate->pipe_hw,
> -				pstate->multirect_index,
> -				pstate->multirect_mode);
> +	if (pipe->sspp->ops.setup_multirect)
> +		pipe->sspp->ops.setup_multirect(
> +				pipe->sspp,
> +				pipe->multirect_index,
> +				pipe->multirect_mode);
>   
> -	if (pstate->pipe_hw->ops.setup_format) {
> +	if (pipe->sspp->ops.setup_format) {
>   		unsigned int rotation;
>   
>   		src_flags = 0x0;
> @@ -1140,10 +1142,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   			src_flags |= DPU_SSPP_FLIP_UD;
>   
>   		/* update format */
> -		pstate->pipe_hw->ops.setup_format(pstate->pipe_hw, fmt, src_flags,
> -				pstate->multirect_index);
> +		pipe->sspp->ops.setup_format(pipe->sspp, fmt, src_flags,
> +				pipe->multirect_index);
>   
> -		if (pstate->pipe_hw->ops.setup_cdp) {
> +		if (pipe->sspp->ops.setup_cdp) {
>   			struct dpu_hw_pipe_cdp_cfg cdp_cfg;
>   
>   			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
> @@ -1157,7 +1159,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   					DPU_FORMAT_IS_TILE(fmt);
>   			cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
>   
> -			pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg, pstate->multirect_index);
> +			pipe->sspp->ops.setup_cdp(pipe->sspp, &cdp_cfg, pipe->multirect_index);
>   		}
>   	}
>   
> @@ -1191,7 +1193,7 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
>   	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>   
>   	trace_dpu_plane_disable(DRMID(plane), false,
> -				pstate->multirect_mode);
> +				pstate->pipe.multirect_mode);
>   
>   	pstate->pending = true;
>   }
> @@ -1305,9 +1307,9 @@ static void dpu_plane_atomic_print_state(struct drm_printer *p,
>   	const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>   
>   	drm_printf(p, "\tstage=%d\n", pstate->stage);
> -	drm_printf(p, "\tsspp=%s\n", pstate->pipe_hw->cap->name);
> -	drm_printf(p, "\tmultirect_mode=%s\n", dpu_get_multirect_mode(pstate->multirect_mode));
> -	drm_printf(p, "\tmultirect_index=%s\n", dpu_get_multirect_index(pstate->multirect_index));
> +	drm_printf(p, "\tsspp=%s\n", pstate->pipe.sspp->cap->name);
> +	drm_printf(p, "\tmultirect_mode=%s\n", dpu_get_multirect_mode(pstate->pipe.multirect_mode));
> +	drm_printf(p, "\tmultirect_index=%s\n", dpu_get_multirect_index(pstate->pipe.multirect_index));
>   }
>   
>   static void dpu_plane_reset(struct drm_plane *plane)
> @@ -1336,7 +1338,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
>   		return;
>   	}
>   
> -	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
> +	pstate->pipe.sspp = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
>   
>   	__drm_atomic_helper_plane_reset(plane, &pstate->base);
>   }
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> index d745cde4ea77..b6fd6f856d6a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -31,11 +31,9 @@ struct dpu_plane_state {
>   	struct msm_gem_address_space *aspace;
>   	enum dpu_stage stage;
>   	bool needs_qos_remap;
> -	uint32_t multirect_index;
> -	uint32_t multirect_mode;
>   	bool pending;
>   
> -	struct dpu_hw_pipe *pipe_hw;
> +	struct dpu_sw_pipe pipe;

Are you sure we dont need this to be a pointer?

Since this is now part of plane_state, its possible that across commits, 
the hw pipe can change for this plane's state. So might be better if 
this is pointer in that case ....

>   
>   	u64 plane_fetch_bw;
>   	u64 plane_clk;

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

* Re: [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe
  2022-05-06 21:30   ` Abhinav Kumar
@ 2022-05-06 21:39     ` Dmitry Baryshkov
  2022-05-06 21:48       ` [Freedreno] " Abhinav Kumar
  0 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-05-06 21:39 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

On 07/05/2022 00:30, Abhinav Kumar wrote:
> 
> 
> On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
>> Wrap SSPP and multirect index/mode into a single structure that
>> represents software view on the pipe used.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c    |   8 +-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  16 ++-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 136 ++++++++++----------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   |   4 +-
>>   4 files changed, 86 insertions(+), 78 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> index ada7d5750536..751c64012058 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> @@ -441,14 +441,14 @@ static void _dpu_crtc_blend_setup_ctl(struct 
>> drm_crtc *crtc)
>>           pstate = to_dpu_plane_state(state);
>> -        sspp_idx = pstate->pipe_hw->idx;
>> +        sspp_idx = pstate->pipe.sspp->idx;
>>           set_bit(sspp_idx, fetch_active);
>>           stage_idx = zpos_cnt[pstate->stage]++;
>>           stage_cfg.stage[pstate->stage][stage_idx] =
>>                       sspp_idx;
>>           stage_cfg.multirect_index[pstate->stage][stage_idx] =
>> -                    pstate->multirect_index;
>> +                    pstate->pipe.multirect_index;
>>           /* blend config update */
>>           for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++)
>> @@ -1118,7 +1118,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
>> *crtc,
>>           pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
>>           pstates[cnt].drm_pstate = pstate;
>>           pstates[cnt].stage = pstate->normalized_zpos;
>> -        pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe_hw->idx;
>> +        pstates[cnt].pipe_id = 
>> to_dpu_plane_state(pstate)->pipe.sspp->idx;
>>           if (pipe_staged[pstates[cnt].pipe_id]) {
>>               multirect_plane[multirect_count].r0 =
>> @@ -1389,7 +1389,7 @@ static int _dpu_debugfs_status_show(struct 
>> seq_file *s, void *data)
>>               state->crtc_x, state->crtc_y, state->crtc_w,
>>               state->crtc_h);
>>           seq_printf(s, "\tmultirect: mode: %d index: %d\n",
>> -            pstate->multirect_mode, pstate->multirect_index);
>> +            pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
>>           seq_puts(s, "\n");
>>       }
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>> index 674f311f99b4..0af2bc6e5df8 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>> @@ -159,15 +159,11 @@ struct dpu_hw_pixel_ext {
>>    * @src_rect:  src ROI, caller takes into account the different 
>> operations
>>    *             such as decimation, flip etc to program this field
>>    * @dest_rect: destination ROI.
>> - * @index:     index of the rectangle of SSPP
>> - * @mode:      parallel or time multiplex multirect mode
>>    */
>>   struct dpu_hw_pipe_cfg {
>>       struct dpu_hw_fmt_layout layout;
>>       struct drm_rect src_rect;
>>       struct drm_rect dst_rect;
>> -    enum dpu_sspp_multirect_index index;
>> -    enum dpu_sspp_multirect_mode mode;
>>   };
>>   /**
>> @@ -218,6 +214,18 @@ struct dpu_hw_pipe_ts_cfg {
>>       u64 time;
>>   };
>> +/**
>> + * struct dpu_sw_pipe - software pipe description
>> + * @sspp:      backing SSPP pipe
>> + * @index:     index of the rectangle of SSPP
>> + * @mode:      parallel or time multiplex multirect mode
>> + */
>> +struct dpu_sw_pipe {
>> +    struct dpu_hw_pipe *sspp;
>> +    enum dpu_sspp_multirect_index multirect_index;
>> +    enum dpu_sspp_multirect_mode multirect_mode;
>> +};
>> +
>>   /**
>>    * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions
>>    * Caller must call the init function to get the pipe context for 
>> each pipe
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index d1f9b4bc10ac..51b5e8a3182b 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -247,7 +247,7 @@ static int _dpu_plane_calc_fill_level(struct 
>> drm_plane *plane,
>>                   ((src_width + 32) * fmt->bpp);
>>           }
>>       } else {
>> -        if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
>> +        if (pstate->pipe.multirect_mode == 
>> DPU_SSPP_MULTIRECT_PARALLEL) {
>>               total_fl = (fixed_buff_size / 2) * 2 /
>>                   ((src_width + 32) * fmt->bpp);
>>           } else {
>> @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct 
>> drm_plane *plane,
>>               fmt ? (char *)&fmt->base.pixel_format : NULL,
>>               pdpu->is_rt_pipe, total_fl, qos_lut);
>> -    pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
>> +    pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut);
>>   }
>>   /**
>> @@ -383,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct 
>> drm_plane *plane,
>>           danger_lut,
>>           safe_lut);
>> -    pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
>> +    pstate->pipe.sspp->ops.setup_danger_safe_lut(pstate->pipe.sspp,
>>               danger_lut, safe_lut);
>>   }
>> @@ -403,9 +403,9 @@ static void _dpu_plane_set_qos_ctrl(struct 
>> drm_plane *plane,
>>       memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>       if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>> -        pipe_qos_cfg.creq_vblank = 
>> pstate->pipe_hw->cap->sblk->creq_vblank;
>> +        pipe_qos_cfg.creq_vblank = 
>> pstate->pipe.sspp->cap->sblk->creq_vblank;
>>           pipe_qos_cfg.danger_vblank =
>> -                pstate->pipe_hw->cap->sblk->danger_vblank;
>> +                pstate->pipe.sspp->cap->sblk->danger_vblank;
>>           pipe_qos_cfg.vblank_en = enable;
>>       }
>> @@ -431,7 +431,7 @@ static void _dpu_plane_set_qos_ctrl(struct 
>> drm_plane *plane,
>>           pipe_qos_cfg.danger_vblank,
>>           pdpu->is_rt_pipe);
>> -    pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
>> +    pstate->pipe.sspp->ops.setup_qos_ctrl(pstate->pipe.sspp,
>>               &pipe_qos_cfg);
>>   }
>> @@ -450,14 +450,14 @@ static void _dpu_plane_set_ot_limit(struct 
>> drm_plane *plane,
>>       struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>>       memset(&ot_params, 0, sizeof(ot_params));
>> -    ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
>> -    ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
>> +    ot_params.xin_id = pstate->pipe.sspp->cap->xin_id;
>> +    ot_params.num = pstate->pipe.sspp->idx - SSPP_NONE;
>>       ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
>>       ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
>>       ot_params.is_wfd = !pdpu->is_rt_pipe;
>>       ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
>>       ot_params.vbif_idx = VBIF_RT;
>> -    ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>> +    ot_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
>>       ot_params.rd = true;
>>       dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
>> @@ -476,9 +476,9 @@ static void _dpu_plane_set_qos_remap(struct 
>> drm_plane *plane)
>>       memset(&qos_params, 0, sizeof(qos_params));
>>       qos_params.vbif_idx = VBIF_RT;
>> -    qos_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>> -    qos_params.xin_id = pstate->pipe_hw->cap->xin_id;
>> -    qos_params.num = pstate->pipe_hw->idx - SSPP_VIG0;
>> +    qos_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
>> +    qos_params.xin_id = pstate->pipe.sspp->cap->xin_id;
>> +    qos_params.num = pstate->pipe.sspp->idx - SSPP_VIG0;
>>       qos_params.is_rt = pdpu->is_rt_pipe;
>>       DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, 
>> clk_ctrl:%d\n",
>> @@ -505,12 +505,12 @@ static void _dpu_plane_set_scanout(struct 
>> drm_plane *plane,
>>           DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
>>       else if (ret)
>>           DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", 
>> ret);
>> -    else if (pstate->pipe_hw->ops.setup_sourceaddress) {
>> -        trace_dpu_plane_set_scanout(pstate->pipe_hw->idx,
>> +    else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
>> +        trace_dpu_plane_set_scanout(pstate->pipe.sspp->idx,
>>                           &pipe_cfg->layout,
>> -                        pstate->multirect_index);
>> -        pstate->pipe_hw->ops.setup_sourceaddress(pstate->pipe_hw, 
>> pipe_cfg,
>> -                        pstate->multirect_index);
>> +                        pstate->pipe.multirect_index);
>> +        pstate->pipe.sspp->ops.setup_sourceaddress(pstate->pipe.sspp, 
>> pipe_cfg,
>> +                        pstate->pipe.multirect_index);
>>       }
>>   }
>> @@ -553,7 +553,7 @@ static void _dpu_plane_setup_scaler3(struct 
>> dpu_plane *pdpu,
>>               scale_cfg->src_height[i] /= chroma_subsmpl_v;
>>           }
>> -        if (pstate->pipe_hw->cap->features &
>> +        if (pstate->pipe.sspp->cap->features &
>>               BIT(DPU_SSPP_SCALER_QSEED4)) {
>>               scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
>>               scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
>> @@ -624,7 +624,7 @@ static const struct dpu_csc_cfg 
>> *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
>>       if (!DPU_FORMAT_IS_YUV(fmt))
>>           return NULL;
>> -    if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe_hw->cap->features)
>> +    if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe.sspp->cap->features)
>>           csc_ptr = &dpu_csc10_YUV2RGB_601L;
>>       else
>>           csc_ptr = &dpu_csc_YUV2RGB_601L;
>> @@ -659,8 +659,8 @@ static void _dpu_plane_setup_scaler(struct 
>> dpu_plane *pdpu,
>>               &scaler3_cfg, &pixel_ext, fmt,
>>               info->hsub, info->vsub);
>> -    if (pstate->pipe_hw->ops.setup_pe)
>> -        pstate->pipe_hw->ops.setup_pe(pstate->pipe_hw,
>> +    if (pstate->pipe.sspp->ops.setup_pe)
>> +        pstate->pipe.sspp->ops.setup_pe(pstate->pipe.sspp,
>>                   &pixel_ext);
>>       /**
>> @@ -668,9 +668,9 @@ static void _dpu_plane_setup_scaler(struct 
>> dpu_plane *pdpu,
>>        * bypassed. Still we need to update alpha and bitwidth
>>        * ONLY for RECT0
>>        */
>> -    if (pstate->pipe_hw->ops.setup_scaler &&
>> -            pstate->multirect_index != DPU_SSPP_RECT_1)
>> -        pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
>> +    if (pstate->pipe.sspp->ops.setup_scaler &&
>> +            pstate->pipe.multirect_index != DPU_SSPP_RECT_1)
>> +        pstate->pipe.sspp->ops.setup_scaler(pstate->pipe.sspp,
>>                   pipe_cfg,
>>                   &scaler3_cfg);
>>   }
>> @@ -699,10 +699,10 @@ static int _dpu_plane_color_fill(struct 
>> dpu_plane *pdpu,
>>       fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>>       /* update sspp */
>> -    if (fmt && pstate->pipe_hw->ops.setup_solidfill) {
>> -        pstate->pipe_hw->ops.setup_solidfill(pstate->pipe_hw,
>> +    if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
>> +        pstate->pipe.sspp->ops.setup_solidfill(pstate->pipe.sspp,
>>                   (color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
>> -                pstate->multirect_index);
>> +                pstate->pipe.multirect_index);
>>           /* override scaler/decimation if solid fill */
>>           pipe_cfg.dst_rect = pstate->base.dst;
>> @@ -714,15 +714,15 @@ static int _dpu_plane_color_fill(struct 
>> dpu_plane *pdpu,
>>           pipe_cfg.src_rect.y2 =
>>               drm_rect_height(&pipe_cfg.dst_rect);
>> -        if (pstate->pipe_hw->ops.setup_format)
>> -            pstate->pipe_hw->ops.setup_format(pstate->pipe_hw,
>> +        if (pstate->pipe.sspp->ops.setup_format)
>> +            pstate->pipe.sspp->ops.setup_format(pstate->pipe.sspp,
>>                       fmt, DPU_SSPP_SOLID_FILL,
>> -                    pstate->multirect_index);
>> +                    pstate->pipe.multirect_index);
>> -        if (pstate->pipe_hw->ops.setup_rects)
>> -            pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>> +        if (pstate->pipe.sspp->ops.setup_rects)
>> +            pstate->pipe.sspp->ops.setup_rects(pstate->pipe.sspp,
>>                       &pipe_cfg,
>> -                    pstate->multirect_index);
>> +                    pstate->pipe.multirect_index);
>>           _dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
>>       }
>> @@ -734,8 +734,8 @@ void dpu_plane_clear_multirect(const struct 
>> drm_plane_state *drm_state)
>>   {
>>       struct dpu_plane_state *pstate = to_dpu_plane_state(drm_state);
>> -    pstate->multirect_index = DPU_SSPP_RECT_SOLO;
>> -    pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
>> +    pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
>> +    pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
>>   }
>>   int dpu_plane_validate_multirect_v2(struct 
>> dpu_multirect_plane_states *plane)
>> @@ -817,8 +817,8 @@ int dpu_plane_validate_multirect_v2(struct 
>> dpu_multirect_plane_states *plane)
>>       /* Prefer PARALLEL FETCH Mode over TIME_MX Mode */
>>       if (parallel_fetch_qualified) {
>> -        pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>> -        pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>> +        pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>> +        pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>>           goto done;
>>       }
>> @@ -828,8 +828,8 @@ int dpu_plane_validate_multirect_v2(struct 
>> dpu_multirect_plane_states *plane)
>>       if (dst[R1].y1 >= dst[R0].y2 + buffer_lines ||
>>           dst[R0].y1 >= dst[R1].y2 + buffer_lines) {
>> -        pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>> -        pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>> +        pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>> +        pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>       } else {
>>           DPU_ERROR(
>>               "No multirect mode possible for the planes (%d - %d)\n",
>> @@ -839,13 +839,13 @@ int dpu_plane_validate_multirect_v2(struct 
>> dpu_multirect_plane_states *plane)
>>       }
>>   done:
>> -    pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
>> -    pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
>> +    pstate[R0]->pipe.multirect_index = DPU_SSPP_RECT_0;
>> +    pstate[R1]->pipe.multirect_index = DPU_SSPP_RECT_1;
>>       DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
>> -        pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
>> +        pstate[R0]->pipe.multirect_mode, 
>> pstate[R0]->pipe.multirect_index);
>>       DPU_DEBUG_PLANE(dpu_plane[R1], "R1: %d - %d\n",
>> -        pstate[R1]->multirect_mode, pstate[R1]->multirect_index);
>> +        pstate[R1]->pipe.multirect_mode, 
>> pstate[R1]->pipe.multirect_index);
>>       return 0;
>>   }
>> @@ -937,6 +937,7 @@ static int dpu_plane_atomic_check(struct drm_plane 
>> *plane,
>>       int ret = 0, min_scale;
>>       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;
>>       const struct drm_crtc_state *crtc_state = NULL;
>>       const struct dpu_format *fmt;
>>       struct drm_rect src, dst, fb_rect = { 0 };
>> @@ -946,10 +947,10 @@ static int dpu_plane_atomic_check(struct 
>> drm_plane *plane,
>>           crtc_state = drm_atomic_get_new_crtc_state(state,
>>                                  new_plane_state->crtc);
>> -    min_scale = FRAC_16_16(1, pstate->pipe_hw->cap->sblk->maxupscale);
>> +    min_scale = FRAC_16_16(1, pipe->sspp->cap->sblk->maxupscale);
>>       ret = drm_atomic_helper_check_plane_state(new_plane_state, 
>> crtc_state,
>>                             min_scale,
>> -                          pstate->pipe_hw->cap->sblk->maxdwnscale << 16,
>> +                          pipe->sspp->cap->sblk->maxdwnscale << 16,
>>                             true, true);
>>       if (ret) {
>>           DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
>> @@ -975,8 +976,8 @@ static int dpu_plane_atomic_check(struct drm_plane 
>> *plane,
>>       min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>       if (DPU_FORMAT_IS_YUV(fmt) &&
>> -        (!(pstate->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
>> -         !(pstate->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
>> +        (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
>> +         !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
>>           DPU_DEBUG_PLANE(pdpu,
>>                   "plane doesn't have scaler/csc for yuv\n");
>>           return -EINVAL;
>> @@ -1037,12 +1038,12 @@ void dpu_plane_flush(struct drm_plane *plane)
>>       else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
>>           /* force 100% alpha */
>>           _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
>> -    else if (pstate->pipe_hw && pstate->pipe_hw->ops.setup_csc) {
>> +    else if (pstate->pipe.sspp && pstate->pipe.sspp->ops.setup_csc) {
>>           const struct dpu_format *fmt = 
>> to_dpu_format(msm_framebuffer_format(plane->state->fb));
>>           const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, 
>> fmt);
>>           if (csc_ptr)
>> -            pstate->pipe_hw->ops.setup_csc(pstate->pipe_hw, csc_ptr);
>> +            pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, 
>> csc_ptr);
>>       }
>>       /* flag h/w flush complete */
>> @@ -1072,6 +1073,7 @@ static void dpu_plane_sspp_atomic_update(struct 
>> drm_plane *plane)
>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>       struct drm_plane_state *state = plane->state;
>>       struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>> +    struct dpu_sw_pipe *pipe = &pstate->pipe;
>>       struct drm_crtc *crtc = state->crtc;
>>       struct drm_framebuffer *fb = state->fb;
>>       bool is_rt_pipe, update_qos_remap;
>> @@ -1109,21 +1111,21 @@ static void 
>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>           return;
>>       }
>> -    if (pstate->pipe_hw->ops.setup_rects) {
>> -        pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>> +    if (pipe->sspp->ops.setup_rects) {
>> +        pipe->sspp->ops.setup_rects(pipe->sspp,
>>                   &pipe_cfg,
>> -                pstate->multirect_index);
>> +                pipe->multirect_index);
>>       }
>>       _dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
>> -    if (pstate->pipe_hw->ops.setup_multirect)
>> -        pstate->pipe_hw->ops.setup_multirect(
>> -                pstate->pipe_hw,
>> -                pstate->multirect_index,
>> -                pstate->multirect_mode);
>> +    if (pipe->sspp->ops.setup_multirect)
>> +        pipe->sspp->ops.setup_multirect(
>> +                pipe->sspp,
>> +                pipe->multirect_index,
>> +                pipe->multirect_mode);
>> -    if (pstate->pipe_hw->ops.setup_format) {
>> +    if (pipe->sspp->ops.setup_format) {
>>           unsigned int rotation;
>>           src_flags = 0x0;
>> @@ -1140,10 +1142,10 @@ static void 
>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>               src_flags |= DPU_SSPP_FLIP_UD;
>>           /* update format */
>> -        pstate->pipe_hw->ops.setup_format(pstate->pipe_hw, fmt, 
>> src_flags,
>> -                pstate->multirect_index);
>> +        pipe->sspp->ops.setup_format(pipe->sspp, fmt, src_flags,
>> +                pipe->multirect_index);
>> -        if (pstate->pipe_hw->ops.setup_cdp) {
>> +        if (pipe->sspp->ops.setup_cdp) {
>>               struct dpu_hw_pipe_cdp_cfg cdp_cfg;
>>               memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
>> @@ -1157,7 +1159,7 @@ static void dpu_plane_sspp_atomic_update(struct 
>> drm_plane *plane)
>>                       DPU_FORMAT_IS_TILE(fmt);
>>               cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
>> -            pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg, 
>> pstate->multirect_index);
>> +            pipe->sspp->ops.setup_cdp(pipe->sspp, &cdp_cfg, 
>> pipe->multirect_index);
>>           }
>>       }
>> @@ -1191,7 +1193,7 @@ static void _dpu_plane_atomic_disable(struct 
>> drm_plane *plane)
>>       struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>       trace_dpu_plane_disable(DRMID(plane), false,
>> -                pstate->multirect_mode);
>> +                pstate->pipe.multirect_mode);
>>       pstate->pending = true;
>>   }
>> @@ -1305,9 +1307,9 @@ static void dpu_plane_atomic_print_state(struct 
>> drm_printer *p,
>>       const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>       drm_printf(p, "\tstage=%d\n", pstate->stage);
>> -    drm_printf(p, "\tsspp=%s\n", pstate->pipe_hw->cap->name);
>> -    drm_printf(p, "\tmultirect_mode=%s\n", 
>> dpu_get_multirect_mode(pstate->multirect_mode));
>> -    drm_printf(p, "\tmultirect_index=%s\n", 
>> dpu_get_multirect_index(pstate->multirect_index));
>> +    drm_printf(p, "\tsspp=%s\n", pstate->pipe.sspp->cap->name);
>> +    drm_printf(p, "\tmultirect_mode=%s\n", 
>> dpu_get_multirect_mode(pstate->pipe.multirect_mode));
>> +    drm_printf(p, "\tmultirect_index=%s\n", 
>> dpu_get_multirect_index(pstate->pipe.multirect_index));
>>   }
>>   static void dpu_plane_reset(struct drm_plane *plane)
>> @@ -1336,7 +1338,7 @@ static void dpu_plane_reset(struct drm_plane 
>> *plane)
>>           return;
>>       }
>> -    pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - 
>> SSPP_NONE]);
>> +    pstate->pipe.sspp = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - 
>> SSPP_NONE]);
>>       __drm_atomic_helper_plane_reset(plane, &pstate->base);
>>   }
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>> index d745cde4ea77..b6fd6f856d6a 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>> @@ -31,11 +31,9 @@ struct dpu_plane_state {
>>       struct msm_gem_address_space *aspace;
>>       enum dpu_stage stage;
>>       bool needs_qos_remap;
>> -    uint32_t multirect_index;
>> -    uint32_t multirect_mode;
>>       bool pending;
>> -    struct dpu_hw_pipe *pipe_hw;
>> +    struct dpu_sw_pipe pipe;
> 
> Are you sure we dont need this to be a pointer?
> 
> Since this is now part of plane_state, its possible that across commits, 
> the hw pipe can change for this plane's state. So might be better if 
> this is pointer in that case ....

A pointer means that it is allocated and deallocated by somebody. 
Probably you meant that it is a pointer into the dpu_hw_pipe member 
(with dpu_hw_pipe having sw_pipe's for rect0 and rect1).

I thought about this. And ended up with the dpu_sw_pipe having a 
dpu_hw_pipe pointer inside, but itself being a member of plane state. 
This way the plane state contains such data as multirect mode and rectangle.


> 
>>       u64 plane_fetch_bw;
>>       u64 plane_clk;


-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe
  2022-05-06 21:39     ` Dmitry Baryshkov
@ 2022-05-06 21:48       ` Abhinav Kumar
  2022-05-06 22:29         ` Dmitry Baryshkov
  0 siblings, 1 reply; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-06 21:48 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd,
	Daniel Vetter, freedreno



On 5/6/2022 2:39 PM, Dmitry Baryshkov wrote:
> On 07/05/2022 00:30, Abhinav Kumar wrote:
>>
>>
>> On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
>>> Wrap SSPP and multirect index/mode into a single structure that
>>> represents software view on the pipe used.
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c    |   8 +-
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  16 ++-
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 136 ++++++++++----------
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   |   4 +-
>>>   4 files changed, 86 insertions(+), 78 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> index ada7d5750536..751c64012058 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> @@ -441,14 +441,14 @@ static void _dpu_crtc_blend_setup_ctl(struct 
>>> drm_crtc *crtc)
>>>           pstate = to_dpu_plane_state(state);
>>> -        sspp_idx = pstate->pipe_hw->idx;
>>> +        sspp_idx = pstate->pipe.sspp->idx;
>>>           set_bit(sspp_idx, fetch_active);
>>>           stage_idx = zpos_cnt[pstate->stage]++;
>>>           stage_cfg.stage[pstate->stage][stage_idx] =
>>>                       sspp_idx;
>>>           stage_cfg.multirect_index[pstate->stage][stage_idx] =
>>> -                    pstate->multirect_index;
>>> +                    pstate->pipe.multirect_index;
>>>           /* blend config update */
>>>           for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++)
>>> @@ -1118,7 +1118,7 @@ static int dpu_crtc_atomic_check(struct 
>>> drm_crtc *crtc,
>>>           pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
>>>           pstates[cnt].drm_pstate = pstate;
>>>           pstates[cnt].stage = pstate->normalized_zpos;
>>> -        pstates[cnt].pipe_id = 
>>> to_dpu_plane_state(pstate)->pipe_hw->idx;
>>> +        pstates[cnt].pipe_id = 
>>> to_dpu_plane_state(pstate)->pipe.sspp->idx;
>>>           if (pipe_staged[pstates[cnt].pipe_id]) {
>>>               multirect_plane[multirect_count].r0 =
>>> @@ -1389,7 +1389,7 @@ static int _dpu_debugfs_status_show(struct 
>>> seq_file *s, void *data)
>>>               state->crtc_x, state->crtc_y, state->crtc_w,
>>>               state->crtc_h);
>>>           seq_printf(s, "\tmultirect: mode: %d index: %d\n",
>>> -            pstate->multirect_mode, pstate->multirect_index);
>>> +            pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
>>>           seq_puts(s, "\n");
>>>       }
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>>> index 674f311f99b4..0af2bc6e5df8 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>>> @@ -159,15 +159,11 @@ struct dpu_hw_pixel_ext {
>>>    * @src_rect:  src ROI, caller takes into account the different 
>>> operations
>>>    *             such as decimation, flip etc to program this field
>>>    * @dest_rect: destination ROI.
>>> - * @index:     index of the rectangle of SSPP
>>> - * @mode:      parallel or time multiplex multirect mode
>>>    */
>>>   struct dpu_hw_pipe_cfg {
>>>       struct dpu_hw_fmt_layout layout;
>>>       struct drm_rect src_rect;
>>>       struct drm_rect dst_rect;
>>> -    enum dpu_sspp_multirect_index index;
>>> -    enum dpu_sspp_multirect_mode mode;
>>>   };
>>>   /**
>>> @@ -218,6 +214,18 @@ struct dpu_hw_pipe_ts_cfg {
>>>       u64 time;
>>>   };
>>> +/**
>>> + * struct dpu_sw_pipe - software pipe description
>>> + * @sspp:      backing SSPP pipe
>>> + * @index:     index of the rectangle of SSPP
>>> + * @mode:      parallel or time multiplex multirect mode
>>> + */
>>> +struct dpu_sw_pipe {
>>> +    struct dpu_hw_pipe *sspp;
>>> +    enum dpu_sspp_multirect_index multirect_index;
>>> +    enum dpu_sspp_multirect_mode multirect_mode;
>>> +};
>>> +
>>>   /**
>>>    * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions
>>>    * Caller must call the init function to get the pipe context for 
>>> each pipe
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> index d1f9b4bc10ac..51b5e8a3182b 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -247,7 +247,7 @@ static int _dpu_plane_calc_fill_level(struct 
>>> drm_plane *plane,
>>>                   ((src_width + 32) * fmt->bpp);
>>>           }
>>>       } else {
>>> -        if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
>>> +        if (pstate->pipe.multirect_mode == 
>>> DPU_SSPP_MULTIRECT_PARALLEL) {
>>>               total_fl = (fixed_buff_size / 2) * 2 /
>>>                   ((src_width + 32) * fmt->bpp);
>>>           } else {
>>> @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct 
>>> drm_plane *plane,
>>>               fmt ? (char *)&fmt->base.pixel_format : NULL,
>>>               pdpu->is_rt_pipe, total_fl, qos_lut);
>>> -    pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
>>> +    pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut);
>>>   }
>>>   /**
>>> @@ -383,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct 
>>> drm_plane *plane,
>>>           danger_lut,
>>>           safe_lut);
>>> -    pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
>>> +    pstate->pipe.sspp->ops.setup_danger_safe_lut(pstate->pipe.sspp,
>>>               danger_lut, safe_lut);
>>>   }
>>> @@ -403,9 +403,9 @@ static void _dpu_plane_set_qos_ctrl(struct 
>>> drm_plane *plane,
>>>       memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>>       if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>>> -        pipe_qos_cfg.creq_vblank = 
>>> pstate->pipe_hw->cap->sblk->creq_vblank;
>>> +        pipe_qos_cfg.creq_vblank = 
>>> pstate->pipe.sspp->cap->sblk->creq_vblank;
>>>           pipe_qos_cfg.danger_vblank =
>>> -                pstate->pipe_hw->cap->sblk->danger_vblank;
>>> +                pstate->pipe.sspp->cap->sblk->danger_vblank;
>>>           pipe_qos_cfg.vblank_en = enable;
>>>       }
>>> @@ -431,7 +431,7 @@ static void _dpu_plane_set_qos_ctrl(struct 
>>> drm_plane *plane,
>>>           pipe_qos_cfg.danger_vblank,
>>>           pdpu->is_rt_pipe);
>>> -    pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
>>> +    pstate->pipe.sspp->ops.setup_qos_ctrl(pstate->pipe.sspp,
>>>               &pipe_qos_cfg);
>>>   }
>>> @@ -450,14 +450,14 @@ static void _dpu_plane_set_ot_limit(struct 
>>> drm_plane *plane,
>>>       struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>>>       memset(&ot_params, 0, sizeof(ot_params));
>>> -    ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
>>> -    ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
>>> +    ot_params.xin_id = pstate->pipe.sspp->cap->xin_id;
>>> +    ot_params.num = pstate->pipe.sspp->idx - SSPP_NONE;
>>>       ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
>>>       ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
>>>       ot_params.is_wfd = !pdpu->is_rt_pipe;
>>>       ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
>>>       ot_params.vbif_idx = VBIF_RT;
>>> -    ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>>> +    ot_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
>>>       ot_params.rd = true;
>>>       dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
>>> @@ -476,9 +476,9 @@ static void _dpu_plane_set_qos_remap(struct 
>>> drm_plane *plane)
>>>       memset(&qos_params, 0, sizeof(qos_params));
>>>       qos_params.vbif_idx = VBIF_RT;
>>> -    qos_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>>> -    qos_params.xin_id = pstate->pipe_hw->cap->xin_id;
>>> -    qos_params.num = pstate->pipe_hw->idx - SSPP_VIG0;
>>> +    qos_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
>>> +    qos_params.xin_id = pstate->pipe.sspp->cap->xin_id;
>>> +    qos_params.num = pstate->pipe.sspp->idx - SSPP_VIG0;
>>>       qos_params.is_rt = pdpu->is_rt_pipe;
>>>       DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, 
>>> clk_ctrl:%d\n",
>>> @@ -505,12 +505,12 @@ static void _dpu_plane_set_scanout(struct 
>>> drm_plane *plane,
>>>           DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
>>>       else if (ret)
>>>           DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", 
>>> ret);
>>> -    else if (pstate->pipe_hw->ops.setup_sourceaddress) {
>>> -        trace_dpu_plane_set_scanout(pstate->pipe_hw->idx,
>>> +    else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
>>> +        trace_dpu_plane_set_scanout(pstate->pipe.sspp->idx,
>>>                           &pipe_cfg->layout,
>>> -                        pstate->multirect_index);
>>> -        pstate->pipe_hw->ops.setup_sourceaddress(pstate->pipe_hw, 
>>> pipe_cfg,
>>> -                        pstate->multirect_index);
>>> +                        pstate->pipe.multirect_index);
>>> +        
>>> pstate->pipe.sspp->ops.setup_sourceaddress(pstate->pipe.sspp, pipe_cfg,
>>> +                        pstate->pipe.multirect_index);
>>>       }
>>>   }
>>> @@ -553,7 +553,7 @@ static void _dpu_plane_setup_scaler3(struct 
>>> dpu_plane *pdpu,
>>>               scale_cfg->src_height[i] /= chroma_subsmpl_v;
>>>           }
>>> -        if (pstate->pipe_hw->cap->features &
>>> +        if (pstate->pipe.sspp->cap->features &
>>>               BIT(DPU_SSPP_SCALER_QSEED4)) {
>>>               scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
>>>               scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
>>> @@ -624,7 +624,7 @@ static const struct dpu_csc_cfg 
>>> *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
>>>       if (!DPU_FORMAT_IS_YUV(fmt))
>>>           return NULL;
>>> -    if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe_hw->cap->features)
>>> +    if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe.sspp->cap->features)
>>>           csc_ptr = &dpu_csc10_YUV2RGB_601L;
>>>       else
>>>           csc_ptr = &dpu_csc_YUV2RGB_601L;
>>> @@ -659,8 +659,8 @@ static void _dpu_plane_setup_scaler(struct 
>>> dpu_plane *pdpu,
>>>               &scaler3_cfg, &pixel_ext, fmt,
>>>               info->hsub, info->vsub);
>>> -    if (pstate->pipe_hw->ops.setup_pe)
>>> -        pstate->pipe_hw->ops.setup_pe(pstate->pipe_hw,
>>> +    if (pstate->pipe.sspp->ops.setup_pe)
>>> +        pstate->pipe.sspp->ops.setup_pe(pstate->pipe.sspp,
>>>                   &pixel_ext);
>>>       /**
>>> @@ -668,9 +668,9 @@ static void _dpu_plane_setup_scaler(struct 
>>> dpu_plane *pdpu,
>>>        * bypassed. Still we need to update alpha and bitwidth
>>>        * ONLY for RECT0
>>>        */
>>> -    if (pstate->pipe_hw->ops.setup_scaler &&
>>> -            pstate->multirect_index != DPU_SSPP_RECT_1)
>>> -        pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
>>> +    if (pstate->pipe.sspp->ops.setup_scaler &&
>>> +            pstate->pipe.multirect_index != DPU_SSPP_RECT_1)
>>> +        pstate->pipe.sspp->ops.setup_scaler(pstate->pipe.sspp,
>>>                   pipe_cfg,
>>>                   &scaler3_cfg);
>>>   }
>>> @@ -699,10 +699,10 @@ static int _dpu_plane_color_fill(struct 
>>> dpu_plane *pdpu,
>>>       fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>>>       /* update sspp */
>>> -    if (fmt && pstate->pipe_hw->ops.setup_solidfill) {
>>> -        pstate->pipe_hw->ops.setup_solidfill(pstate->pipe_hw,
>>> +    if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
>>> +        pstate->pipe.sspp->ops.setup_solidfill(pstate->pipe.sspp,
>>>                   (color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
>>> -                pstate->multirect_index);
>>> +                pstate->pipe.multirect_index);
>>>           /* override scaler/decimation if solid fill */
>>>           pipe_cfg.dst_rect = pstate->base.dst;
>>> @@ -714,15 +714,15 @@ static int _dpu_plane_color_fill(struct 
>>> dpu_plane *pdpu,
>>>           pipe_cfg.src_rect.y2 =
>>>               drm_rect_height(&pipe_cfg.dst_rect);
>>> -        if (pstate->pipe_hw->ops.setup_format)
>>> -            pstate->pipe_hw->ops.setup_format(pstate->pipe_hw,
>>> +        if (pstate->pipe.sspp->ops.setup_format)
>>> +            pstate->pipe.sspp->ops.setup_format(pstate->pipe.sspp,
>>>                       fmt, DPU_SSPP_SOLID_FILL,
>>> -                    pstate->multirect_index);
>>> +                    pstate->pipe.multirect_index);
>>> -        if (pstate->pipe_hw->ops.setup_rects)
>>> -            pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>>> +        if (pstate->pipe.sspp->ops.setup_rects)
>>> +            pstate->pipe.sspp->ops.setup_rects(pstate->pipe.sspp,
>>>                       &pipe_cfg,
>>> -                    pstate->multirect_index);
>>> +                    pstate->pipe.multirect_index);
>>>           _dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
>>>       }
>>> @@ -734,8 +734,8 @@ void dpu_plane_clear_multirect(const struct 
>>> drm_plane_state *drm_state)
>>>   {
>>>       struct dpu_plane_state *pstate = to_dpu_plane_state(drm_state);
>>> -    pstate->multirect_index = DPU_SSPP_RECT_SOLO;
>>> -    pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
>>> +    pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
>>> +    pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
>>>   }
>>>   int dpu_plane_validate_multirect_v2(struct 
>>> dpu_multirect_plane_states *plane)
>>> @@ -817,8 +817,8 @@ int dpu_plane_validate_multirect_v2(struct 
>>> dpu_multirect_plane_states *plane)
>>>       /* Prefer PARALLEL FETCH Mode over TIME_MX Mode */
>>>       if (parallel_fetch_qualified) {
>>> -        pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>>> -        pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>>> +        pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>>> +        pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>>>           goto done;
>>>       }
>>> @@ -828,8 +828,8 @@ int dpu_plane_validate_multirect_v2(struct 
>>> dpu_multirect_plane_states *plane)
>>>       if (dst[R1].y1 >= dst[R0].y2 + buffer_lines ||
>>>           dst[R0].y1 >= dst[R1].y2 + buffer_lines) {
>>> -        pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>> -        pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>> +        pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>> +        pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>>       } else {
>>>           DPU_ERROR(
>>>               "No multirect mode possible for the planes (%d - %d)\n",
>>> @@ -839,13 +839,13 @@ int dpu_plane_validate_multirect_v2(struct 
>>> dpu_multirect_plane_states *plane)
>>>       }
>>>   done:
>>> -    pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
>>> -    pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
>>> +    pstate[R0]->pipe.multirect_index = DPU_SSPP_RECT_0;
>>> +    pstate[R1]->pipe.multirect_index = DPU_SSPP_RECT_1;
>>>       DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
>>> -        pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
>>> +        pstate[R0]->pipe.multirect_mode, 
>>> pstate[R0]->pipe.multirect_index);
>>>       DPU_DEBUG_PLANE(dpu_plane[R1], "R1: %d - %d\n",
>>> -        pstate[R1]->multirect_mode, pstate[R1]->multirect_index);
>>> +        pstate[R1]->pipe.multirect_mode, 
>>> pstate[R1]->pipe.multirect_index);
>>>       return 0;
>>>   }
>>> @@ -937,6 +937,7 @@ static int dpu_plane_atomic_check(struct 
>>> drm_plane *plane,
>>>       int ret = 0, min_scale;
>>>       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;
>>>       const struct drm_crtc_state *crtc_state = NULL;
>>>       const struct dpu_format *fmt;
>>>       struct drm_rect src, dst, fb_rect = { 0 };
>>> @@ -946,10 +947,10 @@ static int dpu_plane_atomic_check(struct 
>>> drm_plane *plane,
>>>           crtc_state = drm_atomic_get_new_crtc_state(state,
>>>                                  new_plane_state->crtc);
>>> -    min_scale = FRAC_16_16(1, pstate->pipe_hw->cap->sblk->maxupscale);
>>> +    min_scale = FRAC_16_16(1, pipe->sspp->cap->sblk->maxupscale);
>>>       ret = drm_atomic_helper_check_plane_state(new_plane_state, 
>>> crtc_state,
>>>                             min_scale,
>>> -                          pstate->pipe_hw->cap->sblk->maxdwnscale << 
>>> 16,
>>> +                          pipe->sspp->cap->sblk->maxdwnscale << 16,
>>>                             true, true);
>>>       if (ret) {
>>>           DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
>>> @@ -975,8 +976,8 @@ static int dpu_plane_atomic_check(struct 
>>> drm_plane *plane,
>>>       min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>>       if (DPU_FORMAT_IS_YUV(fmt) &&
>>> -        (!(pstate->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
>>> -         !(pstate->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
>>> +        (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
>>> +         !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
>>>           DPU_DEBUG_PLANE(pdpu,
>>>                   "plane doesn't have scaler/csc for yuv\n");
>>>           return -EINVAL;
>>> @@ -1037,12 +1038,12 @@ void dpu_plane_flush(struct drm_plane *plane)
>>>       else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
>>>           /* force 100% alpha */
>>>           _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
>>> -    else if (pstate->pipe_hw && pstate->pipe_hw->ops.setup_csc) {
>>> +    else if (pstate->pipe.sspp && pstate->pipe.sspp->ops.setup_csc) {
>>>           const struct dpu_format *fmt = 
>>> to_dpu_format(msm_framebuffer_format(plane->state->fb));
>>>           const struct dpu_csc_cfg *csc_ptr = 
>>> _dpu_plane_get_csc(pdpu, fmt);
>>>           if (csc_ptr)
>>> -            pstate->pipe_hw->ops.setup_csc(pstate->pipe_hw, csc_ptr);
>>> +            pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, 
>>> csc_ptr);
>>>       }
>>>       /* flag h/w flush complete */
>>> @@ -1072,6 +1073,7 @@ static void dpu_plane_sspp_atomic_update(struct 
>>> drm_plane *plane)
>>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>>       struct drm_plane_state *state = plane->state;
>>>       struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>> +    struct dpu_sw_pipe *pipe = &pstate->pipe;
>>>       struct drm_crtc *crtc = state->crtc;
>>>       struct drm_framebuffer *fb = state->fb;
>>>       bool is_rt_pipe, update_qos_remap;
>>> @@ -1109,21 +1111,21 @@ static void 
>>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>           return;
>>>       }
>>> -    if (pstate->pipe_hw->ops.setup_rects) {
>>> -        pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>>> +    if (pipe->sspp->ops.setup_rects) {
>>> +        pipe->sspp->ops.setup_rects(pipe->sspp,
>>>                   &pipe_cfg,
>>> -                pstate->multirect_index);
>>> +                pipe->multirect_index);
>>>       }
>>>       _dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
>>> -    if (pstate->pipe_hw->ops.setup_multirect)
>>> -        pstate->pipe_hw->ops.setup_multirect(
>>> -                pstate->pipe_hw,
>>> -                pstate->multirect_index,
>>> -                pstate->multirect_mode);
>>> +    if (pipe->sspp->ops.setup_multirect)
>>> +        pipe->sspp->ops.setup_multirect(
>>> +                pipe->sspp,
>>> +                pipe->multirect_index,
>>> +                pipe->multirect_mode);
>>> -    if (pstate->pipe_hw->ops.setup_format) {
>>> +    if (pipe->sspp->ops.setup_format) {
>>>           unsigned int rotation;
>>>           src_flags = 0x0;
>>> @@ -1140,10 +1142,10 @@ static void 
>>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>               src_flags |= DPU_SSPP_FLIP_UD;
>>>           /* update format */
>>> -        pstate->pipe_hw->ops.setup_format(pstate->pipe_hw, fmt, 
>>> src_flags,
>>> -                pstate->multirect_index);
>>> +        pipe->sspp->ops.setup_format(pipe->sspp, fmt, src_flags,
>>> +                pipe->multirect_index);
>>> -        if (pstate->pipe_hw->ops.setup_cdp) {
>>> +        if (pipe->sspp->ops.setup_cdp) {
>>>               struct dpu_hw_pipe_cdp_cfg cdp_cfg;
>>>               memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
>>> @@ -1157,7 +1159,7 @@ static void dpu_plane_sspp_atomic_update(struct 
>>> drm_plane *plane)
>>>                       DPU_FORMAT_IS_TILE(fmt);
>>>               cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
>>> -            pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, 
>>> &cdp_cfg, pstate->multirect_index);
>>> +            pipe->sspp->ops.setup_cdp(pipe->sspp, &cdp_cfg, 
>>> pipe->multirect_index);
>>>           }
>>>       }
>>> @@ -1191,7 +1193,7 @@ static void _dpu_plane_atomic_disable(struct 
>>> drm_plane *plane)
>>>       struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>>       trace_dpu_plane_disable(DRMID(plane), false,
>>> -                pstate->multirect_mode);
>>> +                pstate->pipe.multirect_mode);
>>>       pstate->pending = true;
>>>   }
>>> @@ -1305,9 +1307,9 @@ static void dpu_plane_atomic_print_state(struct 
>>> drm_printer *p,
>>>       const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>>       drm_printf(p, "\tstage=%d\n", pstate->stage);
>>> -    drm_printf(p, "\tsspp=%s\n", pstate->pipe_hw->cap->name);
>>> -    drm_printf(p, "\tmultirect_mode=%s\n", 
>>> dpu_get_multirect_mode(pstate->multirect_mode));
>>> -    drm_printf(p, "\tmultirect_index=%s\n", 
>>> dpu_get_multirect_index(pstate->multirect_index));
>>> +    drm_printf(p, "\tsspp=%s\n", pstate->pipe.sspp->cap->name);
>>> +    drm_printf(p, "\tmultirect_mode=%s\n", 
>>> dpu_get_multirect_mode(pstate->pipe.multirect_mode));
>>> +    drm_printf(p, "\tmultirect_index=%s\n", 
>>> dpu_get_multirect_index(pstate->pipe.multirect_index));
>>>   }
>>>   static void dpu_plane_reset(struct drm_plane *plane)
>>> @@ -1336,7 +1338,7 @@ static void dpu_plane_reset(struct drm_plane 
>>> *plane)
>>>           return;
>>>       }
>>> -    pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - 
>>> SSPP_NONE]);
>>> +    pstate->pipe.sspp = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe 
>>> - SSPP_NONE]);
>>>       __drm_atomic_helper_plane_reset(plane, &pstate->base);
>>>   }
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> index d745cde4ea77..b6fd6f856d6a 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> @@ -31,11 +31,9 @@ struct dpu_plane_state {
>>>       struct msm_gem_address_space *aspace;
>>>       enum dpu_stage stage;
>>>       bool needs_qos_remap;
>>> -    uint32_t multirect_index;
>>> -    uint32_t multirect_mode;
>>>       bool pending;
>>> -    struct dpu_hw_pipe *pipe_hw;
>>> +    struct dpu_sw_pipe pipe;
>>
>> Are you sure we dont need this to be a pointer?
>>
>> Since this is now part of plane_state, its possible that across 
>> commits, the hw pipe can change for this plane's state. So might be 
>> better if this is pointer in that case ....
> 
> A pointer means that it is allocated and deallocated by somebody. 
> Probably you meant that it is a pointer into the dpu_hw_pipe member 
> (with dpu_hw_pipe having sw_pipe's for rect0 and rect1).
> 
> I thought about this. And ended up with the dpu_sw_pipe having a 
> dpu_hw_pipe pointer inside, but itself being a member of plane state. 
> This way the plane state contains such data as multirect mode and 
> rectangle.

Right, so what I meant was, previously pipe_hw was a pointer but it was 
not changed dynamically because it was assigned once in dpu_plane_init() 
but after that was not updated to point to a different pipe_hw.

Now, pipe_hw is part of the plane state which means the actual hardware 
which the plane state is using can change across commits with virtual 
plane support.

So it made more sense to me that this was "struct dpu_sw_pipe *pipe" 
because looking at it from a top level it tells me that the dpu_sw_pipe 
can point to a different pipe. Just little more intuitive.

With it being just a member, sure it still means the same thing because 
internal to it, pipe_hw is still a pointer.

Just felt it was more logical to have the whole dpu_sw_pipe as a pointer.

But its just a thought not a strong inclination against current patch.

> 
> 
>>
>>>       u64 plane_fetch_bw;
>>>       u64 plane_clk;
> 
> 

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

* Re: [PATCH 11/25] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
  2022-02-09 17:25 ` [PATCH 11/25] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks Dmitry Baryshkov
@ 2022-05-06 22:24   ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-06 22:24 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> Where feasible, use dpu_sw_pipe rather than a combo of dpu_hw_pipe and
> multirect_index/_mode arguments.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 59 ++++++++++----------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 46 ++++++---------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 62 +++++++++------------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  9 ++-
>   4 files changed, 77 insertions(+), 99 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> index 8714ee767346..d8120168f974 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -168,17 +168,16 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
>   	return rc;
>   }
>   
> -static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
> -		enum dpu_sspp_multirect_index index,
> -		enum dpu_sspp_multirect_mode mode)
> +static void dpu_hw_sspp_setup_multirect(struct dpu_sw_pipe *pipe)
>   {
> +	struct dpu_hw_pipe *ctx = pipe->sspp;
>   	u32 mode_mask;
>   	u32 idx;
>   
>   	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
>   		return;
>   
> -	if (index == DPU_SSPP_RECT_SOLO) {
> +	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
>   		/**
>   		 * if rect index is RECT_SOLO, we cannot expect a
>   		 * virtual plane sharing the same SSPP id. So we go
> @@ -187,8 +186,8 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
>   		mode_mask = 0;
>   	} else {
>   		mode_mask = DPU_REG_READ(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx);
> -		mode_mask |= index;
> -		if (mode == DPU_SSPP_MULTIRECT_TIME_MX)
> +		mode_mask |= pipe->multirect_index;
> +		if (pipe->multirect_mode == DPU_SSPP_MULTIRECT_TIME_MX)
>   			mode_mask |= BIT(2);
>   		else
>   			mode_mask &= ~BIT(2);
> @@ -239,10 +238,10 @@ static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx,
>   /*
>    * Setup source pixel format, flip,
>    */
> -static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
> -		const struct dpu_format *fmt, u32 flags,
> -		enum dpu_sspp_multirect_index rect_mode)
> +static void dpu_hw_sspp_setup_format(struct dpu_sw_pipe *pipe,
> +		const struct dpu_format *fmt, u32 flags)
>   {
> +	struct dpu_hw_pipe *ctx = pipe->sspp;
>   	struct dpu_hw_blk_reg_map *c;
>   	u32 chroma_samp, unpack, src_format;
>   	u32 opmode = 0;
> @@ -253,7 +252,8 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
>   	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx) || !fmt)
>   		return;
>   
> -	if (rect_mode == DPU_SSPP_RECT_SOLO || rect_mode == DPU_SSPP_RECT_0) {
> +	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
> +	    pipe->multirect_index == DPU_SSPP_RECT_0) {
>   		op_mode_off = SSPP_SRC_OP_MODE;
>   		unpack_pat_off = SSPP_SRC_UNPACK_PATTERN;
>   		format_off = SSPP_SRC_FORMAT;
> @@ -443,10 +443,10 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
>   /*
>    * dpu_hw_sspp_setup_rects()
>    */
> -static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
> -		struct dpu_hw_pipe_cfg *cfg,
> -		enum dpu_sspp_multirect_index rect_index)
> +static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
> +		struct dpu_hw_pipe_cfg *cfg)
>   {
> +	struct dpu_hw_pipe *ctx = pipe->sspp;
>   	struct dpu_hw_blk_reg_map *c;
>   	u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
>   	u32 src_size_off, src_xy_off, out_size_off, out_xy_off;
> @@ -457,7 +457,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
>   
>   	c = &ctx->hw;
>   
> -	if (rect_index == DPU_SSPP_RECT_SOLO || rect_index == DPU_SSPP_RECT_0) {
> +	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
> +	    pipe->multirect_index == DPU_SSPP_RECT_0) {
>   		src_size_off = SSPP_SRC_SIZE;
>   		src_xy_off = SSPP_SRC_XY;
>   		out_size_off = SSPP_OUT_SIZE;
> @@ -478,7 +479,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
>   	dst_size = (drm_rect_height(&cfg->dst_rect) << 16) |
>   		drm_rect_width(&cfg->dst_rect);
>   
> -	if (rect_index == DPU_SSPP_RECT_SOLO) {
> +	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
>   		ystride0 = (cfg->layout.plane_pitch[0]) |
>   			(cfg->layout.plane_pitch[1] << 16);
>   		ystride1 = (cfg->layout.plane_pitch[2]) |
> @@ -487,7 +488,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
>   		ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx);
>   		ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx);
>   
> -		if (rect_index == DPU_SSPP_RECT_0) {
> +		if (pipe->multirect_index == DPU_SSPP_RECT_0) {
>   			ystride0 = (ystride0 & 0xFFFF0000) |
>   				(cfg->layout.plane_pitch[0] & 0x0000FFFF);
>   			ystride1 = (ystride1 & 0xFFFF0000)|
> @@ -512,21 +513,21 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
>   	DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
>   }
>   
> -static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_pipe *ctx,
> -		struct dpu_hw_pipe_cfg *cfg,
> -		enum dpu_sspp_multirect_index rect_mode)
> +static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
> +		struct dpu_hw_pipe_cfg *cfg)
>   {
> +	struct dpu_hw_pipe *ctx = pipe->sspp;
>   	int i;
>   	u32 idx;
>   
>   	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
>   		return;
>   
> -	if (rect_mode == DPU_SSPP_RECT_SOLO) {
> +	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
>   		for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
>   			DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4,
>   					cfg->layout.plane_addr[i]);
> -	} else if (rect_mode == DPU_SSPP_RECT_0) {
> +	} else if (pipe->multirect_index == DPU_SSPP_RECT_0) {
>   		DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx,
>   				cfg->layout.plane_addr[0]);
>   		DPU_REG_WRITE(&ctx->hw, SSPP_SRC2_ADDR + idx,
> @@ -556,15 +557,16 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
>   	dpu_hw_csc_setup(&ctx->hw, idx, data, csc10);
>   }
>   
> -static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, enum
> -		dpu_sspp_multirect_index rect_index)
> +static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
>   {
> +	struct dpu_hw_pipe *ctx = pipe->sspp;
>   	u32 idx;
>   
>   	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
>   		return;
>   
> -	if (rect_index == DPU_SSPP_RECT_SOLO || rect_index == DPU_SSPP_RECT_0)
> +	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
> +	    pipe->multirect_index == DPU_SSPP_RECT_0)
>   		DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR + idx, color);
>   	else
>   		DPU_REG_WRITE(&ctx->hw, SSPP_SRC_CONSTANT_COLOR_REC1 + idx,
> @@ -626,10 +628,10 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe *ctx,
>   	DPU_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL + idx, qos_ctrl);
>   }
>   
> -static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
> -		struct dpu_hw_pipe_cdp_cfg *cfg,
> -		enum dpu_sspp_multirect_index index)
> +static void dpu_hw_sspp_setup_cdp(struct dpu_sw_pipe *pipe,
> +		struct dpu_hw_pipe_cdp_cfg *cfg)
>   {
> +	struct dpu_hw_pipe *ctx = pipe->sspp;
>   	u32 idx;
>   	u32 cdp_cntl = 0;
>   	u32 cdp_cntl_offset = 0;
> @@ -640,7 +642,8 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
>   	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
>   		return;
>   
> -	if (index == DPU_SSPP_RECT_SOLO || index == DPU_SSPP_RECT_0)
> +	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO ||
> +	    pipe->multirect_index == DPU_SSPP_RECT_0)
>   		cdp_cntl_offset = SSPP_CDP_CNTL;
>   	else
>   		cdp_cntl_offset = SSPP_CDP_CNTL_REC1;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> index 0af2bc6e5df8..74171fb4e585 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -234,24 +234,20 @@ struct dpu_sw_pipe {
>   struct dpu_hw_sspp_ops {
>   	/**
>   	 * setup_format - setup pixel format cropping rectangle, flip
> -	 * @ctx: Pointer to pipe context
> +	 * @pipe: Pointer to software pipe context
>   	 * @cfg: Pointer to pipe config structure
>   	 * @flags: Extra flags for format config
> -	 * @index: rectangle index in multirect
>   	 */
> -	void (*setup_format)(struct dpu_hw_pipe *ctx,
> -			const struct dpu_format *fmt, u32 flags,
> -			enum dpu_sspp_multirect_index index);
> +	void (*setup_format)(struct dpu_sw_pipe *pipe,
> +			const struct dpu_format *fmt, u32 flags);
>   
>   	/**
>   	 * setup_rects - setup pipe ROI rectangles
> -	 * @ctx: Pointer to pipe context
> +	 * @pipe: Pointer to software pipe context
>   	 * @cfg: Pointer to pipe config structure
> -	 * @index: rectangle index in multirect
>   	 */
> -	void (*setup_rects)(struct dpu_hw_pipe *ctx,
> -			struct dpu_hw_pipe_cfg *cfg,
> -			enum dpu_sspp_multirect_index index);
> +	void (*setup_rects)(struct dpu_sw_pipe *pipe,
> +			struct dpu_hw_pipe_cfg *cfg);
>   
>   	/**
>   	 * setup_pe - setup pipe pixel extension
> @@ -263,13 +259,11 @@ struct dpu_hw_sspp_ops {
>   
>   	/**
>   	 * setup_sourceaddress - setup pipe source addresses
> -	 * @ctx: Pointer to pipe context
> +	 * @pipe: Pointer to software pipe context
>   	 * @cfg: Pointer to pipe config structure
> -	 * @index: rectangle index in multirect
>   	 */
> -	void (*setup_sourceaddress)(struct dpu_hw_pipe *ctx,
> -			struct dpu_hw_pipe_cfg *cfg,
> -			enum dpu_sspp_multirect_index index);
> +	void (*setup_sourceaddress)(struct dpu_sw_pipe *ctx,
> +			struct dpu_hw_pipe_cfg *cfg);
>   
>   	/**
>   	 * setup_csc - setup color space coversion
> @@ -280,24 +274,18 @@ struct dpu_hw_sspp_ops {
>   
>   	/**
>   	 * setup_solidfill - enable/disable colorfill
> -	 * @ctx: Pointer to pipe context
> +	 * @pipe: Pointer to software pipe context
>   	 * @const_color: Fill color value
>   	 * @flags: Pipe flags
> -	 * @index: rectangle index in multirect
>   	 */
> -	void (*setup_solidfill)(struct dpu_hw_pipe *ctx, u32 color,
> -			enum dpu_sspp_multirect_index index);
> +	void (*setup_solidfill)(struct dpu_sw_pipe *pipe, u32 color);
>   
>   	/**
>   	 * setup_multirect - setup multirect configuration
> -	 * @ctx: Pointer to pipe context
> -	 * @index: rectangle index in multirect
> -	 * @mode: parallel fetch / time multiplex multirect mode
> +	 * @pipe: Pointer to software pipe context
>   	 */
>   
> -	void (*setup_multirect)(struct dpu_hw_pipe *ctx,
> -			enum dpu_sspp_multirect_index index,
> -			enum dpu_sspp_multirect_mode mode);
> +	void (*setup_multirect)(struct dpu_sw_pipe *pipe);
>   
>   	/**
>   	 * setup_sharpening - setup sharpening
> @@ -362,13 +350,11 @@ struct dpu_hw_sspp_ops {
>   
>   	/**
>   	 * setup_cdp - setup client driven prefetch
> -	 * @ctx: Pointer to pipe context
> +	 * @pipe: Pointer to software pipe context
>   	 * @cfg: Pointer to cdp configuration
> -	 * @index: rectangle index in multirect
>   	 */
> -	void (*setup_cdp)(struct dpu_hw_pipe *ctx,
> -			struct dpu_hw_pipe_cdp_cfg *cfg,
> -			enum dpu_sspp_multirect_index index);
> +	void (*setup_cdp)(struct dpu_sw_pipe *pipe,
> +			struct dpu_hw_pipe_cdp_cfg *cfg);
>   };
>   
>   /**
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 51b5e8a3182b..d029ce806039 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -506,16 +506,13 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
>   	else if (ret)
>   		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
>   	else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
> -		trace_dpu_plane_set_scanout(pstate->pipe.sspp->idx,
> -					    &pipe_cfg->layout,
> -					    pstate->pipe.multirect_index);
> -		pstate->pipe.sspp->ops.setup_sourceaddress(pstate->pipe.sspp, pipe_cfg,
> -						pstate->pipe.multirect_index);
> +		trace_dpu_plane_set_scanout(&pstate->pipe,
> +					    &pipe_cfg->layout);
> +		pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, pipe_cfg);
>   	}
>   }
>   
> -static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
> -		struct dpu_plane_state *pstate,
> +static void _dpu_plane_setup_scaler3(struct dpu_hw_pipe *pipe_hw,
>   		uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h,
>   		struct dpu_hw_scaler3_cfg *scale_cfg,
>   		struct dpu_hw_pixel_ext *pixel_ext,
> @@ -553,7 +550,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
>   			scale_cfg->src_height[i] /= chroma_subsmpl_v;
>   		}
>   
> -		if (pstate->pipe.sspp->cap->features &
> +		if (pipe_hw->cap->features &
>   			BIT(DPU_SSPP_SCALER_QSEED4)) {
>   			scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
>   			scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
> @@ -637,11 +634,11 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
>   	return csc_ptr;
>   }
>   
> -static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
> -		struct dpu_plane_state *pstate,
> +static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe,
>   		const struct dpu_format *fmt, bool color_fill,
>   		struct dpu_hw_pipe_cfg *pipe_cfg)
>   {
> +	struct dpu_hw_pipe *pipe_hw = pipe->sspp;
>   	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
>   	struct dpu_hw_scaler3_cfg scaler3_cfg;
>   	struct dpu_hw_pixel_ext pixel_ext;
> @@ -651,7 +648,7 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>   
>   	/* don't chroma subsample if decimating */
>   	/* update scaler. calculate default config for QSEED3 */
> -	_dpu_plane_setup_scaler3(pdpu, pstate,
> +	_dpu_plane_setup_scaler3(pipe_hw,
>   			drm_rect_width(&pipe_cfg->src_rect),
>   			drm_rect_height(&pipe_cfg->src_rect),
>   			drm_rect_width(&pipe_cfg->dst_rect),
> @@ -659,8 +656,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>   			&scaler3_cfg, &pixel_ext, fmt,
>   			info->hsub, info->vsub);
>   
> -	if (pstate->pipe.sspp->ops.setup_pe)
> -		pstate->pipe.sspp->ops.setup_pe(pstate->pipe.sspp,
> +	if (pipe_hw->ops.setup_pe)
> +		pipe_hw->ops.setup_pe(pipe_hw,
>   				&pixel_ext);
>   
>   	/**
> @@ -668,9 +665,9 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>   	 * bypassed. Still we need to update alpha and bitwidth
>   	 * ONLY for RECT0
>   	 */
> -	if (pstate->pipe.sspp->ops.setup_scaler &&
> -			pstate->pipe.multirect_index != DPU_SSPP_RECT_1)
> -		pstate->pipe.sspp->ops.setup_scaler(pstate->pipe.sspp,
> +	if (pipe_hw->ops.setup_scaler &&
> +			pipe->multirect_index != DPU_SSPP_RECT_1)
> +		pipe_hw->ops.setup_scaler(pipe_hw,
>   				pipe_cfg,
>   				&scaler3_cfg);
>   }
> @@ -700,9 +697,8 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   
>   	/* update sspp */
>   	if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
> -		pstate->pipe.sspp->ops.setup_solidfill(pstate->pipe.sspp,
> -				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
> -				pstate->pipe.multirect_index);
> +		pstate->pipe.sspp->ops.setup_solidfill(&pstate->pipe,
> +				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24));
>   
>   		/* override scaler/decimation if solid fill */
>   		pipe_cfg.dst_rect = pstate->base.dst;
> @@ -715,16 +711,14 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   			drm_rect_height(&pipe_cfg.dst_rect);
>   
>   		if (pstate->pipe.sspp->ops.setup_format)
> -			pstate->pipe.sspp->ops.setup_format(pstate->pipe.sspp,
> -					fmt, DPU_SSPP_SOLID_FILL,
> -					pstate->pipe.multirect_index);
> +			pstate->pipe.sspp->ops.setup_format(&pstate->pipe,
> +					fmt, DPU_SSPP_SOLID_FILL);
>   
>   		if (pstate->pipe.sspp->ops.setup_rects)
> -			pstate->pipe.sspp->ops.setup_rects(pstate->pipe.sspp,
> -					&pipe_cfg,
> -					pstate->pipe.multirect_index);
> +			pstate->pipe.sspp->ops.setup_rects(&pstate->pipe,
> +					&pipe_cfg);
>   
> -		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
> +		_dpu_plane_setup_scaler(&pstate->pipe, fmt, true, &pipe_cfg);
>   	}
>   
>   	return 0;
> @@ -1112,18 +1106,15 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	}
>   
>   	if (pipe->sspp->ops.setup_rects) {
> -		pipe->sspp->ops.setup_rects(pipe->sspp,
> -				&pipe_cfg,
> -				pipe->multirect_index);
> +		pipe->sspp->ops.setup_rects(pipe,
> +				&pipe_cfg);
>   	}
>   
> -	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
> +	_dpu_plane_setup_scaler(pipe, fmt, false, &pipe_cfg);
>   
>   	if (pipe->sspp->ops.setup_multirect)
>   		pipe->sspp->ops.setup_multirect(
> -				pipe->sspp,
> -				pipe->multirect_index,
> -				pipe->multirect_mode);
> +				pipe);
>   
>   	if (pipe->sspp->ops.setup_format) {
>   		unsigned int rotation;
> @@ -1142,8 +1133,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   			src_flags |= DPU_SSPP_FLIP_UD;
>   
>   		/* update format */
> -		pipe->sspp->ops.setup_format(pipe->sspp, fmt, src_flags,
> -				pipe->multirect_index);
> +		pipe->sspp->ops.setup_format(pipe, fmt, src_flags);
>   
>   		if (pipe->sspp->ops.setup_cdp) {
>   			struct dpu_hw_pipe_cdp_cfg cdp_cfg;
> @@ -1159,7 +1149,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   					DPU_FORMAT_IS_TILE(fmt);
>   			cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
>   
> -			pipe->sspp->ops.setup_cdp(pipe->sspp, &cdp_cfg, pipe->multirect_index);
> +			pipe->sspp->ops.setup_cdp(pipe, &cdp_cfg);
>   		}
>   	}
>   
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> index ecd2f371374d..11b61f9777eb 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> @@ -759,18 +759,17 @@ TRACE_EVENT(dpu_crtc_disable_frame_pending,
>   );
>   
>   TRACE_EVENT(dpu_plane_set_scanout,
> -	TP_PROTO(enum dpu_sspp index, struct dpu_hw_fmt_layout *layout,
> -		 enum dpu_sspp_multirect_index multirect_index),
> -	TP_ARGS(index, layout, multirect_index),
> +	TP_PROTO(struct dpu_sw_pipe *pipe, struct dpu_hw_fmt_layout *layout),
> +	TP_ARGS(pipe, layout),
>   	TP_STRUCT__entry(
>   		__field(	enum dpu_sspp,			index	)
>   		__field_struct(	struct dpu_hw_fmt_layout,	layout	)
>   		__field(	enum dpu_sspp_multirect_index,	multirect_index)
>   	),
>   	TP_fast_assign(
> -		__entry->index = index;
> +		__entry->index = pipe->sspp.idx;
>   		__entry->layout = *layout;
> -		__entry->multirect_index = multirect_index;
> +		__entry->multirect_index = pipe->multirect_index;
>   	),
>   	TP_printk("index:%d layout:{%ux%u @ [%u/%u, %u/%u, %u/%u, %u/%u]} "
>   		  "multirect_index:%d", __entry->index, __entry->layout.width,

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

* Re: [Freedreno] [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe
  2022-05-06 21:48       ` [Freedreno] " Abhinav Kumar
@ 2022-05-06 22:29         ` Dmitry Baryshkov
  2022-05-06 22:46           ` Abhinav Kumar
  0 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-05-06 22:29 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd,
	Daniel Vetter, freedreno

On 07/05/2022 00:48, Abhinav Kumar wrote:
> 
> 
> On 5/6/2022 2:39 PM, Dmitry Baryshkov wrote:
>> On 07/05/2022 00:30, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
>>>> Wrap SSPP and multirect index/mode into a single structure that
>>>> represents software view on the pipe used.
>>>>
>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>> ---
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c    |   8 +-
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  16 ++-
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 136 
>>>> ++++++++++----------
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   |   4 +-
>>>>   4 files changed, 86 insertions(+), 78 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> index ada7d5750536..751c64012058 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> @@ -441,14 +441,14 @@ static void _dpu_crtc_blend_setup_ctl(struct 
>>>> drm_crtc *crtc)
>>>>           pstate = to_dpu_plane_state(state);
>>>> -        sspp_idx = pstate->pipe_hw->idx;
>>>> +        sspp_idx = pstate->pipe.sspp->idx;
>>>>           set_bit(sspp_idx, fetch_active);
>>>>           stage_idx = zpos_cnt[pstate->stage]++;
>>>>           stage_cfg.stage[pstate->stage][stage_idx] =
>>>>                       sspp_idx;
>>>>           stage_cfg.multirect_index[pstate->stage][stage_idx] =
>>>> -                    pstate->multirect_index;
>>>> +                    pstate->pipe.multirect_index;
>>>>           /* blend config update */
>>>>           for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++)
>>>> @@ -1118,7 +1118,7 @@ static int dpu_crtc_atomic_check(struct 
>>>> drm_crtc *crtc,
>>>>           pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
>>>>           pstates[cnt].drm_pstate = pstate;
>>>>           pstates[cnt].stage = pstate->normalized_zpos;
>>>> -        pstates[cnt].pipe_id = 
>>>> to_dpu_plane_state(pstate)->pipe_hw->idx;
>>>> +        pstates[cnt].pipe_id = 
>>>> to_dpu_plane_state(pstate)->pipe.sspp->idx;
>>>>           if (pipe_staged[pstates[cnt].pipe_id]) {
>>>>               multirect_plane[multirect_count].r0 =
>>>> @@ -1389,7 +1389,7 @@ static int _dpu_debugfs_status_show(struct 
>>>> seq_file *s, void *data)
>>>>               state->crtc_x, state->crtc_y, state->crtc_w,
>>>>               state->crtc_h);
>>>>           seq_printf(s, "\tmultirect: mode: %d index: %d\n",
>>>> -            pstate->multirect_mode, pstate->multirect_index);
>>>> +            pstate->pipe.multirect_mode, 
>>>> pstate->pipe.multirect_index);
>>>>           seq_puts(s, "\n");
>>>>       }
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>>>> index 674f311f99b4..0af2bc6e5df8 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>>>> @@ -159,15 +159,11 @@ struct dpu_hw_pixel_ext {
>>>>    * @src_rect:  src ROI, caller takes into account the different 
>>>> operations
>>>>    *             such as decimation, flip etc to program this field
>>>>    * @dest_rect: destination ROI.
>>>> - * @index:     index of the rectangle of SSPP
>>>> - * @mode:      parallel or time multiplex multirect mode
>>>>    */
>>>>   struct dpu_hw_pipe_cfg {
>>>>       struct dpu_hw_fmt_layout layout;
>>>>       struct drm_rect src_rect;
>>>>       struct drm_rect dst_rect;
>>>> -    enum dpu_sspp_multirect_index index;
>>>> -    enum dpu_sspp_multirect_mode mode;
>>>>   };
>>>>   /**
>>>> @@ -218,6 +214,18 @@ struct dpu_hw_pipe_ts_cfg {
>>>>       u64 time;
>>>>   };
>>>> +/**
>>>> + * struct dpu_sw_pipe - software pipe description
>>>> + * @sspp:      backing SSPP pipe
>>>> + * @index:     index of the rectangle of SSPP
>>>> + * @mode:      parallel or time multiplex multirect mode
>>>> + */
>>>> +struct dpu_sw_pipe {
>>>> +    struct dpu_hw_pipe *sspp;
>>>> +    enum dpu_sspp_multirect_index multirect_index;
>>>> +    enum dpu_sspp_multirect_mode multirect_mode;
>>>> +};
>>>> +
>>>>   /**
>>>>    * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver functions
>>>>    * Caller must call the init function to get the pipe context for 
>>>> each pipe
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> index d1f9b4bc10ac..51b5e8a3182b 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> @@ -247,7 +247,7 @@ static int _dpu_plane_calc_fill_level(struct 
>>>> drm_plane *plane,
>>>>                   ((src_width + 32) * fmt->bpp);
>>>>           }
>>>>       } else {
>>>> -        if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
>>>> +        if (pstate->pipe.multirect_mode == 
>>>> DPU_SSPP_MULTIRECT_PARALLEL) {
>>>>               total_fl = (fixed_buff_size / 2) * 2 /
>>>>                   ((src_width + 32) * fmt->bpp);
>>>>           } else {
>>>> @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct 
>>>> drm_plane *plane,
>>>>               fmt ? (char *)&fmt->base.pixel_format : NULL,
>>>>               pdpu->is_rt_pipe, total_fl, qos_lut);
>>>> -    pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
>>>> +    pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut);
>>>>   }
>>>>   /**
>>>> @@ -383,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct 
>>>> drm_plane *plane,
>>>>           danger_lut,
>>>>           safe_lut);
>>>> -    pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
>>>> +    pstate->pipe.sspp->ops.setup_danger_safe_lut(pstate->pipe.sspp,
>>>>               danger_lut, safe_lut);
>>>>   }
>>>> @@ -403,9 +403,9 @@ static void _dpu_plane_set_qos_ctrl(struct 
>>>> drm_plane *plane,
>>>>       memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>>>       if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>>>> -        pipe_qos_cfg.creq_vblank = 
>>>> pstate->pipe_hw->cap->sblk->creq_vblank;
>>>> +        pipe_qos_cfg.creq_vblank = 
>>>> pstate->pipe.sspp->cap->sblk->creq_vblank;
>>>>           pipe_qos_cfg.danger_vblank =
>>>> -                pstate->pipe_hw->cap->sblk->danger_vblank;
>>>> +                pstate->pipe.sspp->cap->sblk->danger_vblank;
>>>>           pipe_qos_cfg.vblank_en = enable;
>>>>       }
>>>> @@ -431,7 +431,7 @@ static void _dpu_plane_set_qos_ctrl(struct 
>>>> drm_plane *plane,
>>>>           pipe_qos_cfg.danger_vblank,
>>>>           pdpu->is_rt_pipe);
>>>> -    pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
>>>> +    pstate->pipe.sspp->ops.setup_qos_ctrl(pstate->pipe.sspp,
>>>>               &pipe_qos_cfg);
>>>>   }
>>>> @@ -450,14 +450,14 @@ static void _dpu_plane_set_ot_limit(struct 
>>>> drm_plane *plane,
>>>>       struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>>>>       memset(&ot_params, 0, sizeof(ot_params));
>>>> -    ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
>>>> -    ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
>>>> +    ot_params.xin_id = pstate->pipe.sspp->cap->xin_id;
>>>> +    ot_params.num = pstate->pipe.sspp->idx - SSPP_NONE;
>>>>       ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
>>>>       ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
>>>>       ot_params.is_wfd = !pdpu->is_rt_pipe;
>>>>       ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
>>>>       ot_params.vbif_idx = VBIF_RT;
>>>> -    ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>>>> +    ot_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
>>>>       ot_params.rd = true;
>>>>       dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
>>>> @@ -476,9 +476,9 @@ static void _dpu_plane_set_qos_remap(struct 
>>>> drm_plane *plane)
>>>>       memset(&qos_params, 0, sizeof(qos_params));
>>>>       qos_params.vbif_idx = VBIF_RT;
>>>> -    qos_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>>>> -    qos_params.xin_id = pstate->pipe_hw->cap->xin_id;
>>>> -    qos_params.num = pstate->pipe_hw->idx - SSPP_VIG0;
>>>> +    qos_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
>>>> +    qos_params.xin_id = pstate->pipe.sspp->cap->xin_id;
>>>> +    qos_params.num = pstate->pipe.sspp->idx - SSPP_VIG0;
>>>>       qos_params.is_rt = pdpu->is_rt_pipe;
>>>>       DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, 
>>>> clk_ctrl:%d\n",
>>>> @@ -505,12 +505,12 @@ static void _dpu_plane_set_scanout(struct 
>>>> drm_plane *plane,
>>>>           DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
>>>>       else if (ret)
>>>>           DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", 
>>>> ret);
>>>> -    else if (pstate->pipe_hw->ops.setup_sourceaddress) {
>>>> -        trace_dpu_plane_set_scanout(pstate->pipe_hw->idx,
>>>> +    else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
>>>> +        trace_dpu_plane_set_scanout(pstate->pipe.sspp->idx,
>>>>                           &pipe_cfg->layout,
>>>> -                        pstate->multirect_index);
>>>> -        pstate->pipe_hw->ops.setup_sourceaddress(pstate->pipe_hw, 
>>>> pipe_cfg,
>>>> -                        pstate->multirect_index);
>>>> +                        pstate->pipe.multirect_index);
>>>> + pstate->pipe.sspp->ops.setup_sourceaddress(pstate->pipe.sspp, 
>>>> pipe_cfg,
>>>> +                        pstate->pipe.multirect_index);
>>>>       }
>>>>   }
>>>> @@ -553,7 +553,7 @@ static void _dpu_plane_setup_scaler3(struct 
>>>> dpu_plane *pdpu,
>>>>               scale_cfg->src_height[i] /= chroma_subsmpl_v;
>>>>           }
>>>> -        if (pstate->pipe_hw->cap->features &
>>>> +        if (pstate->pipe.sspp->cap->features &
>>>>               BIT(DPU_SSPP_SCALER_QSEED4)) {
>>>>               scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
>>>>               scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
>>>> @@ -624,7 +624,7 @@ static const struct dpu_csc_cfg 
>>>> *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
>>>>       if (!DPU_FORMAT_IS_YUV(fmt))
>>>>           return NULL;
>>>> -    if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe_hw->cap->features)
>>>> +    if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe.sspp->cap->features)
>>>>           csc_ptr = &dpu_csc10_YUV2RGB_601L;
>>>>       else
>>>>           csc_ptr = &dpu_csc_YUV2RGB_601L;
>>>> @@ -659,8 +659,8 @@ static void _dpu_plane_setup_scaler(struct 
>>>> dpu_plane *pdpu,
>>>>               &scaler3_cfg, &pixel_ext, fmt,
>>>>               info->hsub, info->vsub);
>>>> -    if (pstate->pipe_hw->ops.setup_pe)
>>>> -        pstate->pipe_hw->ops.setup_pe(pstate->pipe_hw,
>>>> +    if (pstate->pipe.sspp->ops.setup_pe)
>>>> +        pstate->pipe.sspp->ops.setup_pe(pstate->pipe.sspp,
>>>>                   &pixel_ext);
>>>>       /**
>>>> @@ -668,9 +668,9 @@ static void _dpu_plane_setup_scaler(struct 
>>>> dpu_plane *pdpu,
>>>>        * bypassed. Still we need to update alpha and bitwidth
>>>>        * ONLY for RECT0
>>>>        */
>>>> -    if (pstate->pipe_hw->ops.setup_scaler &&
>>>> -            pstate->multirect_index != DPU_SSPP_RECT_1)
>>>> -        pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
>>>> +    if (pstate->pipe.sspp->ops.setup_scaler &&
>>>> +            pstate->pipe.multirect_index != DPU_SSPP_RECT_1)
>>>> +        pstate->pipe.sspp->ops.setup_scaler(pstate->pipe.sspp,
>>>>                   pipe_cfg,
>>>>                   &scaler3_cfg);
>>>>   }
>>>> @@ -699,10 +699,10 @@ static int _dpu_plane_color_fill(struct 
>>>> dpu_plane *pdpu,
>>>>       fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>>>>       /* update sspp */
>>>> -    if (fmt && pstate->pipe_hw->ops.setup_solidfill) {
>>>> -        pstate->pipe_hw->ops.setup_solidfill(pstate->pipe_hw,
>>>> +    if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
>>>> +        pstate->pipe.sspp->ops.setup_solidfill(pstate->pipe.sspp,
>>>>                   (color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
>>>> -                pstate->multirect_index);
>>>> +                pstate->pipe.multirect_index);
>>>>           /* override scaler/decimation if solid fill */
>>>>           pipe_cfg.dst_rect = pstate->base.dst;
>>>> @@ -714,15 +714,15 @@ static int _dpu_plane_color_fill(struct 
>>>> dpu_plane *pdpu,
>>>>           pipe_cfg.src_rect.y2 =
>>>>               drm_rect_height(&pipe_cfg.dst_rect);
>>>> -        if (pstate->pipe_hw->ops.setup_format)
>>>> -            pstate->pipe_hw->ops.setup_format(pstate->pipe_hw,
>>>> +        if (pstate->pipe.sspp->ops.setup_format)
>>>> +            pstate->pipe.sspp->ops.setup_format(pstate->pipe.sspp,
>>>>                       fmt, DPU_SSPP_SOLID_FILL,
>>>> -                    pstate->multirect_index);
>>>> +                    pstate->pipe.multirect_index);
>>>> -        if (pstate->pipe_hw->ops.setup_rects)
>>>> -            pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>>>> +        if (pstate->pipe.sspp->ops.setup_rects)
>>>> +            pstate->pipe.sspp->ops.setup_rects(pstate->pipe.sspp,
>>>>                       &pipe_cfg,
>>>> -                    pstate->multirect_index);
>>>> +                    pstate->pipe.multirect_index);
>>>>           _dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
>>>>       }
>>>> @@ -734,8 +734,8 @@ void dpu_plane_clear_multirect(const struct 
>>>> drm_plane_state *drm_state)
>>>>   {
>>>>       struct dpu_plane_state *pstate = to_dpu_plane_state(drm_state);
>>>> -    pstate->multirect_index = DPU_SSPP_RECT_SOLO;
>>>> -    pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
>>>> +    pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
>>>> +    pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
>>>>   }
>>>>   int dpu_plane_validate_multirect_v2(struct 
>>>> dpu_multirect_plane_states *plane)
>>>> @@ -817,8 +817,8 @@ int dpu_plane_validate_multirect_v2(struct 
>>>> dpu_multirect_plane_states *plane)
>>>>       /* Prefer PARALLEL FETCH Mode over TIME_MX Mode */
>>>>       if (parallel_fetch_qualified) {
>>>> -        pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>>>> -        pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>>>> +        pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>>>> +        pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>>>>           goto done;
>>>>       }
>>>> @@ -828,8 +828,8 @@ int dpu_plane_validate_multirect_v2(struct 
>>>> dpu_multirect_plane_states *plane)
>>>>       if (dst[R1].y1 >= dst[R0].y2 + buffer_lines ||
>>>>           dst[R0].y1 >= dst[R1].y2 + buffer_lines) {
>>>> -        pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>>> -        pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>>> +        pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>>> +        pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>>>       } else {
>>>>           DPU_ERROR(
>>>>               "No multirect mode possible for the planes (%d - %d)\n",
>>>> @@ -839,13 +839,13 @@ int dpu_plane_validate_multirect_v2(struct 
>>>> dpu_multirect_plane_states *plane)
>>>>       }
>>>>   done:
>>>> -    pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
>>>> -    pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
>>>> +    pstate[R0]->pipe.multirect_index = DPU_SSPP_RECT_0;
>>>> +    pstate[R1]->pipe.multirect_index = DPU_SSPP_RECT_1;
>>>>       DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
>>>> -        pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
>>>> +        pstate[R0]->pipe.multirect_mode, 
>>>> pstate[R0]->pipe.multirect_index);
>>>>       DPU_DEBUG_PLANE(dpu_plane[R1], "R1: %d - %d\n",
>>>> -        pstate[R1]->multirect_mode, pstate[R1]->multirect_index);
>>>> +        pstate[R1]->pipe.multirect_mode, 
>>>> pstate[R1]->pipe.multirect_index);
>>>>       return 0;
>>>>   }
>>>> @@ -937,6 +937,7 @@ static int dpu_plane_atomic_check(struct 
>>>> drm_plane *plane,
>>>>       int ret = 0, min_scale;
>>>>       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;
>>>>       const struct drm_crtc_state *crtc_state = NULL;
>>>>       const struct dpu_format *fmt;
>>>>       struct drm_rect src, dst, fb_rect = { 0 };
>>>> @@ -946,10 +947,10 @@ static int dpu_plane_atomic_check(struct 
>>>> drm_plane *plane,
>>>>           crtc_state = drm_atomic_get_new_crtc_state(state,
>>>>                                  new_plane_state->crtc);
>>>> -    min_scale = FRAC_16_16(1, pstate->pipe_hw->cap->sblk->maxupscale);
>>>> +    min_scale = FRAC_16_16(1, pipe->sspp->cap->sblk->maxupscale);
>>>>       ret = drm_atomic_helper_check_plane_state(new_plane_state, 
>>>> crtc_state,
>>>>                             min_scale,
>>>> -                          pstate->pipe_hw->cap->sblk->maxdwnscale 
>>>> << 16,
>>>> +                          pipe->sspp->cap->sblk->maxdwnscale << 16,
>>>>                             true, true);
>>>>       if (ret) {
>>>>           DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", 
>>>> ret);
>>>> @@ -975,8 +976,8 @@ static int dpu_plane_atomic_check(struct 
>>>> drm_plane *plane,
>>>>       min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>>>       if (DPU_FORMAT_IS_YUV(fmt) &&
>>>> -        (!(pstate->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
>>>> -         !(pstate->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
>>>> +        (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
>>>> +         !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
>>>>           DPU_DEBUG_PLANE(pdpu,
>>>>                   "plane doesn't have scaler/csc for yuv\n");
>>>>           return -EINVAL;
>>>> @@ -1037,12 +1038,12 @@ void dpu_plane_flush(struct drm_plane *plane)
>>>>       else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
>>>>           /* force 100% alpha */
>>>>           _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
>>>> -    else if (pstate->pipe_hw && pstate->pipe_hw->ops.setup_csc) {
>>>> +    else if (pstate->pipe.sspp && pstate->pipe.sspp->ops.setup_csc) {
>>>>           const struct dpu_format *fmt = 
>>>> to_dpu_format(msm_framebuffer_format(plane->state->fb));
>>>>           const struct dpu_csc_cfg *csc_ptr = 
>>>> _dpu_plane_get_csc(pdpu, fmt);
>>>>           if (csc_ptr)
>>>> -            pstate->pipe_hw->ops.setup_csc(pstate->pipe_hw, csc_ptr);
>>>> +            pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, 
>>>> csc_ptr);
>>>>       }
>>>>       /* flag h/w flush complete */
>>>> @@ -1072,6 +1073,7 @@ static void 
>>>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>>>       struct drm_plane_state *state = plane->state;
>>>>       struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>>> +    struct dpu_sw_pipe *pipe = &pstate->pipe;
>>>>       struct drm_crtc *crtc = state->crtc;
>>>>       struct drm_framebuffer *fb = state->fb;
>>>>       bool is_rt_pipe, update_qos_remap;
>>>> @@ -1109,21 +1111,21 @@ static void 
>>>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>>           return;
>>>>       }
>>>> -    if (pstate->pipe_hw->ops.setup_rects) {
>>>> -        pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>>>> +    if (pipe->sspp->ops.setup_rects) {
>>>> +        pipe->sspp->ops.setup_rects(pipe->sspp,
>>>>                   &pipe_cfg,
>>>> -                pstate->multirect_index);
>>>> +                pipe->multirect_index);
>>>>       }
>>>>       _dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
>>>> -    if (pstate->pipe_hw->ops.setup_multirect)
>>>> -        pstate->pipe_hw->ops.setup_multirect(
>>>> -                pstate->pipe_hw,
>>>> -                pstate->multirect_index,
>>>> -                pstate->multirect_mode);
>>>> +    if (pipe->sspp->ops.setup_multirect)
>>>> +        pipe->sspp->ops.setup_multirect(
>>>> +                pipe->sspp,
>>>> +                pipe->multirect_index,
>>>> +                pipe->multirect_mode);
>>>> -    if (pstate->pipe_hw->ops.setup_format) {
>>>> +    if (pipe->sspp->ops.setup_format) {
>>>>           unsigned int rotation;
>>>>           src_flags = 0x0;
>>>> @@ -1140,10 +1142,10 @@ static void 
>>>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>>               src_flags |= DPU_SSPP_FLIP_UD;
>>>>           /* update format */
>>>> -        pstate->pipe_hw->ops.setup_format(pstate->pipe_hw, fmt, 
>>>> src_flags,
>>>> -                pstate->multirect_index);
>>>> +        pipe->sspp->ops.setup_format(pipe->sspp, fmt, src_flags,
>>>> +                pipe->multirect_index);
>>>> -        if (pstate->pipe_hw->ops.setup_cdp) {
>>>> +        if (pipe->sspp->ops.setup_cdp) {
>>>>               struct dpu_hw_pipe_cdp_cfg cdp_cfg;
>>>>               memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
>>>> @@ -1157,7 +1159,7 @@ static void 
>>>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>>                       DPU_FORMAT_IS_TILE(fmt);
>>>>               cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
>>>> -            pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, 
>>>> &cdp_cfg, pstate->multirect_index);
>>>> +            pipe->sspp->ops.setup_cdp(pipe->sspp, &cdp_cfg, 
>>>> pipe->multirect_index);
>>>>           }
>>>>       }
>>>> @@ -1191,7 +1193,7 @@ static void _dpu_plane_atomic_disable(struct 
>>>> drm_plane *plane)
>>>>       struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>>>       trace_dpu_plane_disable(DRMID(plane), false,
>>>> -                pstate->multirect_mode);
>>>> +                pstate->pipe.multirect_mode);
>>>>       pstate->pending = true;
>>>>   }
>>>> @@ -1305,9 +1307,9 @@ static void 
>>>> dpu_plane_atomic_print_state(struct drm_printer *p,
>>>>       const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>>>       drm_printf(p, "\tstage=%d\n", pstate->stage);
>>>> -    drm_printf(p, "\tsspp=%s\n", pstate->pipe_hw->cap->name);
>>>> -    drm_printf(p, "\tmultirect_mode=%s\n", 
>>>> dpu_get_multirect_mode(pstate->multirect_mode));
>>>> -    drm_printf(p, "\tmultirect_index=%s\n", 
>>>> dpu_get_multirect_index(pstate->multirect_index));
>>>> +    drm_printf(p, "\tsspp=%s\n", pstate->pipe.sspp->cap->name);
>>>> +    drm_printf(p, "\tmultirect_mode=%s\n", 
>>>> dpu_get_multirect_mode(pstate->pipe.multirect_mode));
>>>> +    drm_printf(p, "\tmultirect_index=%s\n", 
>>>> dpu_get_multirect_index(pstate->pipe.multirect_index));
>>>>   }
>>>>   static void dpu_plane_reset(struct drm_plane *plane)
>>>> @@ -1336,7 +1338,7 @@ static void dpu_plane_reset(struct drm_plane 
>>>> *plane)
>>>>           return;
>>>>       }
>>>> -    pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - 
>>>> SSPP_NONE]);
>>>> +    pstate->pipe.sspp = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe 
>>>> - SSPP_NONE]);
>>>>       __drm_atomic_helper_plane_reset(plane, &pstate->base);
>>>>   }
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>> index d745cde4ea77..b6fd6f856d6a 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>> @@ -31,11 +31,9 @@ struct dpu_plane_state {
>>>>       struct msm_gem_address_space *aspace;
>>>>       enum dpu_stage stage;
>>>>       bool needs_qos_remap;
>>>> -    uint32_t multirect_index;
>>>> -    uint32_t multirect_mode;
>>>>       bool pending;
>>>> -    struct dpu_hw_pipe *pipe_hw;
>>>> +    struct dpu_sw_pipe pipe;
>>>
>>> Are you sure we dont need this to be a pointer?
>>>
>>> Since this is now part of plane_state, its possible that across 
>>> commits, the hw pipe can change for this plane's state. So might be 
>>> better if this is pointer in that case ....
>>
>> A pointer means that it is allocated and deallocated by somebody. 
>> Probably you meant that it is a pointer into the dpu_hw_pipe member 
>> (with dpu_hw_pipe having sw_pipe's for rect0 and rect1).
>>
>> I thought about this. And ended up with the dpu_sw_pipe having a 
>> dpu_hw_pipe pointer inside, but itself being a member of plane state. 
>> This way the plane state contains such data as multirect mode and 
>> rectangle.
> 
> Right, so what I meant was, previously pipe_hw was a pointer but it was 
> not changed dynamically because it was assigned once in dpu_plane_init() 
> but after that was not updated to point to a different pipe_hw.
> 
> Now, pipe_hw is part of the plane state which means the actual hardware 
> which the plane state is using can change across commits with virtual 
> plane support.
> 
> So it made more sense to me that this was "struct dpu_sw_pipe *pipe" 
> because looking at it from a top level it tells me that the dpu_sw_pipe 
> can point to a different pipe. Just little more intuitive.
> 
> With it being just a member, sure it still means the same thing because 
> internal to it, pipe_hw is still a pointer.
> 
> Just felt it was more logical to have the whole dpu_sw_pipe as a pointer.

If it would have been possible to allocate REC0 and REC1 to different 
LMs, then the dpu_sw_pipe would be definitely a pointer into the 
rm-managed resource. However as REC0 and REC1 are not going to be 
handled by the RM, making dpu_sw_pipe a pointer would just complicate 
the design. It will be a pointer to the dpu_hw_pipe's sub-struct. With 
this struct having a back-pointer to the dpu_hw_pipe. And some state 
which we should always clear when reassigning the pipes, etc. So it 
landed naturally as a part of pstate.

> 
> But its just a thought not a strong inclination against current patch.

R-b?

> 
>>
>>
>>>
>>>>       u64 plane_fetch_bw;
>>>>       u64 plane_clk;
>>
>>


-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe
  2022-05-06 22:29         ` Dmitry Baryshkov
@ 2022-05-06 22:46           ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-06 22:46 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: David Airlie, linux-arm-msm, dri-devel, Stephen Boyd,
	Daniel Vetter, freedreno



On 5/6/2022 3:29 PM, Dmitry Baryshkov wrote:
> On 07/05/2022 00:48, Abhinav Kumar wrote:
>>
>>
>> On 5/6/2022 2:39 PM, Dmitry Baryshkov wrote:
>>> On 07/05/2022 00:30, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
>>>>> Wrap SSPP and multirect index/mode into a single structure that
>>>>> represents software view on the pipe used.
>>>>>
>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>> ---
>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c    |   8 +-
>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  16 ++-
>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 136 
>>>>> ++++++++++----------
>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   |   4 +-
>>>>>   4 files changed, 86 insertions(+), 78 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> index ada7d5750536..751c64012058 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> @@ -441,14 +441,14 @@ static void _dpu_crtc_blend_setup_ctl(struct 
>>>>> drm_crtc *crtc)
>>>>>           pstate = to_dpu_plane_state(state);
>>>>> -        sspp_idx = pstate->pipe_hw->idx;
>>>>> +        sspp_idx = pstate->pipe.sspp->idx;
>>>>>           set_bit(sspp_idx, fetch_active);
>>>>>           stage_idx = zpos_cnt[pstate->stage]++;
>>>>>           stage_cfg.stage[pstate->stage][stage_idx] =
>>>>>                       sspp_idx;
>>>>>           stage_cfg.multirect_index[pstate->stage][stage_idx] =
>>>>> -                    pstate->multirect_index;
>>>>> +                    pstate->pipe.multirect_index;
>>>>>           /* blend config update */
>>>>>           for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++)
>>>>> @@ -1118,7 +1118,7 @@ static int dpu_crtc_atomic_check(struct 
>>>>> drm_crtc *crtc,
>>>>>           pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
>>>>>           pstates[cnt].drm_pstate = pstate;
>>>>>           pstates[cnt].stage = pstate->normalized_zpos;
>>>>> -        pstates[cnt].pipe_id = 
>>>>> to_dpu_plane_state(pstate)->pipe_hw->idx;
>>>>> +        pstates[cnt].pipe_id = 
>>>>> to_dpu_plane_state(pstate)->pipe.sspp->idx;
>>>>>           if (pipe_staged[pstates[cnt].pipe_id]) {
>>>>>               multirect_plane[multirect_count].r0 =
>>>>> @@ -1389,7 +1389,7 @@ static int _dpu_debugfs_status_show(struct 
>>>>> seq_file *s, void *data)
>>>>>               state->crtc_x, state->crtc_y, state->crtc_w,
>>>>>               state->crtc_h);
>>>>>           seq_printf(s, "\tmultirect: mode: %d index: %d\n",
>>>>> -            pstate->multirect_mode, pstate->multirect_index);
>>>>> +            pstate->pipe.multirect_mode, 
>>>>> pstate->pipe.multirect_index);
>>>>>           seq_puts(s, "\n");
>>>>>       }
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>>>>> index 674f311f99b4..0af2bc6e5df8 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>>>>> @@ -159,15 +159,11 @@ struct dpu_hw_pixel_ext {
>>>>>    * @src_rect:  src ROI, caller takes into account the different 
>>>>> operations
>>>>>    *             such as decimation, flip etc to program this field
>>>>>    * @dest_rect: destination ROI.
>>>>> - * @index:     index of the rectangle of SSPP
>>>>> - * @mode:      parallel or time multiplex multirect mode
>>>>>    */
>>>>>   struct dpu_hw_pipe_cfg {
>>>>>       struct dpu_hw_fmt_layout layout;
>>>>>       struct drm_rect src_rect;
>>>>>       struct drm_rect dst_rect;
>>>>> -    enum dpu_sspp_multirect_index index;
>>>>> -    enum dpu_sspp_multirect_mode mode;
>>>>>   };
>>>>>   /**
>>>>> @@ -218,6 +214,18 @@ struct dpu_hw_pipe_ts_cfg {
>>>>>       u64 time;
>>>>>   };
>>>>> +/**
>>>>> + * struct dpu_sw_pipe - software pipe description
>>>>> + * @sspp:      backing SSPP pipe
>>>>> + * @index:     index of the rectangle of SSPP
>>>>> + * @mode:      parallel or time multiplex multirect mode
>>>>> + */
>>>>> +struct dpu_sw_pipe {
>>>>> +    struct dpu_hw_pipe *sspp;
>>>>> +    enum dpu_sspp_multirect_index multirect_index;
>>>>> +    enum dpu_sspp_multirect_mode multirect_mode;
>>>>> +};
>>>>> +
>>>>>   /**
>>>>>    * struct dpu_hw_sspp_ops - interface to the SSPP Hw driver 
>>>>> functions
>>>>>    * Caller must call the init function to get the pipe context for 
>>>>> each pipe
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> index d1f9b4bc10ac..51b5e8a3182b 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> @@ -247,7 +247,7 @@ static int _dpu_plane_calc_fill_level(struct 
>>>>> drm_plane *plane,
>>>>>                   ((src_width + 32) * fmt->bpp);
>>>>>           }
>>>>>       } else {
>>>>> -        if (pstate->multirect_mode == DPU_SSPP_MULTIRECT_PARALLEL) {
>>>>> +        if (pstate->pipe.multirect_mode == 
>>>>> DPU_SSPP_MULTIRECT_PARALLEL) {
>>>>>               total_fl = (fixed_buff_size / 2) * 2 /
>>>>>                   ((src_width + 32) * fmt->bpp);
>>>>>           } else {
>>>>> @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct 
>>>>> drm_plane *plane,
>>>>>               fmt ? (char *)&fmt->base.pixel_format : NULL,
>>>>>               pdpu->is_rt_pipe, total_fl, qos_lut);
>>>>> -    pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
>>>>> +    pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, 
>>>>> qos_lut);
>>>>>   }
>>>>>   /**
>>>>> @@ -383,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct 
>>>>> drm_plane *plane,
>>>>>           danger_lut,
>>>>>           safe_lut);
>>>>> -    pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
>>>>> +    pstate->pipe.sspp->ops.setup_danger_safe_lut(pstate->pipe.sspp,
>>>>>               danger_lut, safe_lut);
>>>>>   }
>>>>> @@ -403,9 +403,9 @@ static void _dpu_plane_set_qos_ctrl(struct 
>>>>> drm_plane *plane,
>>>>>       memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>>>>       if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>>>>> -        pipe_qos_cfg.creq_vblank = 
>>>>> pstate->pipe_hw->cap->sblk->creq_vblank;
>>>>> +        pipe_qos_cfg.creq_vblank = 
>>>>> pstate->pipe.sspp->cap->sblk->creq_vblank;
>>>>>           pipe_qos_cfg.danger_vblank =
>>>>> -                pstate->pipe_hw->cap->sblk->danger_vblank;
>>>>> +                pstate->pipe.sspp->cap->sblk->danger_vblank;
>>>>>           pipe_qos_cfg.vblank_en = enable;
>>>>>       }
>>>>> @@ -431,7 +431,7 @@ static void _dpu_plane_set_qos_ctrl(struct 
>>>>> drm_plane *plane,
>>>>>           pipe_qos_cfg.danger_vblank,
>>>>>           pdpu->is_rt_pipe);
>>>>> -    pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
>>>>> +    pstate->pipe.sspp->ops.setup_qos_ctrl(pstate->pipe.sspp,
>>>>>               &pipe_qos_cfg);
>>>>>   }
>>>>> @@ -450,14 +450,14 @@ static void _dpu_plane_set_ot_limit(struct 
>>>>> drm_plane *plane,
>>>>>       struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>>>>>       memset(&ot_params, 0, sizeof(ot_params));
>>>>> -    ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
>>>>> -    ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
>>>>> +    ot_params.xin_id = pstate->pipe.sspp->cap->xin_id;
>>>>> +    ot_params.num = pstate->pipe.sspp->idx - SSPP_NONE;
>>>>>       ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
>>>>>       ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
>>>>>       ot_params.is_wfd = !pdpu->is_rt_pipe;
>>>>>       ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
>>>>>       ot_params.vbif_idx = VBIF_RT;
>>>>> -    ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>>>>> +    ot_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
>>>>>       ot_params.rd = true;
>>>>>       dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
>>>>> @@ -476,9 +476,9 @@ static void _dpu_plane_set_qos_remap(struct 
>>>>> drm_plane *plane)
>>>>>       memset(&qos_params, 0, sizeof(qos_params));
>>>>>       qos_params.vbif_idx = VBIF_RT;
>>>>> -    qos_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>>>>> -    qos_params.xin_id = pstate->pipe_hw->cap->xin_id;
>>>>> -    qos_params.num = pstate->pipe_hw->idx - SSPP_VIG0;
>>>>> +    qos_params.clk_ctrl = pstate->pipe.sspp->cap->clk_ctrl;
>>>>> +    qos_params.xin_id = pstate->pipe.sspp->cap->xin_id;
>>>>> +    qos_params.num = pstate->pipe.sspp->idx - SSPP_VIG0;
>>>>>       qos_params.is_rt = pdpu->is_rt_pipe;
>>>>>       DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, 
>>>>> clk_ctrl:%d\n",
>>>>> @@ -505,12 +505,12 @@ static void _dpu_plane_set_scanout(struct 
>>>>> drm_plane *plane,
>>>>>           DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
>>>>>       else if (ret)
>>>>>           DPU_ERROR_PLANE(pdpu, "failed to get format layout, 
>>>>> %d\n", ret);
>>>>> -    else if (pstate->pipe_hw->ops.setup_sourceaddress) {
>>>>> -        trace_dpu_plane_set_scanout(pstate->pipe_hw->idx,
>>>>> +    else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
>>>>> +        trace_dpu_plane_set_scanout(pstate->pipe.sspp->idx,
>>>>>                           &pipe_cfg->layout,
>>>>> -                        pstate->multirect_index);
>>>>> -        pstate->pipe_hw->ops.setup_sourceaddress(pstate->pipe_hw, 
>>>>> pipe_cfg,
>>>>> -                        pstate->multirect_index);
>>>>> +                        pstate->pipe.multirect_index);
>>>>> + pstate->pipe.sspp->ops.setup_sourceaddress(pstate->pipe.sspp, 
>>>>> pipe_cfg,
>>>>> +                        pstate->pipe.multirect_index);
>>>>>       }
>>>>>   }
>>>>> @@ -553,7 +553,7 @@ static void _dpu_plane_setup_scaler3(struct 
>>>>> dpu_plane *pdpu,
>>>>>               scale_cfg->src_height[i] /= chroma_subsmpl_v;
>>>>>           }
>>>>> -        if (pstate->pipe_hw->cap->features &
>>>>> +        if (pstate->pipe.sspp->cap->features &
>>>>>               BIT(DPU_SSPP_SCALER_QSEED4)) {
>>>>>               scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
>>>>>               scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
>>>>> @@ -624,7 +624,7 @@ static const struct dpu_csc_cfg 
>>>>> *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
>>>>>       if (!DPU_FORMAT_IS_YUV(fmt))
>>>>>           return NULL;
>>>>> -    if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe_hw->cap->features)
>>>>> +    if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe.sspp->cap->features)
>>>>>           csc_ptr = &dpu_csc10_YUV2RGB_601L;
>>>>>       else
>>>>>           csc_ptr = &dpu_csc_YUV2RGB_601L;
>>>>> @@ -659,8 +659,8 @@ static void _dpu_plane_setup_scaler(struct 
>>>>> dpu_plane *pdpu,
>>>>>               &scaler3_cfg, &pixel_ext, fmt,
>>>>>               info->hsub, info->vsub);
>>>>> -    if (pstate->pipe_hw->ops.setup_pe)
>>>>> -        pstate->pipe_hw->ops.setup_pe(pstate->pipe_hw,
>>>>> +    if (pstate->pipe.sspp->ops.setup_pe)
>>>>> +        pstate->pipe.sspp->ops.setup_pe(pstate->pipe.sspp,
>>>>>                   &pixel_ext);
>>>>>       /**
>>>>> @@ -668,9 +668,9 @@ static void _dpu_plane_setup_scaler(struct 
>>>>> dpu_plane *pdpu,
>>>>>        * bypassed. Still we need to update alpha and bitwidth
>>>>>        * ONLY for RECT0
>>>>>        */
>>>>> -    if (pstate->pipe_hw->ops.setup_scaler &&
>>>>> -            pstate->multirect_index != DPU_SSPP_RECT_1)
>>>>> -        pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
>>>>> +    if (pstate->pipe.sspp->ops.setup_scaler &&
>>>>> +            pstate->pipe.multirect_index != DPU_SSPP_RECT_1)
>>>>> +        pstate->pipe.sspp->ops.setup_scaler(pstate->pipe.sspp,
>>>>>                   pipe_cfg,
>>>>>                   &scaler3_cfg);
>>>>>   }
>>>>> @@ -699,10 +699,10 @@ static int _dpu_plane_color_fill(struct 
>>>>> dpu_plane *pdpu,
>>>>>       fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>>>>>       /* update sspp */
>>>>> -    if (fmt && pstate->pipe_hw->ops.setup_solidfill) {
>>>>> -        pstate->pipe_hw->ops.setup_solidfill(pstate->pipe_hw,
>>>>> +    if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
>>>>> +        pstate->pipe.sspp->ops.setup_solidfill(pstate->pipe.sspp,
>>>>>                   (color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
>>>>> -                pstate->multirect_index);
>>>>> +                pstate->pipe.multirect_index);
>>>>>           /* override scaler/decimation if solid fill */
>>>>>           pipe_cfg.dst_rect = pstate->base.dst;
>>>>> @@ -714,15 +714,15 @@ static int _dpu_plane_color_fill(struct 
>>>>> dpu_plane *pdpu,
>>>>>           pipe_cfg.src_rect.y2 =
>>>>>               drm_rect_height(&pipe_cfg.dst_rect);
>>>>> -        if (pstate->pipe_hw->ops.setup_format)
>>>>> -            pstate->pipe_hw->ops.setup_format(pstate->pipe_hw,
>>>>> +        if (pstate->pipe.sspp->ops.setup_format)
>>>>> +            pstate->pipe.sspp->ops.setup_format(pstate->pipe.sspp,
>>>>>                       fmt, DPU_SSPP_SOLID_FILL,
>>>>> -                    pstate->multirect_index);
>>>>> +                    pstate->pipe.multirect_index);
>>>>> -        if (pstate->pipe_hw->ops.setup_rects)
>>>>> -            pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>>>>> +        if (pstate->pipe.sspp->ops.setup_rects)
>>>>> +            pstate->pipe.sspp->ops.setup_rects(pstate->pipe.sspp,
>>>>>                       &pipe_cfg,
>>>>> -                    pstate->multirect_index);
>>>>> +                    pstate->pipe.multirect_index);
>>>>>           _dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
>>>>>       }
>>>>> @@ -734,8 +734,8 @@ void dpu_plane_clear_multirect(const struct 
>>>>> drm_plane_state *drm_state)
>>>>>   {
>>>>>       struct dpu_plane_state *pstate = to_dpu_plane_state(drm_state);
>>>>> -    pstate->multirect_index = DPU_SSPP_RECT_SOLO;
>>>>> -    pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
>>>>> +    pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
>>>>> +    pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
>>>>>   }
>>>>>   int dpu_plane_validate_multirect_v2(struct 
>>>>> dpu_multirect_plane_states *plane)
>>>>> @@ -817,8 +817,8 @@ int dpu_plane_validate_multirect_v2(struct 
>>>>> dpu_multirect_plane_states *plane)
>>>>>       /* Prefer PARALLEL FETCH Mode over TIME_MX Mode */
>>>>>       if (parallel_fetch_qualified) {
>>>>> -        pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>>>>> -        pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
>>>>> +        pstate[R0]->pipe.multirect_mode = 
>>>>> DPU_SSPP_MULTIRECT_PARALLEL;
>>>>> +        pstate[R1]->pipe.multirect_mode = 
>>>>> DPU_SSPP_MULTIRECT_PARALLEL;
>>>>>           goto done;
>>>>>       }
>>>>> @@ -828,8 +828,8 @@ int dpu_plane_validate_multirect_v2(struct 
>>>>> dpu_multirect_plane_states *plane)
>>>>>       if (dst[R1].y1 >= dst[R0].y2 + buffer_lines ||
>>>>>           dst[R0].y1 >= dst[R1].y2 + buffer_lines) {
>>>>> -        pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>>>> -        pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>>>> +        pstate[R0]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>>>> +        pstate[R1]->pipe.multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>>>>>       } else {
>>>>>           DPU_ERROR(
>>>>>               "No multirect mode possible for the planes (%d - %d)\n",
>>>>> @@ -839,13 +839,13 @@ int dpu_plane_validate_multirect_v2(struct 
>>>>> dpu_multirect_plane_states *plane)
>>>>>       }
>>>>>   done:
>>>>> -    pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
>>>>> -    pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
>>>>> +    pstate[R0]->pipe.multirect_index = DPU_SSPP_RECT_0;
>>>>> +    pstate[R1]->pipe.multirect_index = DPU_SSPP_RECT_1;
>>>>>       DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
>>>>> -        pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
>>>>> +        pstate[R0]->pipe.multirect_mode, 
>>>>> pstate[R0]->pipe.multirect_index);
>>>>>       DPU_DEBUG_PLANE(dpu_plane[R1], "R1: %d - %d\n",
>>>>> -        pstate[R1]->multirect_mode, pstate[R1]->multirect_index);
>>>>> +        pstate[R1]->pipe.multirect_mode, 
>>>>> pstate[R1]->pipe.multirect_index);
>>>>>       return 0;
>>>>>   }
>>>>> @@ -937,6 +937,7 @@ static int dpu_plane_atomic_check(struct 
>>>>> drm_plane *plane,
>>>>>       int ret = 0, min_scale;
>>>>>       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;
>>>>>       const struct drm_crtc_state *crtc_state = NULL;
>>>>>       const struct dpu_format *fmt;
>>>>>       struct drm_rect src, dst, fb_rect = { 0 };
>>>>> @@ -946,10 +947,10 @@ static int dpu_plane_atomic_check(struct 
>>>>> drm_plane *plane,
>>>>>           crtc_state = drm_atomic_get_new_crtc_state(state,
>>>>>                                  new_plane_state->crtc);
>>>>> -    min_scale = FRAC_16_16(1, 
>>>>> pstate->pipe_hw->cap->sblk->maxupscale);
>>>>> +    min_scale = FRAC_16_16(1, pipe->sspp->cap->sblk->maxupscale);
>>>>>       ret = drm_atomic_helper_check_plane_state(new_plane_state, 
>>>>> crtc_state,
>>>>>                             min_scale,
>>>>> -                          pstate->pipe_hw->cap->sblk->maxdwnscale 
>>>>> << 16,
>>>>> +                          pipe->sspp->cap->sblk->maxdwnscale << 16,
>>>>>                             true, true);
>>>>>       if (ret) {
>>>>>           DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", 
>>>>> ret);
>>>>> @@ -975,8 +976,8 @@ static int dpu_plane_atomic_check(struct 
>>>>> drm_plane *plane,
>>>>>       min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>>>>       if (DPU_FORMAT_IS_YUV(fmt) &&
>>>>> -        (!(pstate->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
>>>>> -         !(pstate->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
>>>>> +        (!(pipe->sspp->cap->features & DPU_SSPP_SCALER) ||
>>>>> +         !(pipe->sspp->cap->features & DPU_SSPP_CSC_ANY))) {
>>>>>           DPU_DEBUG_PLANE(pdpu,
>>>>>                   "plane doesn't have scaler/csc for yuv\n");
>>>>>           return -EINVAL;
>>>>> @@ -1037,12 +1038,12 @@ void dpu_plane_flush(struct drm_plane *plane)
>>>>>       else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
>>>>>           /* force 100% alpha */
>>>>>           _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
>>>>> -    else if (pstate->pipe_hw && pstate->pipe_hw->ops.setup_csc) {
>>>>> +    else if (pstate->pipe.sspp && pstate->pipe.sspp->ops.setup_csc) {
>>>>>           const struct dpu_format *fmt = 
>>>>> to_dpu_format(msm_framebuffer_format(plane->state->fb));
>>>>>           const struct dpu_csc_cfg *csc_ptr = 
>>>>> _dpu_plane_get_csc(pdpu, fmt);
>>>>>           if (csc_ptr)
>>>>> -            pstate->pipe_hw->ops.setup_csc(pstate->pipe_hw, csc_ptr);
>>>>> +            pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, 
>>>>> csc_ptr);
>>>>>       }
>>>>>       /* flag h/w flush complete */
>>>>> @@ -1072,6 +1073,7 @@ static void 
>>>>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>>>>       struct drm_plane_state *state = plane->state;
>>>>>       struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>>>> +    struct dpu_sw_pipe *pipe = &pstate->pipe;
>>>>>       struct drm_crtc *crtc = state->crtc;
>>>>>       struct drm_framebuffer *fb = state->fb;
>>>>>       bool is_rt_pipe, update_qos_remap;
>>>>> @@ -1109,21 +1111,21 @@ static void 
>>>>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>>>           return;
>>>>>       }
>>>>> -    if (pstate->pipe_hw->ops.setup_rects) {
>>>>> -        pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>>>>> +    if (pipe->sspp->ops.setup_rects) {
>>>>> +        pipe->sspp->ops.setup_rects(pipe->sspp,
>>>>>                   &pipe_cfg,
>>>>> -                pstate->multirect_index);
>>>>> +                pipe->multirect_index);
>>>>>       }
>>>>>       _dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
>>>>> -    if (pstate->pipe_hw->ops.setup_multirect)
>>>>> -        pstate->pipe_hw->ops.setup_multirect(
>>>>> -                pstate->pipe_hw,
>>>>> -                pstate->multirect_index,
>>>>> -                pstate->multirect_mode);
>>>>> +    if (pipe->sspp->ops.setup_multirect)
>>>>> +        pipe->sspp->ops.setup_multirect(
>>>>> +                pipe->sspp,
>>>>> +                pipe->multirect_index,
>>>>> +                pipe->multirect_mode);
>>>>> -    if (pstate->pipe_hw->ops.setup_format) {
>>>>> +    if (pipe->sspp->ops.setup_format) {
>>>>>           unsigned int rotation;
>>>>>           src_flags = 0x0;
>>>>> @@ -1140,10 +1142,10 @@ static void 
>>>>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>>>               src_flags |= DPU_SSPP_FLIP_UD;
>>>>>           /* update format */
>>>>> -        pstate->pipe_hw->ops.setup_format(pstate->pipe_hw, fmt, 
>>>>> src_flags,
>>>>> -                pstate->multirect_index);
>>>>> +        pipe->sspp->ops.setup_format(pipe->sspp, fmt, src_flags,
>>>>> +                pipe->multirect_index);
>>>>> -        if (pstate->pipe_hw->ops.setup_cdp) {
>>>>> +        if (pipe->sspp->ops.setup_cdp) {
>>>>>               struct dpu_hw_pipe_cdp_cfg cdp_cfg;
>>>>>               memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
>>>>> @@ -1157,7 +1159,7 @@ static void 
>>>>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>>>                       DPU_FORMAT_IS_TILE(fmt);
>>>>>               cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
>>>>> -            pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, 
>>>>> &cdp_cfg, pstate->multirect_index);
>>>>> +            pipe->sspp->ops.setup_cdp(pipe->sspp, &cdp_cfg, 
>>>>> pipe->multirect_index);
>>>>>           }
>>>>>       }
>>>>> @@ -1191,7 +1193,7 @@ static void _dpu_plane_atomic_disable(struct 
>>>>> drm_plane *plane)
>>>>>       struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>>>>       trace_dpu_plane_disable(DRMID(plane), false,
>>>>> -                pstate->multirect_mode);
>>>>> +                pstate->pipe.multirect_mode);
>>>>>       pstate->pending = true;
>>>>>   }
>>>>> @@ -1305,9 +1307,9 @@ static void 
>>>>> dpu_plane_atomic_print_state(struct drm_printer *p,
>>>>>       const struct dpu_plane_state *pstate = 
>>>>> to_dpu_plane_state(state);
>>>>>       drm_printf(p, "\tstage=%d\n", pstate->stage);
>>>>> -    drm_printf(p, "\tsspp=%s\n", pstate->pipe_hw->cap->name);
>>>>> -    drm_printf(p, "\tmultirect_mode=%s\n", 
>>>>> dpu_get_multirect_mode(pstate->multirect_mode));
>>>>> -    drm_printf(p, "\tmultirect_index=%s\n", 
>>>>> dpu_get_multirect_index(pstate->multirect_index));
>>>>> +    drm_printf(p, "\tsspp=%s\n", pstate->pipe.sspp->cap->name);
>>>>> +    drm_printf(p, "\tmultirect_mode=%s\n", 
>>>>> dpu_get_multirect_mode(pstate->pipe.multirect_mode));
>>>>> +    drm_printf(p, "\tmultirect_index=%s\n", 
>>>>> dpu_get_multirect_index(pstate->pipe.multirect_index));
>>>>>   }
>>>>>   static void dpu_plane_reset(struct drm_plane *plane)
>>>>> @@ -1336,7 +1338,7 @@ static void dpu_plane_reset(struct drm_plane 
>>>>> *plane)
>>>>>           return;
>>>>>       }
>>>>> -    pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe 
>>>>> - SSPP_NONE]);
>>>>> +    pstate->pipe.sspp = 
>>>>> to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
>>>>>       __drm_atomic_helper_plane_reset(plane, &pstate->base);
>>>>>   }
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>>> index d745cde4ea77..b6fd6f856d6a 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>>> @@ -31,11 +31,9 @@ struct dpu_plane_state {
>>>>>       struct msm_gem_address_space *aspace;
>>>>>       enum dpu_stage stage;
>>>>>       bool needs_qos_remap;
>>>>> -    uint32_t multirect_index;
>>>>> -    uint32_t multirect_mode;
>>>>>       bool pending;
>>>>> -    struct dpu_hw_pipe *pipe_hw;
>>>>> +    struct dpu_sw_pipe pipe;
>>>>
>>>> Are you sure we dont need this to be a pointer?
>>>>
>>>> Since this is now part of plane_state, its possible that across 
>>>> commits, the hw pipe can change for this plane's state. So might be 
>>>> better if this is pointer in that case ....
>>>
>>> A pointer means that it is allocated and deallocated by somebody. 
>>> Probably you meant that it is a pointer into the dpu_hw_pipe member 
>>> (with dpu_hw_pipe having sw_pipe's for rect0 and rect1).
>>>
>>> I thought about this. And ended up with the dpu_sw_pipe having a 
>>> dpu_hw_pipe pointer inside, but itself being a member of plane state. 
>>> This way the plane state contains such data as multirect mode and 
>>> rectangle.
>>
>> Right, so what I meant was, previously pipe_hw was a pointer but it 
>> was not changed dynamically because it was assigned once in 
>> dpu_plane_init() but after that was not updated to point to a 
>> different pipe_hw.
>>
>> Now, pipe_hw is part of the plane state which means the actual 
>> hardware which the plane state is using can change across commits with 
>> virtual plane support.
>>
>> So it made more sense to me that this was "struct dpu_sw_pipe *pipe" 
>> because looking at it from a top level it tells me that the 
>> dpu_sw_pipe can point to a different pipe. Just little more intuitive.
>>
>> With it being just a member, sure it still means the same thing 
>> because internal to it, pipe_hw is still a pointer.
>>
>> Just felt it was more logical to have the whole dpu_sw_pipe as a pointer.
> 
> If it would have been possible to allocate REC0 and REC1 to different 
> LMs, then the dpu_sw_pipe would be definitely a pointer into the 
> rm-managed resource. However as REC0 and REC1 are not going to be 
> handled by the RM, making dpu_sw_pipe a pointer would just complicate 
> the design. It will be a pointer to the dpu_hw_pipe's sub-struct. With 
> this struct having a back-pointer to the dpu_hw_pipe. And some state 
> which we should always clear when reassigning the pipes, etc. So it 
> landed naturally as a part of pstate.
> 

Alright, understood. Lets see if this has to evolve further, but at the 
moment this is fine with me.

>>
>> But its just a thought not a strong inclination against current patch.
> 
> R-b?
Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> 
>>
>>>
>>>
>>>>
>>>>>       u64 plane_fetch_bw;
>>>>>       u64 plane_clk;
>>>
>>>
> 
> 

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

* Re: [PATCH 12/25] drm/msm/dpu: inline _dpu_plane_set_scanout
  2022-02-09 17:25 ` [PATCH 12/25] drm/msm/dpu: inline _dpu_plane_set_scanout Dmitry Baryshkov
@ 2022-05-06 23:33   ` Abhinav Kumar
  2022-05-06 23:34     ` Dmitry Baryshkov
  0 siblings, 1 reply; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-06 23:33 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> In preparation to reworking dpu_plane_sspp_atomic_update() inline the
> _dpu_plane_set_scanout() function.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 41 ++++++++++-------------
>   1 file changed, 18 insertions(+), 23 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index d029ce806039..3ce7dcc285e2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -490,28 +490,6 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
>   	dpu_vbif_set_qos_remap(dpu_kms, &qos_params);
>   }
>   
> -static void _dpu_plane_set_scanout(struct drm_plane *plane,
> -		struct dpu_plane_state *pstate,
> -		struct dpu_hw_pipe_cfg *pipe_cfg,
> -		struct drm_framebuffer *fb)
> -{
> -	struct dpu_plane *pdpu = to_dpu_plane(plane);
> -	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> -	struct msm_gem_address_space *aspace = kms->base.aspace;
> -	int ret;
> -
> -	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout);
> -	if (ret == -EAGAIN)
> -		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
> -	else if (ret)
> -		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> -	else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
> -		trace_dpu_plane_set_scanout(&pstate->pipe,
> -					    &pipe_cfg->layout);
> -		pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, pipe_cfg);
> -	}
> -}
> -
>   static void _dpu_plane_setup_scaler3(struct dpu_hw_pipe *pipe_hw,
>   		uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h,
>   		struct dpu_hw_scaler3_cfg *scale_cfg,
> @@ -1074,10 +1052,27 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	const struct dpu_format *fmt =
>   		to_dpu_format(msm_framebuffer_format(fb));
>   	struct dpu_hw_pipe_cfg pipe_cfg;
> +	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> +	struct msm_gem_address_space *aspace = kms->base.aspace;
> +	bool update_src_addr = true;
> +	int ret;
>   
>   	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
>   
> -	_dpu_plane_set_scanout(plane, pstate, &pipe_cfg, fb);
> +	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg.layout);
> +	if (ret == -EAGAIN) {
> +		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
> +		update_src_addr = false;
> +	} else if (ret) {
> +		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> +		update_src_addr = false;
> +	}
> +
Do we need update_src_addr?

It seems we can just do

if (!ret &&  pipe->sspp->ops.setup_sourceaddress) {
	.....
	.....
}

> +	if (update_src_addr &&
> +	    pipe->sspp->ops.setup_sourceaddress) {
> +		trace_dpu_plane_set_scanout(pipe, &pipe_cfg.layout);
> +		pipe->sspp->ops.setup_sourceaddress(pipe, &pipe_cfg);
> +	}
>   
>   	pstate->pending = true;
>   

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

* Re: [PATCH 12/25] drm/msm/dpu: inline _dpu_plane_set_scanout
  2022-05-06 23:33   ` Abhinav Kumar
@ 2022-05-06 23:34     ` Dmitry Baryshkov
  0 siblings, 0 replies; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-05-06 23:34 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

On 07/05/2022 02:33, Abhinav Kumar wrote:
> 
> 
> On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
>> In preparation to reworking dpu_plane_sspp_atomic_update() inline the
>> _dpu_plane_set_scanout() function.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 41 ++++++++++-------------
>>   1 file changed, 18 insertions(+), 23 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index d029ce806039..3ce7dcc285e2 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -490,28 +490,6 @@ static void _dpu_plane_set_qos_remap(struct 
>> drm_plane *plane)
>>       dpu_vbif_set_qos_remap(dpu_kms, &qos_params);
>>   }
>> -static void _dpu_plane_set_scanout(struct drm_plane *plane,
>> -        struct dpu_plane_state *pstate,
>> -        struct dpu_hw_pipe_cfg *pipe_cfg,
>> -        struct drm_framebuffer *fb)
>> -{
>> -    struct dpu_plane *pdpu = to_dpu_plane(plane);
>> -    struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>> -    struct msm_gem_address_space *aspace = kms->base.aspace;
>> -    int ret;
>> -
>> -    ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout);
>> -    if (ret == -EAGAIN)
>> -        DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
>> -    else if (ret)
>> -        DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
>> -    else if (pstate->pipe.sspp->ops.setup_sourceaddress) {
>> -        trace_dpu_plane_set_scanout(&pstate->pipe,
>> -                        &pipe_cfg->layout);
>> -        pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, 
>> pipe_cfg);
>> -    }
>> -}
>> -
>>   static void _dpu_plane_setup_scaler3(struct dpu_hw_pipe *pipe_hw,
>>           uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h,
>>           struct dpu_hw_scaler3_cfg *scale_cfg,
>> @@ -1074,10 +1052,27 @@ static void 
>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>       const struct dpu_format *fmt =
>>           to_dpu_format(msm_framebuffer_format(fb));
>>       struct dpu_hw_pipe_cfg pipe_cfg;
>> +    struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>> +    struct msm_gem_address_space *aspace = kms->base.aspace;
>> +    bool update_src_addr = true;
>> +    int ret;
>>       memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
>> -    _dpu_plane_set_scanout(plane, pstate, &pipe_cfg, fb);
>> +    ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg.layout);
>> +    if (ret == -EAGAIN) {
>> +        DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
>> +        update_src_addr = false;
>> +    } else if (ret) {
>> +        DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
>> +        update_src_addr = false;
>> +    }
>> +
> Do we need update_src_addr?
> 
> It seems we can just do
> 
> if (!ret &&  pipe->sspp->ops.setup_sourceaddress) {
>      .....
>      .....
> }

Ack, let's do it this way

> 
>> +    if (update_src_addr &&
>> +        pipe->sspp->ops.setup_sourceaddress) {
>> +        trace_dpu_plane_set_scanout(pipe, &pipe_cfg.layout);
>> +        pipe->sspp->ops.setup_sourceaddress(pipe, &pipe_cfg);
>> +    }
>>       pstate->pending = true;


-- 
With best wishes
Dmitry

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

* Re: [PATCH 13/25] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
  2022-02-09 17:25 ` [PATCH 13/25] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3() Dmitry Baryshkov
@ 2022-05-09 22:30   ` Abhinav Kumar
  2022-05-14  6:46     ` Dmitry Baryshkov
  0 siblings, 1 reply; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-09 22:30 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> There is no need to pass full dpu_hw_pipe_cfg instance to
> _dpu_hw_sspp_setup_scaler3, pass just struct dpu_format pointer.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 9 ++++-----
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 7 +++----
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 4 ++--
>   3 files changed, 9 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> index d8120168f974..7194c14f87bc 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -415,19 +415,18 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
>   }
>   
>   static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
> -		struct dpu_hw_pipe_cfg *sspp,
> -		void *scaler_cfg)

This change does two things:

1) pass fmt and stop passing dpu_hw_pipe_cfg
2) change the scaler_cfg from void to struct dpu_hw_scaler3_cfg

So it seems like we had this void casting to allow different versions of 
the scaler to be passed and based on catalog bits the appropriate 
structs can be used (scaler2/scaler3)

In the current DPU we have only scaler3. For that reason this is fine.

I do not know what versions of scaler we will support in DPU.

Do you think we can retain the void casting in this change and just 
change passing the format?



> +		struct dpu_hw_scaler3_cfg *scaler3_cfg,
> +		const struct dpu_format *format)
>   {
>   	u32 idx;
> -	struct dpu_hw_scaler3_cfg *scaler3_cfg = scaler_cfg;
>   
> -	if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) || !sspp
> +	if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx)
>   		|| !scaler3_cfg)
>   		return;
>   
>   	dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg, idx,
>   			ctx->cap->sblk->scaler_blk.version,
> -			sspp->layout.format);
> +			format);
>   }
>   
>   static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> index 74171fb4e585..eee8501ea80d 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -334,13 +334,12 @@ struct dpu_hw_sspp_ops {
>   
>   	/**
>   	 * setup_scaler - setup scaler
> -	 * @ctx: Pointer to pipe context
> -	 * @pipe_cfg: Pointer to pipe configuration
>   	 * @scaler_cfg: Pointer to scaler configuration
> +	 * @format: pixel format parameters
>   	 */
>   	void (*setup_scaler)(struct dpu_hw_pipe *ctx,
> -		struct dpu_hw_pipe_cfg *pipe_cfg,
> -		void *scaler_cfg);
> +		struct dpu_hw_scaler3_cfg *scaler3_cfg,
> +		const struct dpu_format *format);
>   
>   	/**
>   	 * get_scaler_ver - get scaler h/w version
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 3ce7dcc285e2..e9421fa2fb2e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -646,8 +646,8 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe,
>   	if (pipe_hw->ops.setup_scaler &&
>   			pipe->multirect_index != DPU_SSPP_RECT_1)
>   		pipe_hw->ops.setup_scaler(pipe_hw,
> -				pipe_cfg,
> -				&scaler3_cfg);
> +				&scaler3_cfg,
> +				fmt);
>   }
>   
>   /**

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

* Re: [PATCH 14/25] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress
  2022-02-09 17:25 ` [PATCH 14/25] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress Dmitry Baryshkov
@ 2022-05-13 18:50   ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-13 18:50 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> Move stride programming to dpu_hw_sspp_setup_sourceaddress(), so that
> dpu_hw_sspp_setup_rects() programs only source and destination
> rectangles.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

This separation is logically correct, but there is another codepath 
using this.

_dpu_plane_color_fill() calls pdpu->pipe_hw->ops.setup_rects.

So for solid fill, I presume that stride getting programmed is 0 as
there is no buffer to fetch from.

But with this separation, we will miss re-programming stride and it will 
remain at the old value even for solid fil cases?

You might want to add setup_sourceaddress call there? But that wont make 
sense either because for solid fill there is nothing to fetch from.

Perhaps, another op for stride programming then?


> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 57 +++++++++++----------
>   1 file changed, 29 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> index 7194c14f87bc..2186506e6315 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -447,7 +447,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
>   {
>   	struct dpu_hw_pipe *ctx = pipe->sspp;
>   	struct dpu_hw_blk_reg_map *c;
> -	u32 src_size, src_xy, dst_size, dst_xy, ystride0, ystride1;
> +	u32 src_size, src_xy, dst_size, dst_xy;
>   	u32 src_size_off, src_xy_off, out_size_off, out_xy_off;
>   	u32 idx;
>   
> @@ -478,44 +478,18 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
>   	dst_size = (drm_rect_height(&cfg->dst_rect) << 16) |
>   		drm_rect_width(&cfg->dst_rect);
>   
> -	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
> -		ystride0 = (cfg->layout.plane_pitch[0]) |
> -			(cfg->layout.plane_pitch[1] << 16);
> -		ystride1 = (cfg->layout.plane_pitch[2]) |
> -			(cfg->layout.plane_pitch[3] << 16);
> -	} else {
> -		ystride0 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE0 + idx);
> -		ystride1 = DPU_REG_READ(c, SSPP_SRC_YSTRIDE1 + idx);
> -
> -		if (pipe->multirect_index == DPU_SSPP_RECT_0) {
> -			ystride0 = (ystride0 & 0xFFFF0000) |
> -				(cfg->layout.plane_pitch[0] & 0x0000FFFF);
> -			ystride1 = (ystride1 & 0xFFFF0000)|
> -				(cfg->layout.plane_pitch[2] & 0x0000FFFF);
> -		} else {
> -			ystride0 = (ystride0 & 0x0000FFFF) |
> -				((cfg->layout.plane_pitch[0] << 16) &
> -				 0xFFFF0000);
> -			ystride1 = (ystride1 & 0x0000FFFF) |
> -				((cfg->layout.plane_pitch[2] << 16) &
> -				 0xFFFF0000);
> -		}
> -	}
> -
>   	/* rectangle register programming */
>   	DPU_REG_WRITE(c, src_size_off + idx, src_size);
>   	DPU_REG_WRITE(c, src_xy_off + idx, src_xy);
>   	DPU_REG_WRITE(c, out_size_off + idx, dst_size);
>   	DPU_REG_WRITE(c, out_xy_off + idx, dst_xy);
> -
> -	DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE0 + idx, ystride0);
> -	DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
>   }
>   
>   static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
>   		struct dpu_hw_pipe_cfg *cfg)
>   {
>   	struct dpu_hw_pipe *ctx = pipe->sspp;
> +	u32 ystride0, ystride1;
>   	int i;
>   	u32 idx;
>   
> @@ -537,6 +511,33 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
>   		DPU_REG_WRITE(&ctx->hw, SSPP_SRC3_ADDR + idx,
>   				cfg->layout.plane_addr[2]);
>   	}
> +
> +	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
> +		ystride0 = (cfg->layout.plane_pitch[0]) |
> +			(cfg->layout.plane_pitch[1] << 16);
> +		ystride1 = (cfg->layout.plane_pitch[2]) |
> +			(cfg->layout.plane_pitch[3] << 16);
> +	} else {
> +		ystride0 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx);
> +		ystride1 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx);
> +
> +		if (pipe->multirect_index == DPU_SSPP_RECT_0) {
> +			ystride0 = (ystride0 & 0xFFFF0000) |
> +				(cfg->layout.plane_pitch[0] & 0x0000FFFF);
> +			ystride1 = (ystride1 & 0xFFFF0000)|
> +				(cfg->layout.plane_pitch[2] & 0x0000FFFF);
> +		} else {
> +			ystride0 = (ystride0 & 0x0000FFFF) |
> +				((cfg->layout.plane_pitch[0] << 16) &
> +				 0xFFFF0000);
> +			ystride1 = (ystride1 & 0x0000FFFF) |
> +				((cfg->layout.plane_pitch[2] << 16) &
> +				 0xFFFF0000);
> +		}
> +	}
> +
> +	DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx, ystride0);
> +	DPU_REG_WRITE(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx, ystride1);
>   }
>   
>   static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,

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

* Re: [PATCH 15/25] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg
  2022-02-09 17:25 ` [PATCH 15/25] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg Dmitry Baryshkov
@ 2022-05-13 18:58   ` Abhinav Kumar
  2022-05-14  6:53     ` Dmitry Baryshkov
  0 siblings, 1 reply; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-13 18:58 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> Remove dpu_hw_fmt_layout instance from struct dpu_hw_fmt_layout, leaving
> only src_rect and dst_rect.

I believe you meant "remove dpu_hw_fmt_layout instance from struct 
dpu_hw_pipe_cfg" ?.

Otherwise nothing wrong with the change as such, but other than making 
struct dpu_hw_pipe_cfg lighter, is there any other motivation behind 
this change?

Dont you think that dpu_hw_fmt_layout remaining to be a part of the 
struct dpu_hw_pipe_cfg is better and they are indeed tied closely.



> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 30 ++++++++++-----------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  6 ++---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  7 ++---
>   3 files changed, 21 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> index 2186506e6315..df6698778b6d 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -486,7 +486,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
>   }
>   
>   static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
> -		struct dpu_hw_pipe_cfg *cfg)
> +		struct dpu_hw_fmt_layout *layout)
>   {
>   	struct dpu_hw_pipe *ctx = pipe->sspp;
>   	u32 ystride0, ystride1;
> @@ -497,41 +497,41 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
>   		return;
>   
>   	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
> -		for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
> +		for (i = 0; i < ARRAY_SIZE(layout->plane_addr); i++)
>   			DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4,
> -					cfg->layout.plane_addr[i]);
> +					layout->plane_addr[i]);
>   	} else if (pipe->multirect_index == DPU_SSPP_RECT_0) {
>   		DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx,
> -				cfg->layout.plane_addr[0]);
> +				layout->plane_addr[0]);
>   		DPU_REG_WRITE(&ctx->hw, SSPP_SRC2_ADDR + idx,
> -				cfg->layout.plane_addr[2]);
> +				layout->plane_addr[2]);
>   	} else {
>   		DPU_REG_WRITE(&ctx->hw, SSPP_SRC1_ADDR + idx,
> -				cfg->layout.plane_addr[0]);
> +				layout->plane_addr[0]);
>   		DPU_REG_WRITE(&ctx->hw, SSPP_SRC3_ADDR + idx,
> -				cfg->layout.plane_addr[2]);
> +				layout->plane_addr[2]);
>   	}
>   
>   	if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
> -		ystride0 = (cfg->layout.plane_pitch[0]) |
> -			(cfg->layout.plane_pitch[1] << 16);
> -		ystride1 = (cfg->layout.plane_pitch[2]) |
> -			(cfg->layout.plane_pitch[3] << 16);
> +		ystride0 = (layout->plane_pitch[0]) |
> +			(layout->plane_pitch[1] << 16);
> +		ystride1 = (layout->plane_pitch[2]) |
> +			(layout->plane_pitch[3] << 16);
>   	} else {
>   		ystride0 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx);
>   		ystride1 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx);
>   
>   		if (pipe->multirect_index == DPU_SSPP_RECT_0) {
>   			ystride0 = (ystride0 & 0xFFFF0000) |
> -				(cfg->layout.plane_pitch[0] & 0x0000FFFF);
> +				(layout->plane_pitch[0] & 0x0000FFFF);
>   			ystride1 = (ystride1 & 0xFFFF0000)|
> -				(cfg->layout.plane_pitch[2] & 0x0000FFFF);
> +				(layout->plane_pitch[2] & 0x0000FFFF);
>   		} else {
>   			ystride0 = (ystride0 & 0x0000FFFF) |
> -				((cfg->layout.plane_pitch[0] << 16) &
> +				((layout->plane_pitch[0] << 16) &
>   				 0xFFFF0000);
>   			ystride1 = (ystride1 & 0x0000FFFF) |
> -				((cfg->layout.plane_pitch[2] << 16) &
> +				((layout->plane_pitch[2] << 16) &
>   				 0xFFFF0000);
>   		}
>   	}
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> index eee8501ea80d..93b60545ba98 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -155,13 +155,11 @@ struct dpu_hw_pixel_ext {
>   
>   /**
>    * struct dpu_hw_pipe_cfg : Pipe description
> - * @layout:    format layout information for programming buffer to hardware
>    * @src_rect:  src ROI, caller takes into account the different operations
>    *             such as decimation, flip etc to program this field
>    * @dest_rect: destination ROI.
>    */
>   struct dpu_hw_pipe_cfg {
> -	struct dpu_hw_fmt_layout layout;
>   	struct drm_rect src_rect;
>   	struct drm_rect dst_rect;
>   };
> @@ -260,10 +258,10 @@ struct dpu_hw_sspp_ops {
>   	/**
>   	 * setup_sourceaddress - setup pipe source addresses
>   	 * @pipe: Pointer to software pipe context
> -	 * @cfg: Pointer to pipe config structure
> +	 * @layout: format layout information for programming buffer to hardware
>   	 */
>   	void (*setup_sourceaddress)(struct dpu_sw_pipe *ctx,
> -			struct dpu_hw_pipe_cfg *cfg);
> +			struct dpu_hw_fmt_layout *layout);
>   
>   	/**
>   	 * setup_csc - setup color space coversion
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index e9421fa2fb2e..a521c0681af6 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1052,6 +1052,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	const struct dpu_format *fmt =
>   		to_dpu_format(msm_framebuffer_format(fb));
>   	struct dpu_hw_pipe_cfg pipe_cfg;
> +	struct dpu_hw_fmt_layout layout;
>   	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>   	struct msm_gem_address_space *aspace = kms->base.aspace;
>   	bool update_src_addr = true;
> @@ -1059,7 +1060,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   
>   	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
>   
> -	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg.layout);
> +	ret = dpu_format_populate_layout(aspace, fb, &layout);
>   	if (ret == -EAGAIN) {
>   		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
>   		update_src_addr = false;
> @@ -1070,8 +1071,8 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   
>   	if (update_src_addr &&
>   	    pipe->sspp->ops.setup_sourceaddress) {
> -		trace_dpu_plane_set_scanout(pipe, &pipe_cfg.layout);
> -		pipe->sspp->ops.setup_sourceaddress(pipe, &pipe_cfg);
> +		trace_dpu_plane_set_scanout(pipe, &layout);
> +		pipe->sspp->ops.setup_sourceaddress(pipe, &layout);
>   	}
>   
>   	pstate->pending = true;

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

* Re: [PATCH 16/25] drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout
  2022-02-09 17:25 ` [PATCH 16/25] drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout Dmitry Baryshkov
@ 2022-05-13 19:03   ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-13 19:03 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> Since layout is not cached anymore, drop comparison against previous
> layout and corresponding EAGAIN handling.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Isnt this preventing the usermode from programming the same address again?

I thought that this check is good in that way and has nothing to do with 
the caching as such.

So its the other way around, by caching we are ensuring that we dont get 
a new frame update for just updating the same src address.

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 4 ----
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 5 +----
>   2 files changed, 1 insertion(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
> index 440ae93d7bd1..5c7d739143f0 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
> @@ -927,10 +927,6 @@ int dpu_format_populate_layout(
>   	else
>   		ret = _dpu_format_populate_addrs_linear(aspace, fb, layout);
>   
> -	/* check if anything changed */
> -	if (!ret && !memcmp(plane_addr, layout->plane_addr, sizeof(plane_addr)))
> -		ret = -EAGAIN;
> -
>   	return ret;
>   }
>   
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index a521c0681af6..b2395f02f6d3 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1061,10 +1061,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
>   
>   	ret = dpu_format_populate_layout(aspace, fb, &layout);
> -	if (ret == -EAGAIN) {
> -		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
> -		update_src_addr = false;
> -	} else if (ret) {
> +	if (ret) {
>   		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
>   		update_src_addr = false;
>   	}

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

* Re: [PATCH 19/25] drm/msm/dpu: don't use unsupported blend stages
  2022-02-09 17:25 ` [PATCH 19/25] drm/msm/dpu: don't use unsupported blend stages Dmitry Baryshkov
@ 2022-05-14  1:57   ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-14  1:57 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> The atomic_check compares blending stage with DPU_STAGE_MAX (maximum
> amount of blending stages supported by the driver), however we should
> compare it against .max_mixer_blendstages, the maximum blend stage
> supported by the mixer.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

This seems reasonable to me,

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 637d164667e9..952ff11162c0 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -927,9 +927,9 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
>   
>   	pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
> -	if (pstate->stage >= DPU_STAGE_MAX) {
> +	if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
>   		DPU_ERROR("> %d plane stages assigned\n",
> -				DPU_STAGE_MAX - DPU_STAGE_0);
> +				pdpu->catalog->caps->max_mixer_blendstages - DPU_STAGE_0);
>   		return -EINVAL;
>   	}
>   

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

* Re: [PATCH 05/25] drm/msm/dpu: move pipe_hw to dpu_plane_state
  2022-05-03 22:32   ` Abhinav Kumar
@ 2022-05-14  6:37     ` Dmitry Baryshkov
  2022-05-26 20:21       ` Abhinav Kumar
  0 siblings, 1 reply; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-05-14  6:37 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

On 04/05/2022 01:32, Abhinav Kumar wrote:
> 
> 
> On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
>> In preparation to adding fully virtualized planes, move struct
>> dpu_hw_pipe instance from struct dpu_plane to struct dpu_plane_state, as
>> it will become a part of state (allocated during atomic check) rather
>> than part of a plane (allocated during boot).
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 104 ++++++++++++----------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   2 +
>>   2 files changed, 58 insertions(+), 48 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 37742f74a7bf..0247ff8a67a2 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -100,7 +100,6 @@ struct dpu_plane {
>>       enum dpu_sspp pipe;
>> -    struct dpu_hw_pipe *pipe_hw;
>>       uint32_t color_fill;
>>       bool is_error;
>>       bool is_rt_pipe;
>> @@ -300,6 +299,7 @@ static void _dpu_plane_set_qos_lut(struct 
>> drm_plane *plane,
>>           struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg *pipe_cfg)
>>   {
>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>> +    struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>>       const struct dpu_format *fmt = NULL;
>>       u64 qos_lut;
>>       u32 total_fl = 0, lut_usage;
>> @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct 
>> drm_plane *plane,
>>               fmt ? (char *)&fmt->base.pixel_format : NULL,
>>               pdpu->is_rt_pipe, total_fl, qos_lut);
>> -    pdpu->pipe_hw->ops.setup_creq_lut(pdpu->pipe_hw, qos_lut);
>> +    pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
>>   }
>>   /**
>> @@ -343,6 +343,7 @@ static void _dpu_plane_set_danger_lut(struct 
>> drm_plane *plane,
>>           struct drm_framebuffer *fb)
>>   {
>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>> +    struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>>       const struct dpu_format *fmt = NULL;
>>       u32 danger_lut, safe_lut;
>> @@ -382,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct 
>> drm_plane *plane,
>>           danger_lut,
>>           safe_lut);
>> -    pdpu->pipe_hw->ops.setup_danger_safe_lut(pdpu->pipe_hw,
>> +    pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
>>               danger_lut, safe_lut);
>>   }
>> @@ -396,14 +397,15 @@ static void _dpu_plane_set_qos_ctrl(struct 
>> drm_plane *plane,
>>       bool enable, u32 flags)
>>   {
>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>> +    struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>>       struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>>       memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>       if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>> -        pipe_qos_cfg.creq_vblank = 
>> pdpu->pipe_hw->cap->sblk->creq_vblank;
>> +        pipe_qos_cfg.creq_vblank = 
>> pstate->pipe_hw->cap->sblk->creq_vblank;
>>           pipe_qos_cfg.danger_vblank =
>> -                pdpu->pipe_hw->cap->sblk->danger_vblank;
>> +                pstate->pipe_hw->cap->sblk->danger_vblank;
>>           pipe_qos_cfg.vblank_en = enable;
>>       }
>> @@ -429,7 +431,7 @@ static void _dpu_plane_set_qos_ctrl(struct 
>> drm_plane *plane,
>>           pipe_qos_cfg.danger_vblank,
>>           pdpu->is_rt_pipe);
>> -    pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,
>> +    pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
>>               &pipe_qos_cfg);
>>   }
>> @@ -443,18 +445,19 @@ static void _dpu_plane_set_ot_limit(struct 
>> drm_plane *plane,
>>           struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
>>   {
>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>> +    struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>>       struct dpu_vbif_set_ot_params ot_params;
>>       struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>>       memset(&ot_params, 0, sizeof(ot_params));
>> -    ot_params.xin_id = pdpu->pipe_hw->cap->xin_id;
>> -    ot_params.num = pdpu->pipe_hw->idx - SSPP_NONE;
>> +    ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
>> +    ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
>>       ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
>>       ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
>>       ot_params.is_wfd = !pdpu->is_rt_pipe;
>>       ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
>>       ot_params.vbif_idx = VBIF_RT;
>> -    ot_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
>> +    ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>>       ot_params.rd = true;
>>       dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
>> @@ -467,14 +470,15 @@ static void _dpu_plane_set_ot_limit(struct 
>> drm_plane *plane,
>>   static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
>>   {
>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>> +    struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>>       struct dpu_vbif_set_qos_params qos_params;
>>       struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>>       memset(&qos_params, 0, sizeof(qos_params));
>>       qos_params.vbif_idx = VBIF_RT;
>> -    qos_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
>> -    qos_params.xin_id = pdpu->pipe_hw->cap->xin_id;
>> -    qos_params.num = pdpu->pipe_hw->idx - SSPP_VIG0;
>> +    qos_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>> +    qos_params.xin_id = pstate->pipe_hw->cap->xin_id;
>> +    qos_params.num = pstate->pipe_hw->idx - SSPP_VIG0;
>>       qos_params.is_rt = pdpu->is_rt_pipe;
>>       DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, 
>> clk_ctrl:%d\n",
>> @@ -501,11 +505,11 @@ static void _dpu_plane_set_scanout(struct 
>> drm_plane *plane,
>>           DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
>>       else if (ret)
>>           DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", 
>> ret);
>> -    else if (pdpu->pipe_hw->ops.setup_sourceaddress) {
>> -        trace_dpu_plane_set_scanout(pdpu->pipe_hw->idx,
>> +    else if (pstate->pipe_hw->ops.setup_sourceaddress) {
>> +        trace_dpu_plane_set_scanout(pstate->pipe_hw->idx,
>>                           &pipe_cfg->layout,
>>                           pstate->multirect_index);
>> -        pdpu->pipe_hw->ops.setup_sourceaddress(pdpu->pipe_hw, pipe_cfg,
>> +        pstate->pipe_hw->ops.setup_sourceaddress(pstate->pipe_hw, 
>> pipe_cfg,
>>                           pstate->multirect_index);
>>       }
>>   }
>> @@ -549,7 +553,7 @@ static void _dpu_plane_setup_scaler3(struct 
>> dpu_plane *pdpu,
>>               scale_cfg->src_height[i] /= chroma_subsmpl_v;
>>           }
>> -        if (pdpu->pipe_hw->cap->features &
>> +        if (pstate->pipe_hw->cap->features &
>>               BIT(DPU_SSPP_SCALER_QSEED4)) {
>>               scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
>>               scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
>> @@ -609,6 +613,7 @@ static const struct dpu_csc_cfg 
>> dpu_csc10_YUV2RGB_601L = {
>>   static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane 
>> *pdpu, const struct dpu_format *fmt)
>>   {
>> +    struct dpu_plane_state *pstate = 
>> to_dpu_plane_state(pdpu->base.state);
>>       const struct dpu_csc_cfg *csc_ptr;
>>       if (!pdpu) {
>> @@ -619,7 +624,7 @@ static const struct dpu_csc_cfg 
>> *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
>>       if (!DPU_FORMAT_IS_YUV(fmt))
>>           return NULL;
>> -    if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->pipe_hw->cap->features)
>> +    if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe_hw->cap->features)
>>           csc_ptr = &dpu_csc10_YUV2RGB_601L;
>>       else
>>           csc_ptr = &dpu_csc_YUV2RGB_601L;
>> @@ -654,8 +659,8 @@ static void _dpu_plane_setup_scaler(struct 
>> dpu_plane *pdpu,
>>               &scaler3_cfg, &pixel_ext, fmt,
>>               info->hsub, info->vsub);
>> -    if (pdpu->pipe_hw->ops.setup_pe)
>> -        pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
>> +    if (pstate->pipe_hw->ops.setup_pe)
>> +        pstate->pipe_hw->ops.setup_pe(pstate->pipe_hw,
>>                   &pixel_ext);
>>       /**
>> @@ -663,9 +668,9 @@ static void _dpu_plane_setup_scaler(struct 
>> dpu_plane *pdpu,
>>        * bypassed. Still we need to update alpha and bitwidth
>>        * ONLY for RECT0
>>        */
>> -    if (pdpu->pipe_hw->ops.setup_scaler &&
>> +    if (pstate->pipe_hw->ops.setup_scaler &&
>>               pstate->multirect_index != DPU_SSPP_RECT_1)
>> -        pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
>> +        pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
>>                   pipe_cfg,
>>                   &scaler3_cfg);
>>   }
>> @@ -694,8 +699,8 @@ static int _dpu_plane_color_fill(struct dpu_plane 
>> *pdpu,
>>       fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>>       /* update sspp */
>> -    if (fmt && pdpu->pipe_hw->ops.setup_solidfill) {
>> -        pdpu->pipe_hw->ops.setup_solidfill(pdpu->pipe_hw,
>> +    if (fmt && pstate->pipe_hw->ops.setup_solidfill) {
>> +        pstate->pipe_hw->ops.setup_solidfill(pstate->pipe_hw,
>>                   (color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
>>                   pstate->multirect_index);
>> @@ -709,13 +714,13 @@ static int _dpu_plane_color_fill(struct 
>> dpu_plane *pdpu,
>>           pipe_cfg.src_rect.y2 =
>>               drm_rect_height(&pipe_cfg.dst_rect);
>> -        if (pdpu->pipe_hw->ops.setup_format)
>> -            pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw,
>> +        if (pstate->pipe_hw->ops.setup_format)
>> +            pstate->pipe_hw->ops.setup_format(pstate->pipe_hw,
>>                       fmt, DPU_SSPP_SOLID_FILL,
>>                       pstate->multirect_index);
>> -        if (pdpu->pipe_hw->ops.setup_rects)
>> -            pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
>> +        if (pstate->pipe_hw->ops.setup_rects)
>> +            pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>>                       &pipe_cfg,
>>                       pstate->multirect_index);
>> @@ -953,10 +958,10 @@ static int dpu_plane_atomic_check(struct 
>> drm_plane *plane,
>>           crtc_state = drm_atomic_get_new_crtc_state(state,
>>                                  new_plane_state->crtc);
>> -    min_scale = FRAC_16_16(1, pdpu->pipe_hw->cap->sblk->maxupscale);
>> +    min_scale = FRAC_16_16(1, pstate->pipe_hw->cap->sblk->maxupscale);
>>       ret = drm_atomic_helper_check_plane_state(new_plane_state, 
>> crtc_state,
>>                             min_scale,
>> -                          pdpu->pipe_hw->cap->sblk->maxdwnscale << 16,
>> +                          pstate->pipe_hw->cap->sblk->maxdwnscale << 16,
>>                             true, true);
>>       if (ret) {
>>           DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
>> @@ -982,8 +987,8 @@ static int dpu_plane_atomic_check(struct drm_plane 
>> *plane,
>>       min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>       if (DPU_FORMAT_IS_YUV(fmt) &&
>> -        (!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
>> -         !(pdpu->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
>> +        (!(pstate->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
>> +         !(pstate->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
>>           DPU_DEBUG_PLANE(pdpu,
>>                   "plane doesn't have scaler/csc for yuv\n");
>>           return -EINVAL;
>> @@ -1044,12 +1049,12 @@ void dpu_plane_flush(struct drm_plane *plane)
>>       else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
>>           /* force 100% alpha */
>>           _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
>> -    else if (pdpu->pipe_hw && pdpu->pipe_hw->ops.setup_csc) {
>> +    else if (pstate->pipe_hw && pstate->pipe_hw->ops.setup_csc) {
>>           const struct dpu_format *fmt = 
>> to_dpu_format(msm_framebuffer_format(plane->state->fb));
>>           const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, 
>> fmt);
>>           if (csc_ptr)
>> -            pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, csc_ptr);
>> +            pstate->pipe_hw->ops.setup_csc(pstate->pipe_hw, csc_ptr);
>>       }
>>       /* flag h/w flush complete */
>> @@ -1116,21 +1121,21 @@ static void 
>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>           return;
>>       }
>> -    if (pdpu->pipe_hw->ops.setup_rects) {
>> -        pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
>> +    if (pstate->pipe_hw->ops.setup_rects) {
>> +        pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>>                   &pipe_cfg,
>>                   pstate->multirect_index);
>>       }
>>       _dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
>> -    if (pdpu->pipe_hw->ops.setup_multirect)
>> -        pdpu->pipe_hw->ops.setup_multirect(
>> -                pdpu->pipe_hw,
>> +    if (pstate->pipe_hw->ops.setup_multirect)
>> +        pstate->pipe_hw->ops.setup_multirect(
>> +                pstate->pipe_hw,
>>                   pstate->multirect_index,
>>                   pstate->multirect_mode);
>> -    if (pdpu->pipe_hw->ops.setup_format) {
>> +    if (pstate->pipe_hw->ops.setup_format) {
>>           unsigned int rotation;
>>           src_flags = 0x0;
>> @@ -1147,10 +1152,10 @@ static void 
>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>               src_flags |= DPU_SSPP_FLIP_UD;
>>           /* update format */
>> -        pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw, fmt, src_flags,
>> +        pstate->pipe_hw->ops.setup_format(pstate->pipe_hw, fmt, 
>> src_flags,
>>                   pstate->multirect_index);
>> -        if (pdpu->pipe_hw->ops.setup_cdp) {
>> +        if (pstate->pipe_hw->ops.setup_cdp) {
>>               struct dpu_hw_pipe_cdp_cfg cdp_cfg;
>>               memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
>> @@ -1164,7 +1169,7 @@ static void dpu_plane_sspp_atomic_update(struct 
>> drm_plane *plane)
>>                       DPU_FORMAT_IS_TILE(fmt);
>>               cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
>> -            pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, &cdp_cfg, 
>> pstate->multirect_index);
>> +            pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg, 
>> pstate->multirect_index);
>>           }
>>       }
>> @@ -1310,10 +1315,9 @@ static void dpu_plane_atomic_print_state(struct 
>> drm_printer *p,
>>           const struct drm_plane_state *state)
>>   {
>>       const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>> -    const struct dpu_plane *pdpu = to_dpu_plane(state->plane);
>>       drm_printf(p, "\tstage=%d\n", pstate->stage);
>> -    drm_printf(p, "\tsspp=%s\n", pdpu->pipe_hw->cap->name);
>> +    drm_printf(p, "\tsspp=%s\n", pstate->pipe_hw->cap->name);
>>       drm_printf(p, "\tmultirect_mode=%s\n", 
>> dpu_get_multirect_mode(pstate->multirect_mode));
>>       drm_printf(p, "\tmultirect_index=%s\n", 
>> dpu_get_multirect_index(pstate->multirect_index));
>>   }
>> @@ -1322,6 +1326,7 @@ static void dpu_plane_reset(struct drm_plane 
>> *plane)
>>   {
>>       struct dpu_plane *pdpu;
>>       struct dpu_plane_state *pstate;
>> +    struct dpu_kms *kms = _dpu_plane_get_kms(plane);
>>       if (!plane) {
>>           DPU_ERROR("invalid plane\n");
>> @@ -1343,6 +1348,8 @@ static void dpu_plane_reset(struct drm_plane 
>> *plane)
>>           return;
>>       }
>> +    pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - 
>> SSPP_NONE]);
>> +
>>       __drm_atomic_helper_plane_reset(plane, &pstate->base);
>>   }
>> @@ -1411,6 +1418,7 @@ struct drm_plane *dpu_plane_init(struct 
>> drm_device *dev,
>>       struct dpu_plane *pdpu;
>>       struct msm_drm_private *priv = dev->dev_private;
>>       struct dpu_kms *kms = to_dpu_kms(priv->kms);
>> +    struct dpu_hw_pipe *pipe_hw;
>>       uint32_t num_formats;
>>       int ret = -EINVAL;
>> @@ -1429,15 +1437,15 @@ struct drm_plane *dpu_plane_init(struct 
>> drm_device *dev,
>>       /* initialize underlying h/w driver */
>>       if (!kms->rm.sspp_blks[pipe - SSPP_NONE])
>>           goto clean_plane;
>> -    pdpu->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
>> +    pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
>> -    if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
>> +    if (!pipe_hw->cap || !pipe_hw->cap->sblk) {
>>           DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
>>           goto clean_plane;
>>       }
>> -    format_list = pdpu->pipe_hw->cap->sblk->format_list;
>> -    num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
>> +    format_list = pipe_hw->cap->sblk->format_list;
>> +    num_formats = pipe_hw->cap->sblk->num_formats;
>>       ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
>>                   format_list, num_formats,
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>> index d2f60810434e..42b88b6bc9c2 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>> @@ -35,6 +35,8 @@ struct dpu_plane_state {
>>       uint32_t multirect_mode;
>>       bool pending;
>> +    struct dpu_hw_pipe *pipe_hw;
> 
> now that pipe_hw has been made part of the dpu_plane_state, it means
> that it can also change with atomic state.
> 
> In this change, I can see you update this only in dpu_plane_reset() 
> which will be invoked during the drm_mode_config_reset().
> 
> Should this pipe_hw assignment be moved to the dpu_plane_atomic_update() 
> function?


dpu_plane_atomic_update() is too late for the assignment.  Probably you 
meane dpu_plane_atomic_check(). However in this change I didn't want to 
change the logic of the code. Previously pipe_hw was available at all 
the times. With this change I also want to make it available at all the 
times, which means resetting it in the _reset() function. It will be 
moved to atomic_check() later, in the virtual planes series.

Probably I should do two changes for the v2:
- Use inline helper insted of hardcoding kms->rm.sspp_blks[pipe - 
SSPP_NONE] everywhere
- Add the text above as a comment to the assignment in the _reset() 
function.

> 
>> +
>>       u64 plane_fetch_bw;
>>       u64 plane_clk;
>>   };


-- 
With best wishes
Dmitry

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

* Re: [PATCH 13/25] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
  2022-05-09 22:30   ` Abhinav Kumar
@ 2022-05-14  6:46     ` Dmitry Baryshkov
  0 siblings, 0 replies; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-05-14  6:46 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

On 10/05/2022 01:30, Abhinav Kumar wrote:
> 
> 
> On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
>> There is no need to pass full dpu_hw_pipe_cfg instance to
>> _dpu_hw_sspp_setup_scaler3, pass just struct dpu_format pointer.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 9 ++++-----
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 7 +++----
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 4 ++--
>>   3 files changed, 9 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
>> index d8120168f974..7194c14f87bc 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
>> @@ -415,19 +415,18 @@ static void dpu_hw_sspp_setup_pe_config(struct 
>> dpu_hw_pipe *ctx,
>>   }
>>   static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
>> -        struct dpu_hw_pipe_cfg *sspp,
>> -        void *scaler_cfg)
> 
> This change does two things:
> 
> 1) pass fmt and stop passing dpu_hw_pipe_cfg
> 2) change the scaler_cfg from void to struct dpu_hw_scaler3_cfg
> 
> So it seems like we had this void casting to allow different versions of 
> the scaler to be passed and based on catalog bits the appropriate 
> structs can be used (scaler2/scaler3)
> 
> In the current DPU we have only scaler3. For that reason this is fine.
> 
> I do not know what versions of scaler we will support in DPU.
> 
> Do you think we can retain the void casting in this change and just 
> change passing the format?

Generally passing a void pointer for the known structure is a bad 
practice. You loose type safety for no added benefit.

I can take a look on the QSEED2 requirements.

>> +        struct dpu_hw_scaler3_cfg *scaler3_cfg,
>> +        const struct dpu_format *format)
>>   {
>>       u32 idx;
>> -    struct dpu_hw_scaler3_cfg *scaler3_cfg = scaler_cfg;
>> -    if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx) || !sspp
>> +    if (_sspp_subblk_offset(ctx, DPU_SSPP_SCALER_QSEED3, &idx)
>>           || !scaler3_cfg)
>>           return;
>>       dpu_hw_setup_scaler3(&ctx->hw, scaler3_cfg, idx,
>>               ctx->cap->sblk->scaler_blk.version,
>> -            sspp->layout.format);
>> +            format);
>>   }
>>   static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>> index 74171fb4e585..eee8501ea80d 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>> @@ -334,13 +334,12 @@ struct dpu_hw_sspp_ops {
>>       /**
>>        * setup_scaler - setup scaler
>> -     * @ctx: Pointer to pipe context
>> -     * @pipe_cfg: Pointer to pipe configuration
>>        * @scaler_cfg: Pointer to scaler configuration
>> +     * @format: pixel format parameters
>>        */
>>       void (*setup_scaler)(struct dpu_hw_pipe *ctx,
>> -        struct dpu_hw_pipe_cfg *pipe_cfg,
>> -        void *scaler_cfg);
>> +        struct dpu_hw_scaler3_cfg *scaler3_cfg,
>> +        const struct dpu_format *format);
>>       /**
>>        * get_scaler_ver - get scaler h/w version
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 3ce7dcc285e2..e9421fa2fb2e 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -646,8 +646,8 @@ static void _dpu_plane_setup_scaler(struct 
>> dpu_sw_pipe *pipe,
>>       if (pipe_hw->ops.setup_scaler &&
>>               pipe->multirect_index != DPU_SSPP_RECT_1)
>>           pipe_hw->ops.setup_scaler(pipe_hw,
>> -                pipe_cfg,
>> -                &scaler3_cfg);
>> +                &scaler3_cfg,
>> +                fmt);
>>   }
>>   /**


-- 
With best wishes
Dmitry

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

* Re: [PATCH 15/25] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg
  2022-05-13 18:58   ` Abhinav Kumar
@ 2022-05-14  6:53     ` Dmitry Baryshkov
  0 siblings, 0 replies; 59+ messages in thread
From: Dmitry Baryshkov @ 2022-05-14  6:53 UTC (permalink / raw)
  To: Abhinav Kumar, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno

On 13/05/2022 21:58, Abhinav Kumar wrote:
> 
> 
> On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
>> Remove dpu_hw_fmt_layout instance from struct dpu_hw_fmt_layout, leaving
>> only src_rect and dst_rect.
> 
> I believe you meant "remove dpu_hw_fmt_layout instance from struct 
> dpu_hw_pipe_cfg" ?.
> 
> Otherwise nothing wrong with the change as such, but other than making 
> struct dpu_hw_pipe_cfg lighter, is there any other motivation behind 
> this change?
> 
> Dont you think that dpu_hw_fmt_layout remaining to be a part of the 
> struct dpu_hw_pipe_cfg is better and they are indeed tied closely.

The main motivation was to allow using dpu_hw_pipe_cfg for either of 
plane SSPPs while keeping the layout intact. See the patches 20 and 25.
Without this change the layout will be duplicated between both configs.

> 
> 
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 30 ++++++++++-----------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  6 ++---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  7 ++---
>>   3 files changed, 21 insertions(+), 22 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
>> index 2186506e6315..df6698778b6d 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
>> @@ -486,7 +486,7 @@ static void dpu_hw_sspp_setup_rects(struct 
>> dpu_sw_pipe *pipe,
>>   }
>>   static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
>> -        struct dpu_hw_pipe_cfg *cfg)
>> +        struct dpu_hw_fmt_layout *layout)
>>   {
>>       struct dpu_hw_pipe *ctx = pipe->sspp;
>>       u32 ystride0, ystride1;
>> @@ -497,41 +497,41 @@ static void 
>> dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
>>           return;
>>       if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
>> -        for (i = 0; i < ARRAY_SIZE(cfg->layout.plane_addr); i++)
>> +        for (i = 0; i < ARRAY_SIZE(layout->plane_addr); i++)
>>               DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx + i * 0x4,
>> -                    cfg->layout.plane_addr[i]);
>> +                    layout->plane_addr[i]);
>>       } else if (pipe->multirect_index == DPU_SSPP_RECT_0) {
>>           DPU_REG_WRITE(&ctx->hw, SSPP_SRC0_ADDR + idx,
>> -                cfg->layout.plane_addr[0]);
>> +                layout->plane_addr[0]);
>>           DPU_REG_WRITE(&ctx->hw, SSPP_SRC2_ADDR + idx,
>> -                cfg->layout.plane_addr[2]);
>> +                layout->plane_addr[2]);
>>       } else {
>>           DPU_REG_WRITE(&ctx->hw, SSPP_SRC1_ADDR + idx,
>> -                cfg->layout.plane_addr[0]);
>> +                layout->plane_addr[0]);
>>           DPU_REG_WRITE(&ctx->hw, SSPP_SRC3_ADDR + idx,
>> -                cfg->layout.plane_addr[2]);
>> +                layout->plane_addr[2]);
>>       }
>>       if (pipe->multirect_index == DPU_SSPP_RECT_SOLO) {
>> -        ystride0 = (cfg->layout.plane_pitch[0]) |
>> -            (cfg->layout.plane_pitch[1] << 16);
>> -        ystride1 = (cfg->layout.plane_pitch[2]) |
>> -            (cfg->layout.plane_pitch[3] << 16);
>> +        ystride0 = (layout->plane_pitch[0]) |
>> +            (layout->plane_pitch[1] << 16);
>> +        ystride1 = (layout->plane_pitch[2]) |
>> +            (layout->plane_pitch[3] << 16);
>>       } else {
>>           ystride0 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE0 + idx);
>>           ystride1 = DPU_REG_READ(&ctx->hw, SSPP_SRC_YSTRIDE1 + idx);
>>           if (pipe->multirect_index == DPU_SSPP_RECT_0) {
>>               ystride0 = (ystride0 & 0xFFFF0000) |
>> -                (cfg->layout.plane_pitch[0] & 0x0000FFFF);
>> +                (layout->plane_pitch[0] & 0x0000FFFF);
>>               ystride1 = (ystride1 & 0xFFFF0000)|
>> -                (cfg->layout.plane_pitch[2] & 0x0000FFFF);
>> +                (layout->plane_pitch[2] & 0x0000FFFF);
>>           } else {
>>               ystride0 = (ystride0 & 0x0000FFFF) |
>> -                ((cfg->layout.plane_pitch[0] << 16) &
>> +                ((layout->plane_pitch[0] << 16) &
>>                    0xFFFF0000);
>>               ystride1 = (ystride1 & 0x0000FFFF) |
>> -                ((cfg->layout.plane_pitch[2] << 16) &
>> +                ((layout->plane_pitch[2] << 16) &
>>                    0xFFFF0000);
>>           }
>>       }
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>> index eee8501ea80d..93b60545ba98 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
>> @@ -155,13 +155,11 @@ struct dpu_hw_pixel_ext {
>>   /**
>>    * struct dpu_hw_pipe_cfg : Pipe description
>> - * @layout:    format layout information for programming buffer to 
>> hardware
>>    * @src_rect:  src ROI, caller takes into account the different 
>> operations
>>    *             such as decimation, flip etc to program this field
>>    * @dest_rect: destination ROI.
>>    */
>>   struct dpu_hw_pipe_cfg {
>> -    struct dpu_hw_fmt_layout layout;
>>       struct drm_rect src_rect;
>>       struct drm_rect dst_rect;
>>   };
>> @@ -260,10 +258,10 @@ struct dpu_hw_sspp_ops {
>>       /**
>>        * setup_sourceaddress - setup pipe source addresses
>>        * @pipe: Pointer to software pipe context
>> -     * @cfg: Pointer to pipe config structure
>> +     * @layout: format layout information for programming buffer to 
>> hardware
>>        */
>>       void (*setup_sourceaddress)(struct dpu_sw_pipe *ctx,
>> -            struct dpu_hw_pipe_cfg *cfg);
>> +            struct dpu_hw_fmt_layout *layout);
>>       /**
>>        * setup_csc - setup color space coversion
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index e9421fa2fb2e..a521c0681af6 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -1052,6 +1052,7 @@ static void dpu_plane_sspp_atomic_update(struct 
>> drm_plane *plane)
>>       const struct dpu_format *fmt =
>>           to_dpu_format(msm_framebuffer_format(fb));
>>       struct dpu_hw_pipe_cfg pipe_cfg;
>> +    struct dpu_hw_fmt_layout layout;
>>       struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>>       struct msm_gem_address_space *aspace = kms->base.aspace;
>>       bool update_src_addr = true;
>> @@ -1059,7 +1060,7 @@ static void dpu_plane_sspp_atomic_update(struct 
>> drm_plane *plane)
>>       memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
>> -    ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg.layout);
>> +    ret = dpu_format_populate_layout(aspace, fb, &layout);
>>       if (ret == -EAGAIN) {
>>           DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
>>           update_src_addr = false;
>> @@ -1070,8 +1071,8 @@ static void dpu_plane_sspp_atomic_update(struct 
>> drm_plane *plane)
>>       if (update_src_addr &&
>>           pipe->sspp->ops.setup_sourceaddress) {
>> -        trace_dpu_plane_set_scanout(pipe, &pipe_cfg.layout);
>> -        pipe->sspp->ops.setup_sourceaddress(pipe, &pipe_cfg);
>> +        trace_dpu_plane_set_scanout(pipe, &layout);
>> +        pipe->sspp->ops.setup_sourceaddress(pipe, &layout);
>>       }
>>       pstate->pending = true;


-- 
With best wishes
Dmitry

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

* Re: [PATCH 05/25] drm/msm/dpu: move pipe_hw to dpu_plane_state
  2022-05-14  6:37     ` Dmitry Baryshkov
@ 2022-05-26 20:21       ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-26 20:21 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 5/13/2022 11:37 PM, Dmitry Baryshkov wrote:
> On 04/05/2022 01:32, Abhinav Kumar wrote:
>>
>>
>> On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
>>> In preparation to adding fully virtualized planes, move struct
>>> dpu_hw_pipe instance from struct dpu_plane to struct dpu_plane_state, as
>>> it will become a part of state (allocated during atomic check) rather
>>> than part of a plane (allocated during boot).
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 104 ++++++++++++----------
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   2 +
>>>   2 files changed, 58 insertions(+), 48 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> index 37742f74a7bf..0247ff8a67a2 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -100,7 +100,6 @@ struct dpu_plane {
>>>       enum dpu_sspp pipe;
>>> -    struct dpu_hw_pipe *pipe_hw;
>>>       uint32_t color_fill;
>>>       bool is_error;
>>>       bool is_rt_pipe;
>>> @@ -300,6 +299,7 @@ static void _dpu_plane_set_qos_lut(struct 
>>> drm_plane *plane,
>>>           struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg *pipe_cfg)
>>>   {
>>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>> +    struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>>>       const struct dpu_format *fmt = NULL;
>>>       u64 qos_lut;
>>>       u32 total_fl = 0, lut_usage;
>>> @@ -331,7 +331,7 @@ static void _dpu_plane_set_qos_lut(struct 
>>> drm_plane *plane,
>>>               fmt ? (char *)&fmt->base.pixel_format : NULL,
>>>               pdpu->is_rt_pipe, total_fl, qos_lut);
>>> -    pdpu->pipe_hw->ops.setup_creq_lut(pdpu->pipe_hw, qos_lut);
>>> +    pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
>>>   }
>>>   /**
>>> @@ -343,6 +343,7 @@ static void _dpu_plane_set_danger_lut(struct 
>>> drm_plane *plane,
>>>           struct drm_framebuffer *fb)
>>>   {
>>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>> +    struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>>>       const struct dpu_format *fmt = NULL;
>>>       u32 danger_lut, safe_lut;
>>> @@ -382,7 +383,7 @@ static void _dpu_plane_set_danger_lut(struct 
>>> drm_plane *plane,
>>>           danger_lut,
>>>           safe_lut);
>>> -    pdpu->pipe_hw->ops.setup_danger_safe_lut(pdpu->pipe_hw,
>>> +    pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
>>>               danger_lut, safe_lut);
>>>   }
>>> @@ -396,14 +397,15 @@ static void _dpu_plane_set_qos_ctrl(struct 
>>> drm_plane *plane,
>>>       bool enable, u32 flags)
>>>   {
>>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>> +    struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>>>       struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>>>       memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>>       if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>>> -        pipe_qos_cfg.creq_vblank = 
>>> pdpu->pipe_hw->cap->sblk->creq_vblank;
>>> +        pipe_qos_cfg.creq_vblank = 
>>> pstate->pipe_hw->cap->sblk->creq_vblank;
>>>           pipe_qos_cfg.danger_vblank =
>>> -                pdpu->pipe_hw->cap->sblk->danger_vblank;
>>> +                pstate->pipe_hw->cap->sblk->danger_vblank;
>>>           pipe_qos_cfg.vblank_en = enable;
>>>       }
>>> @@ -429,7 +431,7 @@ static void _dpu_plane_set_qos_ctrl(struct 
>>> drm_plane *plane,
>>>           pipe_qos_cfg.danger_vblank,
>>>           pdpu->is_rt_pipe);
>>> -    pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,
>>> +    pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
>>>               &pipe_qos_cfg);
>>>   }
>>> @@ -443,18 +445,19 @@ static void _dpu_plane_set_ot_limit(struct 
>>> drm_plane *plane,
>>>           struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
>>>   {
>>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>> +    struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>>>       struct dpu_vbif_set_ot_params ot_params;
>>>       struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>>>       memset(&ot_params, 0, sizeof(ot_params));
>>> -    ot_params.xin_id = pdpu->pipe_hw->cap->xin_id;
>>> -    ot_params.num = pdpu->pipe_hw->idx - SSPP_NONE;
>>> +    ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
>>> +    ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
>>>       ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
>>>       ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
>>>       ot_params.is_wfd = !pdpu->is_rt_pipe;
>>>       ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
>>>       ot_params.vbif_idx = VBIF_RT;
>>> -    ot_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
>>> +    ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>>>       ot_params.rd = true;
>>>       dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
>>> @@ -467,14 +470,15 @@ static void _dpu_plane_set_ot_limit(struct 
>>> drm_plane *plane,
>>>   static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
>>>   {
>>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>> +    struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>>>       struct dpu_vbif_set_qos_params qos_params;
>>>       struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>>>       memset(&qos_params, 0, sizeof(qos_params));
>>>       qos_params.vbif_idx = VBIF_RT;
>>> -    qos_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
>>> -    qos_params.xin_id = pdpu->pipe_hw->cap->xin_id;
>>> -    qos_params.num = pdpu->pipe_hw->idx - SSPP_VIG0;
>>> +    qos_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
>>> +    qos_params.xin_id = pstate->pipe_hw->cap->xin_id;
>>> +    qos_params.num = pstate->pipe_hw->idx - SSPP_VIG0;
>>>       qos_params.is_rt = pdpu->is_rt_pipe;
>>>       DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, 
>>> clk_ctrl:%d\n",
>>> @@ -501,11 +505,11 @@ static void _dpu_plane_set_scanout(struct 
>>> drm_plane *plane,
>>>           DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
>>>       else if (ret)
>>>           DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", 
>>> ret);
>>> -    else if (pdpu->pipe_hw->ops.setup_sourceaddress) {
>>> -        trace_dpu_plane_set_scanout(pdpu->pipe_hw->idx,
>>> +    else if (pstate->pipe_hw->ops.setup_sourceaddress) {
>>> +        trace_dpu_plane_set_scanout(pstate->pipe_hw->idx,
>>>                           &pipe_cfg->layout,
>>>                           pstate->multirect_index);
>>> -        pdpu->pipe_hw->ops.setup_sourceaddress(pdpu->pipe_hw, pipe_cfg,
>>> +        pstate->pipe_hw->ops.setup_sourceaddress(pstate->pipe_hw, 
>>> pipe_cfg,
>>>                           pstate->multirect_index);
>>>       }
>>>   }
>>> @@ -549,7 +553,7 @@ static void _dpu_plane_setup_scaler3(struct 
>>> dpu_plane *pdpu,
>>>               scale_cfg->src_height[i] /= chroma_subsmpl_v;
>>>           }
>>> -        if (pdpu->pipe_hw->cap->features &
>>> +        if (pstate->pipe_hw->cap->features &
>>>               BIT(DPU_SSPP_SCALER_QSEED4)) {
>>>               scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
>>>               scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
>>> @@ -609,6 +613,7 @@ static const struct dpu_csc_cfg 
>>> dpu_csc10_YUV2RGB_601L = {
>>>   static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct 
>>> dpu_plane *pdpu, const struct dpu_format *fmt)
>>>   {
>>> +    struct dpu_plane_state *pstate = 
>>> to_dpu_plane_state(pdpu->base.state);
>>>       const struct dpu_csc_cfg *csc_ptr;
>>>       if (!pdpu) {
>>> @@ -619,7 +624,7 @@ static const struct dpu_csc_cfg 
>>> *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
>>>       if (!DPU_FORMAT_IS_YUV(fmt))
>>>           return NULL;
>>> -    if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->pipe_hw->cap->features)
>>> +    if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe_hw->cap->features)
>>>           csc_ptr = &dpu_csc10_YUV2RGB_601L;
>>>       else
>>>           csc_ptr = &dpu_csc_YUV2RGB_601L;
>>> @@ -654,8 +659,8 @@ static void _dpu_plane_setup_scaler(struct 
>>> dpu_plane *pdpu,
>>>               &scaler3_cfg, &pixel_ext, fmt,
>>>               info->hsub, info->vsub);
>>> -    if (pdpu->pipe_hw->ops.setup_pe)
>>> -        pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
>>> +    if (pstate->pipe_hw->ops.setup_pe)
>>> +        pstate->pipe_hw->ops.setup_pe(pstate->pipe_hw,
>>>                   &pixel_ext);
>>>       /**
>>> @@ -663,9 +668,9 @@ static void _dpu_plane_setup_scaler(struct 
>>> dpu_plane *pdpu,
>>>        * bypassed. Still we need to update alpha and bitwidth
>>>        * ONLY for RECT0
>>>        */
>>> -    if (pdpu->pipe_hw->ops.setup_scaler &&
>>> +    if (pstate->pipe_hw->ops.setup_scaler &&
>>>               pstate->multirect_index != DPU_SSPP_RECT_1)
>>> -        pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
>>> +        pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
>>>                   pipe_cfg,
>>>                   &scaler3_cfg);
>>>   }
>>> @@ -694,8 +699,8 @@ static int _dpu_plane_color_fill(struct dpu_plane 
>>> *pdpu,
>>>       fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>>>       /* update sspp */
>>> -    if (fmt && pdpu->pipe_hw->ops.setup_solidfill) {
>>> -        pdpu->pipe_hw->ops.setup_solidfill(pdpu->pipe_hw,
>>> +    if (fmt && pstate->pipe_hw->ops.setup_solidfill) {
>>> +        pstate->pipe_hw->ops.setup_solidfill(pstate->pipe_hw,
>>>                   (color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
>>>                   pstate->multirect_index);
>>> @@ -709,13 +714,13 @@ static int _dpu_plane_color_fill(struct 
>>> dpu_plane *pdpu,
>>>           pipe_cfg.src_rect.y2 =
>>>               drm_rect_height(&pipe_cfg.dst_rect);
>>> -        if (pdpu->pipe_hw->ops.setup_format)
>>> -            pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw,
>>> +        if (pstate->pipe_hw->ops.setup_format)
>>> +            pstate->pipe_hw->ops.setup_format(pstate->pipe_hw,
>>>                       fmt, DPU_SSPP_SOLID_FILL,
>>>                       pstate->multirect_index);
>>> -        if (pdpu->pipe_hw->ops.setup_rects)
>>> -            pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
>>> +        if (pstate->pipe_hw->ops.setup_rects)
>>> +            pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>>>                       &pipe_cfg,
>>>                       pstate->multirect_index);
>>> @@ -953,10 +958,10 @@ static int dpu_plane_atomic_check(struct 
>>> drm_plane *plane,
>>>           crtc_state = drm_atomic_get_new_crtc_state(state,
>>>                                  new_plane_state->crtc);
>>> -    min_scale = FRAC_16_16(1, pdpu->pipe_hw->cap->sblk->maxupscale);
>>> +    min_scale = FRAC_16_16(1, pstate->pipe_hw->cap->sblk->maxupscale);
>>>       ret = drm_atomic_helper_check_plane_state(new_plane_state, 
>>> crtc_state,
>>>                             min_scale,
>>> -                          pdpu->pipe_hw->cap->sblk->maxdwnscale << 16,
>>> +                          pstate->pipe_hw->cap->sblk->maxdwnscale << 
>>> 16,
>>>                             true, true);
>>>       if (ret) {
>>>           DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
>>> @@ -982,8 +987,8 @@ static int dpu_plane_atomic_check(struct 
>>> drm_plane *plane,
>>>       min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>>       if (DPU_FORMAT_IS_YUV(fmt) &&
>>> -        (!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
>>> -         !(pdpu->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
>>> +        (!(pstate->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
>>> +         !(pstate->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
>>>           DPU_DEBUG_PLANE(pdpu,
>>>                   "plane doesn't have scaler/csc for yuv\n");
>>>           return -EINVAL;
>>> @@ -1044,12 +1049,12 @@ void dpu_plane_flush(struct drm_plane *plane)
>>>       else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
>>>           /* force 100% alpha */
>>>           _dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
>>> -    else if (pdpu->pipe_hw && pdpu->pipe_hw->ops.setup_csc) {
>>> +    else if (pstate->pipe_hw && pstate->pipe_hw->ops.setup_csc) {
>>>           const struct dpu_format *fmt = 
>>> to_dpu_format(msm_framebuffer_format(plane->state->fb));
>>>           const struct dpu_csc_cfg *csc_ptr = 
>>> _dpu_plane_get_csc(pdpu, fmt);
>>>           if (csc_ptr)
>>> -            pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, csc_ptr);
>>> +            pstate->pipe_hw->ops.setup_csc(pstate->pipe_hw, csc_ptr);
>>>       }
>>>       /* flag h/w flush complete */
>>> @@ -1116,21 +1121,21 @@ static void 
>>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>           return;
>>>       }
>>> -    if (pdpu->pipe_hw->ops.setup_rects) {
>>> -        pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
>>> +    if (pstate->pipe_hw->ops.setup_rects) {
>>> +        pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
>>>                   &pipe_cfg,
>>>                   pstate->multirect_index);
>>>       }
>>>       _dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
>>> -    if (pdpu->pipe_hw->ops.setup_multirect)
>>> -        pdpu->pipe_hw->ops.setup_multirect(
>>> -                pdpu->pipe_hw,
>>> +    if (pstate->pipe_hw->ops.setup_multirect)
>>> +        pstate->pipe_hw->ops.setup_multirect(
>>> +                pstate->pipe_hw,
>>>                   pstate->multirect_index,
>>>                   pstate->multirect_mode);
>>> -    if (pdpu->pipe_hw->ops.setup_format) {
>>> +    if (pstate->pipe_hw->ops.setup_format) {
>>>           unsigned int rotation;
>>>           src_flags = 0x0;
>>> @@ -1147,10 +1152,10 @@ static void 
>>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>               src_flags |= DPU_SSPP_FLIP_UD;
>>>           /* update format */
>>> -        pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw, fmt, src_flags,
>>> +        pstate->pipe_hw->ops.setup_format(pstate->pipe_hw, fmt, 
>>> src_flags,
>>>                   pstate->multirect_index);
>>> -        if (pdpu->pipe_hw->ops.setup_cdp) {
>>> +        if (pstate->pipe_hw->ops.setup_cdp) {
>>>               struct dpu_hw_pipe_cdp_cfg cdp_cfg;
>>>               memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
>>> @@ -1164,7 +1169,7 @@ static void dpu_plane_sspp_atomic_update(struct 
>>> drm_plane *plane)
>>>                       DPU_FORMAT_IS_TILE(fmt);
>>>               cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
>>> -            pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, &cdp_cfg, 
>>> pstate->multirect_index);
>>> +            pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, 
>>> &cdp_cfg, pstate->multirect_index);
>>>           }
>>>       }
>>> @@ -1310,10 +1315,9 @@ static void 
>>> dpu_plane_atomic_print_state(struct drm_printer *p,
>>>           const struct drm_plane_state *state)
>>>   {
>>>       const struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>> -    const struct dpu_plane *pdpu = to_dpu_plane(state->plane);
>>>       drm_printf(p, "\tstage=%d\n", pstate->stage);
>>> -    drm_printf(p, "\tsspp=%s\n", pdpu->pipe_hw->cap->name);
>>> +    drm_printf(p, "\tsspp=%s\n", pstate->pipe_hw->cap->name);
>>>       drm_printf(p, "\tmultirect_mode=%s\n", 
>>> dpu_get_multirect_mode(pstate->multirect_mode));
>>>       drm_printf(p, "\tmultirect_index=%s\n", 
>>> dpu_get_multirect_index(pstate->multirect_index));
>>>   }
>>> @@ -1322,6 +1326,7 @@ static void dpu_plane_reset(struct drm_plane 
>>> *plane)
>>>   {
>>>       struct dpu_plane *pdpu;
>>>       struct dpu_plane_state *pstate;
>>> +    struct dpu_kms *kms = _dpu_plane_get_kms(plane);
>>>       if (!plane) {
>>>           DPU_ERROR("invalid plane\n");
>>> @@ -1343,6 +1348,8 @@ static void dpu_plane_reset(struct drm_plane 
>>> *plane)
>>>           return;
>>>       }
>>> +    pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - 
>>> SSPP_NONE]);
>>> +
>>>       __drm_atomic_helper_plane_reset(plane, &pstate->base);
>>>   }
>>> @@ -1411,6 +1418,7 @@ struct drm_plane *dpu_plane_init(struct 
>>> drm_device *dev,
>>>       struct dpu_plane *pdpu;
>>>       struct msm_drm_private *priv = dev->dev_private;
>>>       struct dpu_kms *kms = to_dpu_kms(priv->kms);
>>> +    struct dpu_hw_pipe *pipe_hw;
>>>       uint32_t num_formats;
>>>       int ret = -EINVAL;
>>> @@ -1429,15 +1437,15 @@ struct drm_plane *dpu_plane_init(struct 
>>> drm_device *dev,
>>>       /* initialize underlying h/w driver */
>>>       if (!kms->rm.sspp_blks[pipe - SSPP_NONE])
>>>           goto clean_plane;
>>> -    pdpu->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - 
>>> SSPP_NONE]);
>>> +    pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
>>> -    if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
>>> +    if (!pipe_hw->cap || !pipe_hw->cap->sblk) {
>>>           DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
>>>           goto clean_plane;
>>>       }
>>> -    format_list = pdpu->pipe_hw->cap->sblk->format_list;
>>> -    num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
>>> +    format_list = pipe_hw->cap->sblk->format_list;
>>> +    num_formats = pipe_hw->cap->sblk->num_formats;
>>>       ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
>>>                   format_list, num_formats,
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> index d2f60810434e..42b88b6bc9c2 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> @@ -35,6 +35,8 @@ struct dpu_plane_state {
>>>       uint32_t multirect_mode;
>>>       bool pending;
>>> +    struct dpu_hw_pipe *pipe_hw;
>>
>> now that pipe_hw has been made part of the dpu_plane_state, it means
>> that it can also change with atomic state.
>>
>> In this change, I can see you update this only in dpu_plane_reset() 
>> which will be invoked during the drm_mode_config_reset().
>>
>> Should this pipe_hw assignment be moved to the 
>> dpu_plane_atomic_update() function?
> 
> 
> dpu_plane_atomic_update() is too late for the assignment.  Probably you 
> meane dpu_plane_atomic_check(). However in this change I didn't want to 
> change the logic of the code. Previously pipe_hw was available at all 
> the times. With this change I also want to make it available at all the 
> times, which means resetting it in the _reset() function. It will be 
> moved to atomic_check() later, in the virtual planes series.
> 
> Probably I should do two changes for the v2:
> - Use inline helper insted of hardcoding kms->rm.sspp_blks[pipe - 
> SSPP_NONE] everywhere
> - Add the text above as a comment to the assignment in the _reset() 
> function.

Yes, my first concern was that dpu_plane_reset() is to reset the state 
so using it to assign the pipe_hw seemed a little strange to me in terms 
of location.

So I think leaving a comment that after virtual planes, this location 
will be changed will make it more clear.

Thanks

Abhinav

> 
>>
>>> +
>>>       u64 plane_fetch_bw;
>>>       u64 plane_clk;
>>>   };
> 
> 

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

* Re: [PATCH 17/25] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check
  2022-02-09 17:25 ` [PATCH 17/25] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check Dmitry Baryshkov
@ 2022-05-26 22:59   ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-26 22:59 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> Neither source split nor multirect are properly supported at this
> moment. Both of these checks depend on normalized_zpos being equal for
> several planes (which is never the case for normalized zpos).
> Drop these checks to simplify dpu_crtc_atomic_check(). The actual
> support for either of these features is not removed from the backend
> code (sspp, ctl, etc).
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

This is true that current implementation of these features is not really 
compatible with any of the existing opensource compositors.

Till we have a better way to utilize this, I am okay to drop this code.

When we do re-visit this implementation especially for src split, 
atleast we have a reference of this PW link of what has been removed and 
can take it from there.

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 166 ++---------------------
>   1 file changed, 12 insertions(+), 154 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 751c64012058..cbd0e50c2bd3 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1046,13 +1046,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
>   	drm_crtc_vblank_on(crtc);
>   }
>   
> -struct plane_state {
> -	struct dpu_plane_state *dpu_pstate;
> -	const struct drm_plane_state *drm_pstate;
> -	int stage;
> -	u32 pipe_id;
> -};
> -
>   static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   		struct drm_atomic_state *state)
>   {
> @@ -1060,28 +1053,21 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   									  crtc);
>   	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
>   	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
> -	struct plane_state *pstates;
>   
>   	const struct drm_plane_state *pstate;
>   	struct drm_plane *plane;
>   	struct drm_display_mode *mode;
>   
> -	int cnt = 0, rc = 0, mixer_width = 0, i, z_pos;
> +	int rc = 0;
>   
> -	struct dpu_multirect_plane_states multirect_plane[DPU_STAGE_MAX * 2];
> -	int multirect_count = 0;
> -	const struct drm_plane_state *pipe_staged[SSPP_MAX];
> -	int left_zpos_cnt = 0, right_zpos_cnt = 0;
>   	struct drm_rect crtc_rect = { 0 };
>   
> -	pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
> -
>   	if (!crtc_state->enable || !crtc_state->active) {
>   		DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n",
>   				crtc->base.id, crtc_state->enable,
>   				crtc_state->active);
>   		memset(&cstate->new_perf, 0, sizeof(cstate->new_perf));
> -		goto end;
> +		return 0;
>   	}
>   
>   	mode = &crtc_state->adjusted_mode;
> @@ -1091,13 +1077,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   	if (crtc_state->active_changed)
>   		crtc_state->mode_changed = true;
>   
> -	memset(pipe_staged, 0, sizeof(pipe_staged));
> -
> -	if (cstate->num_mixers) {
> -		mixer_width = mode->hdisplay / cstate->num_mixers;
> -
> +	if (cstate->num_mixers)
>   		_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
> -	}
>   
>   	crtc_rect.x2 = mode->hdisplay;
>   	crtc_rect.y2 = mode->vdisplay;
> @@ -1105,33 +1086,16 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   	 /* get plane state for all drm planes associated with crtc state */
>   	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
>   		struct drm_rect dst, clip = crtc_rect;
> +		int z_pos;
>   
>   		if (IS_ERR_OR_NULL(pstate)) {
>   			rc = PTR_ERR(pstate);
>   			DPU_ERROR("%s: failed to get plane%d state, %d\n",
>   					dpu_crtc->name, plane->base.id, rc);
> -			goto end;
> -		}
> -		if (cnt >= DPU_STAGE_MAX * 4)
> -			continue;
> -
> -		pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
> -		pstates[cnt].drm_pstate = pstate;
> -		pstates[cnt].stage = pstate->normalized_zpos;
> -		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx;
> -
> -		if (pipe_staged[pstates[cnt].pipe_id]) {
> -			multirect_plane[multirect_count].r0 =
> -				pipe_staged[pstates[cnt].pipe_id];
> -			multirect_plane[multirect_count].r1 = pstate;
> -			multirect_count++;
> -
> -			pipe_staged[pstates[cnt].pipe_id] = NULL;
> -		} else {
> -			pipe_staged[pstates[cnt].pipe_id] = pstate;
> +			return rc;
>   		}
>   
> -		cnt++;
> +		dpu_plane_clear_multirect(pstate);
>   
>   		dst = drm_plane_state_dest(pstate);
>   		if (!drm_rect_intersect(&clip, &dst)) {
> @@ -1139,63 +1103,21 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   			DPU_ERROR("display: " DRM_RECT_FMT " plane: "
>   				  DRM_RECT_FMT "\n", DRM_RECT_ARG(&crtc_rect),
>   				  DRM_RECT_ARG(&dst));
> -			rc = -E2BIG;
> -			goto end;
> +			return -E2BIG;
>   		}
> -	}
> -
> -	for (i = 1; i < SSPP_MAX; i++) {
> -		if (pipe_staged[i])
> -			dpu_plane_clear_multirect(pipe_staged[i]);
> -	}
>   
> -	z_pos = -1;
> -	for (i = 0; i < cnt; i++) {
> -		/* reset counts at every new blend stage */
> -		if (pstates[i].stage != z_pos) {
> -			left_zpos_cnt = 0;
> -			right_zpos_cnt = 0;
> -			z_pos = pstates[i].stage;
> -		}
> +		z_pos = pstate->normalized_zpos;
>   
>   		/* verify z_pos setting before using it */
>   		if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
>   			DPU_ERROR("> %d plane stages assigned\n",
>   					DPU_STAGE_MAX - DPU_STAGE_0);
> -			rc = -EINVAL;
> -			goto end;
> -		} else if (pstates[i].drm_pstate->crtc_x < mixer_width) {
> -			if (left_zpos_cnt == 2) {
> -				DPU_ERROR("> 2 planes @ stage %d on left\n",
> -					z_pos);
> -				rc = -EINVAL;
> -				goto end;
> -			}
> -			left_zpos_cnt++;
> -
> -		} else {
> -			if (right_zpos_cnt == 2) {
> -				DPU_ERROR("> 2 planes @ stage %d on right\n",
> -					z_pos);
> -				rc = -EINVAL;
> -				goto end;
> -			}
> -			right_zpos_cnt++;
> +			return -EINVAL;
>   		}
>   
> -		pstates[i].dpu_pstate->stage = z_pos + DPU_STAGE_0;
> +		to_dpu_plane_state(pstate)->stage = z_pos + DPU_STAGE_0;
>   		DRM_DEBUG_ATOMIC("%s: zpos %d\n", dpu_crtc->name, z_pos);
> -	}
>   
> -	for (i = 0; i < multirect_count; i++) {
> -		if (dpu_plane_validate_multirect_v2(&multirect_plane[i])) {
> -			DPU_ERROR(
> -			"multirect validation failed for planes (%d - %d)\n",
> -					multirect_plane[i].r0->plane->base.id,
> -					multirect_plane[i].r1->plane->base.id);
> -			rc = -EINVAL;
> -			goto end;
> -		}
>   	}
>   
>   	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
> @@ -1204,74 +1126,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   	if (rc) {
>   		DPU_ERROR("crtc%d failed performance check %d\n",
>   				crtc->base.id, rc);
> -		goto end;
> -	}
> -
> -	/* validate source split:
> -	 * use pstates sorted by stage to check planes on same stage
> -	 * we assume that all pipes are in source split so its valid to compare
> -	 * without taking into account left/right mixer placement
> -	 */
> -	for (i = 1; i < cnt; i++) {
> -		struct plane_state *prv_pstate, *cur_pstate;
> -		struct drm_rect left_rect, right_rect;
> -		int32_t left_pid, right_pid;
> -		int32_t stage;
> -
> -		prv_pstate = &pstates[i - 1];
> -		cur_pstate = &pstates[i];
> -		if (prv_pstate->stage != cur_pstate->stage)
> -			continue;
> -
> -		stage = cur_pstate->stage;
> -
> -		left_pid = prv_pstate->dpu_pstate->base.plane->base.id;
> -		left_rect = drm_plane_state_dest(prv_pstate->drm_pstate);
> -
> -		right_pid = cur_pstate->dpu_pstate->base.plane->base.id;
> -		right_rect = drm_plane_state_dest(cur_pstate->drm_pstate);
> -
> -		if (right_rect.x1 < left_rect.x1) {
> -			swap(left_pid, right_pid);
> -			swap(left_rect, right_rect);
> -		}
> -
> -		/**
> -		 * - planes are enumerated in pipe-priority order such that
> -		 *   planes with lower drm_id must be left-most in a shared
> -		 *   blend-stage when using source split.
> -		 * - planes in source split must be contiguous in width
> -		 * - planes in source split must have same dest yoff and height
> -		 */
> -		if (right_pid < left_pid) {
> -			DPU_ERROR(
> -				"invalid src split cfg. priority mismatch. stage: %d left: %d right: %d\n",
> -				stage, left_pid, right_pid);
> -			rc = -EINVAL;
> -			goto end;
> -		} else if (right_rect.x1 != drm_rect_width(&left_rect)) {
> -			DPU_ERROR("non-contiguous coordinates for src split. "
> -				  "stage: %d left: " DRM_RECT_FMT " right: "
> -				  DRM_RECT_FMT "\n", stage,
> -				  DRM_RECT_ARG(&left_rect),
> -				  DRM_RECT_ARG(&right_rect));
> -			rc = -EINVAL;
> -			goto end;
> -		} else if (left_rect.y1 != right_rect.y1 ||
> -			   drm_rect_height(&left_rect) != drm_rect_height(&right_rect)) {
> -			DPU_ERROR("source split at stage: %d. invalid "
> -				  "yoff/height: left: " DRM_RECT_FMT " right: "
> -				  DRM_RECT_FMT "\n", stage,
> -				  DRM_RECT_ARG(&left_rect),
> -				  DRM_RECT_ARG(&right_rect));
> -			rc = -EINVAL;
> -			goto end;
> -		}
> +		return rc;
>   	}
>   
> -end:
> -	kfree(pstates);
> -	return rc;
> +	return 0;
>   }
>   
>   int dpu_crtc_vblank(struct drm_crtc *crtc, bool en)

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

* Re: [PATCH 18/25] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
  2022-02-09 17:25 ` [PATCH 18/25] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check() Dmitry Baryshkov
@ 2022-05-27  0:14   ` Abhinav Kumar
  0 siblings, 0 replies; 59+ messages in thread
From: Abhinav Kumar @ 2022-05-27  0:14 UTC (permalink / raw)
  To: Dmitry Baryshkov, Bjorn Andersson, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, linux-arm-msm,
	dri-devel, freedreno



On 2/9/2022 9:25 AM, Dmitry Baryshkov wrote:
> Remove plane checks/state updates from dpu_crtc_atomic_check(). The
> belong to dpu_plane_atomic_check().
> 
The --> They
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 44 -----------------------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 +++++-----
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ----
>   3 files changed, 10 insertions(+), 58 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index cbd0e50c2bd3..fa279f0358d6 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1054,14 +1054,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   	struct dpu_crtc *dpu_crtc = to_dpu_crtc(crtc);
>   	struct dpu_crtc_state *cstate = to_dpu_crtc_state(crtc_state);
>   
> -	const struct drm_plane_state *pstate;
> -	struct drm_plane *plane;
>   	struct drm_display_mode *mode;
>   
>   	int rc = 0;
>   
> -	struct drm_rect crtc_rect = { 0 };
> -
>   	if (!crtc_state->enable || !crtc_state->active) {
>   		DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n",
>   				crtc->base.id, crtc_state->enable,
> @@ -1080,46 +1076,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   	if (cstate->num_mixers)
>   		_dpu_crtc_setup_lm_bounds(crtc, crtc_state);
>   
> -	crtc_rect.x2 = mode->hdisplay;
> -	crtc_rect.y2 = mode->vdisplay;
> -
> -	 /* get plane state for all drm planes associated with crtc state */
> -	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
> -		struct drm_rect dst, clip = crtc_rect;
> -		int z_pos;
> -
> -		if (IS_ERR_OR_NULL(pstate)) {
> -			rc = PTR_ERR(pstate);
> -			DPU_ERROR("%s: failed to get plane%d state, %d\n",
> -					dpu_crtc->name, plane->base.id, rc);
> -			return rc;
> -		}
> -
> -		dpu_plane_clear_multirect(pstate);
> -
> -		dst = drm_plane_state_dest(pstate);
> -		if (!drm_rect_intersect(&clip, &dst)) {
> -			DPU_ERROR("invalid vertical/horizontal destination\n");
> -			DPU_ERROR("display: " DRM_RECT_FMT " plane: "
> -				  DRM_RECT_FMT "\n", DRM_RECT_ARG(&crtc_rect),
> -				  DRM_RECT_ARG(&dst));
> -			return -E2BIG;
> -		}

Doesnt this check also have to be moved? We need to make sure dest 
rectangle is within CRTC bounds?

> -
> -		z_pos = pstate->normalized_zpos;
> -
> -		/* verify z_pos setting before using it */
> -		if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
> -			DPU_ERROR("> %d plane stages assigned\n",
> -					DPU_STAGE_MAX - DPU_STAGE_0);
> -			return -EINVAL;
> -		}
> -
> -		to_dpu_plane_state(pstate)->stage = z_pos + DPU_STAGE_0;
> -		DRM_DEBUG_ATOMIC("%s: zpos %d\n", dpu_crtc->name, z_pos);
> -
> -	}
> -
>   	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
>   
>   	rc = dpu_core_perf_crtc_check(crtc, crtc_state);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index b2395f02f6d3..637d164667e9 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -702,14 +702,6 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   	return 0;
>   }
>   
> -void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state)
> -{
> -	struct dpu_plane_state *pstate = to_dpu_plane_state(drm_state);
> -
> -	pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
> -	pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> -}
> -
>   int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
>   {
>   	struct dpu_plane_state *pstate[R_MAX];
> @@ -931,6 +923,16 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	if (!new_plane_state->visible)
>   		return 0;
>   
> +	pstate->pipe.multirect_index = DPU_SSPP_RECT_SOLO;
> +	pstate->pipe.multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> +
> +	pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
> +	if (pstate->stage >= DPU_STAGE_MAX) {
> +		DPU_ERROR("> %d plane stages assigned\n",
> +				DPU_STAGE_MAX - DPU_STAGE_0);
> +		return -EINVAL;
> +	}
> +
>   	src.x1 = new_plane_state->src_x >> 16;
>   	src.y1 = new_plane_state->src_y >> 16;
>   	src.x2 = src.x1 + (new_plane_state->src_w >> 16);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> index b6fd6f856d6a..e61c57b045ea 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -83,12 +83,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>    */
>   int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane);
>   
> -/**
> - * dpu_plane_clear_multirect - clear multirect bits for the given pipe
> - * @drm_state: Pointer to DRM plane state
> - */
> -void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state);
> -
>   /**
>    * dpu_plane_color_fill - enables color fill on plane
>    * @plane:  Pointer to DRM plane object

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

end of thread, other threads:[~2022-05-27  0:15 UTC | newest]

Thread overview: 59+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-02-09 17:24 [PATCH 00/25] drm/msm/dpu: wide planes support Dmitry Baryshkov
2022-02-09 17:24 ` [PATCH 01/25] drm/msm/dpu: rip out master " Dmitry Baryshkov
2022-04-27  1:28   ` Abhinav Kumar
2022-02-09 17:24 ` [PATCH 02/25] drm/msm/dpu: do not limit the zpos property Dmitry Baryshkov
2022-04-27  1:32   ` Abhinav Kumar
2022-02-09 17:24 ` [PATCH 03/25] drm/msm/dpu: add support for SSPP allocation to RM Dmitry Baryshkov
2022-04-27  2:06   ` Abhinav Kumar
2022-02-09 17:24 ` [PATCH 04/25] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c Dmitry Baryshkov
2022-05-03 21:34   ` Abhinav Kumar
2022-05-03 22:11     ` Dmitry Baryshkov
2022-05-03 22:34       ` Abhinav Kumar
2022-02-09 17:25 ` [PATCH 05/25] drm/msm/dpu: move pipe_hw to dpu_plane_state Dmitry Baryshkov
2022-05-03 22:32   ` Abhinav Kumar
2022-05-14  6:37     ` Dmitry Baryshkov
2022-05-26 20:21       ` Abhinav Kumar
2022-02-09 17:25 ` [PATCH 06/25] drm/msm/dpu: inline dpu_plane_get_ctl_flush Dmitry Baryshkov
2022-05-03 22:55   ` Abhinav Kumar
2022-02-09 17:25 ` [PATCH 07/25] drm/msm/dpu: drop dpu_plane_pipe function Dmitry Baryshkov
2022-05-03 23:04   ` Abhinav Kumar
2022-02-09 17:25 ` [PATCH 08/25] drm/msm/dpu: get rid of cached flush_mask Dmitry Baryshkov
2022-05-03 23:40   ` Abhinav Kumar
2022-02-09 17:25 ` [PATCH 09/25] drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic Dmitry Baryshkov
2022-05-06 18:56   ` Abhinav Kumar
2022-05-06 20:14     ` Dmitry Baryshkov
2022-02-09 17:25 ` [PATCH 10/25] drm/msm/dpu: introduce struct dpu_sw_pipe Dmitry Baryshkov
2022-05-06 21:30   ` Abhinav Kumar
2022-05-06 21:39     ` Dmitry Baryshkov
2022-05-06 21:48       ` [Freedreno] " Abhinav Kumar
2022-05-06 22:29         ` Dmitry Baryshkov
2022-05-06 22:46           ` Abhinav Kumar
2022-02-09 17:25 ` [PATCH 11/25] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks Dmitry Baryshkov
2022-05-06 22:24   ` Abhinav Kumar
2022-02-09 17:25 ` [PATCH 12/25] drm/msm/dpu: inline _dpu_plane_set_scanout Dmitry Baryshkov
2022-05-06 23:33   ` Abhinav Kumar
2022-05-06 23:34     ` Dmitry Baryshkov
2022-02-09 17:25 ` [PATCH 13/25] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3() Dmitry Baryshkov
2022-05-09 22:30   ` Abhinav Kumar
2022-05-14  6:46     ` Dmitry Baryshkov
2022-02-09 17:25 ` [PATCH 14/25] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress Dmitry Baryshkov
2022-05-13 18:50   ` Abhinav Kumar
2022-02-09 17:25 ` [PATCH 15/25] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg Dmitry Baryshkov
2022-05-13 18:58   ` Abhinav Kumar
2022-05-14  6:53     ` Dmitry Baryshkov
2022-02-09 17:25 ` [PATCH 16/25] drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout Dmitry Baryshkov
2022-05-13 19:03   ` Abhinav Kumar
2022-02-09 17:25 ` [PATCH 17/25] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check Dmitry Baryshkov
2022-05-26 22:59   ` Abhinav Kumar
2022-02-09 17:25 ` [PATCH 18/25] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check() Dmitry Baryshkov
2022-05-27  0:14   ` Abhinav Kumar
2022-02-09 17:25 ` [PATCH 19/25] drm/msm/dpu: don't use unsupported blend stages Dmitry Baryshkov
2022-05-14  1:57   ` Abhinav Kumar
2022-02-09 17:25 ` [PATCH 20/25] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state Dmitry Baryshkov
2022-02-09 17:25 ` [PATCH 21/25] drm/msm/dpu: simplify dpu_plane_validate_src() Dmitry Baryshkov
2022-02-09 17:25 ` [PATCH 22/25] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format Dmitry Baryshkov
2022-02-09 17:25 ` [PATCH 23/25] drm/msm/dpu: rework dpu_plane_atomic_check() and dpu_plane_sspp_atomic_update() Dmitry Baryshkov
2022-02-09 17:25 ` [PATCH 24/25] drm/msm/dpu: populate SmartDMA features in hw catalog Dmitry Baryshkov
2022-02-09 17:25 ` [PATCH 25/25] drm/msm/dpu: add support for wide planes Dmitry Baryshkov
2022-03-17  1:10 ` [PATCH 00/25] drm/msm/dpu: wide planes support Abhinav Kumar
2022-03-17  7:59   ` Dmitry Baryshkov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).