All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 00/27] drm/msm/dpu: wide planes support
@ 2023-02-03 18:21 ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

The review of the first half of v2 took more than a month. Let's update
the reviewed patches in attempt to get the first half of the series into
the acked and mergeable state. This would allow us to lower the impact
(and the patch count). At 27 patches this series is approaching the
limits of manageability.

This patchset brings in multirect usage to support using two SSPP
rectangles for a single plane. Full virtual planes support is omitted
from this pull request, it will come later.

Changes since v1 (which was ages ago):
- Rebased on top of 6.2-rc1
- Dropped the controversial _dpu_crtc_blend_setup() split patch
- Renamed dpu_hw_pipe to dpu_hw_sspp
- Other misc changes

Dmitry Baryshkov (27):
  drm/msm/dpu: rename struct dpu_hw_pipe(_cfg) to dpu_hw_sspp(_cfg)
  drm/msm/dpu: move SSPP allocation to the RM
  drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
  drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout
  drm/msm/dpu: move pipe_hw to dpu_plane_state
  drm/msm/dpu: drop dpu_plane_pipe function
  drm/msm/dpu: introduce struct dpu_sw_pipe
  drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
  drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
  drm/msm/dpu: clean up SRC addresses when setting up SSPP for solid
    fill
  drm/msm/dpu: move stride programming to
    dpu_hw_sspp_setup_sourceaddress
  drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_sspp_cfg
  drm/msm/dpu: drop src_split and multirect check from
    dpu_crtc_atomic_check
  drm/msm/dpu: don't use unsupported blend stages
  drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
  drm/msm/dpu: drop redundant plane dst check from
    dpu_crtc_atomic_check()
  drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe
    and dpu_format
  drm/msm/dpu: populate SmartDMA features in hw catalog
  drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly
  drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
  drm/msm/dpu: simplify dpu_plane_validate_src()
  drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
  drm/msm/dpu: rework dpu_plane_atomic_check()
  drm/msm/dpu: rework plane CSC setting
  drm/msm/dpu: rework static color fill code
  drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
  drm/msm/dpu: add support for wide planes

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c      | 285 ++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c   |  10 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    |  10 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c   | 168 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h   | 110 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c       |  18 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c     | 745 ++++++++++--------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h     |  23 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c        |  22 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h        |  12 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h     |  25 +-
 11 files changed, 707 insertions(+), 721 deletions(-)

-- 
2.39.1


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

* [PATCH v3 00/27] drm/msm/dpu: wide planes support
@ 2023-02-03 18:21 ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

The review of the first half of v2 took more than a month. Let's update
the reviewed patches in attempt to get the first half of the series into
the acked and mergeable state. This would allow us to lower the impact
(and the patch count). At 27 patches this series is approaching the
limits of manageability.

This patchset brings in multirect usage to support using two SSPP
rectangles for a single plane. Full virtual planes support is omitted
from this pull request, it will come later.

Changes since v1 (which was ages ago):
- Rebased on top of 6.2-rc1
- Dropped the controversial _dpu_crtc_blend_setup() split patch
- Renamed dpu_hw_pipe to dpu_hw_sspp
- Other misc changes

Dmitry Baryshkov (27):
  drm/msm/dpu: rename struct dpu_hw_pipe(_cfg) to dpu_hw_sspp(_cfg)
  drm/msm/dpu: move SSPP allocation to the RM
  drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
  drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout
  drm/msm/dpu: move pipe_hw to dpu_plane_state
  drm/msm/dpu: drop dpu_plane_pipe function
  drm/msm/dpu: introduce struct dpu_sw_pipe
  drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
  drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
  drm/msm/dpu: clean up SRC addresses when setting up SSPP for solid
    fill
  drm/msm/dpu: move stride programming to
    dpu_hw_sspp_setup_sourceaddress
  drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_sspp_cfg
  drm/msm/dpu: drop src_split and multirect check from
    dpu_crtc_atomic_check
  drm/msm/dpu: don't use unsupported blend stages
  drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
  drm/msm/dpu: drop redundant plane dst check from
    dpu_crtc_atomic_check()
  drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe
    and dpu_format
  drm/msm/dpu: populate SmartDMA features in hw catalog
  drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly
  drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
  drm/msm/dpu: simplify dpu_plane_validate_src()
  drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
  drm/msm/dpu: rework dpu_plane_atomic_check()
  drm/msm/dpu: rework plane CSC setting
  drm/msm/dpu: rework static color fill code
  drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
  drm/msm/dpu: add support for wide planes

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c      | 285 ++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c   |  10 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    |  10 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c   | 168 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h   | 110 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c       |  18 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c     | 745 ++++++++++--------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h     |  23 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c        |  22 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h        |  12 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h     |  25 +-
 11 files changed, 707 insertions(+), 721 deletions(-)

-- 
2.39.1


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

* [PATCH v3 01/27] drm/msm/dpu: rename struct dpu_hw_pipe(_cfg) to dpu_hw_sspp(_cfg)
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

For all hardware blocks except SSPP the corresponding struct is named
after the block. Rename dpu_hw_pipe (SSPP structure) to dpu_hw_sspp.
Also rename struct dpu_hw_pipe_cfg to dpu_hw_sspp_cfg to follow this
change.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 48 +++++++++----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 52 ++++++++++-----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 20 ++++----
 3 files changed, 60 insertions(+), 60 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 4246ab0b3bee..5cf0803e4187 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -136,7 +136,7 @@
 #define TS_CLK			19200000
 
 
-static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
+static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx,
 		int s_id,
 		u32 *idx)
 {
@@ -168,7 +168,7 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
 	return rc;
 }
 
-static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp *ctx,
 		enum dpu_sspp_multirect_index index,
 		enum dpu_sspp_multirect_mode mode)
 {
@@ -197,7 +197,7 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
 	DPU_REG_WRITE(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx, mode_mask);
 }
 
-static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
+static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx,
 		u32 mask, u8 en)
 {
 	u32 idx;
@@ -218,7 +218,7 @@ static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
 	DPU_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode);
 }
 
-static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx,
+static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp *ctx,
 		u32 mask, u8 en)
 {
 	u32 idx;
@@ -239,7 +239,7 @@ 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,
+static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp *ctx,
 		const struct dpu_format *fmt, u32 flags,
 		enum dpu_sspp_multirect_index rect_mode)
 {
@@ -360,7 +360,7 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
 	DPU_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
 }
 
-static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
 		struct dpu_hw_pixel_ext *pe_ext)
 {
 	struct dpu_hw_blk_reg_map *c;
@@ -418,8 +418,8 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
 			tot_req_pixels[3]);
 }
 
-static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_cfg *sspp,
+static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
+		struct dpu_hw_sspp_cfg *sspp,
 		void *scaler_cfg)
 {
 	u32 idx;
@@ -434,7 +434,7 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
 			sspp->layout.format);
 }
 
-static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
+static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
 {
 	u32 idx;
 
@@ -447,8 +447,8 @@ 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,
+static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
+		struct dpu_hw_sspp_cfg *cfg,
 		enum dpu_sspp_multirect_index rect_index)
 {
 	struct dpu_hw_blk_reg_map *c;
@@ -516,8 +516,8 @@ 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,
+static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_sspp *ctx,
+		struct dpu_hw_sspp_cfg *cfg,
 		enum dpu_sspp_multirect_index rect_mode)
 {
 	int i;
@@ -543,7 +543,7 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_pipe *ctx,
 	}
 }
 
-static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
 		const struct dpu_csc_cfg *data)
 {
 	u32 idx;
@@ -560,7 +560,7 @@ 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
+static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_sspp *ctx, u32 color, enum
 		dpu_sspp_multirect_index rect_index)
 {
 	u32 idx;
@@ -575,7 +575,7 @@ static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, enum
 				color);
 }
 
-static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_sspp *ctx,
 			u32 danger_lut,
 			u32 safe_lut)
 {
@@ -588,7 +588,7 @@ static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
 	DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, safe_lut);
 }
 
-static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_sspp *ctx,
 			u64 creq_lut)
 {
 	u32 idx;
@@ -605,7 +605,7 @@ static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
 	}
 }
 
-static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx,
 		struct dpu_hw_pipe_qos_cfg *cfg)
 {
 	u32 idx;
@@ -630,7 +630,7 @@ 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,
+static void dpu_hw_sspp_setup_cdp(struct dpu_hw_sspp *ctx,
 		struct dpu_hw_cdp_cfg *cfg,
 		enum dpu_sspp_multirect_index index)
 {
@@ -661,7 +661,7 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
 	DPU_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl);
 }
 
-static void _setup_layer_ops(struct dpu_hw_pipe *c,
+static void _setup_layer_ops(struct dpu_hw_sspp *c,
 		unsigned long features)
 {
 	if (test_bit(DPU_SSPP_SRC, &features)) {
@@ -699,7 +699,7 @@ static void _setup_layer_ops(struct dpu_hw_pipe *c,
 }
 
 #ifdef CONFIG_DEBUG_FS
-int _dpu_hw_sspp_init_debugfs(struct dpu_hw_pipe *hw_pipe, struct dpu_kms *kms, struct dentry *entry)
+int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, struct dentry *entry)
 {
 	const struct dpu_sspp_cfg *cfg = hw_pipe->cap;
 	const struct dpu_sspp_sub_blks *sblk = cfg->sblk;
@@ -783,10 +783,10 @@ static const struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp,
 	return ERR_PTR(-ENOMEM);
 }
 
-struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
+struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
 		void __iomem *addr, const struct dpu_mdss_cfg *catalog)
 {
-	struct dpu_hw_pipe *hw_pipe;
+	struct dpu_hw_sspp *hw_pipe;
 	const struct dpu_sspp_cfg *cfg;
 
 	if (!addr || !catalog)
@@ -812,7 +812,7 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
 	return hw_pipe;
 }
 
-void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx)
+void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx)
 {
 	kfree(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 0c95b7e64f6c..084206da851b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -10,7 +10,7 @@
 #include "dpu_hw_util.h"
 #include "dpu_formats.h"
 
-struct dpu_hw_pipe;
+struct dpu_hw_sspp;
 
 /**
  * Flags
@@ -153,7 +153,7 @@ struct dpu_hw_pixel_ext {
 };
 
 /**
- * struct dpu_hw_pipe_cfg : Pipe description
+ * struct dpu_hw_sspp_cfg : SSPP configuration
  * @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
@@ -161,7 +161,7 @@ struct dpu_hw_pixel_ext {
  * @index:     index of the rectangle of SSPP
  * @mode:      parallel or time multiplex multirect mode
  */
-struct dpu_hw_pipe_cfg {
+struct dpu_hw_sspp_cfg {
 	struct dpu_hw_fmt_layout layout;
 	struct drm_rect src_rect;
 	struct drm_rect dst_rect;
@@ -214,7 +214,7 @@ struct dpu_hw_sspp_ops {
 	 * @flags: Extra flags for format config
 	 * @index: rectangle index in multirect
 	 */
-	void (*setup_format)(struct dpu_hw_pipe *ctx,
+	void (*setup_format)(struct dpu_hw_sspp *ctx,
 			const struct dpu_format *fmt, u32 flags,
 			enum dpu_sspp_multirect_index index);
 
@@ -224,8 +224,8 @@ struct dpu_hw_sspp_ops {
 	 * @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,
+	void (*setup_rects)(struct dpu_hw_sspp *ctx,
+			struct dpu_hw_sspp_cfg *cfg,
 			enum dpu_sspp_multirect_index index);
 
 	/**
@@ -233,7 +233,7 @@ struct dpu_hw_sspp_ops {
 	 * @ctx: Pointer to pipe context
 	 * @pe_ext: Pointer to pixel ext settings
 	 */
-	void (*setup_pe)(struct dpu_hw_pipe *ctx,
+	void (*setup_pe)(struct dpu_hw_sspp *ctx,
 			struct dpu_hw_pixel_ext *pe_ext);
 
 	/**
@@ -242,8 +242,8 @@ struct dpu_hw_sspp_ops {
 	 * @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,
+	void (*setup_sourceaddress)(struct dpu_hw_sspp *ctx,
+			struct dpu_hw_sspp_cfg *cfg,
 			enum dpu_sspp_multirect_index index);
 
 	/**
@@ -251,7 +251,7 @@ struct dpu_hw_sspp_ops {
 	 * @ctx: Pointer to pipe context
 	 * @data: Pointer to config structure
 	 */
-	void (*setup_csc)(struct dpu_hw_pipe *ctx, const struct dpu_csc_cfg *data);
+	void (*setup_csc)(struct dpu_hw_sspp *ctx, const struct dpu_csc_cfg *data);
 
 	/**
 	 * setup_solidfill - enable/disable colorfill
@@ -260,7 +260,7 @@ struct dpu_hw_sspp_ops {
 	 * @flags: Pipe flags
 	 * @index: rectangle index in multirect
 	 */
-	void (*setup_solidfill)(struct dpu_hw_pipe *ctx, u32 color,
+	void (*setup_solidfill)(struct dpu_hw_sspp *ctx, u32 color,
 			enum dpu_sspp_multirect_index index);
 
 	/**
@@ -270,7 +270,7 @@ struct dpu_hw_sspp_ops {
 	 * @mode: parallel fetch / time multiplex multirect mode
 	 */
 
-	void (*setup_multirect)(struct dpu_hw_pipe *ctx,
+	void (*setup_multirect)(struct dpu_hw_sspp *ctx,
 			enum dpu_sspp_multirect_index index,
 			enum dpu_sspp_multirect_mode mode);
 
@@ -279,7 +279,7 @@ struct dpu_hw_sspp_ops {
 	 * @ctx: Pointer to pipe context
 	 * @cfg: Pointer to config structure
 	 */
-	void (*setup_sharpening)(struct dpu_hw_pipe *ctx,
+	void (*setup_sharpening)(struct dpu_hw_sspp *ctx,
 			struct dpu_hw_sharp_cfg *cfg);
 
 	/**
@@ -289,7 +289,7 @@ struct dpu_hw_sspp_ops {
 	 * @safe_lut: LUT for generate safe level based on fill level
 	 *
 	 */
-	void (*setup_danger_safe_lut)(struct dpu_hw_pipe *ctx,
+	void (*setup_danger_safe_lut)(struct dpu_hw_sspp *ctx,
 			u32 danger_lut,
 			u32 safe_lut);
 
@@ -299,7 +299,7 @@ struct dpu_hw_sspp_ops {
 	 * @creq_lut: LUT for generate creq level based on fill level
 	 *
 	 */
-	void (*setup_creq_lut)(struct dpu_hw_pipe *ctx,
+	void (*setup_creq_lut)(struct dpu_hw_sspp *ctx,
 			u64 creq_lut);
 
 	/**
@@ -308,7 +308,7 @@ struct dpu_hw_sspp_ops {
 	 * @cfg: Pointer to pipe QoS configuration
 	 *
 	 */
-	void (*setup_qos_ctrl)(struct dpu_hw_pipe *ctx,
+	void (*setup_qos_ctrl)(struct dpu_hw_sspp *ctx,
 			struct dpu_hw_pipe_qos_cfg *cfg);
 
 	/**
@@ -316,7 +316,7 @@ struct dpu_hw_sspp_ops {
 	 * @ctx: Pointer to pipe context
 	 * @cfg: Pointer to histogram configuration
 	 */
-	void (*setup_histogram)(struct dpu_hw_pipe *ctx,
+	void (*setup_histogram)(struct dpu_hw_sspp *ctx,
 			void *cfg);
 
 	/**
@@ -325,15 +325,15 @@ struct dpu_hw_sspp_ops {
 	 * @pipe_cfg: Pointer to pipe configuration
 	 * @scaler_cfg: Pointer to scaler configuration
 	 */
-	void (*setup_scaler)(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_cfg *pipe_cfg,
+	void (*setup_scaler)(struct dpu_hw_sspp *ctx,
+		struct dpu_hw_sspp_cfg *pipe_cfg,
 		void *scaler_cfg);
 
 	/**
 	 * get_scaler_ver - get scaler h/w version
 	 * @ctx: Pointer to pipe context
 	 */
-	u32 (*get_scaler_ver)(struct dpu_hw_pipe *ctx);
+	u32 (*get_scaler_ver)(struct dpu_hw_sspp *ctx);
 
 	/**
 	 * setup_cdp - setup client driven prefetch
@@ -341,13 +341,13 @@ struct dpu_hw_sspp_ops {
 	 * @cfg: Pointer to cdp configuration
 	 * @index: rectangle index in multirect
 	 */
-	void (*setup_cdp)(struct dpu_hw_pipe *ctx,
+	void (*setup_cdp)(struct dpu_hw_sspp *ctx,
 			struct dpu_hw_cdp_cfg *cfg,
 			enum dpu_sspp_multirect_index index);
 };
 
 /**
- * struct dpu_hw_pipe - pipe description
+ * struct dpu_hw_sspp - pipe description
  * @base: hardware block base structure
  * @hw: block hardware details
  * @catalog: back pointer to catalog
@@ -356,7 +356,7 @@ struct dpu_hw_sspp_ops {
  * @cap: pointer to layer_cfg
  * @ops: pointer to operations possible for this pipe
  */
-struct dpu_hw_pipe {
+struct dpu_hw_sspp {
 	struct dpu_hw_blk base;
 	struct dpu_hw_blk_reg_map hw;
 	const struct dpu_mdss_cfg *catalog;
@@ -378,7 +378,7 @@ struct dpu_kms;
  * @addr: Mapped register io address of MDP
  * @catalog : Pointer to mdss catalog data
  */
-struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
+struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
 		void __iomem *addr, const struct dpu_mdss_cfg *catalog);
 
 /**
@@ -386,10 +386,10 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
  * should be called during Hw pipe cleanup.
  * @ctx:  Pointer to SSPP driver context returned by dpu_hw_sspp_init
  */
-void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx);
+void dpu_hw_sspp_destroy(struct dpu_hw_sspp *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);
+int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, struct dentry *entry);
 
 #endif /*_DPU_HW_SSPP_H */
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index bfd5be89e8b8..5a4578ab62a6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -104,7 +104,7 @@ struct dpu_plane {
 
 	enum dpu_sspp pipe;
 
-	struct dpu_hw_pipe *pipe_hw;
+	struct dpu_hw_sspp *pipe_hw;
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
@@ -137,7 +137,7 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane)
  */
 static void _dpu_plane_calc_bw(struct drm_plane *plane,
 	struct drm_framebuffer *fb,
-	struct dpu_hw_pipe_cfg *pipe_cfg)
+	struct dpu_hw_sspp_cfg *pipe_cfg)
 {
 	struct dpu_plane_state *pstate;
 	struct drm_display_mode *mode;
@@ -192,7 +192,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
  * 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 void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_sspp_cfg *pipe_cfg)
 {
 	struct dpu_plane_state *pstate;
 	struct drm_display_mode *mode;
@@ -276,7 +276,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
  * @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 drm_framebuffer *fb, struct dpu_hw_sspp_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	const struct dpu_format *fmt = NULL;
@@ -419,7 +419,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
  * @pipe_cfg:		Pointer to pipe configuration
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
-		struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
+		struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_vbif_set_ot_params ot_params;
@@ -467,7 +467,7 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
 
 static void _dpu_plane_set_scanout(struct drm_plane *plane,
 		struct dpu_plane_state *pstate,
-		struct dpu_hw_pipe_cfg *pipe_cfg,
+		struct dpu_hw_sspp_cfg *pipe_cfg,
 		struct drm_framebuffer *fb)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
@@ -635,7 +635,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
 static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 		struct dpu_plane_state *pstate,
 		const struct dpu_format *fmt, bool color_fill,
-		struct dpu_hw_pipe_cfg *pipe_cfg)
+		struct dpu_hw_sspp_cfg *pipe_cfg)
 {
 	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
 	struct dpu_hw_scaler3_cfg scaler3_cfg;
@@ -691,7 +691,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 	const struct dpu_format *fmt;
 	const struct drm_plane *plane = &pdpu->base;
 	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-	struct dpu_hw_pipe_cfg pipe_cfg;
+	struct dpu_hw_sspp_cfg pipe_cfg;
 
 	DPU_DEBUG_PLANE(pdpu, "\n");
 
@@ -1129,9 +1129,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	bool is_rt_pipe;
 	const struct dpu_format *fmt =
 		to_dpu_format(msm_framebuffer_format(fb));
-	struct dpu_hw_pipe_cfg pipe_cfg;
+	struct dpu_hw_sspp_cfg pipe_cfg;
 
-	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
+	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_sspp_cfg));
 
 	_dpu_plane_set_scanout(plane, pstate, &pipe_cfg, fb);
 
-- 
2.39.1


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

* [PATCH v3 01/27] drm/msm/dpu: rename struct dpu_hw_pipe(_cfg) to dpu_hw_sspp(_cfg)
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

For all hardware blocks except SSPP the corresponding struct is named
after the block. Rename dpu_hw_pipe (SSPP structure) to dpu_hw_sspp.
Also rename struct dpu_hw_pipe_cfg to dpu_hw_sspp_cfg to follow this
change.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 48 +++++++++----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 52 ++++++++++-----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 20 ++++----
 3 files changed, 60 insertions(+), 60 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 4246ab0b3bee..5cf0803e4187 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -136,7 +136,7 @@
 #define TS_CLK			19200000
 
 
-static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
+static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx,
 		int s_id,
 		u32 *idx)
 {
@@ -168,7 +168,7 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
 	return rc;
 }
 
-static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp *ctx,
 		enum dpu_sspp_multirect_index index,
 		enum dpu_sspp_multirect_mode mode)
 {
@@ -197,7 +197,7 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
 	DPU_REG_WRITE(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx, mode_mask);
 }
 
-static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
+static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx,
 		u32 mask, u8 en)
 {
 	u32 idx;
@@ -218,7 +218,7 @@ static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
 	DPU_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode);
 }
 
-static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx,
+static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp *ctx,
 		u32 mask, u8 en)
 {
 	u32 idx;
@@ -239,7 +239,7 @@ 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,
+static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp *ctx,
 		const struct dpu_format *fmt, u32 flags,
 		enum dpu_sspp_multirect_index rect_mode)
 {
@@ -360,7 +360,7 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
 	DPU_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
 }
 
-static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
 		struct dpu_hw_pixel_ext *pe_ext)
 {
 	struct dpu_hw_blk_reg_map *c;
@@ -418,8 +418,8 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
 			tot_req_pixels[3]);
 }
 
-static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_cfg *sspp,
+static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
+		struct dpu_hw_sspp_cfg *sspp,
 		void *scaler_cfg)
 {
 	u32 idx;
@@ -434,7 +434,7 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
 			sspp->layout.format);
 }
 
-static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
+static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
 {
 	u32 idx;
 
@@ -447,8 +447,8 @@ 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,
+static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
+		struct dpu_hw_sspp_cfg *cfg,
 		enum dpu_sspp_multirect_index rect_index)
 {
 	struct dpu_hw_blk_reg_map *c;
@@ -516,8 +516,8 @@ 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,
+static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_sspp *ctx,
+		struct dpu_hw_sspp_cfg *cfg,
 		enum dpu_sspp_multirect_index rect_mode)
 {
 	int i;
@@ -543,7 +543,7 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_pipe *ctx,
 	}
 }
 
-static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
 		const struct dpu_csc_cfg *data)
 {
 	u32 idx;
@@ -560,7 +560,7 @@ 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
+static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_sspp *ctx, u32 color, enum
 		dpu_sspp_multirect_index rect_index)
 {
 	u32 idx;
@@ -575,7 +575,7 @@ static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, enum
 				color);
 }
 
-static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_sspp *ctx,
 			u32 danger_lut,
 			u32 safe_lut)
 {
@@ -588,7 +588,7 @@ static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
 	DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, safe_lut);
 }
 
-static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_sspp *ctx,
 			u64 creq_lut)
 {
 	u32 idx;
@@ -605,7 +605,7 @@ static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
 	}
 }
 
-static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe *ctx,
+static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx,
 		struct dpu_hw_pipe_qos_cfg *cfg)
 {
 	u32 idx;
@@ -630,7 +630,7 @@ 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,
+static void dpu_hw_sspp_setup_cdp(struct dpu_hw_sspp *ctx,
 		struct dpu_hw_cdp_cfg *cfg,
 		enum dpu_sspp_multirect_index index)
 {
@@ -661,7 +661,7 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
 	DPU_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl);
 }
 
-static void _setup_layer_ops(struct dpu_hw_pipe *c,
+static void _setup_layer_ops(struct dpu_hw_sspp *c,
 		unsigned long features)
 {
 	if (test_bit(DPU_SSPP_SRC, &features)) {
@@ -699,7 +699,7 @@ static void _setup_layer_ops(struct dpu_hw_pipe *c,
 }
 
 #ifdef CONFIG_DEBUG_FS
-int _dpu_hw_sspp_init_debugfs(struct dpu_hw_pipe *hw_pipe, struct dpu_kms *kms, struct dentry *entry)
+int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, struct dentry *entry)
 {
 	const struct dpu_sspp_cfg *cfg = hw_pipe->cap;
 	const struct dpu_sspp_sub_blks *sblk = cfg->sblk;
@@ -783,10 +783,10 @@ static const struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp,
 	return ERR_PTR(-ENOMEM);
 }
 
-struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
+struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
 		void __iomem *addr, const struct dpu_mdss_cfg *catalog)
 {
-	struct dpu_hw_pipe *hw_pipe;
+	struct dpu_hw_sspp *hw_pipe;
 	const struct dpu_sspp_cfg *cfg;
 
 	if (!addr || !catalog)
@@ -812,7 +812,7 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
 	return hw_pipe;
 }
 
-void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx)
+void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx)
 {
 	kfree(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 0c95b7e64f6c..084206da851b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -10,7 +10,7 @@
 #include "dpu_hw_util.h"
 #include "dpu_formats.h"
 
-struct dpu_hw_pipe;
+struct dpu_hw_sspp;
 
 /**
  * Flags
@@ -153,7 +153,7 @@ struct dpu_hw_pixel_ext {
 };
 
 /**
- * struct dpu_hw_pipe_cfg : Pipe description
+ * struct dpu_hw_sspp_cfg : SSPP configuration
  * @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
@@ -161,7 +161,7 @@ struct dpu_hw_pixel_ext {
  * @index:     index of the rectangle of SSPP
  * @mode:      parallel or time multiplex multirect mode
  */
-struct dpu_hw_pipe_cfg {
+struct dpu_hw_sspp_cfg {
 	struct dpu_hw_fmt_layout layout;
 	struct drm_rect src_rect;
 	struct drm_rect dst_rect;
@@ -214,7 +214,7 @@ struct dpu_hw_sspp_ops {
 	 * @flags: Extra flags for format config
 	 * @index: rectangle index in multirect
 	 */
-	void (*setup_format)(struct dpu_hw_pipe *ctx,
+	void (*setup_format)(struct dpu_hw_sspp *ctx,
 			const struct dpu_format *fmt, u32 flags,
 			enum dpu_sspp_multirect_index index);
 
@@ -224,8 +224,8 @@ struct dpu_hw_sspp_ops {
 	 * @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,
+	void (*setup_rects)(struct dpu_hw_sspp *ctx,
+			struct dpu_hw_sspp_cfg *cfg,
 			enum dpu_sspp_multirect_index index);
 
 	/**
@@ -233,7 +233,7 @@ struct dpu_hw_sspp_ops {
 	 * @ctx: Pointer to pipe context
 	 * @pe_ext: Pointer to pixel ext settings
 	 */
-	void (*setup_pe)(struct dpu_hw_pipe *ctx,
+	void (*setup_pe)(struct dpu_hw_sspp *ctx,
 			struct dpu_hw_pixel_ext *pe_ext);
 
 	/**
@@ -242,8 +242,8 @@ struct dpu_hw_sspp_ops {
 	 * @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,
+	void (*setup_sourceaddress)(struct dpu_hw_sspp *ctx,
+			struct dpu_hw_sspp_cfg *cfg,
 			enum dpu_sspp_multirect_index index);
 
 	/**
@@ -251,7 +251,7 @@ struct dpu_hw_sspp_ops {
 	 * @ctx: Pointer to pipe context
 	 * @data: Pointer to config structure
 	 */
-	void (*setup_csc)(struct dpu_hw_pipe *ctx, const struct dpu_csc_cfg *data);
+	void (*setup_csc)(struct dpu_hw_sspp *ctx, const struct dpu_csc_cfg *data);
 
 	/**
 	 * setup_solidfill - enable/disable colorfill
@@ -260,7 +260,7 @@ struct dpu_hw_sspp_ops {
 	 * @flags: Pipe flags
 	 * @index: rectangle index in multirect
 	 */
-	void (*setup_solidfill)(struct dpu_hw_pipe *ctx, u32 color,
+	void (*setup_solidfill)(struct dpu_hw_sspp *ctx, u32 color,
 			enum dpu_sspp_multirect_index index);
 
 	/**
@@ -270,7 +270,7 @@ struct dpu_hw_sspp_ops {
 	 * @mode: parallel fetch / time multiplex multirect mode
 	 */
 
-	void (*setup_multirect)(struct dpu_hw_pipe *ctx,
+	void (*setup_multirect)(struct dpu_hw_sspp *ctx,
 			enum dpu_sspp_multirect_index index,
 			enum dpu_sspp_multirect_mode mode);
 
@@ -279,7 +279,7 @@ struct dpu_hw_sspp_ops {
 	 * @ctx: Pointer to pipe context
 	 * @cfg: Pointer to config structure
 	 */
-	void (*setup_sharpening)(struct dpu_hw_pipe *ctx,
+	void (*setup_sharpening)(struct dpu_hw_sspp *ctx,
 			struct dpu_hw_sharp_cfg *cfg);
 
 	/**
@@ -289,7 +289,7 @@ struct dpu_hw_sspp_ops {
 	 * @safe_lut: LUT for generate safe level based on fill level
 	 *
 	 */
-	void (*setup_danger_safe_lut)(struct dpu_hw_pipe *ctx,
+	void (*setup_danger_safe_lut)(struct dpu_hw_sspp *ctx,
 			u32 danger_lut,
 			u32 safe_lut);
 
@@ -299,7 +299,7 @@ struct dpu_hw_sspp_ops {
 	 * @creq_lut: LUT for generate creq level based on fill level
 	 *
 	 */
-	void (*setup_creq_lut)(struct dpu_hw_pipe *ctx,
+	void (*setup_creq_lut)(struct dpu_hw_sspp *ctx,
 			u64 creq_lut);
 
 	/**
@@ -308,7 +308,7 @@ struct dpu_hw_sspp_ops {
 	 * @cfg: Pointer to pipe QoS configuration
 	 *
 	 */
-	void (*setup_qos_ctrl)(struct dpu_hw_pipe *ctx,
+	void (*setup_qos_ctrl)(struct dpu_hw_sspp *ctx,
 			struct dpu_hw_pipe_qos_cfg *cfg);
 
 	/**
@@ -316,7 +316,7 @@ struct dpu_hw_sspp_ops {
 	 * @ctx: Pointer to pipe context
 	 * @cfg: Pointer to histogram configuration
 	 */
-	void (*setup_histogram)(struct dpu_hw_pipe *ctx,
+	void (*setup_histogram)(struct dpu_hw_sspp *ctx,
 			void *cfg);
 
 	/**
@@ -325,15 +325,15 @@ struct dpu_hw_sspp_ops {
 	 * @pipe_cfg: Pointer to pipe configuration
 	 * @scaler_cfg: Pointer to scaler configuration
 	 */
-	void (*setup_scaler)(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_cfg *pipe_cfg,
+	void (*setup_scaler)(struct dpu_hw_sspp *ctx,
+		struct dpu_hw_sspp_cfg *pipe_cfg,
 		void *scaler_cfg);
 
 	/**
 	 * get_scaler_ver - get scaler h/w version
 	 * @ctx: Pointer to pipe context
 	 */
-	u32 (*get_scaler_ver)(struct dpu_hw_pipe *ctx);
+	u32 (*get_scaler_ver)(struct dpu_hw_sspp *ctx);
 
 	/**
 	 * setup_cdp - setup client driven prefetch
@@ -341,13 +341,13 @@ struct dpu_hw_sspp_ops {
 	 * @cfg: Pointer to cdp configuration
 	 * @index: rectangle index in multirect
 	 */
-	void (*setup_cdp)(struct dpu_hw_pipe *ctx,
+	void (*setup_cdp)(struct dpu_hw_sspp *ctx,
 			struct dpu_hw_cdp_cfg *cfg,
 			enum dpu_sspp_multirect_index index);
 };
 
 /**
- * struct dpu_hw_pipe - pipe description
+ * struct dpu_hw_sspp - pipe description
  * @base: hardware block base structure
  * @hw: block hardware details
  * @catalog: back pointer to catalog
@@ -356,7 +356,7 @@ struct dpu_hw_sspp_ops {
  * @cap: pointer to layer_cfg
  * @ops: pointer to operations possible for this pipe
  */
-struct dpu_hw_pipe {
+struct dpu_hw_sspp {
 	struct dpu_hw_blk base;
 	struct dpu_hw_blk_reg_map hw;
 	const struct dpu_mdss_cfg *catalog;
@@ -378,7 +378,7 @@ struct dpu_kms;
  * @addr: Mapped register io address of MDP
  * @catalog : Pointer to mdss catalog data
  */
-struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
+struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
 		void __iomem *addr, const struct dpu_mdss_cfg *catalog);
 
 /**
@@ -386,10 +386,10 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
  * should be called during Hw pipe cleanup.
  * @ctx:  Pointer to SSPP driver context returned by dpu_hw_sspp_init
  */
-void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx);
+void dpu_hw_sspp_destroy(struct dpu_hw_sspp *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);
+int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, struct dentry *entry);
 
 #endif /*_DPU_HW_SSPP_H */
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index bfd5be89e8b8..5a4578ab62a6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -104,7 +104,7 @@ struct dpu_plane {
 
 	enum dpu_sspp pipe;
 
-	struct dpu_hw_pipe *pipe_hw;
+	struct dpu_hw_sspp *pipe_hw;
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
@@ -137,7 +137,7 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane)
  */
 static void _dpu_plane_calc_bw(struct drm_plane *plane,
 	struct drm_framebuffer *fb,
-	struct dpu_hw_pipe_cfg *pipe_cfg)
+	struct dpu_hw_sspp_cfg *pipe_cfg)
 {
 	struct dpu_plane_state *pstate;
 	struct drm_display_mode *mode;
@@ -192,7 +192,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
  * 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 void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_sspp_cfg *pipe_cfg)
 {
 	struct dpu_plane_state *pstate;
 	struct drm_display_mode *mode;
@@ -276,7 +276,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
  * @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 drm_framebuffer *fb, struct dpu_hw_sspp_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	const struct dpu_format *fmt = NULL;
@@ -419,7 +419,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
  * @pipe_cfg:		Pointer to pipe configuration
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
-		struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
+		struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_vbif_set_ot_params ot_params;
@@ -467,7 +467,7 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
 
 static void _dpu_plane_set_scanout(struct drm_plane *plane,
 		struct dpu_plane_state *pstate,
-		struct dpu_hw_pipe_cfg *pipe_cfg,
+		struct dpu_hw_sspp_cfg *pipe_cfg,
 		struct drm_framebuffer *fb)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
@@ -635,7 +635,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
 static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 		struct dpu_plane_state *pstate,
 		const struct dpu_format *fmt, bool color_fill,
-		struct dpu_hw_pipe_cfg *pipe_cfg)
+		struct dpu_hw_sspp_cfg *pipe_cfg)
 {
 	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
 	struct dpu_hw_scaler3_cfg scaler3_cfg;
@@ -691,7 +691,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 	const struct dpu_format *fmt;
 	const struct drm_plane *plane = &pdpu->base;
 	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-	struct dpu_hw_pipe_cfg pipe_cfg;
+	struct dpu_hw_sspp_cfg pipe_cfg;
 
 	DPU_DEBUG_PLANE(pdpu, "\n");
 
@@ -1129,9 +1129,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	bool is_rt_pipe;
 	const struct dpu_format *fmt =
 		to_dpu_format(msm_framebuffer_format(fb));
-	struct dpu_hw_pipe_cfg pipe_cfg;
+	struct dpu_hw_sspp_cfg pipe_cfg;
 
-	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
+	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_sspp_cfg));
 
 	_dpu_plane_set_scanout(plane, pstate, &pipe_cfg, fb);
 
-- 
2.39.1


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

* [PATCH v3 02/27] drm/msm/dpu: move SSPP allocation to the RM
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

Follow the example of all other hw blocks and initialize SSPP blocks in
Resource Manager.

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 17 ++++-------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c    | 22 ++++++++++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h    | 12 ++++++++++++
 3 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 5a4578ab62a6..b054055f120b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1275,8 +1275,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);
 	}
 }
@@ -1482,14 +1480,10 @@ 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);
+	pdpu->pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
+	if (!pdpu->pipe_hw || !pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
+		DPU_ERROR("[%u]SSPP is invalid\n", pipe);
 		goto clean_plane;
-	} else if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
-		DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
-		goto clean_sspp;
 	}
 
 	format_list = pdpu->pipe_hw->cap->sblk->format_list;
@@ -1499,7 +1493,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;
 
@@ -1532,9 +1526,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 396429e63756..53c644ca52ef 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_wb.h"
 #include "dpu_hw_dspp.h"
@@ -91,6 +92,9 @@ int dpu_rm_destroy(struct dpu_rm *rm)
 	for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++)
 		dpu_hw_wb_destroy(rm->hw_wb[i]);
 
+	for (i = 0; i < ARRAY_SIZE(rm->hw_sspp); i++)
+		dpu_hw_sspp_destroy(rm->hw_sspp[i]);
+
 	return 0;
 }
 
@@ -255,6 +259,24 @@ int dpu_rm_init(struct dpu_rm *rm,
 		rm->dsc_blks[dsc->id - DSC_0] = &hw->base;
 	}
 
+	for (i = 0; i < cat->sspp_count; i++) {
+		struct dpu_hw_sspp *hw;
+		const struct dpu_sspp_cfg *sspp = &cat->sspp[i];
+
+		if (sspp->id < SSPP_NONE || sspp->id >= SSPP_MAX) {
+			DPU_ERROR("skip intf %d with invalid id\n", sspp->id);
+			continue;
+		}
+
+		hw = dpu_hw_sspp_init(sspp->id, mmio, cat);
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed sspp object creation: err %d\n", rc);
+			goto fail;
+		}
+		rm->hw_sspp[sspp->id - SSPP_NONE] = hw;
+	}
+
 	return 0;
 
 fail:
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 59de72b381f9..d62c2edb2460 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -21,6 +21,7 @@ struct dpu_global_state;
  * @hw_intf: array of intf hardware resources
  * @hw_wb: array of wb hardware resources
  * @dspp_blks: array of dspp hardware resources
+ * @hw_sspp: array of sspp hardware resources
  */
 struct dpu_rm {
 	struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
@@ -31,6 +32,7 @@ struct dpu_rm {
 	struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
 	struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
 	struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];
+	struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE];
 };
 
 /**
@@ -108,5 +110,15 @@ static inline struct dpu_hw_wb *dpu_rm_get_wb(struct dpu_rm *rm, enum dpu_wb wb_
 	return rm->hw_wb[wb_idx - WB_0];
 }
 
+/**
+ * dpu_rm_get_sspp - Return a struct dpu_hw_sspp instance given it's index.
+ * @rm: DPU Resource Manager handle
+ * @sspp_idx: SSPP index
+ */
+static inline struct dpu_hw_sspp *dpu_rm_get_sspp(struct dpu_rm *rm, enum dpu_sspp sspp_idx)
+{
+	return rm->hw_sspp[sspp_idx - SSPP_NONE];
+}
+
 #endif /* __DPU_RM_H__ */
 
-- 
2.39.1


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

* [PATCH v3 02/27] drm/msm/dpu: move SSPP allocation to the RM
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

Follow the example of all other hw blocks and initialize SSPP blocks in
Resource Manager.

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 17 ++++-------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c    | 22 ++++++++++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h    | 12 ++++++++++++
 3 files changed, 38 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 5a4578ab62a6..b054055f120b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1275,8 +1275,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);
 	}
 }
@@ -1482,14 +1480,10 @@ 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);
+	pdpu->pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
+	if (!pdpu->pipe_hw || !pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
+		DPU_ERROR("[%u]SSPP is invalid\n", pipe);
 		goto clean_plane;
-	} else if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
-		DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
-		goto clean_sspp;
 	}
 
 	format_list = pdpu->pipe_hw->cap->sblk->format_list;
@@ -1499,7 +1493,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;
 
@@ -1532,9 +1526,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 396429e63756..53c644ca52ef 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_wb.h"
 #include "dpu_hw_dspp.h"
@@ -91,6 +92,9 @@ int dpu_rm_destroy(struct dpu_rm *rm)
 	for (i = 0; i < ARRAY_SIZE(rm->hw_wb); i++)
 		dpu_hw_wb_destroy(rm->hw_wb[i]);
 
+	for (i = 0; i < ARRAY_SIZE(rm->hw_sspp); i++)
+		dpu_hw_sspp_destroy(rm->hw_sspp[i]);
+
 	return 0;
 }
 
@@ -255,6 +259,24 @@ int dpu_rm_init(struct dpu_rm *rm,
 		rm->dsc_blks[dsc->id - DSC_0] = &hw->base;
 	}
 
+	for (i = 0; i < cat->sspp_count; i++) {
+		struct dpu_hw_sspp *hw;
+		const struct dpu_sspp_cfg *sspp = &cat->sspp[i];
+
+		if (sspp->id < SSPP_NONE || sspp->id >= SSPP_MAX) {
+			DPU_ERROR("skip intf %d with invalid id\n", sspp->id);
+			continue;
+		}
+
+		hw = dpu_hw_sspp_init(sspp->id, mmio, cat);
+		if (IS_ERR(hw)) {
+			rc = PTR_ERR(hw);
+			DPU_ERROR("failed sspp object creation: err %d\n", rc);
+			goto fail;
+		}
+		rm->hw_sspp[sspp->id - SSPP_NONE] = hw;
+	}
+
 	return 0;
 
 fail:
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
index 59de72b381f9..d62c2edb2460 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h
@@ -21,6 +21,7 @@ struct dpu_global_state;
  * @hw_intf: array of intf hardware resources
  * @hw_wb: array of wb hardware resources
  * @dspp_blks: array of dspp hardware resources
+ * @hw_sspp: array of sspp hardware resources
  */
 struct dpu_rm {
 	struct dpu_hw_blk *pingpong_blks[PINGPONG_MAX - PINGPONG_0];
@@ -31,6 +32,7 @@ struct dpu_rm {
 	struct dpu_hw_blk *dspp_blks[DSPP_MAX - DSPP_0];
 	struct dpu_hw_blk *merge_3d_blks[MERGE_3D_MAX - MERGE_3D_0];
 	struct dpu_hw_blk *dsc_blks[DSC_MAX - DSC_0];
+	struct dpu_hw_sspp *hw_sspp[SSPP_MAX - SSPP_NONE];
 };
 
 /**
@@ -108,5 +110,15 @@ static inline struct dpu_hw_wb *dpu_rm_get_wb(struct dpu_rm *rm, enum dpu_wb wb_
 	return rm->hw_wb[wb_idx - WB_0];
 }
 
+/**
+ * dpu_rm_get_sspp - Return a struct dpu_hw_sspp instance given it's index.
+ * @rm: DPU Resource Manager handle
+ * @sspp_idx: SSPP index
+ */
+static inline struct dpu_hw_sspp *dpu_rm_get_sspp(struct dpu_rm *rm, enum dpu_sspp sspp_idx)
+{
+	return rm->hw_sspp[sspp_idx - SSPP_NONE];
+}
+
 #endif /* __DPU_RM_H__ */
 
-- 
2.39.1


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

* [PATCH v3 03/27] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

As SSPP blocks are now visible through dpu_kms->rm.sspp_blocks, move
SSPP debugfs creation from dpu_plane to dpu_kms. We are going to break
the 1:1 correspondence between planes and SSPPs, so it makes no sense
anymore to create SSPP debugfs entries in dpu_plane.c

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     | 18 ++++++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 16 ----------------
 3 files changed, 18 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 084206da851b..00aedad975ca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -388,7 +388,6 @@ struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
  */
 void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx);
 
-void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root);
 int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *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 a683bd9b5a04..0d2ef83c38ea 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -250,6 +250,24 @@ void dpu_debugfs_create_regset32(const char *name, umode_t mode,
 	debugfs_create_file(name, mode, parent, regset, &dpu_regset32_fops);
 }
 
+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_sspp *hw = dpu_rm_get_sspp(&dpu_kms->rm, i);
+
+		if (!hw)
+			continue;
+
+		_dpu_hw_sspp_init_debugfs(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 b054055f120b..2b0ebdd4c207 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1399,22 +1399,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.39.1


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

* [PATCH v3 03/27] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	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. We are going to break
the 1:1 correspondence between planes and SSPPs, so it makes no sense
anymore to create SSPP debugfs entries in dpu_plane.c

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     | 18 ++++++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 16 ----------------
 3 files changed, 18 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 084206da851b..00aedad975ca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -388,7 +388,6 @@ struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
  */
 void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx);
 
-void dpu_debugfs_sspp_init(struct dpu_kms *dpu_kms, struct dentry *debugfs_root);
 int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *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 a683bd9b5a04..0d2ef83c38ea 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -250,6 +250,24 @@ void dpu_debugfs_create_regset32(const char *name, umode_t mode,
 	debugfs_create_file(name, mode, parent, regset, &dpu_regset32_fops);
 }
 
+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_sspp *hw = dpu_rm_get_sspp(&dpu_kms->rm, i);
+
+		if (!hw)
+			continue;
+
+		_dpu_hw_sspp_init_debugfs(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 b054055f120b..2b0ebdd4c207 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1399,22 +1399,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.39.1


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

* [PATCH v3 04/27] drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

The pipe's layout is not cached, corresponding data structure is zeroed
out each time in the dpu_plane_sspp_atomic_update(), right before the
call to _dpu_plane_set_scanout() -> dpu_format_populate_layout().

Drop plane_addr comparison against previous layout and corresponding
EAGAIN handling.

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 10 +---------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  4 +---
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
index d95540309d4d..ec1001e10f4f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
@@ -918,8 +918,7 @@ int dpu_format_populate_layout(
 		struct drm_framebuffer *fb,
 		struct dpu_hw_fmt_layout *layout)
 {
-	uint32_t plane_addr[DPU_MAX_PLANES];
-	int i, ret;
+	int ret;
 
 	if (!fb || !layout) {
 		DRM_ERROR("invalid arguments\n");
@@ -940,9 +939,6 @@ int dpu_format_populate_layout(
 	if (ret)
 		return ret;
 
-	for (i = 0; i < DPU_MAX_PLANES; ++i)
-		plane_addr[i] = layout->plane_addr[i];
-
 	/* Populate the addresses given the fb */
 	if (DPU_FORMAT_IS_UBWC(layout->format) ||
 			DPU_FORMAT_IS_TILE(layout->format))
@@ -950,10 +946,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 2b0ebdd4c207..d6518ef1beb2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -476,9 +476,7 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 	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)
+	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,
-- 
2.39.1


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

* [PATCH v3 04/27] drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

The pipe's layout is not cached, corresponding data structure is zeroed
out each time in the dpu_plane_sspp_atomic_update(), right before the
call to _dpu_plane_set_scanout() -> dpu_format_populate_layout().

Drop plane_addr comparison against previous layout and corresponding
EAGAIN handling.

Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 10 +---------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  4 +---
 2 files changed, 2 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
index d95540309d4d..ec1001e10f4f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c
@@ -918,8 +918,7 @@ int dpu_format_populate_layout(
 		struct drm_framebuffer *fb,
 		struct dpu_hw_fmt_layout *layout)
 {
-	uint32_t plane_addr[DPU_MAX_PLANES];
-	int i, ret;
+	int ret;
 
 	if (!fb || !layout) {
 		DRM_ERROR("invalid arguments\n");
@@ -940,9 +939,6 @@ int dpu_format_populate_layout(
 	if (ret)
 		return ret;
 
-	for (i = 0; i < DPU_MAX_PLANES; ++i)
-		plane_addr[i] = layout->plane_addr[i];
-
 	/* Populate the addresses given the fb */
 	if (DPU_FORMAT_IS_UBWC(layout->format) ||
 			DPU_FORMAT_IS_TILE(layout->format))
@@ -950,10 +946,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 2b0ebdd4c207..d6518ef1beb2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -476,9 +476,7 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 	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)
+	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,
-- 
2.39.1


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

* [PATCH v3 05/27] drm/msm/dpu: move pipe_hw to dpu_plane_state
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

In preparation to adding fully virtualized planes, move struct
dpu_hw_sspp instance from struct dpu_plane to struct dpu_plane_state, as
it will become a part of state (variable, changes during runtime) rather
than part of a plane (ideally should be statically allocated during boot).

The sspp pointer is set at the dpu_plane_reset(), since this is the
function which allocates the state. Once we have fully virtual
plane<->SSPP relationship, the SSPP will be allocated dynamically in the
dpu_plane_atomic_check() function.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index d6518ef1beb2..9eac02f53fc1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -104,7 +104,6 @@ struct dpu_plane {
 
 	enum dpu_sspp pipe;
 
-	struct dpu_hw_sspp *pipe_hw;
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
@@ -279,6 +278,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 		struct drm_framebuffer *fb, struct dpu_hw_sspp_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;
@@ -310,7 +310,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->hw_sspp->ops.setup_creq_lut(pstate->hw_sspp, qos_lut);
 }
 
 /**
@@ -322,6 +322,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;
 
@@ -361,7 +362,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->hw_sspp->ops.setup_danger_safe_lut(pstate->hw_sspp,
 			danger_lut, safe_lut);
 }
 
@@ -375,14 +376,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->hw_sspp->cap->sblk->creq_vblank;
 		pipe_qos_cfg.danger_vblank =
-				pdpu->pipe_hw->cap->sblk->danger_vblank;
+				pstate->hw_sspp->cap->sblk->danger_vblank;
 		pipe_qos_cfg.vblank_en = enable;
 	}
 
@@ -408,7 +410,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->hw_sspp->ops.setup_qos_ctrl(pstate->hw_sspp,
 			&pipe_qos_cfg);
 }
 
@@ -422,18 +424,19 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 		struct drm_crtc *crtc, struct dpu_hw_sspp_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->hw_sspp->cap->xin_id;
+	ot_params.num = pstate->hw_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 = pdpu->pipe_hw->cap->clk_ctrl;
+	ot_params.clk_ctrl = pstate->hw_sspp->cap->clk_ctrl;
 	ot_params.rd = true;
 
 	dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
@@ -446,14 +449,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->hw_sspp->cap->clk_ctrl;
+	qos_params.xin_id = pstate->hw_sspp->cap->xin_id;
+	qos_params.num = pstate->hw_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",
@@ -478,11 +482,11 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout);
 	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->hw_sspp->ops.setup_sourceaddress) {
+		trace_dpu_plane_set_scanout(pstate->hw_sspp->idx,
 					    &pipe_cfg->layout,
 					    pstate->multirect_index);
-		pdpu->pipe_hw->ops.setup_sourceaddress(pdpu->pipe_hw, pipe_cfg,
+		pstate->hw_sspp->ops.setup_sourceaddress(pstate->hw_sspp, pipe_cfg,
 						pstate->multirect_index);
 	}
 }
@@ -534,7 +538,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->hw_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;
@@ -607,6 +611,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) {
@@ -617,7 +622,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->hw_sspp->cap->features)
 		csc_ptr = &dpu_csc10_YUV2RGB_601L;
 	else
 		csc_ptr = &dpu_csc_YUV2RGB_601L;
@@ -660,8 +665,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 	_dpu_plane_setup_pixel_ext(&scaler3_cfg, &pixel_ext,
 			src_width, src_height, info->hsub, info->vsub);
 
-	if (pdpu->pipe_hw->ops.setup_pe)
-		pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
+	if (pstate->hw_sspp->ops.setup_pe)
+		pstate->hw_sspp->ops.setup_pe(pstate->hw_sspp,
 				&pixel_ext);
 
 	/**
@@ -669,9 +674,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->hw_sspp->ops.setup_scaler &&
 			pstate->multirect_index != DPU_SSPP_RECT_1)
-		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
+		pstate->hw_sspp->ops.setup_scaler(pstate->hw_sspp,
 				pipe_cfg,
 				&scaler3_cfg);
 }
@@ -700,8 +705,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->hw_sspp->ops.setup_solidfill) {
+		pstate->hw_sspp->ops.setup_solidfill(pstate->hw_sspp,
 				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
 				pstate->multirect_index);
 
@@ -715,13 +720,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->hw_sspp->ops.setup_format)
+			pstate->hw_sspp->ops.setup_format(pstate->hw_sspp,
 					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->hw_sspp->ops.setup_rects)
+			pstate->hw_sspp->ops.setup_rects(pstate->hw_sspp,
 					&pipe_cfg,
 					pstate->multirect_index);
 
@@ -973,8 +978,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	uint32_t min_src_size, max_linewidth;
 	unsigned int rotation;
 	uint32_t supported_rotations;
-	const struct dpu_sspp_cfg *pipe_hw_caps = pdpu->pipe_hw->cap;
-	const struct dpu_sspp_sub_blks *sblk = pdpu->pipe_hw->cap->sblk;
+	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->hw_sspp->cap;
+	const struct dpu_sspp_sub_blks *sblk = pstate->hw_sspp->cap->sblk;
 
 	if (new_plane_state->crtc)
 		crtc_state = drm_atomic_get_new_crtc_state(state,
@@ -1087,12 +1092,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->hw_sspp && pstate->hw_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)
-			pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, csc_ptr);
+			pstate->hw_sspp->ops.setup_csc(pstate->hw_sspp, csc_ptr);
 	}
 
 	/* flag h/w flush complete */
@@ -1162,21 +1167,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->hw_sspp->ops.setup_rects) {
+		pstate->hw_sspp->ops.setup_rects(pstate->hw_sspp,
 				&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->hw_sspp->ops.setup_multirect)
+		pstate->hw_sspp->ops.setup_multirect(
+				pstate->hw_sspp,
 				pstate->multirect_index,
 				pstate->multirect_mode);
 
-	if (pdpu->pipe_hw->ops.setup_format) {
+	if (pstate->hw_sspp->ops.setup_format) {
 		unsigned int rotation = pstate->rotation;
 
 		src_flags = 0x0;
@@ -1191,10 +1196,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			src_flags |= DPU_SSPP_ROT_90;
 
 		/* update format */
-		pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw, fmt, src_flags,
+		pstate->hw_sspp->ops.setup_format(pstate->hw_sspp, fmt, src_flags,
 				pstate->multirect_index);
 
-		if (pdpu->pipe_hw->ops.setup_cdp) {
+		if (pstate->hw_sspp->ops.setup_cdp) {
 			struct dpu_hw_cdp_cfg cdp_cfg;
 
 			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_cdp_cfg));
@@ -1208,7 +1213,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->hw_sspp->ops.setup_cdp(pstate->hw_sspp, &cdp_cfg, pstate->multirect_index);
 		}
 	}
 
@@ -1348,10 +1353,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->hw_sspp->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));
 }
@@ -1360,6 +1364,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu;
 	struct dpu_plane_state *pstate;
+	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
 	if (!plane) {
 		DPU_ERROR("invalid plane\n");
@@ -1381,6 +1386,12 @@ static void dpu_plane_reset(struct drm_plane *plane)
 		return;
 	}
 
+	/*
+	 * Set the SSPP here until we have proper virtualized DPU planes.
+	 * This is the place where the state is allocated, so fill it fully.
+	 */
+	pstate->hw_sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
+
 	__drm_atomic_helper_plane_reset(plane, &pstate->base);
 }
 
@@ -1445,6 +1456,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_sspp *pipe_hw;
 	uint32_t num_formats;
 	uint32_t supported_rotations;
 	int ret = -EINVAL;
@@ -1462,14 +1474,14 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	pdpu->pipe = pipe;
 
 	/* initialize underlying h/w driver */
-	pdpu->pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
-	if (!pdpu->pipe_hw || !pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
+	pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
+	if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) {
 		DPU_ERROR("[%u]SSPP is invalid\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,
@@ -1491,7 +1503,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 
 	supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
 
-	if (pdpu->pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION))
+	if (pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION))
 		supported_rotations |= DRM_MODE_ROTATE_MASK;
 
 	drm_plane_create_rotation_property(plane,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index b7b1b05199c2..08a4b6a99f51 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -18,6 +18,7 @@
  * struct dpu_plane_state: Define dpu extension of drm plane state object
  * @base:	base drm plane state object
  * @aspace:	pointer to address space for input/output buffers
+ * @hw_sspp:	pointer to corresponding SSPP instance
  * @stage:	assigned by crtc blender
  * @needs_qos_remap: qos remap settings need to be updated
  * @multirect_index: index of the rectangle of SSPP
@@ -31,6 +32,7 @@
 struct dpu_plane_state {
 	struct drm_plane_state base;
 	struct msm_gem_address_space *aspace;
+	struct dpu_hw_sspp *hw_sspp;
 	enum dpu_stage stage;
 	bool needs_qos_remap;
 	uint32_t multirect_index;
-- 
2.39.1


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

* [PATCH v3 05/27] drm/msm/dpu: move pipe_hw to dpu_plane_state
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

In preparation to adding fully virtualized planes, move struct
dpu_hw_sspp instance from struct dpu_plane to struct dpu_plane_state, as
it will become a part of state (variable, changes during runtime) rather
than part of a plane (ideally should be statically allocated during boot).

The sspp pointer is set at the dpu_plane_reset(), since this is the
function which allocates the state. Once we have fully virtual
plane<->SSPP relationship, the SSPP will be allocated dynamically in the
dpu_plane_atomic_check() function.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index d6518ef1beb2..9eac02f53fc1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -104,7 +104,6 @@ struct dpu_plane {
 
 	enum dpu_sspp pipe;
 
-	struct dpu_hw_sspp *pipe_hw;
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
@@ -279,6 +278,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 		struct drm_framebuffer *fb, struct dpu_hw_sspp_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;
@@ -310,7 +310,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->hw_sspp->ops.setup_creq_lut(pstate->hw_sspp, qos_lut);
 }
 
 /**
@@ -322,6 +322,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;
 
@@ -361,7 +362,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->hw_sspp->ops.setup_danger_safe_lut(pstate->hw_sspp,
 			danger_lut, safe_lut);
 }
 
@@ -375,14 +376,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->hw_sspp->cap->sblk->creq_vblank;
 		pipe_qos_cfg.danger_vblank =
-				pdpu->pipe_hw->cap->sblk->danger_vblank;
+				pstate->hw_sspp->cap->sblk->danger_vblank;
 		pipe_qos_cfg.vblank_en = enable;
 	}
 
@@ -408,7 +410,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->hw_sspp->ops.setup_qos_ctrl(pstate->hw_sspp,
 			&pipe_qos_cfg);
 }
 
@@ -422,18 +424,19 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 		struct drm_crtc *crtc, struct dpu_hw_sspp_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->hw_sspp->cap->xin_id;
+	ot_params.num = pstate->hw_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 = pdpu->pipe_hw->cap->clk_ctrl;
+	ot_params.clk_ctrl = pstate->hw_sspp->cap->clk_ctrl;
 	ot_params.rd = true;
 
 	dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
@@ -446,14 +449,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->hw_sspp->cap->clk_ctrl;
+	qos_params.xin_id = pstate->hw_sspp->cap->xin_id;
+	qos_params.num = pstate->hw_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",
@@ -478,11 +482,11 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout);
 	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->hw_sspp->ops.setup_sourceaddress) {
+		trace_dpu_plane_set_scanout(pstate->hw_sspp->idx,
 					    &pipe_cfg->layout,
 					    pstate->multirect_index);
-		pdpu->pipe_hw->ops.setup_sourceaddress(pdpu->pipe_hw, pipe_cfg,
+		pstate->hw_sspp->ops.setup_sourceaddress(pstate->hw_sspp, pipe_cfg,
 						pstate->multirect_index);
 	}
 }
@@ -534,7 +538,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->hw_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;
@@ -607,6 +611,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) {
@@ -617,7 +622,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->hw_sspp->cap->features)
 		csc_ptr = &dpu_csc10_YUV2RGB_601L;
 	else
 		csc_ptr = &dpu_csc_YUV2RGB_601L;
@@ -660,8 +665,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 	_dpu_plane_setup_pixel_ext(&scaler3_cfg, &pixel_ext,
 			src_width, src_height, info->hsub, info->vsub);
 
-	if (pdpu->pipe_hw->ops.setup_pe)
-		pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
+	if (pstate->hw_sspp->ops.setup_pe)
+		pstate->hw_sspp->ops.setup_pe(pstate->hw_sspp,
 				&pixel_ext);
 
 	/**
@@ -669,9 +674,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->hw_sspp->ops.setup_scaler &&
 			pstate->multirect_index != DPU_SSPP_RECT_1)
-		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
+		pstate->hw_sspp->ops.setup_scaler(pstate->hw_sspp,
 				pipe_cfg,
 				&scaler3_cfg);
 }
@@ -700,8 +705,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->hw_sspp->ops.setup_solidfill) {
+		pstate->hw_sspp->ops.setup_solidfill(pstate->hw_sspp,
 				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
 				pstate->multirect_index);
 
@@ -715,13 +720,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->hw_sspp->ops.setup_format)
+			pstate->hw_sspp->ops.setup_format(pstate->hw_sspp,
 					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->hw_sspp->ops.setup_rects)
+			pstate->hw_sspp->ops.setup_rects(pstate->hw_sspp,
 					&pipe_cfg,
 					pstate->multirect_index);
 
@@ -973,8 +978,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	uint32_t min_src_size, max_linewidth;
 	unsigned int rotation;
 	uint32_t supported_rotations;
-	const struct dpu_sspp_cfg *pipe_hw_caps = pdpu->pipe_hw->cap;
-	const struct dpu_sspp_sub_blks *sblk = pdpu->pipe_hw->cap->sblk;
+	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->hw_sspp->cap;
+	const struct dpu_sspp_sub_blks *sblk = pstate->hw_sspp->cap->sblk;
 
 	if (new_plane_state->crtc)
 		crtc_state = drm_atomic_get_new_crtc_state(state,
@@ -1087,12 +1092,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->hw_sspp && pstate->hw_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)
-			pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, csc_ptr);
+			pstate->hw_sspp->ops.setup_csc(pstate->hw_sspp, csc_ptr);
 	}
 
 	/* flag h/w flush complete */
@@ -1162,21 +1167,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->hw_sspp->ops.setup_rects) {
+		pstate->hw_sspp->ops.setup_rects(pstate->hw_sspp,
 				&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->hw_sspp->ops.setup_multirect)
+		pstate->hw_sspp->ops.setup_multirect(
+				pstate->hw_sspp,
 				pstate->multirect_index,
 				pstate->multirect_mode);
 
-	if (pdpu->pipe_hw->ops.setup_format) {
+	if (pstate->hw_sspp->ops.setup_format) {
 		unsigned int rotation = pstate->rotation;
 
 		src_flags = 0x0;
@@ -1191,10 +1196,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			src_flags |= DPU_SSPP_ROT_90;
 
 		/* update format */
-		pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw, fmt, src_flags,
+		pstate->hw_sspp->ops.setup_format(pstate->hw_sspp, fmt, src_flags,
 				pstate->multirect_index);
 
-		if (pdpu->pipe_hw->ops.setup_cdp) {
+		if (pstate->hw_sspp->ops.setup_cdp) {
 			struct dpu_hw_cdp_cfg cdp_cfg;
 
 			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_cdp_cfg));
@@ -1208,7 +1213,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->hw_sspp->ops.setup_cdp(pstate->hw_sspp, &cdp_cfg, pstate->multirect_index);
 		}
 	}
 
@@ -1348,10 +1353,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->hw_sspp->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));
 }
@@ -1360,6 +1364,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu;
 	struct dpu_plane_state *pstate;
+	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
 	if (!plane) {
 		DPU_ERROR("invalid plane\n");
@@ -1381,6 +1386,12 @@ static void dpu_plane_reset(struct drm_plane *plane)
 		return;
 	}
 
+	/*
+	 * Set the SSPP here until we have proper virtualized DPU planes.
+	 * This is the place where the state is allocated, so fill it fully.
+	 */
+	pstate->hw_sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
+
 	__drm_atomic_helper_plane_reset(plane, &pstate->base);
 }
 
@@ -1445,6 +1456,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_sspp *pipe_hw;
 	uint32_t num_formats;
 	uint32_t supported_rotations;
 	int ret = -EINVAL;
@@ -1462,14 +1474,14 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	pdpu->pipe = pipe;
 
 	/* initialize underlying h/w driver */
-	pdpu->pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
-	if (!pdpu->pipe_hw || !pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
+	pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
+	if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) {
 		DPU_ERROR("[%u]SSPP is invalid\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,
@@ -1491,7 +1503,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 
 	supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
 
-	if (pdpu->pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION))
+	if (pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION))
 		supported_rotations |= DRM_MODE_ROTATE_MASK;
 
 	drm_plane_create_rotation_property(plane,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index b7b1b05199c2..08a4b6a99f51 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -18,6 +18,7 @@
  * struct dpu_plane_state: Define dpu extension of drm plane state object
  * @base:	base drm plane state object
  * @aspace:	pointer to address space for input/output buffers
+ * @hw_sspp:	pointer to corresponding SSPP instance
  * @stage:	assigned by crtc blender
  * @needs_qos_remap: qos remap settings need to be updated
  * @multirect_index: index of the rectangle of SSPP
@@ -31,6 +32,7 @@
 struct dpu_plane_state {
 	struct drm_plane_state base;
 	struct msm_gem_address_space *aspace;
+	struct dpu_hw_sspp *hw_sspp;
 	enum dpu_stage stage;
 	bool needs_qos_remap;
 	uint32_t multirect_index;
-- 
2.39.1


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

* [PATCH v3 06/27] drm/msm/dpu: drop dpu_plane_pipe function
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	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.

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  | 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 f29a339a3705..eff1a3cc1cec 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -431,7 +431,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->hw_sspp->idx;
 		set_bit(sspp_idx, fetch_active);
 
 		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
@@ -1202,7 +1202,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		pstates[cnt].dpu_pstate = dpu_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)->hw_sspp->idx;
 
 		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 9eac02f53fc1..c2b34d97e065 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1441,11 +1441,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 08a4b6a99f51..25e261cabadc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -59,13 +59,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.39.1


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

* [PATCH v3 06/27] drm/msm/dpu: drop dpu_plane_pipe function
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

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

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  | 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 f29a339a3705..eff1a3cc1cec 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -431,7 +431,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->hw_sspp->idx;
 		set_bit(sspp_idx, fetch_active);
 
 		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
@@ -1202,7 +1202,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		pstates[cnt].dpu_pstate = dpu_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)->hw_sspp->idx;
 
 		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 9eac02f53fc1..c2b34d97e065 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1441,11 +1441,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 08a4b6a99f51..25e261cabadc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -59,13 +59,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.39.1


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

* [PATCH v3 07/27] drm/msm/dpu: introduce struct dpu_sw_pipe
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

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

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    |   9 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  16 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 131 ++++++++++----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   |   6 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  10 +-
 5 files changed, 89 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index eff1a3cc1cec..037347e51eb8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -431,7 +431,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		pstate = to_dpu_plane_state(state);
 		fb = state->fb;
 
-		sspp_idx = pstate->hw_sspp->idx;
+		sspp_idx = pstate->pipe.sspp->idx;
 		set_bit(sspp_idx, fetch_active);
 
 		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
@@ -450,11 +450,10 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		stage_cfg->stage[pstate->stage][stage_idx] =
 					sspp_idx;
 		stage_cfg->multirect_index[pstate->stage][stage_idx] =
-					pstate->multirect_index;
+					pstate->pipe.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);
 
@@ -1202,7 +1201,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		pstates[cnt].dpu_pstate = dpu_pstate;
 		pstates[cnt].drm_pstate = pstate;
 		pstates[cnt].stage = pstate->normalized_zpos;
-		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->hw_sspp->idx;
+		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx;
 
 		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
@@ -1475,7 +1474,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 00aedad975ca..a3bdce6e20df 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -158,15 +158,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_sspp_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;
 };
 
 /**
@@ -201,6 +197,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_sspp *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 c2b34d97e065..229447ca1e0f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -251,7 +251,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 {
@@ -310,7 +310,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->hw_sspp->ops.setup_creq_lut(pstate->hw_sspp, qos_lut);
+	pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut);
 }
 
 /**
@@ -362,7 +362,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
 		danger_lut,
 		safe_lut);
 
-	pstate->hw_sspp->ops.setup_danger_safe_lut(pstate->hw_sspp,
+	pstate->pipe.sspp->ops.setup_danger_safe_lut(pstate->pipe.sspp,
 			danger_lut, safe_lut);
 }
 
@@ -382,9 +382,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->hw_sspp->cap->sblk->creq_vblank;
+		pipe_qos_cfg.creq_vblank = pstate->pipe.sspp->cap->sblk->creq_vblank;
 		pipe_qos_cfg.danger_vblank =
-				pstate->hw_sspp->cap->sblk->danger_vblank;
+				pstate->pipe.sspp->cap->sblk->danger_vblank;
 		pipe_qos_cfg.vblank_en = enable;
 	}
 
@@ -410,7 +410,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 		pipe_qos_cfg.danger_vblank,
 		pdpu->is_rt_pipe);
 
-	pstate->hw_sspp->ops.setup_qos_ctrl(pstate->hw_sspp,
+	pstate->pipe.sspp->ops.setup_qos_ctrl(pstate->pipe.sspp,
 			&pipe_qos_cfg);
 }
 
@@ -429,14 +429,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->hw_sspp->cap->xin_id;
-	ot_params.num = pstate->hw_sspp->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->hw_sspp->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);
@@ -455,9 +455,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->hw_sspp->cap->clk_ctrl;
-	qos_params.xin_id = pstate->hw_sspp->cap->xin_id;
-	qos_params.num = pstate->hw_sspp->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",
@@ -482,12 +482,12 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout);
 	if (ret)
 		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-	else if (pstate->hw_sspp->ops.setup_sourceaddress) {
-		trace_dpu_plane_set_scanout(pstate->hw_sspp->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->hw_sspp->ops.setup_sourceaddress(pstate->hw_sspp, pipe_cfg,
-						pstate->multirect_index);
+					    pstate->pipe.multirect_index);
+		pstate->pipe.sspp->ops.setup_sourceaddress(pstate->pipe.sspp, pipe_cfg,
+						pstate->pipe.multirect_index);
 	}
 }
 
@@ -538,7 +538,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 			scale_cfg->src_height[i] /= chroma_subsmpl_v;
 		}
 
-		if (pstate->hw_sspp->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;
@@ -622,7 +622,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->hw_sspp->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;
@@ -665,8 +665,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 	_dpu_plane_setup_pixel_ext(&scaler3_cfg, &pixel_ext,
 			src_width, src_height, info->hsub, info->vsub);
 
-	if (pstate->hw_sspp->ops.setup_pe)
-		pstate->hw_sspp->ops.setup_pe(pstate->hw_sspp,
+	if (pstate->pipe.sspp->ops.setup_pe)
+		pstate->pipe.sspp->ops.setup_pe(pstate->pipe.sspp,
 				&pixel_ext);
 
 	/**
@@ -674,9 +674,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->hw_sspp->ops.setup_scaler &&
-			pstate->multirect_index != DPU_SSPP_RECT_1)
-		pstate->hw_sspp->ops.setup_scaler(pstate->hw_sspp,
+	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);
 }
@@ -705,10 +705,10 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
 
 	/* update sspp */
-	if (fmt && pstate->hw_sspp->ops.setup_solidfill) {
-		pstate->hw_sspp->ops.setup_solidfill(pstate->hw_sspp,
+	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;
@@ -720,15 +720,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->hw_sspp->ops.setup_format)
-			pstate->hw_sspp->ops.setup_format(pstate->hw_sspp,
+		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->hw_sspp->ops.setup_rects)
-			pstate->hw_sspp->ops.setup_rects(pstate->hw_sspp,
+		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);
 	}
@@ -740,8 +740,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)
@@ -823,8 +823,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;
 	}
@@ -834,8 +834,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",
@@ -845,13 +845,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;
 }
 
@@ -978,8 +978,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	uint32_t min_src_size, max_linewidth;
 	unsigned int rotation;
 	uint32_t supported_rotations;
-	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->hw_sspp->cap;
-	const struct dpu_sspp_sub_blks *sblk = pstate->hw_sspp->cap->sblk;
+	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
+	const struct dpu_sspp_sub_blks *sblk = pstate->pipe.sspp->cap->sblk;
 
 	if (new_plane_state->crtc)
 		crtc_state = drm_atomic_get_new_crtc_state(state,
@@ -1092,12 +1092,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->hw_sspp && pstate->hw_sspp->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->hw_sspp->ops.setup_csc(pstate->hw_sspp, csc_ptr);
+			pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, csc_ptr);
 	}
 
 	/* flag h/w flush complete */
@@ -1127,6 +1127,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;
@@ -1167,21 +1168,21 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		return;
 	}
 
-	if (pstate->hw_sspp->ops.setup_rects) {
-		pstate->hw_sspp->ops.setup_rects(pstate->hw_sspp,
+	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->hw_sspp->ops.setup_multirect)
-		pstate->hw_sspp->ops.setup_multirect(
-				pstate->hw_sspp,
-				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->hw_sspp->ops.setup_format) {
+	if (pipe->sspp->ops.setup_format) {
 		unsigned int rotation = pstate->rotation;
 
 		src_flags = 0x0;
@@ -1196,10 +1197,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			src_flags |= DPU_SSPP_ROT_90;
 
 		/* update format */
-		pstate->hw_sspp->ops.setup_format(pstate->hw_sspp, fmt, src_flags,
-				pstate->multirect_index);
+		pipe->sspp->ops.setup_format(pipe->sspp, fmt, src_flags,
+				pipe->multirect_index);
 
-		if (pstate->hw_sspp->ops.setup_cdp) {
+		if (pipe->sspp->ops.setup_cdp) {
 			struct dpu_hw_cdp_cfg cdp_cfg;
 
 			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_cdp_cfg));
@@ -1213,7 +1214,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->hw_sspp->ops.setup_cdp(pstate->hw_sspp, &cdp_cfg, pstate->multirect_index);
+			pipe->sspp->ops.setup_cdp(pipe->sspp, &cdp_cfg, pipe->multirect_index);
 		}
 	}
 
@@ -1241,7 +1242,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;
 }
@@ -1355,9 +1356,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->hw_sspp->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)
@@ -1390,7 +1391,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
 	 * Set the SSPP here until we have proper virtualized DPU planes.
 	 * This is the place where the state is allocated, so fill it fully.
 	 */
-	pstate->hw_sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
+	pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
 
 	__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 25e261cabadc..228db401e905 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -18,7 +18,7 @@
  * struct dpu_plane_state: Define dpu extension of drm plane state object
  * @base:	base drm plane state object
  * @aspace:	pointer to address space for input/output buffers
- * @hw_sspp:	pointer to corresponding SSPP instance
+ * @pipe:	software pipe description
  * @stage:	assigned by crtc blender
  * @needs_qos_remap: qos remap settings need to be updated
  * @multirect_index: index of the rectangle of SSPP
@@ -32,11 +32,9 @@
 struct dpu_plane_state {
 	struct drm_plane_state base;
 	struct msm_gem_address_space *aspace;
-	struct dpu_hw_sspp *hw_sspp;
+	struct dpu_sw_pipe pipe;
 	enum dpu_stage stage;
 	bool needs_qos_remap;
-	uint32_t multirect_index;
-	uint32_t multirect_mode;
 	bool pending;
 
 	u64 plane_fetch_bw;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
index 76169f406505..d7059972499f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -633,9 +633,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		)
@@ -659,9 +659,9 @@ 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->sspp = pstate->pipe.sspp->idx;
+		__entry->multirect_idx = pstate->pipe.multirect_index;
+		__entry->multirect_mode = pstate->pipe.multirect_mode;
 		__entry->pixel_format = pixel_format;
 		__entry->modifier = modifier;
 	),
-- 
2.39.1


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

* [PATCH v3 07/27] drm/msm/dpu: introduce struct dpu_sw_pipe
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

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

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    |   9 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  16 ++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 131 ++++++++++----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   |   6 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  10 +-
 5 files changed, 89 insertions(+), 83 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index eff1a3cc1cec..037347e51eb8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -431,7 +431,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		pstate = to_dpu_plane_state(state);
 		fb = state->fb;
 
-		sspp_idx = pstate->hw_sspp->idx;
+		sspp_idx = pstate->pipe.sspp->idx;
 		set_bit(sspp_idx, fetch_active);
 
 		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
@@ -450,11 +450,10 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		stage_cfg->stage[pstate->stage][stage_idx] =
 					sspp_idx;
 		stage_cfg->multirect_index[pstate->stage][stage_idx] =
-					pstate->multirect_index;
+					pstate->pipe.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);
 
@@ -1202,7 +1201,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		pstates[cnt].dpu_pstate = dpu_pstate;
 		pstates[cnt].drm_pstate = pstate;
 		pstates[cnt].stage = pstate->normalized_zpos;
-		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->hw_sspp->idx;
+		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx;
 
 		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
@@ -1475,7 +1474,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 00aedad975ca..a3bdce6e20df 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -158,15 +158,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_sspp_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;
 };
 
 /**
@@ -201,6 +197,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_sspp *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 c2b34d97e065..229447ca1e0f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -251,7 +251,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 {
@@ -310,7 +310,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->hw_sspp->ops.setup_creq_lut(pstate->hw_sspp, qos_lut);
+	pstate->pipe.sspp->ops.setup_creq_lut(pstate->pipe.sspp, qos_lut);
 }
 
 /**
@@ -362,7 +362,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
 		danger_lut,
 		safe_lut);
 
-	pstate->hw_sspp->ops.setup_danger_safe_lut(pstate->hw_sspp,
+	pstate->pipe.sspp->ops.setup_danger_safe_lut(pstate->pipe.sspp,
 			danger_lut, safe_lut);
 }
 
@@ -382,9 +382,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->hw_sspp->cap->sblk->creq_vblank;
+		pipe_qos_cfg.creq_vblank = pstate->pipe.sspp->cap->sblk->creq_vblank;
 		pipe_qos_cfg.danger_vblank =
-				pstate->hw_sspp->cap->sblk->danger_vblank;
+				pstate->pipe.sspp->cap->sblk->danger_vblank;
 		pipe_qos_cfg.vblank_en = enable;
 	}
 
@@ -410,7 +410,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 		pipe_qos_cfg.danger_vblank,
 		pdpu->is_rt_pipe);
 
-	pstate->hw_sspp->ops.setup_qos_ctrl(pstate->hw_sspp,
+	pstate->pipe.sspp->ops.setup_qos_ctrl(pstate->pipe.sspp,
 			&pipe_qos_cfg);
 }
 
@@ -429,14 +429,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->hw_sspp->cap->xin_id;
-	ot_params.num = pstate->hw_sspp->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->hw_sspp->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);
@@ -455,9 +455,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->hw_sspp->cap->clk_ctrl;
-	qos_params.xin_id = pstate->hw_sspp->cap->xin_id;
-	qos_params.num = pstate->hw_sspp->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",
@@ -482,12 +482,12 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout);
 	if (ret)
 		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-	else if (pstate->hw_sspp->ops.setup_sourceaddress) {
-		trace_dpu_plane_set_scanout(pstate->hw_sspp->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->hw_sspp->ops.setup_sourceaddress(pstate->hw_sspp, pipe_cfg,
-						pstate->multirect_index);
+					    pstate->pipe.multirect_index);
+		pstate->pipe.sspp->ops.setup_sourceaddress(pstate->pipe.sspp, pipe_cfg,
+						pstate->pipe.multirect_index);
 	}
 }
 
@@ -538,7 +538,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 			scale_cfg->src_height[i] /= chroma_subsmpl_v;
 		}
 
-		if (pstate->hw_sspp->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;
@@ -622,7 +622,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->hw_sspp->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;
@@ -665,8 +665,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 	_dpu_plane_setup_pixel_ext(&scaler3_cfg, &pixel_ext,
 			src_width, src_height, info->hsub, info->vsub);
 
-	if (pstate->hw_sspp->ops.setup_pe)
-		pstate->hw_sspp->ops.setup_pe(pstate->hw_sspp,
+	if (pstate->pipe.sspp->ops.setup_pe)
+		pstate->pipe.sspp->ops.setup_pe(pstate->pipe.sspp,
 				&pixel_ext);
 
 	/**
@@ -674,9 +674,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->hw_sspp->ops.setup_scaler &&
-			pstate->multirect_index != DPU_SSPP_RECT_1)
-		pstate->hw_sspp->ops.setup_scaler(pstate->hw_sspp,
+	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);
 }
@@ -705,10 +705,10 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
 
 	/* update sspp */
-	if (fmt && pstate->hw_sspp->ops.setup_solidfill) {
-		pstate->hw_sspp->ops.setup_solidfill(pstate->hw_sspp,
+	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;
@@ -720,15 +720,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->hw_sspp->ops.setup_format)
-			pstate->hw_sspp->ops.setup_format(pstate->hw_sspp,
+		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->hw_sspp->ops.setup_rects)
-			pstate->hw_sspp->ops.setup_rects(pstate->hw_sspp,
+		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);
 	}
@@ -740,8 +740,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)
@@ -823,8 +823,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;
 	}
@@ -834,8 +834,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",
@@ -845,13 +845,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;
 }
 
@@ -978,8 +978,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	uint32_t min_src_size, max_linewidth;
 	unsigned int rotation;
 	uint32_t supported_rotations;
-	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->hw_sspp->cap;
-	const struct dpu_sspp_sub_blks *sblk = pstate->hw_sspp->cap->sblk;
+	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
+	const struct dpu_sspp_sub_blks *sblk = pstate->pipe.sspp->cap->sblk;
 
 	if (new_plane_state->crtc)
 		crtc_state = drm_atomic_get_new_crtc_state(state,
@@ -1092,12 +1092,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->hw_sspp && pstate->hw_sspp->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->hw_sspp->ops.setup_csc(pstate->hw_sspp, csc_ptr);
+			pstate->pipe.sspp->ops.setup_csc(pstate->pipe.sspp, csc_ptr);
 	}
 
 	/* flag h/w flush complete */
@@ -1127,6 +1127,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;
@@ -1167,21 +1168,21 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		return;
 	}
 
-	if (pstate->hw_sspp->ops.setup_rects) {
-		pstate->hw_sspp->ops.setup_rects(pstate->hw_sspp,
+	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->hw_sspp->ops.setup_multirect)
-		pstate->hw_sspp->ops.setup_multirect(
-				pstate->hw_sspp,
-				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->hw_sspp->ops.setup_format) {
+	if (pipe->sspp->ops.setup_format) {
 		unsigned int rotation = pstate->rotation;
 
 		src_flags = 0x0;
@@ -1196,10 +1197,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			src_flags |= DPU_SSPP_ROT_90;
 
 		/* update format */
-		pstate->hw_sspp->ops.setup_format(pstate->hw_sspp, fmt, src_flags,
-				pstate->multirect_index);
+		pipe->sspp->ops.setup_format(pipe->sspp, fmt, src_flags,
+				pipe->multirect_index);
 
-		if (pstate->hw_sspp->ops.setup_cdp) {
+		if (pipe->sspp->ops.setup_cdp) {
 			struct dpu_hw_cdp_cfg cdp_cfg;
 
 			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_cdp_cfg));
@@ -1213,7 +1214,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->hw_sspp->ops.setup_cdp(pstate->hw_sspp, &cdp_cfg, pstate->multirect_index);
+			pipe->sspp->ops.setup_cdp(pipe->sspp, &cdp_cfg, pipe->multirect_index);
 		}
 	}
 
@@ -1241,7 +1242,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;
 }
@@ -1355,9 +1356,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->hw_sspp->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)
@@ -1390,7 +1391,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
 	 * Set the SSPP here until we have proper virtualized DPU planes.
 	 * This is the place where the state is allocated, so fill it fully.
 	 */
-	pstate->hw_sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
+	pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
 
 	__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 25e261cabadc..228db401e905 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -18,7 +18,7 @@
  * struct dpu_plane_state: Define dpu extension of drm plane state object
  * @base:	base drm plane state object
  * @aspace:	pointer to address space for input/output buffers
- * @hw_sspp:	pointer to corresponding SSPP instance
+ * @pipe:	software pipe description
  * @stage:	assigned by crtc blender
  * @needs_qos_remap: qos remap settings need to be updated
  * @multirect_index: index of the rectangle of SSPP
@@ -32,11 +32,9 @@
 struct dpu_plane_state {
 	struct drm_plane_state base;
 	struct msm_gem_address_space *aspace;
-	struct dpu_hw_sspp *hw_sspp;
+	struct dpu_sw_pipe pipe;
 	enum dpu_stage stage;
 	bool needs_qos_remap;
-	uint32_t multirect_index;
-	uint32_t multirect_mode;
 	bool pending;
 
 	u64 plane_fetch_bw;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
index 76169f406505..d7059972499f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -633,9 +633,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		)
@@ -659,9 +659,9 @@ 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->sspp = pstate->pipe.sspp->idx;
+		__entry->multirect_idx = pstate->pipe.multirect_index;
+		__entry->multirect_mode = pstate->pipe.multirect_mode;
 		__entry->pixel_format = pixel_format;
 		__entry->modifier = modifier;
 	),
-- 
2.39.1


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

* [PATCH v3 08/27] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

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

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.c | 59 +++++++++--------
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 46 +++++--------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 73 ++++++++++-----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  9 ++-
 4 files changed, 84 insertions(+), 103 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 5cf0803e4187..4d3ca8532563 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_sspp *ctx,
 	return rc;
 }
 
-static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp *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_sspp *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_sspp *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_sspp *ctx,
 /*
  * Setup source pixel format, flip,
  */
-static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp *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_sspp *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_sspp *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;
@@ -447,10 +447,10 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
 /*
  * dpu_hw_sspp_setup_rects()
  */
-static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
-		struct dpu_hw_sspp_cfg *cfg,
-		enum dpu_sspp_multirect_index rect_index)
+static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
+		struct dpu_hw_sspp_cfg *cfg)
 {
+	struct dpu_hw_sspp *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;
@@ -461,7 +461,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *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;
@@ -482,7 +483,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *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]) |
@@ -491,7 +492,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *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)|
@@ -516,21 +517,21 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
 	DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
-static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_sspp *ctx,
-		struct dpu_hw_sspp_cfg *cfg,
-		enum dpu_sspp_multirect_index rect_mode)
+static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
+		struct dpu_hw_sspp_cfg *cfg)
 {
+	struct dpu_hw_sspp *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,
@@ -560,15 +561,16 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
 	dpu_hw_csc_setup(&ctx->hw, idx, data, csc10);
 }
 
-static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_sspp *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_sspp *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,
@@ -630,10 +632,10 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx,
 	DPU_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL + idx, qos_ctrl);
 }
 
-static void dpu_hw_sspp_setup_cdp(struct dpu_hw_sspp *ctx,
-		struct dpu_hw_cdp_cfg *cfg,
-		enum dpu_sspp_multirect_index index)
+static void dpu_hw_sspp_setup_cdp(struct dpu_sw_pipe *pipe,
+		struct dpu_hw_cdp_cfg *cfg)
 {
+	struct dpu_hw_sspp *ctx = pipe->sspp;
 	u32 idx;
 	u32 cdp_cntl = 0;
 	u32 cdp_cntl_offset = 0;
@@ -644,7 +646,8 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_sspp *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 a3bdce6e20df..8d566ad1877e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -217,24 +217,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_sspp *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_sspp *ctx,
-			struct dpu_hw_sspp_cfg *cfg,
-			enum dpu_sspp_multirect_index index);
+	void (*setup_rects)(struct dpu_sw_pipe *pipe,
+			    struct dpu_hw_sspp_cfg *cfg);
 
 	/**
 	 * setup_pe - setup pipe pixel extension
@@ -246,13 +242,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_sspp *ctx,
-			struct dpu_hw_sspp_cfg *cfg,
-			enum dpu_sspp_multirect_index index);
+	void (*setup_sourceaddress)(struct dpu_sw_pipe *ctx,
+				    struct dpu_hw_sspp_cfg *cfg);
 
 	/**
 	 * setup_csc - setup color space coversion
@@ -263,24 +257,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_sspp *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_sspp *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
@@ -345,13 +333,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_sspp *ctx,
-			struct dpu_hw_cdp_cfg *cfg,
-			enum dpu_sspp_multirect_index index);
+	void (*setup_cdp)(struct dpu_sw_pipe *pipe,
+			  struct dpu_hw_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 229447ca1e0f..8f1767619d06 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -483,23 +483,21 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 	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_sspp *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,
 		const struct dpu_format *fmt,
-		uint32_t chroma_subsmpl_h, uint32_t chroma_subsmpl_v)
+		uint32_t chroma_subsmpl_h, uint32_t chroma_subsmpl_v,
+		unsigned int rotation)
 {
 	uint32_t i;
-	bool inline_rotation = pstate->rotation & DRM_MODE_ROTATE_90;
+	bool inline_rotation = rotation & DRM_MODE_ROTATE_90;
 
 	/*
 	 * For inline rotation cases, scaler config is post-rotation,
@@ -538,7 +536,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;
@@ -635,11 +633,12 @@ 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_sspp_cfg *pipe_cfg)
+		struct dpu_hw_sspp_cfg *pipe_cfg,
+		unsigned int rotation)
 {
+	struct dpu_hw_sspp *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;
@@ -653,20 +652,21 @@ 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,
 			src_width,
 			src_height,
 			dst_width,
 			dst_height,
 			&scaler3_cfg, fmt,
-			info->hsub, info->vsub);
+			info->hsub, info->vsub,
+			rotation);
 
 	/* configure pixel extension based on scalar config */
 	_dpu_plane_setup_pixel_ext(&scaler3_cfg, &pixel_ext,
 			src_width, src_height, 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);
 
 	/**
@@ -674,9 +674,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);
 }
@@ -706,9 +706,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;
@@ -721,16 +720,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, pstate->rotation);
 	}
 
 	return 0;
@@ -1169,18 +1166,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, pstate->rotation);
 
 	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 = pstate->rotation;
@@ -1197,8 +1191,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			src_flags |= DPU_SSPP_ROT_90;
 
 		/* 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_cdp_cfg cdp_cfg;
@@ -1214,7 +1207,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 d7059972499f..0ad148cc2fb8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -762,18 +762,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.39.1


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

* [PATCH v3 08/27] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

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

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.c | 59 +++++++++--------
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 46 +++++--------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 73 ++++++++++-----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h   |  9 ++-
 4 files changed, 84 insertions(+), 103 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 5cf0803e4187..4d3ca8532563 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_sspp *ctx,
 	return rc;
 }
 
-static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp *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_sspp *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_sspp *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_sspp *ctx,
 /*
  * Setup source pixel format, flip,
  */
-static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp *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_sspp *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_sspp *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;
@@ -447,10 +447,10 @@ static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
 /*
  * dpu_hw_sspp_setup_rects()
  */
-static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
-		struct dpu_hw_sspp_cfg *cfg,
-		enum dpu_sspp_multirect_index rect_index)
+static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
+		struct dpu_hw_sspp_cfg *cfg)
 {
+	struct dpu_hw_sspp *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;
@@ -461,7 +461,8 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *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;
@@ -482,7 +483,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *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]) |
@@ -491,7 +492,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *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)|
@@ -516,21 +517,21 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
 	DPU_REG_WRITE(c, SSPP_SRC_YSTRIDE1 + idx, ystride1);
 }
 
-static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_sspp *ctx,
-		struct dpu_hw_sspp_cfg *cfg,
-		enum dpu_sspp_multirect_index rect_mode)
+static void dpu_hw_sspp_setup_sourceaddress(struct dpu_sw_pipe *pipe,
+		struct dpu_hw_sspp_cfg *cfg)
 {
+	struct dpu_hw_sspp *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,
@@ -560,15 +561,16 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
 	dpu_hw_csc_setup(&ctx->hw, idx, data, csc10);
 }
 
-static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_sspp *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_sspp *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,
@@ -630,10 +632,10 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx,
 	DPU_REG_WRITE(&ctx->hw, SSPP_QOS_CTRL + idx, qos_ctrl);
 }
 
-static void dpu_hw_sspp_setup_cdp(struct dpu_hw_sspp *ctx,
-		struct dpu_hw_cdp_cfg *cfg,
-		enum dpu_sspp_multirect_index index)
+static void dpu_hw_sspp_setup_cdp(struct dpu_sw_pipe *pipe,
+		struct dpu_hw_cdp_cfg *cfg)
 {
+	struct dpu_hw_sspp *ctx = pipe->sspp;
 	u32 idx;
 	u32 cdp_cntl = 0;
 	u32 cdp_cntl_offset = 0;
@@ -644,7 +646,8 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_sspp *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 a3bdce6e20df..8d566ad1877e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -217,24 +217,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_sspp *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_sspp *ctx,
-			struct dpu_hw_sspp_cfg *cfg,
-			enum dpu_sspp_multirect_index index);
+	void (*setup_rects)(struct dpu_sw_pipe *pipe,
+			    struct dpu_hw_sspp_cfg *cfg);
 
 	/**
 	 * setup_pe - setup pipe pixel extension
@@ -246,13 +242,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_sspp *ctx,
-			struct dpu_hw_sspp_cfg *cfg,
-			enum dpu_sspp_multirect_index index);
+	void (*setup_sourceaddress)(struct dpu_sw_pipe *ctx,
+				    struct dpu_hw_sspp_cfg *cfg);
 
 	/**
 	 * setup_csc - setup color space coversion
@@ -263,24 +257,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_sspp *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_sspp *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
@@ -345,13 +333,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_sspp *ctx,
-			struct dpu_hw_cdp_cfg *cfg,
-			enum dpu_sspp_multirect_index index);
+	void (*setup_cdp)(struct dpu_sw_pipe *pipe,
+			  struct dpu_hw_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 229447ca1e0f..8f1767619d06 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -483,23 +483,21 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 	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_sspp *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,
 		const struct dpu_format *fmt,
-		uint32_t chroma_subsmpl_h, uint32_t chroma_subsmpl_v)
+		uint32_t chroma_subsmpl_h, uint32_t chroma_subsmpl_v,
+		unsigned int rotation)
 {
 	uint32_t i;
-	bool inline_rotation = pstate->rotation & DRM_MODE_ROTATE_90;
+	bool inline_rotation = rotation & DRM_MODE_ROTATE_90;
 
 	/*
 	 * For inline rotation cases, scaler config is post-rotation,
@@ -538,7 +536,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;
@@ -635,11 +633,12 @@ 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_sspp_cfg *pipe_cfg)
+		struct dpu_hw_sspp_cfg *pipe_cfg,
+		unsigned int rotation)
 {
+	struct dpu_hw_sspp *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;
@@ -653,20 +652,21 @@ 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,
 			src_width,
 			src_height,
 			dst_width,
 			dst_height,
 			&scaler3_cfg, fmt,
-			info->hsub, info->vsub);
+			info->hsub, info->vsub,
+			rotation);
 
 	/* configure pixel extension based on scalar config */
 	_dpu_plane_setup_pixel_ext(&scaler3_cfg, &pixel_ext,
 			src_width, src_height, 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);
 
 	/**
@@ -674,9 +674,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);
 }
@@ -706,9 +706,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;
@@ -721,16 +720,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, pstate->rotation);
 	}
 
 	return 0;
@@ -1169,18 +1166,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, pstate->rotation);
 
 	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 = pstate->rotation;
@@ -1197,8 +1191,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			src_flags |= DPU_SSPP_ROT_90;
 
 		/* 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_cdp_cfg cdp_cfg;
@@ -1214,7 +1207,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 d7059972499f..0ad148cc2fb8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -762,18 +762,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.39.1


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

* [PATCH v3 09/27] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

There is no need to pass full dpu_hw_sspp_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 | 9 ++++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 4 ++--
 3 files changed, 10 insertions(+), 12 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 4d3ca8532563..abf499275242 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -419,19 +419,18 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
 }
 
 static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
-		struct dpu_hw_sspp_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_sspp *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 8d566ad1877e..5e9b07090a21 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -317,13 +317,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
+	 * @scaler3_cfg: Pointer to scaler configuration
+	 * @format: pixel format parameters
 	 */
 	void (*setup_scaler)(struct dpu_hw_sspp *ctx,
-		struct dpu_hw_sspp_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 8f1767619d06..4f5c44d78332 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -677,8 +677,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.39.1


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

* [PATCH v3 09/27] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

There is no need to pass full dpu_hw_sspp_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 | 9 ++++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 4 ++--
 3 files changed, 10 insertions(+), 12 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 4d3ca8532563..abf499275242 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -419,19 +419,18 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
 }
 
 static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
-		struct dpu_hw_sspp_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_sspp *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 8d566ad1877e..5e9b07090a21 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -317,13 +317,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
+	 * @scaler3_cfg: Pointer to scaler configuration
+	 * @format: pixel format parameters
 	 */
 	void (*setup_scaler)(struct dpu_hw_sspp *ctx,
-		struct dpu_hw_sspp_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 8f1767619d06..4f5c44d78332 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -677,8 +677,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.39.1


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

* [PATCH v3 10/27] drm/msm/dpu: clean up SRC addresses when setting up SSPP for solid fill
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

Set SSPP_SRCn_ADDR registers to 0 while setting up solid fill, as we can
not be sure that the previous address is still valid.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index abf499275242..4c05f4b5e050 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -563,11 +563,16 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
 static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
 {
 	struct dpu_hw_sspp *ctx = pipe->sspp;
+	struct dpu_hw_sspp_cfg cfg;
 	u32 idx;
 
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
 		return;
 
+	/* cleanup source addresses */
+	memset(&cfg, 0, sizeof(cfg));
+	ctx->ops.setup_sourceaddress(pipe, &cfg);
+
 	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);
-- 
2.39.1


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

* [PATCH v3 10/27] drm/msm/dpu: clean up SRC addresses when setting up SSPP for solid fill
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

Set SSPP_SRCn_ADDR registers to 0 while setting up solid fill, as we can
not be sure that the previous address is still valid.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index abf499275242..4c05f4b5e050 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -563,11 +563,16 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
 static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
 {
 	struct dpu_hw_sspp *ctx = pipe->sspp;
+	struct dpu_hw_sspp_cfg cfg;
 	u32 idx;
 
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
 		return;
 
+	/* cleanup source addresses */
+	memset(&cfg, 0, sizeof(cfg));
+	ctx->ops.setup_sourceaddress(pipe, &cfg);
+
 	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);
-- 
2.39.1


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

* [PATCH v3 11/27] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	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 4c05f4b5e050..fbfb39a7a229 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -451,7 +451,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
 {
 	struct dpu_hw_sspp *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;
 
@@ -482,44 +482,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_sspp_cfg *cfg)
 {
 	struct dpu_hw_sspp *ctx = pipe->sspp;
+	u32 ystride0, ystride1;
 	int i;
 	u32 idx;
 
@@ -541,6 +515,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_sspp *ctx,
-- 
2.39.1


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

* [PATCH v3 11/27] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

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 4c05f4b5e050..fbfb39a7a229 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -451,7 +451,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
 {
 	struct dpu_hw_sspp *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;
 
@@ -482,44 +482,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_sspp_cfg *cfg)
 {
 	struct dpu_hw_sspp *ctx = pipe->sspp;
+	u32 ystride0, ystride1;
 	int i;
 	u32 idx;
 
@@ -541,6 +515,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_sspp *ctx,
-- 
2.39.1


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

* [PATCH v3 12/27] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_sspp_cfg
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

Remove dpu_hw_fmt_layout instance from struct dpu_hw_sspp_cfg, leaving
only src_rect and dst_rect. This way all the pipes used by the plane
will have a common layout instance (as the framebuffer is shared between
them), while still keeping a separate src/dst rectangle configuration
for each pipe.

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.c | 32 ++++++++++-----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  6 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 10 +++----
 3 files changed, 23 insertions(+), 25 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 fbfb39a7a229..0f069931d0ba 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -490,7 +490,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_sspp_cfg *cfg)
+		struct dpu_hw_fmt_layout *layout)
 {
 	struct dpu_hw_sspp *ctx = pipe->sspp;
 	u32 ystride0, ystride1;
@@ -501,41 +501,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);
 		}
 	}
@@ -564,7 +564,7 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
 static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
 {
 	struct dpu_hw_sspp *ctx = pipe->sspp;
-	struct dpu_hw_sspp_cfg cfg;
+	struct dpu_hw_fmt_layout cfg;
 	u32 idx;
 
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
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 5e9b07090a21..551036224876 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -154,13 +154,11 @@ struct dpu_hw_pixel_ext {
 
 /**
  * struct dpu_hw_sspp_cfg : SSPP configuration
- * @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_sspp_cfg {
-	struct dpu_hw_fmt_layout layout;
 	struct drm_rect src_rect;
 	struct drm_rect dst_rect;
 };
@@ -243,10 +241,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_sspp_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 4f5c44d78332..1b3033b15bfa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -471,21 +471,21 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
 
 static void _dpu_plane_set_scanout(struct drm_plane *plane,
 		struct dpu_plane_state *pstate,
-		struct dpu_hw_sspp_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;
+	struct dpu_hw_fmt_layout layout;
 	int ret;
 
-	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout);
+	ret = dpu_format_populate_layout(aspace, fb, &layout);
 	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);
+					    &layout);
+		pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, &layout);
 	}
 }
 
@@ -1134,7 +1134,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_sspp_cfg));
 
-	_dpu_plane_set_scanout(plane, pstate, &pipe_cfg, fb);
+	_dpu_plane_set_scanout(plane, pstate, fb);
 
 	pstate->pending = true;
 
-- 
2.39.1


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

* [PATCH v3 12/27] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_sspp_cfg
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

Remove dpu_hw_fmt_layout instance from struct dpu_hw_sspp_cfg, leaving
only src_rect and dst_rect. This way all the pipes used by the plane
will have a common layout instance (as the framebuffer is shared between
them), while still keeping a separate src/dst rectangle configuration
for each pipe.

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.c | 32 ++++++++++-----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  6 ++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 10 +++----
 3 files changed, 23 insertions(+), 25 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 fbfb39a7a229..0f069931d0ba 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -490,7 +490,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_sspp_cfg *cfg)
+		struct dpu_hw_fmt_layout *layout)
 {
 	struct dpu_hw_sspp *ctx = pipe->sspp;
 	u32 ystride0, ystride1;
@@ -501,41 +501,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);
 		}
 	}
@@ -564,7 +564,7 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
 static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
 {
 	struct dpu_hw_sspp *ctx = pipe->sspp;
-	struct dpu_hw_sspp_cfg cfg;
+	struct dpu_hw_fmt_layout cfg;
 	u32 idx;
 
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
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 5e9b07090a21..551036224876 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -154,13 +154,11 @@ struct dpu_hw_pixel_ext {
 
 /**
  * struct dpu_hw_sspp_cfg : SSPP configuration
- * @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_sspp_cfg {
-	struct dpu_hw_fmt_layout layout;
 	struct drm_rect src_rect;
 	struct drm_rect dst_rect;
 };
@@ -243,10 +241,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_sspp_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 4f5c44d78332..1b3033b15bfa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -471,21 +471,21 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
 
 static void _dpu_plane_set_scanout(struct drm_plane *plane,
 		struct dpu_plane_state *pstate,
-		struct dpu_hw_sspp_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;
+	struct dpu_hw_fmt_layout layout;
 	int ret;
 
-	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout);
+	ret = dpu_format_populate_layout(aspace, fb, &layout);
 	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);
+					    &layout);
+		pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, &layout);
 	}
 }
 
@@ -1134,7 +1134,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_sspp_cfg));
 
-	_dpu_plane_set_scanout(plane, pstate, &pipe_cfg, fb);
+	_dpu_plane_set_scanout(plane, pstate, fb);
 
 	pstate->pending = true;
 
-- 
2.39.1


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

* [PATCH v3 13/27] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	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).

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 | 168 ++---------------------
 1 file changed, 12 insertions(+), 156 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 037347e51eb8..c1579d6f5060 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1108,13 +1108,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 bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
 {
 	struct drm_crtc *crtc = cstate->crtc;
@@ -1136,31 +1129,22 @@ 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 };
 	bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
 
-	pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
-	if (!pstates)
-		return -ENOMEM;
-
 	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;
@@ -1170,13 +1154,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;
@@ -1185,38 +1164,21 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
 		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
 		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;
+			return rc;
 		}
-		if (cnt >= DPU_STAGE_MAX * 4)
-			continue;
 
 		if (!pstate->visible)
 			continue;
 
-		pstates[cnt].dpu_pstate = dpu_pstate;
-		pstates[cnt].drm_pstate = pstate;
-		pstates[cnt].stage = pstate->normalized_zpos;
-		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx;
-
 		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
-		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;
-		}
-
-		cnt++;
+		dpu_plane_clear_multirect(pstate);
 
 		dst = drm_plane_state_dest(pstate);
 		if (!drm_rect_intersect(&clip, &dst)) {
@@ -1224,63 +1186,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);
@@ -1289,74 +1209,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.39.1


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

* [PATCH v3 13/27] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

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).

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 | 168 ++---------------------
 1 file changed, 12 insertions(+), 156 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 037347e51eb8..c1579d6f5060 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1108,13 +1108,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 bool dpu_crtc_needs_dirtyfb(struct drm_crtc_state *cstate)
 {
 	struct drm_crtc *crtc = cstate->crtc;
@@ -1136,31 +1129,22 @@ 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 };
 	bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
 
-	pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
-	if (!pstates)
-		return -ENOMEM;
-
 	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;
@@ -1170,13 +1154,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;
@@ -1185,38 +1164,21 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
 		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
 		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;
+			return rc;
 		}
-		if (cnt >= DPU_STAGE_MAX * 4)
-			continue;
 
 		if (!pstate->visible)
 			continue;
 
-		pstates[cnt].dpu_pstate = dpu_pstate;
-		pstates[cnt].drm_pstate = pstate;
-		pstates[cnt].stage = pstate->normalized_zpos;
-		pstates[cnt].pipe_id = to_dpu_plane_state(pstate)->pipe.sspp->idx;
-
 		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
-		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;
-		}
-
-		cnt++;
+		dpu_plane_clear_multirect(pstate);
 
 		dst = drm_plane_state_dest(pstate);
 		if (!drm_rect_intersect(&clip, &dst)) {
@@ -1224,63 +1186,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);
@@ -1289,74 +1209,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.39.1


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

* [PATCH v3 14/27] drm/msm/dpu: don't use unsupported blend stages
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

The dpu_crtc_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_crtc.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index c1579d6f5060..b485234eefb2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1129,6 +1129,7 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
 
 	const struct drm_plane_state *pstate;
 	struct drm_plane *plane;
@@ -1164,7 +1165,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
 		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
 		struct drm_rect dst, clip = crtc_rect;
-		int z_pos;
+		int stage;
 
 		if (IS_ERR_OR_NULL(pstate)) {
 			rc = PTR_ERR(pstate);
@@ -1189,17 +1190,16 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 			return -E2BIG;
 		}
 
-		z_pos = pstate->normalized_zpos;
-
-		/* verify z_pos setting before using it */
-		if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
+		/* verify stage setting before using it */
+		stage = DPU_STAGE_0 + pstate->normalized_zpos;
+		if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
 			DPU_ERROR("> %d plane stages assigned\n",
-					DPU_STAGE_MAX - DPU_STAGE_0);
+					dpu_kms->catalog->caps->max_mixer_blendstages - 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);
+		to_dpu_plane_state(pstate)->stage = stage;
+		DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
 
 	}
 
-- 
2.39.1


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

* [PATCH v3 14/27] drm/msm/dpu: don't use unsupported blend stages
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

The dpu_crtc_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_crtc.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index c1579d6f5060..b485234eefb2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1129,6 +1129,7 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
 
 	const struct drm_plane_state *pstate;
 	struct drm_plane *plane;
@@ -1164,7 +1165,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
 		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
 		struct drm_rect dst, clip = crtc_rect;
-		int z_pos;
+		int stage;
 
 		if (IS_ERR_OR_NULL(pstate)) {
 			rc = PTR_ERR(pstate);
@@ -1189,17 +1190,16 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 			return -E2BIG;
 		}
 
-		z_pos = pstate->normalized_zpos;
-
-		/* verify z_pos setting before using it */
-		if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
+		/* verify stage setting before using it */
+		stage = DPU_STAGE_0 + pstate->normalized_zpos;
+		if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
 			DPU_ERROR("> %d plane stages assigned\n",
-					DPU_STAGE_MAX - DPU_STAGE_0);
+					dpu_kms->catalog->caps->max_mixer_blendstages - 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);
+		to_dpu_plane_state(pstate)->stage = stage;
+		DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
 
 	}
 
-- 
2.39.1


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

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

Move plane state updates from dpu_crtc_atomic_check() to the function
where they belong: to dpu_plane_atomic_check().

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index b485234eefb2..bd09bb319a58 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1129,7 +1129,6 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
 
 	const struct drm_plane_state *pstate;
 	struct drm_plane *plane;
@@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	crtc_rect.x2 = mode->hdisplay;
 	crtc_rect.y2 = mode->vdisplay;
 
-	 /* get plane state for all drm planes associated with crtc state */
+	/* FIXME: move this to dpu_plane_atomic_check? */
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
 		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
 		struct drm_rect dst, clip = crtc_rect;
-		int stage;
 
 		if (IS_ERR_OR_NULL(pstate)) {
 			rc = PTR_ERR(pstate);
@@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
 		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
-		dpu_plane_clear_multirect(pstate);
-
 		dst = drm_plane_state_dest(pstate);
 		if (!drm_rect_intersect(&clip, &dst)) {
 			DPU_ERROR("invalid vertical/horizontal destination\n");
@@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 				  DRM_RECT_ARG(&dst));
 			return -E2BIG;
 		}
-
-		/* verify stage setting before using it */
-		stage = DPU_STAGE_0 + pstate->normalized_zpos;
-		if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
-			DPU_ERROR("> %d plane stages assigned\n",
-					dpu_kms->catalog->caps->max_mixer_blendstages - DPU_STAGE_0);
-			return -EINVAL;
-		}
-
-		to_dpu_plane_state(pstate)->stage = stage;
-		DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
-
 	}
 
 	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 1b3033b15bfa..5aabf9694a53 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -733,14 +733,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];
@@ -994,6 +986,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 >= pdpu->catalog->caps->max_mixer_blendstages) {
+		DPU_ERROR("> %d plane stages assigned\n",
+				pdpu->catalog->caps->max_mixer_blendstages - 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 228db401e905..a08b0539513b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -88,12 +88,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.39.1


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

* [PATCH v3 15/27] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

Move plane state updates from dpu_crtc_atomic_check() to the function
where they belong: to dpu_plane_atomic_check().

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index b485234eefb2..bd09bb319a58 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1129,7 +1129,6 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
 
 	const struct drm_plane_state *pstate;
 	struct drm_plane *plane;
@@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	crtc_rect.x2 = mode->hdisplay;
 	crtc_rect.y2 = mode->vdisplay;
 
-	 /* get plane state for all drm planes associated with crtc state */
+	/* FIXME: move this to dpu_plane_atomic_check? */
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
 		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
 		struct drm_rect dst, clip = crtc_rect;
-		int stage;
 
 		if (IS_ERR_OR_NULL(pstate)) {
 			rc = PTR_ERR(pstate);
@@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
 		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
 
-		dpu_plane_clear_multirect(pstate);
-
 		dst = drm_plane_state_dest(pstate);
 		if (!drm_rect_intersect(&clip, &dst)) {
 			DPU_ERROR("invalid vertical/horizontal destination\n");
@@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 				  DRM_RECT_ARG(&dst));
 			return -E2BIG;
 		}
-
-		/* verify stage setting before using it */
-		stage = DPU_STAGE_0 + pstate->normalized_zpos;
-		if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
-			DPU_ERROR("> %d plane stages assigned\n",
-					dpu_kms->catalog->caps->max_mixer_blendstages - DPU_STAGE_0);
-			return -EINVAL;
-		}
-
-		to_dpu_plane_state(pstate)->stage = stage;
-		DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
-
 	}
 
 	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 1b3033b15bfa..5aabf9694a53 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -733,14 +733,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];
@@ -994,6 +986,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 >= pdpu->catalog->caps->max_mixer_blendstages) {
+		DPU_ERROR("> %d plane stages assigned\n",
+				pdpu->catalog->caps->max_mixer_blendstages - 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 228db401e905..a08b0539513b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -88,12 +88,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.39.1


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

* [PATCH v3 16/27] drm/msm/dpu: drop redundant plane dst check from dpu_crtc_atomic_check()
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

The helper drm_atomic_helper_check_plane_state() already checks whether
the scaled and clipped plane falls into the CRTC visible region (and
clears plane_state->visible if it doesn't). Drop the redundant check
from dpu_crtc_atomic_check().

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index bd09bb319a58..73e1a8c69ef0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1132,11 +1132,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
 	const struct drm_plane_state *pstate;
 	struct drm_plane *plane;
-	struct drm_display_mode *mode;
 
 	int rc = 0;
 
-	struct drm_rect crtc_rect = { 0 };
 	bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
 
 	if (!crtc_state->enable || !crtc_state->active) {
@@ -1147,7 +1145,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		return 0;
 	}
 
-	mode = &crtc_state->adjusted_mode;
 	DRM_DEBUG_ATOMIC("%s: check\n", dpu_crtc->name);
 
 	/* force a full mode set if active state changed */
@@ -1157,13 +1154,9 @@ 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;
-
 	/* FIXME: move this to dpu_plane_atomic_check? */
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
 		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
-		struct drm_rect dst, clip = crtc_rect;
 
 		if (IS_ERR_OR_NULL(pstate)) {
 			rc = PTR_ERR(pstate);
@@ -1176,15 +1169,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 			continue;
 
 		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
-
-		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;
-		}
 	}
 
 	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
-- 
2.39.1


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

* [PATCH v3 16/27] drm/msm/dpu: drop redundant plane dst check from dpu_crtc_atomic_check()
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

The helper drm_atomic_helper_check_plane_state() already checks whether
the scaled and clipped plane falls into the CRTC visible region (and
clears plane_state->visible if it doesn't). Drop the redundant check
from dpu_crtc_atomic_check().

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index bd09bb319a58..73e1a8c69ef0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -1132,11 +1132,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
 	const struct drm_plane_state *pstate;
 	struct drm_plane *plane;
-	struct drm_display_mode *mode;
 
 	int rc = 0;
 
-	struct drm_rect crtc_rect = { 0 };
 	bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
 
 	if (!crtc_state->enable || !crtc_state->active) {
@@ -1147,7 +1145,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		return 0;
 	}
 
-	mode = &crtc_state->adjusted_mode;
 	DRM_DEBUG_ATOMIC("%s: check\n", dpu_crtc->name);
 
 	/* force a full mode set if active state changed */
@@ -1157,13 +1154,9 @@ 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;
-
 	/* FIXME: move this to dpu_plane_atomic_check? */
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
 		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
-		struct drm_rect dst, clip = crtc_rect;
 
 		if (IS_ERR_OR_NULL(pstate)) {
 			rc = PTR_ERR(pstate);
@@ -1176,15 +1169,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 			continue;
 
 		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
-
-		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;
-		}
 	}
 
 	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
-- 
2.39.1


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

* [PATCH v3 17/27] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	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 5aabf9694a53..ee261a591d45 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -128,19 +128,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_sspp_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;
@@ -152,8 +151,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);
@@ -217,25 +214,25 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_sspp_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 */
@@ -251,7 +248,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 {
@@ -261,7 +258,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);
 
@@ -271,25 +268,22 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
 /**
  * _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_sspp_cfg *pipe_cfg)
+		struct dpu_sw_pipe *pipe,
+		const struct dpu_format *fmt, struct dpu_hw_sspp_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))
@@ -301,7 +295,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 	qos_lut = _dpu_hw_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);
 
@@ -310,20 +304,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) {
@@ -332,10 +326,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];
@@ -362,29 +352,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;
 	}
 
@@ -410,33 +401,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_sspp_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);
@@ -445,19 +437,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",
@@ -1144,7 +1137,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
 	pdpu->is_rt_pipe = is_rt_pipe;
 
-	_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),
@@ -1213,20 +1206,20 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		}
 	}
 
-	_dpu_plane_set_qos_lut(plane, fb, &pipe_cfg);
-	_dpu_plane_set_danger_lut(plane, fb);
+	_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, true, DPU_PLANE_QOS_PANIC_CTRL);
-		_dpu_plane_set_ot_limit(plane, crtc, &pipe_cfg);
+		_dpu_plane_set_qos_ctrl(plane, pipe, true, DPU_PLANE_QOS_PANIC_CTRL);
+		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pipe_cfg);
 	}
 
 	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, &pipe_cfg);
+	_dpu_plane_calc_bw(plane, fmt, &pipe_cfg);
 
 	_dpu_plane_calc_clk(plane, &pipe_cfg);
 }
@@ -1263,11 +1256,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);
 
@@ -1395,13 +1390,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.39.1


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

* [PATCH v3 17/27] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

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 5aabf9694a53..ee261a591d45 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -128,19 +128,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_sspp_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;
@@ -152,8 +151,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);
@@ -217,25 +214,25 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_sspp_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 */
@@ -251,7 +248,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 {
@@ -261,7 +258,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);
 
@@ -271,25 +268,22 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
 /**
  * _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_sspp_cfg *pipe_cfg)
+		struct dpu_sw_pipe *pipe,
+		const struct dpu_format *fmt, struct dpu_hw_sspp_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))
@@ -301,7 +295,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 	qos_lut = _dpu_hw_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);
 
@@ -310,20 +304,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) {
@@ -332,10 +326,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];
@@ -362,29 +352,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;
 	}
 
@@ -410,33 +401,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_sspp_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);
@@ -445,19 +437,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",
@@ -1144,7 +1137,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
 	pdpu->is_rt_pipe = is_rt_pipe;
 
-	_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),
@@ -1213,20 +1206,20 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		}
 	}
 
-	_dpu_plane_set_qos_lut(plane, fb, &pipe_cfg);
-	_dpu_plane_set_danger_lut(plane, fb);
+	_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, true, DPU_PLANE_QOS_PANIC_CTRL);
-		_dpu_plane_set_ot_limit(plane, crtc, &pipe_cfg);
+		_dpu_plane_set_qos_ctrl(plane, pipe, true, DPU_PLANE_QOS_PANIC_CTRL);
+		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pipe_cfg);
 	}
 
 	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, &pipe_cfg);
+	_dpu_plane_calc_bw(plane, fmt, &pipe_cfg);
 
 	_dpu_plane_calc_clk(plane, &pipe_cfg);
 }
@@ -1263,11 +1256,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);
 
@@ -1395,13 +1390,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.39.1


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

* [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	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 cf053e8f081e..fc818b0273e7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -21,13 +21,16 @@
 	(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
 
 #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
 
@@ -42,6 +45,7 @@
 #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.39.1


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

* [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

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 cf053e8f081e..fc818b0273e7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -21,13 +21,16 @@
 	(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
 
 #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
 
@@ -42,6 +45,7 @@
 #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.39.1


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

* [PATCH v3 19/27] drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

Rework bandwidth/clock calculation functions to use mode directly rather
than fetching it through the plane data.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ee261a591d45..09a3fde1c910 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -127,20 +127,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_sspp_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;
@@ -148,9 +147,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);
@@ -158,7 +154,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;
 
@@ -178,37 +174,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_sspp_cfg *pipe_cfg)
+static u64 _dpu_plane_calc_clk(const struct drm_display_mode *mode,
+		struct dpu_hw_sspp_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;
 }
 
 /**
@@ -1219,9 +1214,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		_dpu_plane_set_qos_remap(plane, pipe);
 	}
 
-	_dpu_plane_calc_bw(plane, fmt, &pipe_cfg);
+	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pipe_cfg);
 
-	_dpu_plane_calc_clk(plane, &pipe_cfg);
+	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &pipe_cfg);
 }
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
-- 
2.39.1


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

* [PATCH v3 19/27] drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

Rework bandwidth/clock calculation functions to use mode directly rather
than fetching it through the plane data.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ee261a591d45..09a3fde1c910 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -127,20 +127,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_sspp_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;
@@ -148,9 +147,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);
@@ -158,7 +154,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;
 
@@ -178,37 +174,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_sspp_cfg *pipe_cfg)
+static u64 _dpu_plane_calc_clk(const struct drm_display_mode *mode,
+		struct dpu_hw_sspp_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;
 }
 
 /**
@@ -1219,9 +1214,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		_dpu_plane_set_qos_remap(plane, pipe);
 	}
 
-	_dpu_plane_calc_bw(plane, fmt, &pipe_cfg);
+	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pipe_cfg);
 
-	_dpu_plane_calc_clk(plane, &pipe_cfg);
+	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &pipe_cfg);
 }
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
-- 
2.39.1


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

* [PATCH v3 20/27] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	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 | 64 ++++++++++-------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  2 +
 2 files changed, 30 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 09a3fde1c910..ecf5402ab61a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -951,7 +951,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
 	const struct drm_crtc_state *crtc_state = NULL;
 	const struct dpu_format *fmt;
-	struct drm_rect src, dst, fb_rect = { 0 };
+	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
+	struct drm_rect fb_rect = { 0 };
 	uint32_t min_src_size, max_linewidth;
 	unsigned int rotation;
 	uint32_t supported_rotations;
@@ -984,12 +985,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;
@@ -1008,30 +1012,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;
 	}
 
@@ -1045,7 +1049,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	if ((pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) &&
 		(rotation & DRM_MODE_ROTATE_90)) {
-		ret = dpu_plane_check_inline_rotation(pdpu, sblk, src, fmt);
+		ret = dpu_plane_check_inline_rotation(pdpu, sblk, pipe_cfg->src_rect, fmt);
 		if (ret)
 			return ret;
 	}
@@ -1120,9 +1124,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	bool is_rt_pipe;
 	const struct dpu_format *fmt =
 		to_dpu_format(msm_framebuffer_format(fb));
-	struct dpu_hw_sspp_cfg pipe_cfg;
-
-	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_sspp_cfg));
+	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
 
 	_dpu_plane_set_scanout(plane, pstate, fb);
 
@@ -1139,16 +1141,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 */
@@ -1157,10 +1149,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, pstate->rotation);
+	_dpu_plane_setup_scaler(pipe, fmt, false, pipe_cfg, pstate->rotation);
 
 	if (pipe->sspp->ops.setup_multirect)
 		pipe->sspp->ops.setup_multirect(
@@ -1201,12 +1193,12 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		}
 	}
 
-	_dpu_plane_set_qos_lut(plane, pipe, fmt, &pipe_cfg);
+	_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, pipe, true, DPU_PLANE_QOS_PANIC_CTRL);
-		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pipe_cfg);
+		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pstate->pipe_cfg);
 	}
 
 	if (pstate->needs_qos_remap) {
@@ -1214,9 +1206,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		_dpu_plane_set_qos_remap(plane, pipe);
 	}
 
-	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pipe_cfg);
+	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pstate->pipe_cfg);
 
-	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &pipe_cfg);
+	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &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 a08b0539513b..079dad83eb37 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -19,6 +19,7 @@
  * @base:	base drm plane state object
  * @aspace:	pointer to address space for input/output buffers
  * @pipe:	software pipe description
+ * @pipe_cfg:	software pipe configuration
  * @stage:	assigned by crtc blender
  * @needs_qos_remap: qos remap settings need to be updated
  * @multirect_index: index of the rectangle of SSPP
@@ -33,6 +34,7 @@ struct dpu_plane_state {
 	struct drm_plane_state base;
 	struct msm_gem_address_space *aspace;
 	struct dpu_sw_pipe pipe;
+	struct dpu_hw_sspp_cfg pipe_cfg;
 	enum dpu_stage stage;
 	bool needs_qos_remap;
 	bool pending;
-- 
2.39.1


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

* [PATCH v3 20/27] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

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 | 64 ++++++++++-------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  2 +
 2 files changed, 30 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 09a3fde1c910..ecf5402ab61a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -951,7 +951,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
 	const struct drm_crtc_state *crtc_state = NULL;
 	const struct dpu_format *fmt;
-	struct drm_rect src, dst, fb_rect = { 0 };
+	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
+	struct drm_rect fb_rect = { 0 };
 	uint32_t min_src_size, max_linewidth;
 	unsigned int rotation;
 	uint32_t supported_rotations;
@@ -984,12 +985,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;
@@ -1008,30 +1012,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;
 	}
 
@@ -1045,7 +1049,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	if ((pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) &&
 		(rotation & DRM_MODE_ROTATE_90)) {
-		ret = dpu_plane_check_inline_rotation(pdpu, sblk, src, fmt);
+		ret = dpu_plane_check_inline_rotation(pdpu, sblk, pipe_cfg->src_rect, fmt);
 		if (ret)
 			return ret;
 	}
@@ -1120,9 +1124,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	bool is_rt_pipe;
 	const struct dpu_format *fmt =
 		to_dpu_format(msm_framebuffer_format(fb));
-	struct dpu_hw_sspp_cfg pipe_cfg;
-
-	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_sspp_cfg));
+	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
 
 	_dpu_plane_set_scanout(plane, pstate, fb);
 
@@ -1139,16 +1141,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 */
@@ -1157,10 +1149,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, pstate->rotation);
+	_dpu_plane_setup_scaler(pipe, fmt, false, pipe_cfg, pstate->rotation);
 
 	if (pipe->sspp->ops.setup_multirect)
 		pipe->sspp->ops.setup_multirect(
@@ -1201,12 +1193,12 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		}
 	}
 
-	_dpu_plane_set_qos_lut(plane, pipe, fmt, &pipe_cfg);
+	_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, pipe, true, DPU_PLANE_QOS_PANIC_CTRL);
-		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pipe_cfg);
+		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pstate->pipe_cfg);
 	}
 
 	if (pstate->needs_qos_remap) {
@@ -1214,9 +1206,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		_dpu_plane_set_qos_remap(plane, pipe);
 	}
 
-	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pipe_cfg);
+	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pstate->pipe_cfg);
 
-	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &pipe_cfg);
+	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &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 a08b0539513b..079dad83eb37 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -19,6 +19,7 @@
  * @base:	base drm plane state object
  * @aspace:	pointer to address space for input/output buffers
  * @pipe:	software pipe description
+ * @pipe_cfg:	software pipe configuration
  * @stage:	assigned by crtc blender
  * @needs_qos_remap: qos remap settings need to be updated
  * @multirect_index: index of the rectangle of SSPP
@@ -33,6 +34,7 @@ struct dpu_plane_state {
 	struct drm_plane_state base;
 	struct msm_gem_address_space *aspace;
 	struct dpu_sw_pipe pipe;
+	struct dpu_hw_sspp_cfg pipe_cfg;
 	enum dpu_stage stage;
 	bool needs_qos_remap;
 	bool pending;
-- 
2.39.1


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

* [PATCH v3 21/27] drm/msm/dpu: simplify dpu_plane_validate_src()
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	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 ecf5402ab61a..0986e740b978 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
 				old_pstate->needs_dirtyfb);
 }
 
-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_check_inline_rotation(struct dpu_plane *pdpu,
 						const struct dpu_sspp_sub_blks *sblk,
 						struct drm_rect src, const struct dpu_format *fmt)
@@ -998,6 +979,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));
@@ -1012,7 +1001,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.39.1


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

* [PATCH v3 21/27] drm/msm/dpu: simplify dpu_plane_validate_src()
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

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 ecf5402ab61a..0986e740b978 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
 				old_pstate->needs_dirtyfb);
 }
 
-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_check_inline_rotation(struct dpu_plane *pdpu,
 						const struct dpu_sspp_sub_blks *sblk,
 						struct drm_rect src, const struct dpu_format *fmt)
@@ -998,6 +979,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));
@@ -1012,7 +1001,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.39.1


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

* [PATCH v3 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the
separate function dpu_plane_sspp_update_pipe(). This is one of
preparational steps to add r_pipe support.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 0986e740b978..f94e132733f3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -404,12 +404,13 @@ 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
  * @pipe:		Pointer to software pipe
- * @crtc:		Pointer to drm crtc
  * @pipe_cfg:		Pointer to pipe configuration
+ * @frame_rate:		CRTC's frame rate
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 		struct dpu_sw_pipe *pipe,
-		struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
+		struct dpu_hw_sspp_cfg *pipe_cfg,
+		int frame_rate)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_vbif_set_ot_params ot_params;
@@ -421,7 +422,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 = frame_rate;
 	ot_params.vbif_idx = VBIF_RT;
 	ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
 	ot_params.rd = true;
@@ -457,26 +458,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 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;
-	struct dpu_hw_fmt_layout layout;
-	int ret;
-
-	ret = dpu_format_populate_layout(aspace, fb, &layout);
-	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,
-					    &layout);
-		pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, &layout);
-	}
-}
-
 static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *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,
@@ -1102,35 +1083,25 @@ 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_sspp_update_pipe(struct drm_plane *plane,
+				       struct dpu_sw_pipe *pipe,
+				       struct dpu_hw_sspp_cfg *pipe_cfg,
+				       const struct dpu_format *fmt,
+				       int frame_rate,
+				       struct dpu_hw_fmt_layout *layout)
 {
 	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;
-	const struct dpu_format *fmt =
-		to_dpu_format(msm_framebuffer_format(fb));
-	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
 
-	_dpu_plane_set_scanout(plane, pstate, fb);
-
-	pstate->pending = true;
-
-	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
-	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
-	pdpu->is_rt_pipe = is_rt_pipe;
+	if (layout && pipe->sspp->ops.setup_sourceaddress) {
+		trace_dpu_plane_set_scanout(pipe, layout);
+		pipe->sspp->ops.setup_sourceaddress(pipe, layout);
+	}
 
 	_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 */
@@ -1183,22 +1154,64 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		}
 	}
 
-	_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, frame_rate);
 	}
 
-	if (pstate->needs_qos_remap) {
-		pstate->needs_qos_remap = false;
+	if (pstate->needs_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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
+
+	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
+	struct msm_gem_address_space *aspace = kms->base.aspace;
+	struct dpu_hw_fmt_layout layout;
+	bool layout_valid = false;
+	int ret;
+
+	ret = dpu_format_populate_layout(aspace, fb, &layout);
+	if (ret)
+		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
+	else
+		layout_valid = true;
+
+	pstate->pending = true;
+
+	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
+	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
+	pdpu->is_rt_pipe = is_rt_pipe;
+
+	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));
+
+	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
+				   drm_mode_vrefresh(&crtc->mode),
+				   layout_valid ? &layout: NULL);
+
+	if (pstate->needs_qos_remap)
+		pstate->needs_qos_remap = false;
 
-	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pstate->pipe_cfg);
+	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, pipe_cfg);
 
-	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &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.39.1


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

* [PATCH v3 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the
separate function dpu_plane_sspp_update_pipe(). This is one of
preparational steps to add r_pipe support.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 0986e740b978..f94e132733f3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -404,12 +404,13 @@ 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
  * @pipe:		Pointer to software pipe
- * @crtc:		Pointer to drm crtc
  * @pipe_cfg:		Pointer to pipe configuration
+ * @frame_rate:		CRTC's frame rate
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 		struct dpu_sw_pipe *pipe,
-		struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
+		struct dpu_hw_sspp_cfg *pipe_cfg,
+		int frame_rate)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_vbif_set_ot_params ot_params;
@@ -421,7 +422,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 = frame_rate;
 	ot_params.vbif_idx = VBIF_RT;
 	ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
 	ot_params.rd = true;
@@ -457,26 +458,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 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;
-	struct dpu_hw_fmt_layout layout;
-	int ret;
-
-	ret = dpu_format_populate_layout(aspace, fb, &layout);
-	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,
-					    &layout);
-		pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, &layout);
-	}
-}
-
 static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *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,
@@ -1102,35 +1083,25 @@ 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_sspp_update_pipe(struct drm_plane *plane,
+				       struct dpu_sw_pipe *pipe,
+				       struct dpu_hw_sspp_cfg *pipe_cfg,
+				       const struct dpu_format *fmt,
+				       int frame_rate,
+				       struct dpu_hw_fmt_layout *layout)
 {
 	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;
-	const struct dpu_format *fmt =
-		to_dpu_format(msm_framebuffer_format(fb));
-	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
 
-	_dpu_plane_set_scanout(plane, pstate, fb);
-
-	pstate->pending = true;
-
-	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
-	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
-	pdpu->is_rt_pipe = is_rt_pipe;
+	if (layout && pipe->sspp->ops.setup_sourceaddress) {
+		trace_dpu_plane_set_scanout(pipe, layout);
+		pipe->sspp->ops.setup_sourceaddress(pipe, layout);
+	}
 
 	_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 */
@@ -1183,22 +1154,64 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		}
 	}
 
-	_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, frame_rate);
 	}
 
-	if (pstate->needs_qos_remap) {
-		pstate->needs_qos_remap = false;
+	if (pstate->needs_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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
+
+	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
+	struct msm_gem_address_space *aspace = kms->base.aspace;
+	struct dpu_hw_fmt_layout layout;
+	bool layout_valid = false;
+	int ret;
+
+	ret = dpu_format_populate_layout(aspace, fb, &layout);
+	if (ret)
+		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
+	else
+		layout_valid = true;
+
+	pstate->pending = true;
+
+	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
+	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
+	pdpu->is_rt_pipe = is_rt_pipe;
+
+	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));
+
+	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
+				   drm_mode_vrefresh(&crtc->mode),
+				   layout_valid ? &layout: NULL);
+
+	if (pstate->needs_qos_remap)
+		pstate->needs_qos_remap = false;
 
-	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pstate->pipe_cfg);
+	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, pipe_cfg);
 
-	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &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.39.1


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

* [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

Split pipe-dependent code from dpu_plane_atomic_check() into the
separate function dpu_plane_atomic_check_pipe(). This is one of
preparational steps to add r_pipe support.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 ++++++++++++++---------
 1 file changed, 53 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 f94e132733f3..e69499490d39 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -903,6 +903,51 @@ static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
 	return 0;
 }
 
+static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
+		struct dpu_sw_pipe *pipe,
+		struct dpu_hw_sspp_cfg *pipe_cfg,
+		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 */
+	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 */
+	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 */
+	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;
+	}
+
+	return 0;
+}
+
 static int dpu_plane_atomic_check(struct drm_plane *plane,
 				  struct drm_atomic_state *state)
 {
@@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	const struct dpu_format *fmt;
 	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
 	struct drm_rect fb_rect = { 0 };
-	uint32_t min_src_size, max_linewidth;
+	uint32_t max_linewidth;
 	unsigned int rotation;
 	uint32_t supported_rotations;
 	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
@@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	max_linewidth = pdpu->catalog->caps->max_linewidth;
 
-	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_hw_caps->features & DPU_SSPP_SCALER) ||
-		 !(pipe_hw_caps->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) {
+	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;
 	}
 
+	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
+
+	ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
+	if (ret)
+		return ret;
+
 	supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
 
 	if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
-- 
2.39.1


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

* [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

Split pipe-dependent code from dpu_plane_atomic_check() into the
separate function dpu_plane_atomic_check_pipe(). This is one of
preparational steps to add r_pipe support.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 ++++++++++++++---------
 1 file changed, 53 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 f94e132733f3..e69499490d39 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -903,6 +903,51 @@ static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
 	return 0;
 }
 
+static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
+		struct dpu_sw_pipe *pipe,
+		struct dpu_hw_sspp_cfg *pipe_cfg,
+		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 */
+	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 */
+	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 */
+	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;
+	}
+
+	return 0;
+}
+
 static int dpu_plane_atomic_check(struct drm_plane *plane,
 				  struct drm_atomic_state *state)
 {
@@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	const struct dpu_format *fmt;
 	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
 	struct drm_rect fb_rect = { 0 };
-	uint32_t min_src_size, max_linewidth;
+	uint32_t max_linewidth;
 	unsigned int rotation;
 	uint32_t supported_rotations;
 	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
@@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	max_linewidth = pdpu->catalog->caps->max_linewidth;
 
-	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_hw_caps->features & DPU_SSPP_SCALER) ||
-		 !(pipe_hw_caps->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) {
+	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;
 	}
 
+	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
+
+	ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
+	if (ret)
+		return ret;
+
 	supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
 
 	if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
-- 
2.39.1


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

* [PATCH v3 24/27] drm/msm/dpu: rework plane CSC setting
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

Rework the code flushing CSC settings for the plane. Separate out the
pipe and pipe_cfg as a preparation for r_pipe support.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++----------
 1 file changed, 25 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 e69499490d39..05047192cb37 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -576,29 +576,18 @@ 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_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) {
-		DPU_ERROR("invalid plane\n");
-		return NULL;
-	}
-
 	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;
 
-	DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
-			csc_ptr->csc_mv[0],
-			csc_ptr->csc_mv[1],
-			csc_ptr->csc_mv[2]);
-
 	return csc_ptr;
 }
 
@@ -1049,6 +1038,27 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	return 0;
 }
 
+static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe)
+{
+	const struct dpu_format *format = to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
+	const struct dpu_csc_cfg *csc_ptr;
+
+	if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
+		return;
+
+	csc_ptr = _dpu_plane_get_csc(pipe, format);
+	if (!csc_ptr)
+		return;
+
+	DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
+			csc_ptr->csc_mv[0],
+			csc_ptr->csc_mv[1],
+			csc_ptr->csc_mv[2]);
+
+	pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
+
+}
+
 void dpu_plane_flush(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu;
@@ -1072,13 +1082,8 @@ 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) {
-		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);
-	}
+	else
+		dpu_plane_flush_csc(pdpu, &pstate->pipe);
 
 	/* flag h/w flush complete */
 	if (plane->state)
-- 
2.39.1


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

* [PATCH v3 24/27] drm/msm/dpu: rework plane CSC setting
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

Rework the code flushing CSC settings for the plane. Separate out the
pipe and pipe_cfg as a preparation for r_pipe support.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++----------
 1 file changed, 25 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 e69499490d39..05047192cb37 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -576,29 +576,18 @@ 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_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) {
-		DPU_ERROR("invalid plane\n");
-		return NULL;
-	}
-
 	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;
 
-	DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
-			csc_ptr->csc_mv[0],
-			csc_ptr->csc_mv[1],
-			csc_ptr->csc_mv[2]);
-
 	return csc_ptr;
 }
 
@@ -1049,6 +1038,27 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	return 0;
 }
 
+static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe)
+{
+	const struct dpu_format *format = to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
+	const struct dpu_csc_cfg *csc_ptr;
+
+	if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
+		return;
+
+	csc_ptr = _dpu_plane_get_csc(pipe, format);
+	if (!csc_ptr)
+		return;
+
+	DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
+			csc_ptr->csc_mv[0],
+			csc_ptr->csc_mv[1],
+			csc_ptr->csc_mv[2]);
+
+	pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
+
+}
+
 void dpu_plane_flush(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu;
@@ -1072,13 +1082,8 @@ 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) {
-		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);
-	}
+	else
+		dpu_plane_flush_csc(pdpu, &pstate->pipe);
 
 	/* flag h/w flush complete */
 	if (plane->state)
-- 
2.39.1


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

* [PATCH v3 25/27] drm/msm/dpu: rework static color fill code
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

Rework static color fill code to separate the pipe / pipe_cfg handling.
This is a preparation for the r_pipe support.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 05047192cb37..e2e85688ed3c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -639,20 +639,54 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe,
 				fmt);
 }
 
+static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
+		struct dpu_sw_pipe *pipe,
+		struct dpu_hw_sspp_cfg *old_pipe_cfg,
+		u32 fill_color,
+		const struct dpu_format *fmt)
+{
+	struct dpu_hw_sspp_cfg pipe_cfg;
+
+	/* update sspp */
+	if (!pipe->sspp->ops.setup_solidfill)
+		return 0;
+
+	pipe->sspp->ops.setup_solidfill(pipe, fill_color);
+
+	/* override scaler/decimation if solid fill */
+	pipe_cfg.dst_rect = old_pipe_cfg->dst_rect;
+
+	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);
+
+	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, pstate->rotation);
+
+	return 0;
+}
+
 /**
  * _dpu_plane_color_fill - enables color fill on plane
  * @pdpu:   Pointer to DPU plane object
  * @color:  RGB fill color value, [23..16] Blue, [15..8] Green, [7..0] Red
  * @alpha:  8-bit fill alpha value, 255 selects 100% alpha
- * Returns: 0 on success
  */
-static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
+static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
 		uint32_t color, uint32_t alpha)
 {
 	const struct dpu_format *fmt;
 	const struct drm_plane *plane = &pdpu->base;
 	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-	struct dpu_hw_sspp_cfg pipe_cfg;
+	u32 fill_color = (color & 0xFFFFFF) | ((alpha & 0xFF) << 24);
 
 	DPU_DEBUG_PLANE(pdpu, "\n");
 
@@ -661,34 +695,12 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 	 * h/w only supports RGB variants
 	 */
 	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
+	/* should not happen ever */
+	if (!fmt)
+		return;
 
 	/* update sspp */
-	if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
-		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;
-
-		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);
-
-		if (pstate->pipe.sspp->ops.setup_format)
-			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,
-					&pipe_cfg);
-
-		_dpu_plane_setup_scaler(&pstate->pipe, fmt, true, &pipe_cfg, pstate->rotation);
-	}
-
-	return 0;
+	_dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
 }
 
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
-- 
2.39.1


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

* [PATCH v3 25/27] drm/msm/dpu: rework static color fill code
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

Rework static color fill code to separate the pipe / pipe_cfg handling.
This is a preparation for the r_pipe support.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 05047192cb37..e2e85688ed3c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -639,20 +639,54 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe,
 				fmt);
 }
 
+static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
+		struct dpu_sw_pipe *pipe,
+		struct dpu_hw_sspp_cfg *old_pipe_cfg,
+		u32 fill_color,
+		const struct dpu_format *fmt)
+{
+	struct dpu_hw_sspp_cfg pipe_cfg;
+
+	/* update sspp */
+	if (!pipe->sspp->ops.setup_solidfill)
+		return 0;
+
+	pipe->sspp->ops.setup_solidfill(pipe, fill_color);
+
+	/* override scaler/decimation if solid fill */
+	pipe_cfg.dst_rect = old_pipe_cfg->dst_rect;
+
+	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);
+
+	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, pstate->rotation);
+
+	return 0;
+}
+
 /**
  * _dpu_plane_color_fill - enables color fill on plane
  * @pdpu:   Pointer to DPU plane object
  * @color:  RGB fill color value, [23..16] Blue, [15..8] Green, [7..0] Red
  * @alpha:  8-bit fill alpha value, 255 selects 100% alpha
- * Returns: 0 on success
  */
-static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
+static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
 		uint32_t color, uint32_t alpha)
 {
 	const struct dpu_format *fmt;
 	const struct drm_plane *plane = &pdpu->base;
 	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
-	struct dpu_hw_sspp_cfg pipe_cfg;
+	u32 fill_color = (color & 0xFFFFFF) | ((alpha & 0xFF) << 24);
 
 	DPU_DEBUG_PLANE(pdpu, "\n");
 
@@ -661,34 +695,12 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 	 * h/w only supports RGB variants
 	 */
 	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
+	/* should not happen ever */
+	if (!fmt)
+		return;
 
 	/* update sspp */
-	if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
-		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;
-
-		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);
-
-		if (pstate->pipe.sspp->ops.setup_format)
-			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,
-					&pipe_cfg);
-
-		_dpu_plane_setup_scaler(&pstate->pipe, fmt, true, &pipe_cfg, pstate->rotation);
-	}
-
-	return 0;
+	_dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
 }
 
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
-- 
2.39.1


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

* [PATCH v3 26/27] drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

Rework _dpu_crtc_blend_setup_mixer() to split away pipe handling to a
separate functon. This is a preparation for the r_pipe support.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 73e1a8c69ef0..0ca3bc38ff7e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -400,6 +400,47 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
 	}
 }
 
+static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
+				       struct drm_plane *plane,
+				       struct dpu_crtc_mixer *mixer,
+				       u32 num_mixers,
+				       struct dpu_hw_stage_cfg *stage_cfg,
+				       enum dpu_stage stage,
+				       unsigned int stage_idx,
+				       unsigned long *fetch_active,
+				       struct dpu_sw_pipe *pipe
+				      )
+{
+	uint32_t lm_idx;
+	enum dpu_sspp sspp_idx;
+	struct drm_plane_state *state;
+
+	if (!pipe->sspp)
+		return;
+
+	sspp_idx = pipe->sspp->idx;
+
+	state = plane->state;
+
+	DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
+			 crtc->base.id,
+			 stage,
+			 plane->base.id,
+			 sspp_idx - SSPP_NONE,
+			 state->fb ? state->fb->base.id : -1);
+
+	set_bit(sspp_idx, fetch_active);
+
+	stage_cfg->stage[stage][stage_idx] = sspp_idx;
+	stage_cfg->multirect_index[stage][stage_idx] =
+				pipe->multirect_index;
+
+	/* blend config update */
+	for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
+		mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl,
+								    sspp_idx);
+}
+
 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)
@@ -412,15 +453,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	struct dpu_format *format;
 	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
 
-	uint32_t stage_idx, lm_idx;
-	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
+	uint32_t lm_idx;
 	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;
-
 		state = plane->state;
 		if (!state)
 			continue;
@@ -431,39 +469,25 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		pstate = to_dpu_plane_state(state);
 		fb = state->fb;
 
-		sspp_idx = pstate->pipe.sspp->idx;
-		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,
-				sspp_idx - SSPP_VIG0,
-				state->fb ? state->fb->base.id : -1);
-
 		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
 
 		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->pipe.multirect_index;
-
 		trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
-					   state, pstate, stage_idx,
+					   state, pstate,
 					   format->base.pixel_format,
 					   fb ? fb->modifier : 0);
 
+		_dpu_crtc_blend_setup_pipe(crtc, plane,
+					   mixer, cstate->num_mixers,
+					   stage_cfg, pstate->stage, 0,
+					   fetch_active,
+					   &pstate->pipe);
+
 		/* blend config update */
 		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
-			_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);
+			_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
 
 			if (bg_alpha_enable && !format->alpha_enable)
 				mixer[lm_idx].mixer_op_mode = 0;
@@ -1297,8 +1321,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, "\tmultirect: mode: %d index: %d\n",
+		seq_printf(s, "\tsspp[0]:%d\n",
+			   pstate->pipe.sspp->idx - SSPP_NONE);
+		seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
 			pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
+		if (pstate->r_pipe.sspp) {
+			seq_printf(s, "\tsspp[1]:%d\n",
+				   pstate->r_pipe.sspp->idx - SSPP_NONE);
+			seq_printf(s, "\tmultirect[1]: 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_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
index 0ad148cc2fb8..5ec4f89e8814 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -633,9 +633,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, uint32_t pixel_format,
+		 uint32_t pixel_format,
 		 uint64_t modifier),
-	TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
+	TP_ARGS(crtc_id, plane_id, state, pstate,
 		pixel_format, modifier),
 	TP_STRUCT__entry(
 		__field(	uint32_t,		crtc_id		)
@@ -643,7 +643,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
 		__field(	uint32_t,		fb_id		)
 		__field_struct(	struct drm_rect,	src_rect	)
 		__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	)
@@ -657,7 +656,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
 		__entry->fb_id = state ? state->fb->base.id : 0;
 		__entry->src_rect = drm_plane_state_src(state);
 		__entry->dst_rect = drm_plane_state_dest(state);
-		__entry->stage_idx = stage_idx;
 		__entry->stage = pstate->stage;
 		__entry->sspp = pstate->pipe.sspp->idx;
 		__entry->multirect_idx = pstate->pipe.multirect_index;
@@ -666,13 +664,13 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
 		__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:%d, sspp:%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, __entry->sspp,
 		  __entry->multirect_idx, __entry->multirect_mode,
 		  __entry->pixel_format, __entry->modifier)
 );
-- 
2.39.1


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

* [PATCH v3 26/27] drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

Rework _dpu_crtc_blend_setup_mixer() to split away pipe handling to a
separate functon. This is a preparation for the r_pipe support.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 73e1a8c69ef0..0ca3bc38ff7e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -400,6 +400,47 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
 	}
 }
 
+static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
+				       struct drm_plane *plane,
+				       struct dpu_crtc_mixer *mixer,
+				       u32 num_mixers,
+				       struct dpu_hw_stage_cfg *stage_cfg,
+				       enum dpu_stage stage,
+				       unsigned int stage_idx,
+				       unsigned long *fetch_active,
+				       struct dpu_sw_pipe *pipe
+				      )
+{
+	uint32_t lm_idx;
+	enum dpu_sspp sspp_idx;
+	struct drm_plane_state *state;
+
+	if (!pipe->sspp)
+		return;
+
+	sspp_idx = pipe->sspp->idx;
+
+	state = plane->state;
+
+	DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
+			 crtc->base.id,
+			 stage,
+			 plane->base.id,
+			 sspp_idx - SSPP_NONE,
+			 state->fb ? state->fb->base.id : -1);
+
+	set_bit(sspp_idx, fetch_active);
+
+	stage_cfg->stage[stage][stage_idx] = sspp_idx;
+	stage_cfg->multirect_index[stage][stage_idx] =
+				pipe->multirect_index;
+
+	/* blend config update */
+	for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
+		mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl,
+								    sspp_idx);
+}
+
 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)
@@ -412,15 +453,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	struct dpu_format *format;
 	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
 
-	uint32_t stage_idx, lm_idx;
-	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
+	uint32_t lm_idx;
 	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;
-
 		state = plane->state;
 		if (!state)
 			continue;
@@ -431,39 +469,25 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		pstate = to_dpu_plane_state(state);
 		fb = state->fb;
 
-		sspp_idx = pstate->pipe.sspp->idx;
-		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,
-				sspp_idx - SSPP_VIG0,
-				state->fb ? state->fb->base.id : -1);
-
 		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
 
 		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->pipe.multirect_index;
-
 		trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
-					   state, pstate, stage_idx,
+					   state, pstate,
 					   format->base.pixel_format,
 					   fb ? fb->modifier : 0);
 
+		_dpu_crtc_blend_setup_pipe(crtc, plane,
+					   mixer, cstate->num_mixers,
+					   stage_cfg, pstate->stage, 0,
+					   fetch_active,
+					   &pstate->pipe);
+
 		/* blend config update */
 		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
-			_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);
+			_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
 
 			if (bg_alpha_enable && !format->alpha_enable)
 				mixer[lm_idx].mixer_op_mode = 0;
@@ -1297,8 +1321,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, "\tmultirect: mode: %d index: %d\n",
+		seq_printf(s, "\tsspp[0]:%d\n",
+			   pstate->pipe.sspp->idx - SSPP_NONE);
+		seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
 			pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
+		if (pstate->r_pipe.sspp) {
+			seq_printf(s, "\tsspp[1]:%d\n",
+				   pstate->r_pipe.sspp->idx - SSPP_NONE);
+			seq_printf(s, "\tmultirect[1]: 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_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
index 0ad148cc2fb8..5ec4f89e8814 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -633,9 +633,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, uint32_t pixel_format,
+		 uint32_t pixel_format,
 		 uint64_t modifier),
-	TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
+	TP_ARGS(crtc_id, plane_id, state, pstate,
 		pixel_format, modifier),
 	TP_STRUCT__entry(
 		__field(	uint32_t,		crtc_id		)
@@ -643,7 +643,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
 		__field(	uint32_t,		fb_id		)
 		__field_struct(	struct drm_rect,	src_rect	)
 		__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	)
@@ -657,7 +656,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
 		__entry->fb_id = state ? state->fb->base.id : 0;
 		__entry->src_rect = drm_plane_state_src(state);
 		__entry->dst_rect = drm_plane_state_dest(state);
-		__entry->stage_idx = stage_idx;
 		__entry->stage = pstate->stage;
 		__entry->sspp = pstate->pipe.sspp->idx;
 		__entry->multirect_idx = pstate->pipe.multirect_index;
@@ -666,13 +664,13 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
 		__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:%d, sspp:%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, __entry->sspp,
 		  __entry->multirect_idx, __entry->multirect_mode,
 		  __entry->pixel_format, __entry->modifier)
 );
-- 
2.39.1


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

* [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
  2023-02-03 18:21 ` Dmitry Baryshkov
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	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  |   6 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
 3 files changed, 114 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 0ca3bc38ff7e..867832a752b2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 					   fetch_active,
 					   &pstate->pipe);
 
+		_dpu_crtc_blend_setup_pipe(crtc, plane,
+					   mixer, cstate->num_mixers,
+					   stage_cfg, pstate->stage, 1,
+					   fetch_active,
+					   &pstate->r_pipe);
+
 		/* blend config update */
 		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
 			_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index e2e85688ed3c..401ead64c6bd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
 
+	if (!pipe->sspp)
+		return;
+
 	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
 	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
@@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
 {
 	struct dpu_hw_sspp_cfg pipe_cfg;
 
+	if (!pipe->sspp)
+		return 0;
+
 	/* update sspp */
 	if (!pipe->sspp->ops.setup_solidfill)
 		return 0;
@@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
 
 	/* update sspp */
 	_dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
+
+	_dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
 }
 
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
@@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
 {
 	uint32_t min_src_size;
 
+	if (!pipe->sspp)
+		return 0;
+
 	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
 
 	if (DPU_FORMAT_IS_YUV(fmt) &&
@@ -957,9 +968,12 @@ 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;
+	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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
+	struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
 	struct drm_rect fb_rect = { 0 };
 	uint32_t max_linewidth;
 	unsigned int rotation;
@@ -983,8 +997,11 @@ 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;
+	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) {
@@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	max_linewidth = pdpu->catalog->caps->max_linewidth;
 
-	/* check decimated source width */
 	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;
+		/* 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
+		 */
+		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;
 	}
 
 	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
 
-	ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
+	ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
+	if (ret)
+		return ret;
+
+	ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
 	if (ret)
 		return ret;
 
@@ -1094,8 +1148,10 @@ 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
+	else {
 		dpu_plane_flush_csc(pdpu, &pstate->pipe);
+		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
+	}
 
 	/* flag h/w flush complete */
 	if (plane->state)
@@ -1130,6 +1186,9 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
 	struct drm_plane_state *state = plane->state;
 	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
 
+	if (!pipe->sspp)
+		return;
+
 	if (layout && pipe->sspp->ops.setup_sourceaddress) {
 		trace_dpu_plane_set_scanout(pipe, layout);
 		pipe->sspp->ops.setup_sourceaddress(pipe, layout);
@@ -1207,13 +1266,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
-
+	struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
 	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
 	struct msm_gem_address_space *aspace = kms->base.aspace;
 	struct dpu_hw_fmt_layout layout;
@@ -1241,12 +1301,22 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 				   drm_mode_vrefresh(&crtc->mode),
 				   layout_valid ? &layout: NULL);
 
+	dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
+				   drm_mode_vrefresh(&crtc->mode),
+				   layout_valid ? &layout: NULL);
+
 	if (pstate->needs_qos_remap)
 		pstate->needs_qos_remap = false;
 
 	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) {
+		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)
@@ -1289,6 +1359,8 @@ 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);
 
+		_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 */
@@ -1369,11 +1441,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
+	const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
+	const struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_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));
+
+	if (r_pipe->sspp) {
+		drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
+		drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(r_pipe->multirect_mode));
+		drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(r_pipe->multirect_index));
+		drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
+		drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
+	}
 }
 
 static void dpu_plane_reset(struct drm_plane *plane)
@@ -1407,6 +1494,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
 	 * This is the place where the state is allocated, so fill it fully.
 	 */
 	pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
+	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);
 }
@@ -1423,6 +1514,7 @@ 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);
+	_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 079dad83eb37..183c95949885 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -19,7 +19,9 @@
  * @base:	base drm plane state object
  * @aspace:	pointer to address space for input/output buffers
  * @pipe:	software pipe description
+ * @r_pipe:	software pipe description of the second pipe
  * @pipe_cfg:	software pipe configuration
+ * @r_pipe_cfg:	software pipe configuration for the second pipe
  * @stage:	assigned by crtc blender
  * @needs_qos_remap: qos remap settings need to be updated
  * @multirect_index: index of the rectangle of SSPP
@@ -34,7 +36,9 @@ struct dpu_plane_state {
 	struct drm_plane_state base;
 	struct msm_gem_address_space *aspace;
 	struct dpu_sw_pipe pipe;
+	struct dpu_sw_pipe r_pipe;
 	struct dpu_hw_sspp_cfg pipe_cfg;
+	struct dpu_hw_sspp_cfg r_pipe_cfg;
 	enum dpu_stage stage;
 	bool needs_qos_remap;
 	bool pending;
-- 
2.39.1


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

* [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
@ 2023-02-03 18:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:21 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

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  |   6 ++
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
 3 files changed, 114 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 0ca3bc38ff7e..867832a752b2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 					   fetch_active,
 					   &pstate->pipe);
 
+		_dpu_crtc_blend_setup_pipe(crtc, plane,
+					   mixer, cstate->num_mixers,
+					   stage_cfg, pstate->stage, 1,
+					   fetch_active,
+					   &pstate->r_pipe);
+
 		/* blend config update */
 		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
 			_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index e2e85688ed3c..401ead64c6bd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
 
+	if (!pipe->sspp)
+		return;
+
 	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
 	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
@@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
 {
 	struct dpu_hw_sspp_cfg pipe_cfg;
 
+	if (!pipe->sspp)
+		return 0;
+
 	/* update sspp */
 	if (!pipe->sspp->ops.setup_solidfill)
 		return 0;
@@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
 
 	/* update sspp */
 	_dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
+
+	_dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
 }
 
 int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
@@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
 {
 	uint32_t min_src_size;
 
+	if (!pipe->sspp)
+		return 0;
+
 	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
 
 	if (DPU_FORMAT_IS_YUV(fmt) &&
@@ -957,9 +968,12 @@ 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;
+	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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
+	struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
 	struct drm_rect fb_rect = { 0 };
 	uint32_t max_linewidth;
 	unsigned int rotation;
@@ -983,8 +997,11 @@ 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;
+	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) {
@@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	max_linewidth = pdpu->catalog->caps->max_linewidth;
 
-	/* check decimated source width */
 	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;
+		/* 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
+		 */
+		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;
 	}
 
 	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
 
-	ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
+	ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
+	if (ret)
+		return ret;
+
+	ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
 	if (ret)
 		return ret;
 
@@ -1094,8 +1148,10 @@ 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
+	else {
 		dpu_plane_flush_csc(pdpu, &pstate->pipe);
+		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
+	}
 
 	/* flag h/w flush complete */
 	if (plane->state)
@@ -1130,6 +1186,9 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
 	struct drm_plane_state *state = plane->state;
 	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
 
+	if (!pipe->sspp)
+		return;
+
 	if (layout && pipe->sspp->ops.setup_sourceaddress) {
 		trace_dpu_plane_set_scanout(pipe, layout);
 		pipe->sspp->ops.setup_sourceaddress(pipe, layout);
@@ -1207,13 +1266,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
-
+	struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
 	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
 	struct msm_gem_address_space *aspace = kms->base.aspace;
 	struct dpu_hw_fmt_layout layout;
@@ -1241,12 +1301,22 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 				   drm_mode_vrefresh(&crtc->mode),
 				   layout_valid ? &layout: NULL);
 
+	dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
+				   drm_mode_vrefresh(&crtc->mode),
+				   layout_valid ? &layout: NULL);
+
 	if (pstate->needs_qos_remap)
 		pstate->needs_qos_remap = false;
 
 	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) {
+		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)
@@ -1289,6 +1359,8 @@ 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);
 
+		_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 */
@@ -1369,11 +1441,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
+	const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
+	const struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_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));
+
+	if (r_pipe->sspp) {
+		drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
+		drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(r_pipe->multirect_mode));
+		drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(r_pipe->multirect_index));
+		drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
+		drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
+	}
 }
 
 static void dpu_plane_reset(struct drm_plane *plane)
@@ -1407,6 +1494,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
 	 * This is the place where the state is allocated, so fill it fully.
 	 */
 	pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
+	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);
 }
@@ -1423,6 +1514,7 @@ 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);
+	_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 079dad83eb37..183c95949885 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -19,7 +19,9 @@
  * @base:	base drm plane state object
  * @aspace:	pointer to address space for input/output buffers
  * @pipe:	software pipe description
+ * @r_pipe:	software pipe description of the second pipe
  * @pipe_cfg:	software pipe configuration
+ * @r_pipe_cfg:	software pipe configuration for the second pipe
  * @stage:	assigned by crtc blender
  * @needs_qos_remap: qos remap settings need to be updated
  * @multirect_index: index of the rectangle of SSPP
@@ -34,7 +36,9 @@ struct dpu_plane_state {
 	struct drm_plane_state base;
 	struct msm_gem_address_space *aspace;
 	struct dpu_sw_pipe pipe;
+	struct dpu_sw_pipe r_pipe;
 	struct dpu_hw_sspp_cfg pipe_cfg;
+	struct dpu_hw_sspp_cfg r_pipe_cfg;
 	enum dpu_stage stage;
 	bool needs_qos_remap;
 	bool pending;
-- 
2.39.1


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

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

On 03/02/2023 20:21, Dmitry Baryshkov wrote:
> The review of the first half of v2 took more than a month. Let's update
> the reviewed patches in attempt to get the first half of the series into
> the acked and mergeable state. This would allow us to lower the impact
> (and the patch count). At 27 patches this series is approaching the
> limits of manageability.
> 
> This patchset brings in multirect usage to support using two SSPP
> rectangles for a single plane. Full virtual planes support is omitted
> from this pull request, it will come later.
> 
> Changes since v1 (which was ages ago):
> - Rebased on top of 6.2-rc1
> - Dropped the controversial _dpu_crtc_blend_setup() split patch
> - Renamed dpu_hw_pipe to dpu_hw_sspp
> - Other misc changes

I forgot to add it here, please excuse me:

Changes since v2:

- Renamed dpu_hw_pipe_cfg to dpu_hw_sspp_cfg
- Added a patch to clean up src add / layout for the solid fill planes
- Fixed several comments and commit messages which caused confusion
- Added documentation for new dpu_plane_state members
- Slightly reworked dpu_plane_atomic_check() to make it more logical and 
obvious

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 00/27] drm/msm/dpu: wide planes support
@ 2023-02-03 18:24   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 18:24 UTC (permalink / raw)
  To: Rob Clark, Sean Paul, Abhinav Kumar
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 03/02/2023 20:21, Dmitry Baryshkov wrote:
> The review of the first half of v2 took more than a month. Let's update
> the reviewed patches in attempt to get the first half of the series into
> the acked and mergeable state. This would allow us to lower the impact
> (and the patch count). At 27 patches this series is approaching the
> limits of manageability.
> 
> This patchset brings in multirect usage to support using two SSPP
> rectangles for a single plane. Full virtual planes support is omitted
> from this pull request, it will come later.
> 
> Changes since v1 (which was ages ago):
> - Rebased on top of 6.2-rc1
> - Dropped the controversial _dpu_crtc_blend_setup() split patch
> - Renamed dpu_hw_pipe to dpu_hw_sspp
> - Other misc changes

I forgot to add it here, please excuse me:

Changes since v2:

- Renamed dpu_hw_pipe_cfg to dpu_hw_sspp_cfg
- Added a patch to clean up src add / layout for the solid fill planes
- Fixed several comments and commit messages which caused confusion
- Added documentation for new dpu_plane_state members
- Slightly reworked dpu_plane_atomic_check() to make it more logical and 
obvious

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 01/27] drm/msm/dpu: rename struct dpu_hw_pipe(_cfg) to dpu_hw_sspp(_cfg)
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-03 19:31     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 19:31 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> For all hardware blocks except SSPP the corresponding struct is named
> after the block. Rename dpu_hw_pipe (SSPP structure) to dpu_hw_sspp.
> Also rename struct dpu_hw_pipe_cfg to dpu_hw_sspp_cfg to follow this
> change.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

LGTM now,

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

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 48 +++++++++----------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 52 ++++++++++-----------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 20 ++++----
>   3 files changed, 60 insertions(+), 60 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 4246ab0b3bee..5cf0803e4187 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -136,7 +136,7 @@
>   #define TS_CLK			19200000
>   
>   
> -static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
> +static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx,
>   		int s_id,
>   		u32 *idx)
>   {
> @@ -168,7 +168,7 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
>   	return rc;
>   }
>   
> -static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
> +static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp *ctx,
>   		enum dpu_sspp_multirect_index index,
>   		enum dpu_sspp_multirect_mode mode)
>   {
> @@ -197,7 +197,7 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
>   	DPU_REG_WRITE(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx, mode_mask);
>   }
>   
> -static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
> +static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx,
>   		u32 mask, u8 en)
>   {
>   	u32 idx;
> @@ -218,7 +218,7 @@ static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
>   	DPU_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode);
>   }
>   
> -static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx,
> +static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp *ctx,
>   		u32 mask, u8 en)
>   {
>   	u32 idx;
> @@ -239,7 +239,7 @@ 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,
> +static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp *ctx,
>   		const struct dpu_format *fmt, u32 flags,
>   		enum dpu_sspp_multirect_index rect_mode)
>   {
> @@ -360,7 +360,7 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
>   	DPU_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
>   }
>   
> -static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
> +static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
>   		struct dpu_hw_pixel_ext *pe_ext)
>   {
>   	struct dpu_hw_blk_reg_map *c;
> @@ -418,8 +418,8 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
>   			tot_req_pixels[3]);
>   }
>   
> -static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
> -		struct dpu_hw_pipe_cfg *sspp,
> +static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
> +		struct dpu_hw_sspp_cfg *sspp,
>   		void *scaler_cfg)
>   {
>   	u32 idx;
> @@ -434,7 +434,7 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
>   			sspp->layout.format);
>   }
>   
> -static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
> +static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
>   {
>   	u32 idx;
>   
> @@ -447,8 +447,8 @@ 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,
> +static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
> +		struct dpu_hw_sspp_cfg *cfg,
>   		enum dpu_sspp_multirect_index rect_index)
>   {
>   	struct dpu_hw_blk_reg_map *c;
> @@ -516,8 +516,8 @@ 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,
> +static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_sspp *ctx,
> +		struct dpu_hw_sspp_cfg *cfg,
>   		enum dpu_sspp_multirect_index rect_mode)
>   {
>   	int i;
> @@ -543,7 +543,7 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_pipe *ctx,
>   	}
>   }
>   
> -static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
> +static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
>   		const struct dpu_csc_cfg *data)
>   {
>   	u32 idx;
> @@ -560,7 +560,7 @@ 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
> +static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_sspp *ctx, u32 color, enum
>   		dpu_sspp_multirect_index rect_index)
>   {
>   	u32 idx;
> @@ -575,7 +575,7 @@ static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, enum
>   				color);
>   }
>   
> -static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
> +static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_sspp *ctx,
>   			u32 danger_lut,
>   			u32 safe_lut)
>   {
> @@ -588,7 +588,7 @@ static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
>   	DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, safe_lut);
>   }
>   
> -static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
> +static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_sspp *ctx,
>   			u64 creq_lut)
>   {
>   	u32 idx;
> @@ -605,7 +605,7 @@ static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
>   	}
>   }
>   
> -static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe *ctx,
> +static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx,
>   		struct dpu_hw_pipe_qos_cfg *cfg)
>   {
>   	u32 idx;
> @@ -630,7 +630,7 @@ 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,
> +static void dpu_hw_sspp_setup_cdp(struct dpu_hw_sspp *ctx,
>   		struct dpu_hw_cdp_cfg *cfg,
>   		enum dpu_sspp_multirect_index index)
>   {
> @@ -661,7 +661,7 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
>   	DPU_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl);
>   }
>   
> -static void _setup_layer_ops(struct dpu_hw_pipe *c,
> +static void _setup_layer_ops(struct dpu_hw_sspp *c,
>   		unsigned long features)
>   {
>   	if (test_bit(DPU_SSPP_SRC, &features)) {
> @@ -699,7 +699,7 @@ static void _setup_layer_ops(struct dpu_hw_pipe *c,
>   }
>   
>   #ifdef CONFIG_DEBUG_FS
> -int _dpu_hw_sspp_init_debugfs(struct dpu_hw_pipe *hw_pipe, struct dpu_kms *kms, struct dentry *entry)
> +int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, struct dentry *entry)
>   {
>   	const struct dpu_sspp_cfg *cfg = hw_pipe->cap;
>   	const struct dpu_sspp_sub_blks *sblk = cfg->sblk;
> @@ -783,10 +783,10 @@ static const struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp,
>   	return ERR_PTR(-ENOMEM);
>   }
>   
> -struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
> +struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
>   		void __iomem *addr, const struct dpu_mdss_cfg *catalog)
>   {
> -	struct dpu_hw_pipe *hw_pipe;
> +	struct dpu_hw_sspp *hw_pipe;
>   	const struct dpu_sspp_cfg *cfg;
>   
>   	if (!addr || !catalog)
> @@ -812,7 +812,7 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
>   	return hw_pipe;
>   }
>   
> -void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx)
> +void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx)
>   {
>   	kfree(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 0c95b7e64f6c..084206da851b 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -10,7 +10,7 @@
>   #include "dpu_hw_util.h"
>   #include "dpu_formats.h"
>   
> -struct dpu_hw_pipe;
> +struct dpu_hw_sspp;
>   
>   /**
>    * Flags
> @@ -153,7 +153,7 @@ struct dpu_hw_pixel_ext {
>   };
>   
>   /**
> - * struct dpu_hw_pipe_cfg : Pipe description
> + * struct dpu_hw_sspp_cfg : SSPP configuration
>    * @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
> @@ -161,7 +161,7 @@ struct dpu_hw_pixel_ext {
>    * @index:     index of the rectangle of SSPP
>    * @mode:      parallel or time multiplex multirect mode
>    */
> -struct dpu_hw_pipe_cfg {
> +struct dpu_hw_sspp_cfg {
>   	struct dpu_hw_fmt_layout layout;
>   	struct drm_rect src_rect;
>   	struct drm_rect dst_rect;
> @@ -214,7 +214,7 @@ struct dpu_hw_sspp_ops {
>   	 * @flags: Extra flags for format config
>   	 * @index: rectangle index in multirect
>   	 */
> -	void (*setup_format)(struct dpu_hw_pipe *ctx,
> +	void (*setup_format)(struct dpu_hw_sspp *ctx,
>   			const struct dpu_format *fmt, u32 flags,
>   			enum dpu_sspp_multirect_index index);
>   
> @@ -224,8 +224,8 @@ struct dpu_hw_sspp_ops {
>   	 * @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,
> +	void (*setup_rects)(struct dpu_hw_sspp *ctx,
> +			struct dpu_hw_sspp_cfg *cfg,
>   			enum dpu_sspp_multirect_index index);
>   
>   	/**
> @@ -233,7 +233,7 @@ struct dpu_hw_sspp_ops {
>   	 * @ctx: Pointer to pipe context
>   	 * @pe_ext: Pointer to pixel ext settings
>   	 */
> -	void (*setup_pe)(struct dpu_hw_pipe *ctx,
> +	void (*setup_pe)(struct dpu_hw_sspp *ctx,
>   			struct dpu_hw_pixel_ext *pe_ext);
>   
>   	/**
> @@ -242,8 +242,8 @@ struct dpu_hw_sspp_ops {
>   	 * @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,
> +	void (*setup_sourceaddress)(struct dpu_hw_sspp *ctx,
> +			struct dpu_hw_sspp_cfg *cfg,
>   			enum dpu_sspp_multirect_index index);
>   
>   	/**
> @@ -251,7 +251,7 @@ struct dpu_hw_sspp_ops {
>   	 * @ctx: Pointer to pipe context
>   	 * @data: Pointer to config structure
>   	 */
> -	void (*setup_csc)(struct dpu_hw_pipe *ctx, const struct dpu_csc_cfg *data);
> +	void (*setup_csc)(struct dpu_hw_sspp *ctx, const struct dpu_csc_cfg *data);
>   
>   	/**
>   	 * setup_solidfill - enable/disable colorfill
> @@ -260,7 +260,7 @@ struct dpu_hw_sspp_ops {
>   	 * @flags: Pipe flags
>   	 * @index: rectangle index in multirect
>   	 */
> -	void (*setup_solidfill)(struct dpu_hw_pipe *ctx, u32 color,
> +	void (*setup_solidfill)(struct dpu_hw_sspp *ctx, u32 color,
>   			enum dpu_sspp_multirect_index index);
>   
>   	/**
> @@ -270,7 +270,7 @@ struct dpu_hw_sspp_ops {
>   	 * @mode: parallel fetch / time multiplex multirect mode
>   	 */
>   
> -	void (*setup_multirect)(struct dpu_hw_pipe *ctx,
> +	void (*setup_multirect)(struct dpu_hw_sspp *ctx,
>   			enum dpu_sspp_multirect_index index,
>   			enum dpu_sspp_multirect_mode mode);
>   
> @@ -279,7 +279,7 @@ struct dpu_hw_sspp_ops {
>   	 * @ctx: Pointer to pipe context
>   	 * @cfg: Pointer to config structure
>   	 */
> -	void (*setup_sharpening)(struct dpu_hw_pipe *ctx,
> +	void (*setup_sharpening)(struct dpu_hw_sspp *ctx,
>   			struct dpu_hw_sharp_cfg *cfg);
>   
>   	/**
> @@ -289,7 +289,7 @@ struct dpu_hw_sspp_ops {
>   	 * @safe_lut: LUT for generate safe level based on fill level
>   	 *
>   	 */
> -	void (*setup_danger_safe_lut)(struct dpu_hw_pipe *ctx,
> +	void (*setup_danger_safe_lut)(struct dpu_hw_sspp *ctx,
>   			u32 danger_lut,
>   			u32 safe_lut);
>   
> @@ -299,7 +299,7 @@ struct dpu_hw_sspp_ops {
>   	 * @creq_lut: LUT for generate creq level based on fill level
>   	 *
>   	 */
> -	void (*setup_creq_lut)(struct dpu_hw_pipe *ctx,
> +	void (*setup_creq_lut)(struct dpu_hw_sspp *ctx,
>   			u64 creq_lut);
>   
>   	/**
> @@ -308,7 +308,7 @@ struct dpu_hw_sspp_ops {
>   	 * @cfg: Pointer to pipe QoS configuration
>   	 *
>   	 */
> -	void (*setup_qos_ctrl)(struct dpu_hw_pipe *ctx,
> +	void (*setup_qos_ctrl)(struct dpu_hw_sspp *ctx,
>   			struct dpu_hw_pipe_qos_cfg *cfg);
>   
>   	/**
> @@ -316,7 +316,7 @@ struct dpu_hw_sspp_ops {
>   	 * @ctx: Pointer to pipe context
>   	 * @cfg: Pointer to histogram configuration
>   	 */
> -	void (*setup_histogram)(struct dpu_hw_pipe *ctx,
> +	void (*setup_histogram)(struct dpu_hw_sspp *ctx,
>   			void *cfg);
>   
>   	/**
> @@ -325,15 +325,15 @@ struct dpu_hw_sspp_ops {
>   	 * @pipe_cfg: Pointer to pipe configuration
>   	 * @scaler_cfg: Pointer to scaler configuration
>   	 */
> -	void (*setup_scaler)(struct dpu_hw_pipe *ctx,
> -		struct dpu_hw_pipe_cfg *pipe_cfg,
> +	void (*setup_scaler)(struct dpu_hw_sspp *ctx,
> +		struct dpu_hw_sspp_cfg *pipe_cfg,
>   		void *scaler_cfg);
>   
>   	/**
>   	 * get_scaler_ver - get scaler h/w version
>   	 * @ctx: Pointer to pipe context
>   	 */
> -	u32 (*get_scaler_ver)(struct dpu_hw_pipe *ctx);
> +	u32 (*get_scaler_ver)(struct dpu_hw_sspp *ctx);
>   
>   	/**
>   	 * setup_cdp - setup client driven prefetch
> @@ -341,13 +341,13 @@ struct dpu_hw_sspp_ops {
>   	 * @cfg: Pointer to cdp configuration
>   	 * @index: rectangle index in multirect
>   	 */
> -	void (*setup_cdp)(struct dpu_hw_pipe *ctx,
> +	void (*setup_cdp)(struct dpu_hw_sspp *ctx,
>   			struct dpu_hw_cdp_cfg *cfg,
>   			enum dpu_sspp_multirect_index index);
>   };
>   
>   /**
> - * struct dpu_hw_pipe - pipe description
> + * struct dpu_hw_sspp - pipe description
>    * @base: hardware block base structure
>    * @hw: block hardware details
>    * @catalog: back pointer to catalog
> @@ -356,7 +356,7 @@ struct dpu_hw_sspp_ops {
>    * @cap: pointer to layer_cfg
>    * @ops: pointer to operations possible for this pipe
>    */
> -struct dpu_hw_pipe {
> +struct dpu_hw_sspp {
>   	struct dpu_hw_blk base;
>   	struct dpu_hw_blk_reg_map hw;
>   	const struct dpu_mdss_cfg *catalog;
> @@ -378,7 +378,7 @@ struct dpu_kms;
>    * @addr: Mapped register io address of MDP
>    * @catalog : Pointer to mdss catalog data
>    */
> -struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
> +struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
>   		void __iomem *addr, const struct dpu_mdss_cfg *catalog);
>   
>   /**
> @@ -386,10 +386,10 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
>    * should be called during Hw pipe cleanup.
>    * @ctx:  Pointer to SSPP driver context returned by dpu_hw_sspp_init
>    */
> -void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx);
> +void dpu_hw_sspp_destroy(struct dpu_hw_sspp *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);
> +int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, struct dentry *entry);
>   
>   #endif /*_DPU_HW_SSPP_H */
>   
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index bfd5be89e8b8..5a4578ab62a6 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -104,7 +104,7 @@ struct dpu_plane {
>   
>   	enum dpu_sspp pipe;
>   
> -	struct dpu_hw_pipe *pipe_hw;
> +	struct dpu_hw_sspp *pipe_hw;
>   	uint32_t color_fill;
>   	bool is_error;
>   	bool is_rt_pipe;
> @@ -137,7 +137,7 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane)
>    */
>   static void _dpu_plane_calc_bw(struct drm_plane *plane,
>   	struct drm_framebuffer *fb,
> -	struct dpu_hw_pipe_cfg *pipe_cfg)
> +	struct dpu_hw_sspp_cfg *pipe_cfg)
>   {
>   	struct dpu_plane_state *pstate;
>   	struct drm_display_mode *mode;
> @@ -192,7 +192,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
>    * 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 void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_sspp_cfg *pipe_cfg)
>   {
>   	struct dpu_plane_state *pstate;
>   	struct drm_display_mode *mode;
> @@ -276,7 +276,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
>    * @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 drm_framebuffer *fb, struct dpu_hw_sspp_cfg *pipe_cfg)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
>   	const struct dpu_format *fmt = NULL;
> @@ -419,7 +419,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>    * @pipe_cfg:		Pointer to pipe configuration
>    */
>   static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
> -		struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
> +		struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
>   	struct dpu_vbif_set_ot_params ot_params;
> @@ -467,7 +467,7 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
>   
>   static void _dpu_plane_set_scanout(struct drm_plane *plane,
>   		struct dpu_plane_state *pstate,
> -		struct dpu_hw_pipe_cfg *pipe_cfg,
> +		struct dpu_hw_sspp_cfg *pipe_cfg,
>   		struct drm_framebuffer *fb)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
> @@ -635,7 +635,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
>   static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>   		struct dpu_plane_state *pstate,
>   		const struct dpu_format *fmt, bool color_fill,
> -		struct dpu_hw_pipe_cfg *pipe_cfg)
> +		struct dpu_hw_sspp_cfg *pipe_cfg)
>   {
>   	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
>   	struct dpu_hw_scaler3_cfg scaler3_cfg;
> @@ -691,7 +691,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   	const struct dpu_format *fmt;
>   	const struct drm_plane *plane = &pdpu->base;
>   	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
> -	struct dpu_hw_pipe_cfg pipe_cfg;
> +	struct dpu_hw_sspp_cfg pipe_cfg;
>   
>   	DPU_DEBUG_PLANE(pdpu, "\n");
>   
> @@ -1129,9 +1129,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	bool is_rt_pipe;
>   	const struct dpu_format *fmt =
>   		to_dpu_format(msm_framebuffer_format(fb));
> -	struct dpu_hw_pipe_cfg pipe_cfg;
> +	struct dpu_hw_sspp_cfg pipe_cfg;
>   
> -	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
> +	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_sspp_cfg));
>   
>   	_dpu_plane_set_scanout(plane, pstate, &pipe_cfg, fb);
>   

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

* Re: [PATCH v3 01/27] drm/msm/dpu: rename struct dpu_hw_pipe(_cfg) to dpu_hw_sspp(_cfg)
@ 2023-02-03 19:31     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 19:31 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> For all hardware blocks except SSPP the corresponding struct is named
> after the block. Rename dpu_hw_pipe (SSPP structure) to dpu_hw_sspp.
> Also rename struct dpu_hw_pipe_cfg to dpu_hw_sspp_cfg to follow this
> change.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

LGTM now,

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

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 48 +++++++++----------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 52 ++++++++++-----------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 20 ++++----
>   3 files changed, 60 insertions(+), 60 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 4246ab0b3bee..5cf0803e4187 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -136,7 +136,7 @@
>   #define TS_CLK			19200000
>   
>   
> -static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
> +static int _sspp_subblk_offset(struct dpu_hw_sspp *ctx,
>   		int s_id,
>   		u32 *idx)
>   {
> @@ -168,7 +168,7 @@ static int _sspp_subblk_offset(struct dpu_hw_pipe *ctx,
>   	return rc;
>   }
>   
> -static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
> +static void dpu_hw_sspp_setup_multirect(struct dpu_hw_sspp *ctx,
>   		enum dpu_sspp_multirect_index index,
>   		enum dpu_sspp_multirect_mode mode)
>   {
> @@ -197,7 +197,7 @@ static void dpu_hw_sspp_setup_multirect(struct dpu_hw_pipe *ctx,
>   	DPU_REG_WRITE(&ctx->hw, SSPP_MULTIRECT_OPMODE + idx, mode_mask);
>   }
>   
> -static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
> +static void _sspp_setup_opmode(struct dpu_hw_sspp *ctx,
>   		u32 mask, u8 en)
>   {
>   	u32 idx;
> @@ -218,7 +218,7 @@ static void _sspp_setup_opmode(struct dpu_hw_pipe *ctx,
>   	DPU_REG_WRITE(&ctx->hw, SSPP_VIG_OP_MODE + idx, opmode);
>   }
>   
> -static void _sspp_setup_csc10_opmode(struct dpu_hw_pipe *ctx,
> +static void _sspp_setup_csc10_opmode(struct dpu_hw_sspp *ctx,
>   		u32 mask, u8 en)
>   {
>   	u32 idx;
> @@ -239,7 +239,7 @@ 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,
> +static void dpu_hw_sspp_setup_format(struct dpu_hw_sspp *ctx,
>   		const struct dpu_format *fmt, u32 flags,
>   		enum dpu_sspp_multirect_index rect_mode)
>   {
> @@ -360,7 +360,7 @@ static void dpu_hw_sspp_setup_format(struct dpu_hw_pipe *ctx,
>   	DPU_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
>   }
>   
> -static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
> +static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
>   		struct dpu_hw_pixel_ext *pe_ext)
>   {
>   	struct dpu_hw_blk_reg_map *c;
> @@ -418,8 +418,8 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_pipe *ctx,
>   			tot_req_pixels[3]);
>   }
>   
> -static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
> -		struct dpu_hw_pipe_cfg *sspp,
> +static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
> +		struct dpu_hw_sspp_cfg *sspp,
>   		void *scaler_cfg)
>   {
>   	u32 idx;
> @@ -434,7 +434,7 @@ static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_pipe *ctx,
>   			sspp->layout.format);
>   }
>   
> -static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_pipe *ctx)
> +static u32 _dpu_hw_sspp_get_scaler3_ver(struct dpu_hw_sspp *ctx)
>   {
>   	u32 idx;
>   
> @@ -447,8 +447,8 @@ 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,
> +static void dpu_hw_sspp_setup_rects(struct dpu_hw_sspp *ctx,
> +		struct dpu_hw_sspp_cfg *cfg,
>   		enum dpu_sspp_multirect_index rect_index)
>   {
>   	struct dpu_hw_blk_reg_map *c;
> @@ -516,8 +516,8 @@ 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,
> +static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_sspp *ctx,
> +		struct dpu_hw_sspp_cfg *cfg,
>   		enum dpu_sspp_multirect_index rect_mode)
>   {
>   	int i;
> @@ -543,7 +543,7 @@ static void dpu_hw_sspp_setup_sourceaddress(struct dpu_hw_pipe *ctx,
>   	}
>   }
>   
> -static void dpu_hw_sspp_setup_csc(struct dpu_hw_pipe *ctx,
> +static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
>   		const struct dpu_csc_cfg *data)
>   {
>   	u32 idx;
> @@ -560,7 +560,7 @@ 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
> +static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_sspp *ctx, u32 color, enum
>   		dpu_sspp_multirect_index rect_index)
>   {
>   	u32 idx;
> @@ -575,7 +575,7 @@ static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, enum
>   				color);
>   }
>   
> -static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
> +static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_sspp *ctx,
>   			u32 danger_lut,
>   			u32 safe_lut)
>   {
> @@ -588,7 +588,7 @@ static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
>   	DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, safe_lut);
>   }
>   
> -static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
> +static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_sspp *ctx,
>   			u64 creq_lut)
>   {
>   	u32 idx;
> @@ -605,7 +605,7 @@ static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
>   	}
>   }
>   
> -static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe *ctx,
> +static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_sspp *ctx,
>   		struct dpu_hw_pipe_qos_cfg *cfg)
>   {
>   	u32 idx;
> @@ -630,7 +630,7 @@ 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,
> +static void dpu_hw_sspp_setup_cdp(struct dpu_hw_sspp *ctx,
>   		struct dpu_hw_cdp_cfg *cfg,
>   		enum dpu_sspp_multirect_index index)
>   {
> @@ -661,7 +661,7 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
>   	DPU_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl);
>   }
>   
> -static void _setup_layer_ops(struct dpu_hw_pipe *c,
> +static void _setup_layer_ops(struct dpu_hw_sspp *c,
>   		unsigned long features)
>   {
>   	if (test_bit(DPU_SSPP_SRC, &features)) {
> @@ -699,7 +699,7 @@ static void _setup_layer_ops(struct dpu_hw_pipe *c,
>   }
>   
>   #ifdef CONFIG_DEBUG_FS
> -int _dpu_hw_sspp_init_debugfs(struct dpu_hw_pipe *hw_pipe, struct dpu_kms *kms, struct dentry *entry)
> +int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, struct dentry *entry)
>   {
>   	const struct dpu_sspp_cfg *cfg = hw_pipe->cap;
>   	const struct dpu_sspp_sub_blks *sblk = cfg->sblk;
> @@ -783,10 +783,10 @@ static const struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp,
>   	return ERR_PTR(-ENOMEM);
>   }
>   
> -struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
> +struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
>   		void __iomem *addr, const struct dpu_mdss_cfg *catalog)
>   {
> -	struct dpu_hw_pipe *hw_pipe;
> +	struct dpu_hw_sspp *hw_pipe;
>   	const struct dpu_sspp_cfg *cfg;
>   
>   	if (!addr || !catalog)
> @@ -812,7 +812,7 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
>   	return hw_pipe;
>   }
>   
> -void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx)
> +void dpu_hw_sspp_destroy(struct dpu_hw_sspp *ctx)
>   {
>   	kfree(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 0c95b7e64f6c..084206da851b 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -10,7 +10,7 @@
>   #include "dpu_hw_util.h"
>   #include "dpu_formats.h"
>   
> -struct dpu_hw_pipe;
> +struct dpu_hw_sspp;
>   
>   /**
>    * Flags
> @@ -153,7 +153,7 @@ struct dpu_hw_pixel_ext {
>   };
>   
>   /**
> - * struct dpu_hw_pipe_cfg : Pipe description
> + * struct dpu_hw_sspp_cfg : SSPP configuration
>    * @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
> @@ -161,7 +161,7 @@ struct dpu_hw_pixel_ext {
>    * @index:     index of the rectangle of SSPP
>    * @mode:      parallel or time multiplex multirect mode
>    */
> -struct dpu_hw_pipe_cfg {
> +struct dpu_hw_sspp_cfg {
>   	struct dpu_hw_fmt_layout layout;
>   	struct drm_rect src_rect;
>   	struct drm_rect dst_rect;
> @@ -214,7 +214,7 @@ struct dpu_hw_sspp_ops {
>   	 * @flags: Extra flags for format config
>   	 * @index: rectangle index in multirect
>   	 */
> -	void (*setup_format)(struct dpu_hw_pipe *ctx,
> +	void (*setup_format)(struct dpu_hw_sspp *ctx,
>   			const struct dpu_format *fmt, u32 flags,
>   			enum dpu_sspp_multirect_index index);
>   
> @@ -224,8 +224,8 @@ struct dpu_hw_sspp_ops {
>   	 * @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,
> +	void (*setup_rects)(struct dpu_hw_sspp *ctx,
> +			struct dpu_hw_sspp_cfg *cfg,
>   			enum dpu_sspp_multirect_index index);
>   
>   	/**
> @@ -233,7 +233,7 @@ struct dpu_hw_sspp_ops {
>   	 * @ctx: Pointer to pipe context
>   	 * @pe_ext: Pointer to pixel ext settings
>   	 */
> -	void (*setup_pe)(struct dpu_hw_pipe *ctx,
> +	void (*setup_pe)(struct dpu_hw_sspp *ctx,
>   			struct dpu_hw_pixel_ext *pe_ext);
>   
>   	/**
> @@ -242,8 +242,8 @@ struct dpu_hw_sspp_ops {
>   	 * @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,
> +	void (*setup_sourceaddress)(struct dpu_hw_sspp *ctx,
> +			struct dpu_hw_sspp_cfg *cfg,
>   			enum dpu_sspp_multirect_index index);
>   
>   	/**
> @@ -251,7 +251,7 @@ struct dpu_hw_sspp_ops {
>   	 * @ctx: Pointer to pipe context
>   	 * @data: Pointer to config structure
>   	 */
> -	void (*setup_csc)(struct dpu_hw_pipe *ctx, const struct dpu_csc_cfg *data);
> +	void (*setup_csc)(struct dpu_hw_sspp *ctx, const struct dpu_csc_cfg *data);
>   
>   	/**
>   	 * setup_solidfill - enable/disable colorfill
> @@ -260,7 +260,7 @@ struct dpu_hw_sspp_ops {
>   	 * @flags: Pipe flags
>   	 * @index: rectangle index in multirect
>   	 */
> -	void (*setup_solidfill)(struct dpu_hw_pipe *ctx, u32 color,
> +	void (*setup_solidfill)(struct dpu_hw_sspp *ctx, u32 color,
>   			enum dpu_sspp_multirect_index index);
>   
>   	/**
> @@ -270,7 +270,7 @@ struct dpu_hw_sspp_ops {
>   	 * @mode: parallel fetch / time multiplex multirect mode
>   	 */
>   
> -	void (*setup_multirect)(struct dpu_hw_pipe *ctx,
> +	void (*setup_multirect)(struct dpu_hw_sspp *ctx,
>   			enum dpu_sspp_multirect_index index,
>   			enum dpu_sspp_multirect_mode mode);
>   
> @@ -279,7 +279,7 @@ struct dpu_hw_sspp_ops {
>   	 * @ctx: Pointer to pipe context
>   	 * @cfg: Pointer to config structure
>   	 */
> -	void (*setup_sharpening)(struct dpu_hw_pipe *ctx,
> +	void (*setup_sharpening)(struct dpu_hw_sspp *ctx,
>   			struct dpu_hw_sharp_cfg *cfg);
>   
>   	/**
> @@ -289,7 +289,7 @@ struct dpu_hw_sspp_ops {
>   	 * @safe_lut: LUT for generate safe level based on fill level
>   	 *
>   	 */
> -	void (*setup_danger_safe_lut)(struct dpu_hw_pipe *ctx,
> +	void (*setup_danger_safe_lut)(struct dpu_hw_sspp *ctx,
>   			u32 danger_lut,
>   			u32 safe_lut);
>   
> @@ -299,7 +299,7 @@ struct dpu_hw_sspp_ops {
>   	 * @creq_lut: LUT for generate creq level based on fill level
>   	 *
>   	 */
> -	void (*setup_creq_lut)(struct dpu_hw_pipe *ctx,
> +	void (*setup_creq_lut)(struct dpu_hw_sspp *ctx,
>   			u64 creq_lut);
>   
>   	/**
> @@ -308,7 +308,7 @@ struct dpu_hw_sspp_ops {
>   	 * @cfg: Pointer to pipe QoS configuration
>   	 *
>   	 */
> -	void (*setup_qos_ctrl)(struct dpu_hw_pipe *ctx,
> +	void (*setup_qos_ctrl)(struct dpu_hw_sspp *ctx,
>   			struct dpu_hw_pipe_qos_cfg *cfg);
>   
>   	/**
> @@ -316,7 +316,7 @@ struct dpu_hw_sspp_ops {
>   	 * @ctx: Pointer to pipe context
>   	 * @cfg: Pointer to histogram configuration
>   	 */
> -	void (*setup_histogram)(struct dpu_hw_pipe *ctx,
> +	void (*setup_histogram)(struct dpu_hw_sspp *ctx,
>   			void *cfg);
>   
>   	/**
> @@ -325,15 +325,15 @@ struct dpu_hw_sspp_ops {
>   	 * @pipe_cfg: Pointer to pipe configuration
>   	 * @scaler_cfg: Pointer to scaler configuration
>   	 */
> -	void (*setup_scaler)(struct dpu_hw_pipe *ctx,
> -		struct dpu_hw_pipe_cfg *pipe_cfg,
> +	void (*setup_scaler)(struct dpu_hw_sspp *ctx,
> +		struct dpu_hw_sspp_cfg *pipe_cfg,
>   		void *scaler_cfg);
>   
>   	/**
>   	 * get_scaler_ver - get scaler h/w version
>   	 * @ctx: Pointer to pipe context
>   	 */
> -	u32 (*get_scaler_ver)(struct dpu_hw_pipe *ctx);
> +	u32 (*get_scaler_ver)(struct dpu_hw_sspp *ctx);
>   
>   	/**
>   	 * setup_cdp - setup client driven prefetch
> @@ -341,13 +341,13 @@ struct dpu_hw_sspp_ops {
>   	 * @cfg: Pointer to cdp configuration
>   	 * @index: rectangle index in multirect
>   	 */
> -	void (*setup_cdp)(struct dpu_hw_pipe *ctx,
> +	void (*setup_cdp)(struct dpu_hw_sspp *ctx,
>   			struct dpu_hw_cdp_cfg *cfg,
>   			enum dpu_sspp_multirect_index index);
>   };
>   
>   /**
> - * struct dpu_hw_pipe - pipe description
> + * struct dpu_hw_sspp - pipe description
>    * @base: hardware block base structure
>    * @hw: block hardware details
>    * @catalog: back pointer to catalog
> @@ -356,7 +356,7 @@ struct dpu_hw_sspp_ops {
>    * @cap: pointer to layer_cfg
>    * @ops: pointer to operations possible for this pipe
>    */
> -struct dpu_hw_pipe {
> +struct dpu_hw_sspp {
>   	struct dpu_hw_blk base;
>   	struct dpu_hw_blk_reg_map hw;
>   	const struct dpu_mdss_cfg *catalog;
> @@ -378,7 +378,7 @@ struct dpu_kms;
>    * @addr: Mapped register io address of MDP
>    * @catalog : Pointer to mdss catalog data
>    */
> -struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
> +struct dpu_hw_sspp *dpu_hw_sspp_init(enum dpu_sspp idx,
>   		void __iomem *addr, const struct dpu_mdss_cfg *catalog);
>   
>   /**
> @@ -386,10 +386,10 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
>    * should be called during Hw pipe cleanup.
>    * @ctx:  Pointer to SSPP driver context returned by dpu_hw_sspp_init
>    */
> -void dpu_hw_sspp_destroy(struct dpu_hw_pipe *ctx);
> +void dpu_hw_sspp_destroy(struct dpu_hw_sspp *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);
> +int _dpu_hw_sspp_init_debugfs(struct dpu_hw_sspp *hw_pipe, struct dpu_kms *kms, struct dentry *entry);
>   
>   #endif /*_DPU_HW_SSPP_H */
>   
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index bfd5be89e8b8..5a4578ab62a6 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -104,7 +104,7 @@ struct dpu_plane {
>   
>   	enum dpu_sspp pipe;
>   
> -	struct dpu_hw_pipe *pipe_hw;
> +	struct dpu_hw_sspp *pipe_hw;
>   	uint32_t color_fill;
>   	bool is_error;
>   	bool is_rt_pipe;
> @@ -137,7 +137,7 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane)
>    */
>   static void _dpu_plane_calc_bw(struct drm_plane *plane,
>   	struct drm_framebuffer *fb,
> -	struct dpu_hw_pipe_cfg *pipe_cfg)
> +	struct dpu_hw_sspp_cfg *pipe_cfg)
>   {
>   	struct dpu_plane_state *pstate;
>   	struct drm_display_mode *mode;
> @@ -192,7 +192,7 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
>    * 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 void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_sspp_cfg *pipe_cfg)
>   {
>   	struct dpu_plane_state *pstate;
>   	struct drm_display_mode *mode;
> @@ -276,7 +276,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
>    * @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 drm_framebuffer *fb, struct dpu_hw_sspp_cfg *pipe_cfg)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
>   	const struct dpu_format *fmt = NULL;
> @@ -419,7 +419,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>    * @pipe_cfg:		Pointer to pipe configuration
>    */
>   static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
> -		struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
> +		struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
>   	struct dpu_vbif_set_ot_params ot_params;
> @@ -467,7 +467,7 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
>   
>   static void _dpu_plane_set_scanout(struct drm_plane *plane,
>   		struct dpu_plane_state *pstate,
> -		struct dpu_hw_pipe_cfg *pipe_cfg,
> +		struct dpu_hw_sspp_cfg *pipe_cfg,
>   		struct drm_framebuffer *fb)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
> @@ -635,7 +635,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
>   static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>   		struct dpu_plane_state *pstate,
>   		const struct dpu_format *fmt, bool color_fill,
> -		struct dpu_hw_pipe_cfg *pipe_cfg)
> +		struct dpu_hw_sspp_cfg *pipe_cfg)
>   {
>   	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
>   	struct dpu_hw_scaler3_cfg scaler3_cfg;
> @@ -691,7 +691,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   	const struct dpu_format *fmt;
>   	const struct drm_plane *plane = &pdpu->base;
>   	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
> -	struct dpu_hw_pipe_cfg pipe_cfg;
> +	struct dpu_hw_sspp_cfg pipe_cfg;
>   
>   	DPU_DEBUG_PLANE(pdpu, "\n");
>   
> @@ -1129,9 +1129,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	bool is_rt_pipe;
>   	const struct dpu_format *fmt =
>   		to_dpu_format(msm_framebuffer_format(fb));
> -	struct dpu_hw_pipe_cfg pipe_cfg;
> +	struct dpu_hw_sspp_cfg pipe_cfg;
>   
> -	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
> +	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_sspp_cfg));
>   
>   	_dpu_plane_set_scanout(plane, pstate, &pipe_cfg, fb);
>   

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

* Re: [PATCH v3 05/27] drm/msm/dpu: move pipe_hw to dpu_plane_state
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-03 19:34     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 19:34 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> In preparation to adding fully virtualized planes, move struct
> dpu_hw_sspp instance from struct dpu_plane to struct dpu_plane_state, as
> it will become a part of state (variable, changes during runtime) rather
> than part of a plane (ideally should be statically allocated during boot).
> 
> The sspp pointer is set at the dpu_plane_reset(), since this is the
> function which allocates the state. Once we have fully virtual
> plane<->SSPP relationship, the SSPP will be allocated dynamically in the
> dpu_plane_atomic_check() function.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

LGTM now,

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

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 106 ++++++++++++----------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   2 +
>   2 files changed, 61 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index d6518ef1beb2..9eac02f53fc1 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -104,7 +104,6 @@ struct dpu_plane {
>   
>   	enum dpu_sspp pipe;
>   
> -	struct dpu_hw_sspp *pipe_hw;
>   	uint32_t color_fill;
>   	bool is_error;
>   	bool is_rt_pipe;
> @@ -279,6 +278,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
>   		struct drm_framebuffer *fb, struct dpu_hw_sspp_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;
> @@ -310,7 +310,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->hw_sspp->ops.setup_creq_lut(pstate->hw_sspp, qos_lut);
>   }
>   
>   /**
> @@ -322,6 +322,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;
>   
> @@ -361,7 +362,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->hw_sspp->ops.setup_danger_safe_lut(pstate->hw_sspp,
>   			danger_lut, safe_lut);
>   }
>   
> @@ -375,14 +376,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->hw_sspp->cap->sblk->creq_vblank;
>   		pipe_qos_cfg.danger_vblank =
> -				pdpu->pipe_hw->cap->sblk->danger_vblank;
> +				pstate->hw_sspp->cap->sblk->danger_vblank;
>   		pipe_qos_cfg.vblank_en = enable;
>   	}
>   
> @@ -408,7 +410,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->hw_sspp->ops.setup_qos_ctrl(pstate->hw_sspp,
>   			&pipe_qos_cfg);
>   }
>   
> @@ -422,18 +424,19 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
>   		struct drm_crtc *crtc, struct dpu_hw_sspp_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->hw_sspp->cap->xin_id;
> +	ot_params.num = pstate->hw_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 = pdpu->pipe_hw->cap->clk_ctrl;
> +	ot_params.clk_ctrl = pstate->hw_sspp->cap->clk_ctrl;
>   	ot_params.rd = true;
>   
>   	dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
> @@ -446,14 +449,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->hw_sspp->cap->clk_ctrl;
> +	qos_params.xin_id = pstate->hw_sspp->cap->xin_id;
> +	qos_params.num = pstate->hw_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",
> @@ -478,11 +482,11 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
>   	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout);
>   	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->hw_sspp->ops.setup_sourceaddress) {
> +		trace_dpu_plane_set_scanout(pstate->hw_sspp->idx,
>   					    &pipe_cfg->layout,
>   					    pstate->multirect_index);
> -		pdpu->pipe_hw->ops.setup_sourceaddress(pdpu->pipe_hw, pipe_cfg,
> +		pstate->hw_sspp->ops.setup_sourceaddress(pstate->hw_sspp, pipe_cfg,
>   						pstate->multirect_index);
>   	}
>   }
> @@ -534,7 +538,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->hw_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;
> @@ -607,6 +611,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) {
> @@ -617,7 +622,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->hw_sspp->cap->features)
>   		csc_ptr = &dpu_csc10_YUV2RGB_601L;
>   	else
>   		csc_ptr = &dpu_csc_YUV2RGB_601L;
> @@ -660,8 +665,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>   	_dpu_plane_setup_pixel_ext(&scaler3_cfg, &pixel_ext,
>   			src_width, src_height, info->hsub, info->vsub);
>   
> -	if (pdpu->pipe_hw->ops.setup_pe)
> -		pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
> +	if (pstate->hw_sspp->ops.setup_pe)
> +		pstate->hw_sspp->ops.setup_pe(pstate->hw_sspp,
>   				&pixel_ext);
>   
>   	/**
> @@ -669,9 +674,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->hw_sspp->ops.setup_scaler &&
>   			pstate->multirect_index != DPU_SSPP_RECT_1)
> -		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
> +		pstate->hw_sspp->ops.setup_scaler(pstate->hw_sspp,
>   				pipe_cfg,
>   				&scaler3_cfg);
>   }
> @@ -700,8 +705,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->hw_sspp->ops.setup_solidfill) {
> +		pstate->hw_sspp->ops.setup_solidfill(pstate->hw_sspp,
>   				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
>   				pstate->multirect_index);
>   
> @@ -715,13 +720,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->hw_sspp->ops.setup_format)
> +			pstate->hw_sspp->ops.setup_format(pstate->hw_sspp,
>   					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->hw_sspp->ops.setup_rects)
> +			pstate->hw_sspp->ops.setup_rects(pstate->hw_sspp,
>   					&pipe_cfg,
>   					pstate->multirect_index);
>   
> @@ -973,8 +978,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	uint32_t min_src_size, max_linewidth;
>   	unsigned int rotation;
>   	uint32_t supported_rotations;
> -	const struct dpu_sspp_cfg *pipe_hw_caps = pdpu->pipe_hw->cap;
> -	const struct dpu_sspp_sub_blks *sblk = pdpu->pipe_hw->cap->sblk;
> +	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->hw_sspp->cap;
> +	const struct dpu_sspp_sub_blks *sblk = pstate->hw_sspp->cap->sblk;
>   
>   	if (new_plane_state->crtc)
>   		crtc_state = drm_atomic_get_new_crtc_state(state,
> @@ -1087,12 +1092,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->hw_sspp && pstate->hw_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)
> -			pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, csc_ptr);
> +			pstate->hw_sspp->ops.setup_csc(pstate->hw_sspp, csc_ptr);
>   	}
>   
>   	/* flag h/w flush complete */
> @@ -1162,21 +1167,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->hw_sspp->ops.setup_rects) {
> +		pstate->hw_sspp->ops.setup_rects(pstate->hw_sspp,
>   				&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->hw_sspp->ops.setup_multirect)
> +		pstate->hw_sspp->ops.setup_multirect(
> +				pstate->hw_sspp,
>   				pstate->multirect_index,
>   				pstate->multirect_mode);
>   
> -	if (pdpu->pipe_hw->ops.setup_format) {
> +	if (pstate->hw_sspp->ops.setup_format) {
>   		unsigned int rotation = pstate->rotation;
>   
>   		src_flags = 0x0;
> @@ -1191,10 +1196,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   			src_flags |= DPU_SSPP_ROT_90;
>   
>   		/* update format */
> -		pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw, fmt, src_flags,
> +		pstate->hw_sspp->ops.setup_format(pstate->hw_sspp, fmt, src_flags,
>   				pstate->multirect_index);
>   
> -		if (pdpu->pipe_hw->ops.setup_cdp) {
> +		if (pstate->hw_sspp->ops.setup_cdp) {
>   			struct dpu_hw_cdp_cfg cdp_cfg;
>   
>   			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_cdp_cfg));
> @@ -1208,7 +1213,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->hw_sspp->ops.setup_cdp(pstate->hw_sspp, &cdp_cfg, pstate->multirect_index);
>   		}
>   	}
>   
> @@ -1348,10 +1353,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->hw_sspp->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));
>   }
> @@ -1360,6 +1364,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
>   {
>   	struct dpu_plane *pdpu;
>   	struct dpu_plane_state *pstate;
> +	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>   
>   	if (!plane) {
>   		DPU_ERROR("invalid plane\n");
> @@ -1381,6 +1386,12 @@ static void dpu_plane_reset(struct drm_plane *plane)
>   		return;
>   	}
>   
> +	/*
> +	 * Set the SSPP here until we have proper virtualized DPU planes.
> +	 * This is the place where the state is allocated, so fill it fully.
> +	 */
> +	pstate->hw_sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
> +
>   	__drm_atomic_helper_plane_reset(plane, &pstate->base);
>   }
>   
> @@ -1445,6 +1456,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_sspp *pipe_hw;
>   	uint32_t num_formats;
>   	uint32_t supported_rotations;
>   	int ret = -EINVAL;
> @@ -1462,14 +1474,14 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   	pdpu->pipe = pipe;
>   
>   	/* initialize underlying h/w driver */
> -	pdpu->pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
> -	if (!pdpu->pipe_hw || !pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
> +	pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
> +	if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) {
>   		DPU_ERROR("[%u]SSPP is invalid\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,
> @@ -1491,7 +1503,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   
>   	supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
>   
> -	if (pdpu->pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION))
> +	if (pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION))
>   		supported_rotations |= DRM_MODE_ROTATE_MASK;
>   
>   	drm_plane_create_rotation_property(plane,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> index b7b1b05199c2..08a4b6a99f51 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -18,6 +18,7 @@
>    * struct dpu_plane_state: Define dpu extension of drm plane state object
>    * @base:	base drm plane state object
>    * @aspace:	pointer to address space for input/output buffers
> + * @hw_sspp:	pointer to corresponding SSPP instance
>    * @stage:	assigned by crtc blender
>    * @needs_qos_remap: qos remap settings need to be updated
>    * @multirect_index: index of the rectangle of SSPP
> @@ -31,6 +32,7 @@
>   struct dpu_plane_state {
>   	struct drm_plane_state base;
>   	struct msm_gem_address_space *aspace;
> +	struct dpu_hw_sspp *hw_sspp;
>   	enum dpu_stage stage;
>   	bool needs_qos_remap;
>   	uint32_t multirect_index;

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

* Re: [PATCH v3 05/27] drm/msm/dpu: move pipe_hw to dpu_plane_state
@ 2023-02-03 19:34     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 19:34 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> In preparation to adding fully virtualized planes, move struct
> dpu_hw_sspp instance from struct dpu_plane to struct dpu_plane_state, as
> it will become a part of state (variable, changes during runtime) rather
> than part of a plane (ideally should be statically allocated during boot).
> 
> The sspp pointer is set at the dpu_plane_reset(), since this is the
> function which allocates the state. Once we have fully virtual
> plane<->SSPP relationship, the SSPP will be allocated dynamically in the
> dpu_plane_atomic_check() function.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

LGTM now,

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

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 106 ++++++++++++----------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   2 +
>   2 files changed, 61 insertions(+), 47 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index d6518ef1beb2..9eac02f53fc1 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -104,7 +104,6 @@ struct dpu_plane {
>   
>   	enum dpu_sspp pipe;
>   
> -	struct dpu_hw_sspp *pipe_hw;
>   	uint32_t color_fill;
>   	bool is_error;
>   	bool is_rt_pipe;
> @@ -279,6 +278,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
>   		struct drm_framebuffer *fb, struct dpu_hw_sspp_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;
> @@ -310,7 +310,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->hw_sspp->ops.setup_creq_lut(pstate->hw_sspp, qos_lut);
>   }
>   
>   /**
> @@ -322,6 +322,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;
>   
> @@ -361,7 +362,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->hw_sspp->ops.setup_danger_safe_lut(pstate->hw_sspp,
>   			danger_lut, safe_lut);
>   }
>   
> @@ -375,14 +376,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->hw_sspp->cap->sblk->creq_vblank;
>   		pipe_qos_cfg.danger_vblank =
> -				pdpu->pipe_hw->cap->sblk->danger_vblank;
> +				pstate->hw_sspp->cap->sblk->danger_vblank;
>   		pipe_qos_cfg.vblank_en = enable;
>   	}
>   
> @@ -408,7 +410,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->hw_sspp->ops.setup_qos_ctrl(pstate->hw_sspp,
>   			&pipe_qos_cfg);
>   }
>   
> @@ -422,18 +424,19 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
>   		struct drm_crtc *crtc, struct dpu_hw_sspp_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->hw_sspp->cap->xin_id;
> +	ot_params.num = pstate->hw_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 = pdpu->pipe_hw->cap->clk_ctrl;
> +	ot_params.clk_ctrl = pstate->hw_sspp->cap->clk_ctrl;
>   	ot_params.rd = true;
>   
>   	dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
> @@ -446,14 +449,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->hw_sspp->cap->clk_ctrl;
> +	qos_params.xin_id = pstate->hw_sspp->cap->xin_id;
> +	qos_params.num = pstate->hw_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",
> @@ -478,11 +482,11 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
>   	ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout);
>   	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->hw_sspp->ops.setup_sourceaddress) {
> +		trace_dpu_plane_set_scanout(pstate->hw_sspp->idx,
>   					    &pipe_cfg->layout,
>   					    pstate->multirect_index);
> -		pdpu->pipe_hw->ops.setup_sourceaddress(pdpu->pipe_hw, pipe_cfg,
> +		pstate->hw_sspp->ops.setup_sourceaddress(pstate->hw_sspp, pipe_cfg,
>   						pstate->multirect_index);
>   	}
>   }
> @@ -534,7 +538,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->hw_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;
> @@ -607,6 +611,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) {
> @@ -617,7 +622,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->hw_sspp->cap->features)
>   		csc_ptr = &dpu_csc10_YUV2RGB_601L;
>   	else
>   		csc_ptr = &dpu_csc_YUV2RGB_601L;
> @@ -660,8 +665,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
>   	_dpu_plane_setup_pixel_ext(&scaler3_cfg, &pixel_ext,
>   			src_width, src_height, info->hsub, info->vsub);
>   
> -	if (pdpu->pipe_hw->ops.setup_pe)
> -		pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
> +	if (pstate->hw_sspp->ops.setup_pe)
> +		pstate->hw_sspp->ops.setup_pe(pstate->hw_sspp,
>   				&pixel_ext);
>   
>   	/**
> @@ -669,9 +674,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->hw_sspp->ops.setup_scaler &&
>   			pstate->multirect_index != DPU_SSPP_RECT_1)
> -		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
> +		pstate->hw_sspp->ops.setup_scaler(pstate->hw_sspp,
>   				pipe_cfg,
>   				&scaler3_cfg);
>   }
> @@ -700,8 +705,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->hw_sspp->ops.setup_solidfill) {
> +		pstate->hw_sspp->ops.setup_solidfill(pstate->hw_sspp,
>   				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
>   				pstate->multirect_index);
>   
> @@ -715,13 +720,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->hw_sspp->ops.setup_format)
> +			pstate->hw_sspp->ops.setup_format(pstate->hw_sspp,
>   					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->hw_sspp->ops.setup_rects)
> +			pstate->hw_sspp->ops.setup_rects(pstate->hw_sspp,
>   					&pipe_cfg,
>   					pstate->multirect_index);
>   
> @@ -973,8 +978,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	uint32_t min_src_size, max_linewidth;
>   	unsigned int rotation;
>   	uint32_t supported_rotations;
> -	const struct dpu_sspp_cfg *pipe_hw_caps = pdpu->pipe_hw->cap;
> -	const struct dpu_sspp_sub_blks *sblk = pdpu->pipe_hw->cap->sblk;
> +	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->hw_sspp->cap;
> +	const struct dpu_sspp_sub_blks *sblk = pstate->hw_sspp->cap->sblk;
>   
>   	if (new_plane_state->crtc)
>   		crtc_state = drm_atomic_get_new_crtc_state(state,
> @@ -1087,12 +1092,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->hw_sspp && pstate->hw_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)
> -			pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, csc_ptr);
> +			pstate->hw_sspp->ops.setup_csc(pstate->hw_sspp, csc_ptr);
>   	}
>   
>   	/* flag h/w flush complete */
> @@ -1162,21 +1167,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->hw_sspp->ops.setup_rects) {
> +		pstate->hw_sspp->ops.setup_rects(pstate->hw_sspp,
>   				&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->hw_sspp->ops.setup_multirect)
> +		pstate->hw_sspp->ops.setup_multirect(
> +				pstate->hw_sspp,
>   				pstate->multirect_index,
>   				pstate->multirect_mode);
>   
> -	if (pdpu->pipe_hw->ops.setup_format) {
> +	if (pstate->hw_sspp->ops.setup_format) {
>   		unsigned int rotation = pstate->rotation;
>   
>   		src_flags = 0x0;
> @@ -1191,10 +1196,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   			src_flags |= DPU_SSPP_ROT_90;
>   
>   		/* update format */
> -		pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw, fmt, src_flags,
> +		pstate->hw_sspp->ops.setup_format(pstate->hw_sspp, fmt, src_flags,
>   				pstate->multirect_index);
>   
> -		if (pdpu->pipe_hw->ops.setup_cdp) {
> +		if (pstate->hw_sspp->ops.setup_cdp) {
>   			struct dpu_hw_cdp_cfg cdp_cfg;
>   
>   			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_cdp_cfg));
> @@ -1208,7 +1213,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->hw_sspp->ops.setup_cdp(pstate->hw_sspp, &cdp_cfg, pstate->multirect_index);
>   		}
>   	}
>   
> @@ -1348,10 +1353,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->hw_sspp->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));
>   }
> @@ -1360,6 +1364,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
>   {
>   	struct dpu_plane *pdpu;
>   	struct dpu_plane_state *pstate;
> +	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
>   
>   	if (!plane) {
>   		DPU_ERROR("invalid plane\n");
> @@ -1381,6 +1386,12 @@ static void dpu_plane_reset(struct drm_plane *plane)
>   		return;
>   	}
>   
> +	/*
> +	 * Set the SSPP here until we have proper virtualized DPU planes.
> +	 * This is the place where the state is allocated, so fill it fully.
> +	 */
> +	pstate->hw_sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
> +
>   	__drm_atomic_helper_plane_reset(plane, &pstate->base);
>   }
>   
> @@ -1445,6 +1456,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_sspp *pipe_hw;
>   	uint32_t num_formats;
>   	uint32_t supported_rotations;
>   	int ret = -EINVAL;
> @@ -1462,14 +1474,14 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   	pdpu->pipe = pipe;
>   
>   	/* initialize underlying h/w driver */
> -	pdpu->pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
> -	if (!pdpu->pipe_hw || !pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
> +	pipe_hw = dpu_rm_get_sspp(&kms->rm, pipe);
> +	if (!pipe_hw || !pipe_hw->cap || !pipe_hw->cap->sblk) {
>   		DPU_ERROR("[%u]SSPP is invalid\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,
> @@ -1491,7 +1503,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
>   
>   	supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
>   
> -	if (pdpu->pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION))
> +	if (pipe_hw->cap->features & BIT(DPU_SSPP_INLINE_ROTATION))
>   		supported_rotations |= DRM_MODE_ROTATE_MASK;
>   
>   	drm_plane_create_rotation_property(plane,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> index b7b1b05199c2..08a4b6a99f51 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -18,6 +18,7 @@
>    * struct dpu_plane_state: Define dpu extension of drm plane state object
>    * @base:	base drm plane state object
>    * @aspace:	pointer to address space for input/output buffers
> + * @hw_sspp:	pointer to corresponding SSPP instance
>    * @stage:	assigned by crtc blender
>    * @needs_qos_remap: qos remap settings need to be updated
>    * @multirect_index: index of the rectangle of SSPP
> @@ -31,6 +32,7 @@
>   struct dpu_plane_state {
>   	struct drm_plane_state base;
>   	struct msm_gem_address_space *aspace;
> +	struct dpu_hw_sspp *hw_sspp;
>   	enum dpu_stage stage;
>   	bool needs_qos_remap;
>   	uint32_t multirect_index;

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

* Re: [PATCH v3 09/27] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-03 19:36     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 19:36 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> There is no need to pass full dpu_hw_sspp_cfg instance to
> _dpu_hw_sspp_setup_scaler3, pass just struct dpu_format pointer.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

LGTM now,

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

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 9 ++++-----
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 9 ++++-----
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 4 ++--
>   3 files changed, 10 insertions(+), 12 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 4d3ca8532563..abf499275242 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -419,19 +419,18 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
>   }
>   
>   static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
> -		struct dpu_hw_sspp_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_sspp *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 8d566ad1877e..5e9b07090a21 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -317,13 +317,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
> +	 * @scaler3_cfg: Pointer to scaler configuration
> +	 * @format: pixel format parameters
>   	 */
>   	void (*setup_scaler)(struct dpu_hw_sspp *ctx,
> -		struct dpu_hw_sspp_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 8f1767619d06..4f5c44d78332 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -677,8 +677,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] 176+ messages in thread

* Re: [PATCH v3 09/27] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3()
@ 2023-02-03 19:36     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 19:36 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> There is no need to pass full dpu_hw_sspp_cfg instance to
> _dpu_hw_sspp_setup_scaler3, pass just struct dpu_format pointer.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

LGTM now,

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

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 9 ++++-----
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 9 ++++-----
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 4 ++--
>   3 files changed, 10 insertions(+), 12 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 4d3ca8532563..abf499275242 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -419,19 +419,18 @@ static void dpu_hw_sspp_setup_pe_config(struct dpu_hw_sspp *ctx,
>   }
>   
>   static void _dpu_hw_sspp_setup_scaler3(struct dpu_hw_sspp *ctx,
> -		struct dpu_hw_sspp_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_sspp *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 8d566ad1877e..5e9b07090a21 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -317,13 +317,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
> +	 * @scaler3_cfg: Pointer to scaler configuration
> +	 * @format: pixel format parameters
>   	 */
>   	void (*setup_scaler)(struct dpu_hw_sspp *ctx,
> -		struct dpu_hw_sspp_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 8f1767619d06..4f5c44d78332 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -677,8 +677,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] 176+ messages in thread

* Re: [PATCH v3 10/27] drm/msm/dpu: clean up SRC addresses when setting up SSPP for solid fill
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-03 20:36     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 20:36 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Set SSPP_SRCn_ADDR registers to 0 while setting up solid fill, as we can
> not be sure that the previous address is still valid.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

I am yet to confirm with HW team if programming 0 stride and 0 address 
is absolutely needed for solid fill or not.

Ideally, in solid fill mode these should just be ignored by the HW.

But this change and the next wont break anything. Should just be a no-op 
for HW.

Hence,

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

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 5 +++++
>   1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> index abf499275242..4c05f4b5e050 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -563,11 +563,16 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
>   static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
>   {
>   	struct dpu_hw_sspp *ctx = pipe->sspp;
> +	struct dpu_hw_sspp_cfg cfg;
>   	u32 idx;
>   
>   	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
>   		return;
>   
> +	/* cleanup source addresses */
> +	memset(&cfg, 0, sizeof(cfg));
> +	ctx->ops.setup_sourceaddress(pipe, &cfg);
> +
>   	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);

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

* Re: [PATCH v3 10/27] drm/msm/dpu: clean up SRC addresses when setting up SSPP for solid fill
@ 2023-02-03 20:36     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 20:36 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Set SSPP_SRCn_ADDR registers to 0 while setting up solid fill, as we can
> not be sure that the previous address is still valid.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

I am yet to confirm with HW team if programming 0 stride and 0 address 
is absolutely needed for solid fill or not.

Ideally, in solid fill mode these should just be ignored by the HW.

But this change and the next wont break anything. Should just be a no-op 
for HW.

Hence,

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

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 5 +++++
>   1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> index abf499275242..4c05f4b5e050 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -563,11 +563,16 @@ static void dpu_hw_sspp_setup_csc(struct dpu_hw_sspp *ctx,
>   static void dpu_hw_sspp_setup_solidfill(struct dpu_sw_pipe *pipe, u32 color)
>   {
>   	struct dpu_hw_sspp *ctx = pipe->sspp;
> +	struct dpu_hw_sspp_cfg cfg;
>   	u32 idx;
>   
>   	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
>   		return;
>   
> +	/* cleanup source addresses */
> +	memset(&cfg, 0, sizeof(cfg));
> +	ctx->ops.setup_sourceaddress(pipe, &cfg);
> +
>   	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);

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

* Re: [PATCH v3 11/27] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-03 20:37     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 20:37 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 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>

Now with the prev change, this is

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

> ---
>   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 4c05f4b5e050..fbfb39a7a229 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -451,7 +451,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
>   {
>   	struct dpu_hw_sspp *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;
>   
> @@ -482,44 +482,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_sspp_cfg *cfg)
>   {
>   	struct dpu_hw_sspp *ctx = pipe->sspp;
> +	u32 ystride0, ystride1;
>   	int i;
>   	u32 idx;
>   
> @@ -541,6 +515,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_sspp *ctx,

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

* Re: [PATCH v3 11/27] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress
@ 2023-02-03 20:37     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 20:37 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 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>

Now with the prev change, this is

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

> ---
>   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 4c05f4b5e050..fbfb39a7a229 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -451,7 +451,7 @@ static void dpu_hw_sspp_setup_rects(struct dpu_sw_pipe *pipe,
>   {
>   	struct dpu_hw_sspp *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;
>   
> @@ -482,44 +482,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_sspp_cfg *cfg)
>   {
>   	struct dpu_hw_sspp *ctx = pipe->sspp;
> +	u32 ystride0, ystride1;
>   	int i;
>   	u32 idx;
>   
> @@ -541,6 +515,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_sspp *ctx,

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

* Re: [PATCH v3 14/27] drm/msm/dpu: don't use unsupported blend stages
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-03 20:42     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 20:42 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> The dpu_crtc_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>

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

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 16 ++++++++--------
>   1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index c1579d6f5060..b485234eefb2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1129,6 +1129,7 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>   
>   	const struct drm_plane_state *pstate;
>   	struct drm_plane *plane;
> @@ -1164,7 +1165,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
>   		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
>   		struct drm_rect dst, clip = crtc_rect;
> -		int z_pos;
> +		int stage;
>   
>   		if (IS_ERR_OR_NULL(pstate)) {
>   			rc = PTR_ERR(pstate);
> @@ -1189,17 +1190,16 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   			return -E2BIG;
>   		}
>   
> -		z_pos = pstate->normalized_zpos;
> -
> -		/* verify z_pos setting before using it */
> -		if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
> +		/* verify stage setting before using it */
> +		stage = DPU_STAGE_0 + pstate->normalized_zpos;
> +		if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
>   			DPU_ERROR("> %d plane stages assigned\n",
> -					DPU_STAGE_MAX - DPU_STAGE_0);
> +					dpu_kms->catalog->caps->max_mixer_blendstages - 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);
> +		to_dpu_plane_state(pstate)->stage = stage;
> +		DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
>   
>   	}
>   

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

* Re: [PATCH v3 14/27] drm/msm/dpu: don't use unsupported blend stages
@ 2023-02-03 20:42     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 20:42 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> The dpu_crtc_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>

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

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 16 ++++++++--------
>   1 file changed, 8 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index c1579d6f5060..b485234eefb2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1129,6 +1129,7 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>   
>   	const struct drm_plane_state *pstate;
>   	struct drm_plane *plane;
> @@ -1164,7 +1165,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
>   		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
>   		struct drm_rect dst, clip = crtc_rect;
> -		int z_pos;
> +		int stage;
>   
>   		if (IS_ERR_OR_NULL(pstate)) {
>   			rc = PTR_ERR(pstate);
> @@ -1189,17 +1190,16 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   			return -E2BIG;
>   		}
>   
> -		z_pos = pstate->normalized_zpos;
> -
> -		/* verify z_pos setting before using it */
> -		if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
> +		/* verify stage setting before using it */
> +		stage = DPU_STAGE_0 + pstate->normalized_zpos;
> +		if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
>   			DPU_ERROR("> %d plane stages assigned\n",
> -					DPU_STAGE_MAX - DPU_STAGE_0);
> +					dpu_kms->catalog->caps->max_mixer_blendstages - 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);
> +		to_dpu_plane_state(pstate)->stage = stage;
> +		DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
>   
>   	}
>   

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

* Re: [PATCH v3 15/27] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-03 22:44     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 22:44 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Move plane state updates from dpu_crtc_atomic_check() to the function
> where they belong: to dpu_plane_atomic_check().
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-----------------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++++++++++--------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ------
>   3 files changed, 11 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index b485234eefb2..bd09bb319a58 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1129,7 +1129,6 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>   
>   	const struct drm_plane_state *pstate;
>   	struct drm_plane *plane;
> @@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   	crtc_rect.x2 = mode->hdisplay;
>   	crtc_rect.y2 = mode->vdisplay;
>   
> -	 /* get plane state for all drm planes associated with crtc state */
> +	/* FIXME: move this to dpu_plane_atomic_check? */
>   	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
>   		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
>   		struct drm_rect dst, clip = crtc_rect;
> -		int stage;
>   
>   		if (IS_ERR_OR_NULL(pstate)) {
>   			rc = PTR_ERR(pstate);
> @@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   
>   		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
>   
> -		dpu_plane_clear_multirect(pstate);
> -
>   		dst = drm_plane_state_dest(pstate);
>   		if (!drm_rect_intersect(&clip, &dst)) {
>   			DPU_ERROR("invalid vertical/horizontal destination\n");
> @@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   				  DRM_RECT_ARG(&dst));
>   			return -E2BIG;
>   		}
> -
> -		/* verify stage setting before using it */
> -		stage = DPU_STAGE_0 + pstate->normalized_zpos;
> -		if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
> -			DPU_ERROR("> %d plane stages assigned\n",
> -					dpu_kms->catalog->caps->max_mixer_blendstages - DPU_STAGE_0);
> -			return -EINVAL;
> -		}
> -
> -		to_dpu_plane_state(pstate)->stage = stage;
> -		DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
> -
>   	}
>   
>   	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 1b3033b15bfa..5aabf9694a53 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -733,14 +733,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];
> @@ -994,6 +986,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;
> +

But I am not sure if clearing the multirect belongs here and now I want 
to clarify one thing about 
https://patchwork.freedesktop.org/patch/521354/?series=99909&rev=4 which 
was R-bed in the v1 and carried fwd since then.

So prior to that change, we were only clearing the multirects of the 
planes that were staged to the crtc and we were getting those from the 
crtc state. But now we are clearing the multirect of all the planes.

Dont we have to keep that in the crtc_atomic_check() since we do that on 
all the planes attached to a certain CRTC.

In that case shouldnt we keep this in the crtc_atomic_check() and bring 
back pipe_staged[] without the multirect and source split cases ofcourse.

> +	pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
> +	if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
> +		DPU_ERROR("> %d plane stages assigned\n",
> +				pdpu->catalog->caps->max_mixer_blendstages - DPU_STAGE_0);
> +		return -EINVAL;
> +	}
> +

I agree that this check belongs to the plane_atomic_check().

>   	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 228db401e905..a08b0539513b 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -88,12 +88,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] 176+ messages in thread

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



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Move plane state updates from dpu_crtc_atomic_check() to the function
> where they belong: to dpu_plane_atomic_check().
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-----------------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++++++++++--------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ------
>   3 files changed, 11 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index b485234eefb2..bd09bb319a58 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1129,7 +1129,6 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>   
>   	const struct drm_plane_state *pstate;
>   	struct drm_plane *plane;
> @@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   	crtc_rect.x2 = mode->hdisplay;
>   	crtc_rect.y2 = mode->vdisplay;
>   
> -	 /* get plane state for all drm planes associated with crtc state */
> +	/* FIXME: move this to dpu_plane_atomic_check? */
>   	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
>   		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
>   		struct drm_rect dst, clip = crtc_rect;
> -		int stage;
>   
>   		if (IS_ERR_OR_NULL(pstate)) {
>   			rc = PTR_ERR(pstate);
> @@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   
>   		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
>   
> -		dpu_plane_clear_multirect(pstate);
> -
>   		dst = drm_plane_state_dest(pstate);
>   		if (!drm_rect_intersect(&clip, &dst)) {
>   			DPU_ERROR("invalid vertical/horizontal destination\n");
> @@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   				  DRM_RECT_ARG(&dst));
>   			return -E2BIG;
>   		}
> -
> -		/* verify stage setting before using it */
> -		stage = DPU_STAGE_0 + pstate->normalized_zpos;
> -		if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
> -			DPU_ERROR("> %d plane stages assigned\n",
> -					dpu_kms->catalog->caps->max_mixer_blendstages - DPU_STAGE_0);
> -			return -EINVAL;
> -		}
> -
> -		to_dpu_plane_state(pstate)->stage = stage;
> -		DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
> -
>   	}
>   
>   	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 1b3033b15bfa..5aabf9694a53 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -733,14 +733,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];
> @@ -994,6 +986,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;
> +

But I am not sure if clearing the multirect belongs here and now I want 
to clarify one thing about 
https://patchwork.freedesktop.org/patch/521354/?series=99909&rev=4 which 
was R-bed in the v1 and carried fwd since then.

So prior to that change, we were only clearing the multirects of the 
planes that were staged to the crtc and we were getting those from the 
crtc state. But now we are clearing the multirect of all the planes.

Dont we have to keep that in the crtc_atomic_check() since we do that on 
all the planes attached to a certain CRTC.

In that case shouldnt we keep this in the crtc_atomic_check() and bring 
back pipe_staged[] without the multirect and source split cases ofcourse.

> +	pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
> +	if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
> +		DPU_ERROR("> %d plane stages assigned\n",
> +				pdpu->catalog->caps->max_mixer_blendstages - DPU_STAGE_0);
> +		return -EINVAL;
> +	}
> +

I agree that this check belongs to the plane_atomic_check().

>   	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 228db401e905..a08b0539513b 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -88,12 +88,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] 176+ messages in thread

* Re: [PATCH v3 15/27] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
  2023-02-03 22:44     ` Abhinav Kumar
@ 2023-02-03 22:55       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 22:55 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 04/02/2023 00:44, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Move plane state updates from dpu_crtc_atomic_check() to the function
>> where they belong: to dpu_plane_atomic_check().
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-----------------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++++++++++--------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ------
>>   3 files changed, 11 insertions(+), 31 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> index b485234eefb2..bd09bb319a58 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> @@ -1129,7 +1129,6 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>>       const struct drm_plane_state *pstate;
>>       struct drm_plane *plane;
>> @@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct 
>> drm_crtc *crtc,
>>       crtc_rect.x2 = mode->hdisplay;
>>       crtc_rect.y2 = mode->vdisplay;
>> -     /* get plane state for all drm planes associated with crtc state */
>> +    /* FIXME: move this to dpu_plane_atomic_check? */
>>       drm_atomic_crtc_state_for_each_plane_state(plane, pstate, 
>> crtc_state) {
>>           struct dpu_plane_state *dpu_pstate = 
>> to_dpu_plane_state(pstate);
>>           struct drm_rect dst, clip = crtc_rect;
>> -        int stage;
>>           if (IS_ERR_OR_NULL(pstate)) {
>>               rc = PTR_ERR(pstate);
>> @@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
>> *crtc,
>>           dpu_pstate->needs_dirtyfb = needs_dirtyfb;
>> -        dpu_plane_clear_multirect(pstate);
>> -
>>           dst = drm_plane_state_dest(pstate);
>>           if (!drm_rect_intersect(&clip, &dst)) {
>>               DPU_ERROR("invalid vertical/horizontal destination\n");
>> @@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct 
>> drm_crtc *crtc,
>>                     DRM_RECT_ARG(&dst));
>>               return -E2BIG;
>>           }
>> -
>> -        /* verify stage setting before using it */
>> -        stage = DPU_STAGE_0 + pstate->normalized_zpos;
>> -        if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
>> -            DPU_ERROR("> %d plane stages assigned\n",
>> -                    dpu_kms->catalog->caps->max_mixer_blendstages - 
>> DPU_STAGE_0);
>> -            return -EINVAL;
>> -        }
>> -
>> -        to_dpu_plane_state(pstate)->stage = stage;
>> -        DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
>> -
>>       }
>>       atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 1b3033b15bfa..5aabf9694a53 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -733,14 +733,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];
>> @@ -994,6 +986,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;
>> +
> 
> But I am not sure if clearing the multirect belongs here and now I want 
> to clarify one thing about 
> https://patchwork.freedesktop.org/patch/521354/?series=99909&rev=4 which 
> was R-bed in the v1 and carried fwd since then.
> 
> So prior to that change, we were only clearing the multirects of the 
> planes that were staged to the crtc and we were getting those from the 
> crtc state. But now we are clearing the multirect of all the planes.
> 
> Dont we have to keep that in the crtc_atomic_check() since we do that on 
> all the planes attached to a certain CRTC.
> 
> In that case shouldnt we keep this in the crtc_atomic_check() and bring 
> back pipe_staged[] without the multirect and source split cases ofcourse.

What for? In other words, what would be the difference?

> 
>> +    pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
>> +    if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
>> +        DPU_ERROR("> %d plane stages assigned\n",
>> +                pdpu->catalog->caps->max_mixer_blendstages - 
>> DPU_STAGE_0);
>> +        return -EINVAL;
>> +    }
>> +
> 
> I agree that this check belongs to the plane_atomic_check().
> 
>>       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 228db401e905..a08b0539513b 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>> @@ -88,12 +88,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

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 15/27] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
@ 2023-02-03 22:55       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 22:55 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 04/02/2023 00:44, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Move plane state updates from dpu_crtc_atomic_check() to the function
>> where they belong: to dpu_plane_atomic_check().
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-----------------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++++++++++--------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ------
>>   3 files changed, 11 insertions(+), 31 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> index b485234eefb2..bd09bb319a58 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> @@ -1129,7 +1129,6 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>>       const struct drm_plane_state *pstate;
>>       struct drm_plane *plane;
>> @@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct 
>> drm_crtc *crtc,
>>       crtc_rect.x2 = mode->hdisplay;
>>       crtc_rect.y2 = mode->vdisplay;
>> -     /* get plane state for all drm planes associated with crtc state */
>> +    /* FIXME: move this to dpu_plane_atomic_check? */
>>       drm_atomic_crtc_state_for_each_plane_state(plane, pstate, 
>> crtc_state) {
>>           struct dpu_plane_state *dpu_pstate = 
>> to_dpu_plane_state(pstate);
>>           struct drm_rect dst, clip = crtc_rect;
>> -        int stage;
>>           if (IS_ERR_OR_NULL(pstate)) {
>>               rc = PTR_ERR(pstate);
>> @@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
>> *crtc,
>>           dpu_pstate->needs_dirtyfb = needs_dirtyfb;
>> -        dpu_plane_clear_multirect(pstate);
>> -
>>           dst = drm_plane_state_dest(pstate);
>>           if (!drm_rect_intersect(&clip, &dst)) {
>>               DPU_ERROR("invalid vertical/horizontal destination\n");
>> @@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct 
>> drm_crtc *crtc,
>>                     DRM_RECT_ARG(&dst));
>>               return -E2BIG;
>>           }
>> -
>> -        /* verify stage setting before using it */
>> -        stage = DPU_STAGE_0 + pstate->normalized_zpos;
>> -        if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
>> -            DPU_ERROR("> %d plane stages assigned\n",
>> -                    dpu_kms->catalog->caps->max_mixer_blendstages - 
>> DPU_STAGE_0);
>> -            return -EINVAL;
>> -        }
>> -
>> -        to_dpu_plane_state(pstate)->stage = stage;
>> -        DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
>> -
>>       }
>>       atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 1b3033b15bfa..5aabf9694a53 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -733,14 +733,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];
>> @@ -994,6 +986,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;
>> +
> 
> But I am not sure if clearing the multirect belongs here and now I want 
> to clarify one thing about 
> https://patchwork.freedesktop.org/patch/521354/?series=99909&rev=4 which 
> was R-bed in the v1 and carried fwd since then.
> 
> So prior to that change, we were only clearing the multirects of the 
> planes that were staged to the crtc and we were getting those from the 
> crtc state. But now we are clearing the multirect of all the planes.
> 
> Dont we have to keep that in the crtc_atomic_check() since we do that on 
> all the planes attached to a certain CRTC.
> 
> In that case shouldnt we keep this in the crtc_atomic_check() and bring 
> back pipe_staged[] without the multirect and source split cases ofcourse.

What for? In other words, what would be the difference?

> 
>> +    pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
>> +    if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
>> +        DPU_ERROR("> %d plane stages assigned\n",
>> +                pdpu->catalog->caps->max_mixer_blendstages - 
>> DPU_STAGE_0);
>> +        return -EINVAL;
>> +    }
>> +
> 
> I agree that this check belongs to the plane_atomic_check().
> 
>>       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 228db401e905..a08b0539513b 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>> @@ -88,12 +88,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

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 16/27] drm/msm/dpu: drop redundant plane dst check from dpu_crtc_atomic_check()
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-03 22:57     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 22:57 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> The helper drm_atomic_helper_check_plane_state() already checks whether
> the scaled and clipped plane falls into the CRTC visible region (and
> clears plane_state->visible if it doesn't). Drop the redundant check
> from dpu_crtc_atomic_check().
> 
> 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 | 16 ----------------
>   1 file changed, 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index bd09bb319a58..73e1a8c69ef0 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1132,11 +1132,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   
>   	const struct drm_plane_state *pstate;
>   	struct drm_plane *plane;
> -	struct drm_display_mode *mode;
>   
>   	int rc = 0;
>   
> -	struct drm_rect crtc_rect = { 0 };
>   	bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
>   
>   	if (!crtc_state->enable || !crtc_state->active) {
> @@ -1147,7 +1145,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   		return 0;
>   	}
>   
> -	mode = &crtc_state->adjusted_mode;
>   	DRM_DEBUG_ATOMIC("%s: check\n", dpu_crtc->name);
>   
>   	/* force a full mode set if active state changed */
> @@ -1157,13 +1154,9 @@ 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;
> -
>   	/* FIXME: move this to dpu_plane_atomic_check? */
>   	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
>   		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
> -		struct drm_rect dst, clip = crtc_rect;
>   
>   		if (IS_ERR_OR_NULL(pstate)) {
>   			rc = PTR_ERR(pstate);
> @@ -1176,15 +1169,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   			continue;
>   
>   		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
> -
> -		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;
> -		}
>   	}
>   
>   	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);

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

* Re: [PATCH v3 16/27] drm/msm/dpu: drop redundant plane dst check from dpu_crtc_atomic_check()
@ 2023-02-03 22:57     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 22:57 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> The helper drm_atomic_helper_check_plane_state() already checks whether
> the scaled and clipped plane falls into the CRTC visible region (and
> clears plane_state->visible if it doesn't). Drop the redundant check
> from dpu_crtc_atomic_check().
> 
> 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 | 16 ----------------
>   1 file changed, 16 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index bd09bb319a58..73e1a8c69ef0 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -1132,11 +1132,9 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   
>   	const struct drm_plane_state *pstate;
>   	struct drm_plane *plane;
> -	struct drm_display_mode *mode;
>   
>   	int rc = 0;
>   
> -	struct drm_rect crtc_rect = { 0 };
>   	bool needs_dirtyfb = dpu_crtc_needs_dirtyfb(crtc_state);
>   
>   	if (!crtc_state->enable || !crtc_state->active) {
> @@ -1147,7 +1145,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   		return 0;
>   	}
>   
> -	mode = &crtc_state->adjusted_mode;
>   	DRM_DEBUG_ATOMIC("%s: check\n", dpu_crtc->name);
>   
>   	/* force a full mode set if active state changed */
> @@ -1157,13 +1154,9 @@ 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;
> -
>   	/* FIXME: move this to dpu_plane_atomic_check? */
>   	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
>   		struct dpu_plane_state *dpu_pstate = to_dpu_plane_state(pstate);
> -		struct drm_rect dst, clip = crtc_rect;
>   
>   		if (IS_ERR_OR_NULL(pstate)) {
>   			rc = PTR_ERR(pstate);
> @@ -1176,15 +1169,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
>   			continue;
>   
>   		dpu_pstate->needs_dirtyfb = needs_dirtyfb;
> -
> -		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;
> -		}
>   	}
>   
>   	atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);

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

* Re: [PATCH v3 17/27] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-03 23:07     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 23:07 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> 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>

Nothing wrong with the change as such but why is this needed?
I looked through tne next patches in the series briefly and unless I am 
missing something, I am not able to see how this rewrite is helping or 
needed for the remaining patches.

> ---
>   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 5aabf9694a53..ee261a591d45 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -128,19 +128,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_sspp_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;
> @@ -152,8 +151,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);
> @@ -217,25 +214,25 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_sspp_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 */
> @@ -251,7 +248,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 {
> @@ -261,7 +258,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);
>   
> @@ -271,25 +268,22 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
>   /**
>    * _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_sspp_cfg *pipe_cfg)
> +		struct dpu_sw_pipe *pipe,
> +		const struct dpu_format *fmt, struct dpu_hw_sspp_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))
> @@ -301,7 +295,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
>   	qos_lut = _dpu_hw_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);
>   
> @@ -310,20 +304,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) {
> @@ -332,10 +326,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];
> @@ -362,29 +352,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;
>   	}
>   
> @@ -410,33 +401,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_sspp_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);
> @@ -445,19 +437,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",
> @@ -1144,7 +1137,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
>   	pdpu->is_rt_pipe = is_rt_pipe;
>   
> -	_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),
> @@ -1213,20 +1206,20 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   		}
>   	}
>   
> -	_dpu_plane_set_qos_lut(plane, fb, &pipe_cfg);
> -	_dpu_plane_set_danger_lut(plane, fb);
> +	_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, true, DPU_PLANE_QOS_PANIC_CTRL);
> -		_dpu_plane_set_ot_limit(plane, crtc, &pipe_cfg);
> +		_dpu_plane_set_qos_ctrl(plane, pipe, true, DPU_PLANE_QOS_PANIC_CTRL);
> +		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pipe_cfg);
>   	}
>   
>   	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, &pipe_cfg);
> +	_dpu_plane_calc_bw(plane, fmt, &pipe_cfg);
>   
>   	_dpu_plane_calc_clk(plane, &pipe_cfg);
>   }
> @@ -1263,11 +1256,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);
>   
> @@ -1395,13 +1390,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

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

* Re: [PATCH v3 17/27] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format
@ 2023-02-03 23:07     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 23:07 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> 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>

Nothing wrong with the change as such but why is this needed?
I looked through tne next patches in the series briefly and unless I am 
missing something, I am not able to see how this rewrite is helping or 
needed for the remaining patches.

> ---
>   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 5aabf9694a53..ee261a591d45 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -128,19 +128,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_sspp_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;
> @@ -152,8 +151,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);
> @@ -217,25 +214,25 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_sspp_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 */
> @@ -251,7 +248,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 {
> @@ -261,7 +258,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);
>   
> @@ -271,25 +268,22 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
>   /**
>    * _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_sspp_cfg *pipe_cfg)
> +		struct dpu_sw_pipe *pipe,
> +		const struct dpu_format *fmt, struct dpu_hw_sspp_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))
> @@ -301,7 +295,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
>   	qos_lut = _dpu_hw_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);
>   
> @@ -310,20 +304,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) {
> @@ -332,10 +326,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];
> @@ -362,29 +352,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;
>   	}
>   
> @@ -410,33 +401,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_sspp_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);
> @@ -445,19 +437,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",
> @@ -1144,7 +1137,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
>   	pdpu->is_rt_pipe = is_rt_pipe;
>   
> -	_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),
> @@ -1213,20 +1206,20 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   		}
>   	}
>   
> -	_dpu_plane_set_qos_lut(plane, fb, &pipe_cfg);
> -	_dpu_plane_set_danger_lut(plane, fb);
> +	_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, true, DPU_PLANE_QOS_PANIC_CTRL);
> -		_dpu_plane_set_ot_limit(plane, crtc, &pipe_cfg);
> +		_dpu_plane_set_qos_ctrl(plane, pipe, true, DPU_PLANE_QOS_PANIC_CTRL);
> +		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pipe_cfg);
>   	}
>   
>   	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, &pipe_cfg);
> +	_dpu_plane_calc_bw(plane, fmt, &pipe_cfg);
>   
>   	_dpu_plane_calc_clk(plane, &pipe_cfg);
>   }
> @@ -1263,11 +1256,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);
>   
> @@ -1395,13 +1390,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

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

* Re: [PATCH v3 17/27] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format
  2023-02-03 23:07     ` Abhinav Kumar
@ 2023-02-03 23:20       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 23:20 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 04/02/2023 01:07, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> 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>
> 
> Nothing wrong with the change as such but why is this needed?
> I looked through tne next patches in the series briefly and unless I am 
> missing something, I am not able to see how this rewrite is helping or 
> needed for the remaining patches.

Having a separate pipe argument eases adding support for r_pipe. After 
all these changes only upper level functions access pstate->pipe. Then 
it becomes natural to do:

dpu_plane_do_something(plane->pipe);
if (plane->r_pipe)
     dpu_plane_do_something(plane->r_pipe);

> 
>> ---
>>   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 5aabf9694a53..ee261a591d45 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -128,19 +128,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_sspp_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;
>> @@ -152,8 +151,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);
>> @@ -217,25 +214,25 @@ static void _dpu_plane_calc_clk(struct drm_plane 
>> *plane, struct dpu_hw_sspp_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 */
>> @@ -251,7 +248,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 {
>> @@ -261,7 +258,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);
>> @@ -271,25 +268,22 @@ static int _dpu_plane_calc_fill_level(struct 
>> drm_plane *plane,
>>   /**
>>    * _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_sspp_cfg *pipe_cfg)
>> +        struct dpu_sw_pipe *pipe,
>> +        const struct dpu_format *fmt, struct dpu_hw_sspp_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))
>> @@ -301,7 +295,7 @@ static void _dpu_plane_set_qos_lut(struct 
>> drm_plane *plane,
>>       qos_lut = _dpu_hw_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);
>> @@ -310,20 +304,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) {
>> @@ -332,10 +326,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];
>> @@ -362,29 +352,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;
>>       }
>> @@ -410,33 +401,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_sspp_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);
>> @@ -445,19 +437,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",
>> @@ -1144,7 +1137,7 @@ static void dpu_plane_sspp_atomic_update(struct 
>> drm_plane *plane)
>>       pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
>>       pdpu->is_rt_pipe = is_rt_pipe;
>> -    _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),
>> @@ -1213,20 +1206,20 @@ static void 
>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>           }
>>       }
>> -    _dpu_plane_set_qos_lut(plane, fb, &pipe_cfg);
>> -    _dpu_plane_set_danger_lut(plane, fb);
>> +    _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, true, DPU_PLANE_QOS_PANIC_CTRL);
>> -        _dpu_plane_set_ot_limit(plane, crtc, &pipe_cfg);
>> +        _dpu_plane_set_qos_ctrl(plane, pipe, true, 
>> DPU_PLANE_QOS_PANIC_CTRL);
>> +        _dpu_plane_set_ot_limit(plane, pipe, crtc, &pipe_cfg);
>>       }
>>       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, &pipe_cfg);
>> +    _dpu_plane_calc_bw(plane, fmt, &pipe_cfg);
>>       _dpu_plane_calc_clk(plane, &pipe_cfg);
>>   }
>> @@ -1263,11 +1256,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);
>> @@ -1395,13 +1390,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

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 17/27] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format
@ 2023-02-03 23:20       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-03 23:20 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 04/02/2023 01:07, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> 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>
> 
> Nothing wrong with the change as such but why is this needed?
> I looked through tne next patches in the series briefly and unless I am 
> missing something, I am not able to see how this rewrite is helping or 
> needed for the remaining patches.

Having a separate pipe argument eases adding support for r_pipe. After 
all these changes only upper level functions access pstate->pipe. Then 
it becomes natural to do:

dpu_plane_do_something(plane->pipe);
if (plane->r_pipe)
     dpu_plane_do_something(plane->r_pipe);

> 
>> ---
>>   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 5aabf9694a53..ee261a591d45 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -128,19 +128,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_sspp_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;
>> @@ -152,8 +151,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);
>> @@ -217,25 +214,25 @@ static void _dpu_plane_calc_clk(struct drm_plane 
>> *plane, struct dpu_hw_sspp_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 */
>> @@ -251,7 +248,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 {
>> @@ -261,7 +258,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);
>> @@ -271,25 +268,22 @@ static int _dpu_plane_calc_fill_level(struct 
>> drm_plane *plane,
>>   /**
>>    * _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_sspp_cfg *pipe_cfg)
>> +        struct dpu_sw_pipe *pipe,
>> +        const struct dpu_format *fmt, struct dpu_hw_sspp_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))
>> @@ -301,7 +295,7 @@ static void _dpu_plane_set_qos_lut(struct 
>> drm_plane *plane,
>>       qos_lut = _dpu_hw_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);
>> @@ -310,20 +304,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) {
>> @@ -332,10 +326,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];
>> @@ -362,29 +352,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;
>>       }
>> @@ -410,33 +401,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_sspp_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);
>> @@ -445,19 +437,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",
>> @@ -1144,7 +1137,7 @@ static void dpu_plane_sspp_atomic_update(struct 
>> drm_plane *plane)
>>       pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
>>       pdpu->is_rt_pipe = is_rt_pipe;
>> -    _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),
>> @@ -1213,20 +1206,20 @@ static void 
>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>           }
>>       }
>> -    _dpu_plane_set_qos_lut(plane, fb, &pipe_cfg);
>> -    _dpu_plane_set_danger_lut(plane, fb);
>> +    _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, true, DPU_PLANE_QOS_PANIC_CTRL);
>> -        _dpu_plane_set_ot_limit(plane, crtc, &pipe_cfg);
>> +        _dpu_plane_set_qos_ctrl(plane, pipe, true, 
>> DPU_PLANE_QOS_PANIC_CTRL);
>> +        _dpu_plane_set_ot_limit(plane, pipe, crtc, &pipe_cfg);
>>       }
>>       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, &pipe_cfg);
>> +    _dpu_plane_calc_bw(plane, fmt, &pipe_cfg);
>>       _dpu_plane_calc_clk(plane, &pipe_cfg);
>>   }
>> @@ -1263,11 +1256,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);
>> @@ -1395,13 +1390,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

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-03 23:35     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 23:35 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> 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.
> 

While reviewing this patch, I had a first hand experience of how we are 
reusing SSPP bitmasks for so many chipsets but I think overall you got 
them right here :)

> 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 cf053e8f081e..fc818b0273e7 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -21,13 +21,16 @@
>   	(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>   
>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>   
> @@ -42,6 +45,7 @@
>   #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 \

VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other chipsets 
like 8250, 8450, 8550.

At the moment, for visual validation of this series, I only have 
sc7180/sc7280. We are leaving the rest for CI.

Was that an intentional approach?

If so, we will need tested-by tags from folks having 
8350/8450/8550/sc8280x,qcm2290?

I am only owning the visual validation on sc7280 atm.

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-03 23:35     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-03 23:35 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> 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.
> 

While reviewing this patch, I had a first hand experience of how we are 
reusing SSPP bitmasks for so many chipsets but I think overall you got 
them right here :)

> 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 cf053e8f081e..fc818b0273e7 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -21,13 +21,16 @@
>   	(VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>   
>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>   
> @@ -42,6 +45,7 @@
>   #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 \

VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other chipsets 
like 8250, 8450, 8550.

At the moment, for visual validation of this series, I only have 
sc7180/sc7280. We are leaving the rest for CI.

Was that an intentional approach?

If so, we will need tested-by tags from folks having 
8350/8450/8550/sc8280x,qcm2290?

I am only owning the visual validation on sc7280 atm.

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-03 23:35     ` Abhinav Kumar
@ 2023-02-04  2:29       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-04  2:29 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 04/02/2023 01:35, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> 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.
>>
> 
> While reviewing this patch, I had a first hand experience of how we are 
> reusing SSPP bitmasks for so many chipsets but I think overall you got 
> them right here :)
> 
>> 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 cf053e8f081e..fc818b0273e7 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>> @@ -21,13 +21,16 @@
>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>> @@ -42,6 +45,7 @@
>>   #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 \
> 
> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other chipsets 
> like 8250, 8450, 8550.
> 
> At the moment, for visual validation of this series, I only have 
> sc7180/sc7280. We are leaving the rest for CI.
> 
> Was that an intentional approach?
> 
> If so, we will need tested-by tags from folks having 
> 8350/8450/8550/sc8280x,qcm2290?
> 
> I am only owning the visual validation on sc7280 atm.

I'm not quite sure what is your intent here. Are there any SoCs after 
845 that do not have SmartDMA 2.5? Or do you propose to enable SmartDMA 
only for the chipsets that we can visually test? That sounds strange.

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-04  2:29       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-04  2:29 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 04/02/2023 01:35, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> 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.
>>
> 
> While reviewing this patch, I had a first hand experience of how we are 
> reusing SSPP bitmasks for so many chipsets but I think overall you got 
> them right here :)
> 
>> 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 cf053e8f081e..fc818b0273e7 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>> @@ -21,13 +21,16 @@
>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>> @@ -42,6 +45,7 @@
>>   #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 \
> 
> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other chipsets 
> like 8250, 8450, 8550.
> 
> At the moment, for visual validation of this series, I only have 
> sc7180/sc7280. We are leaving the rest for CI.
> 
> Was that an intentional approach?
> 
> If so, we will need tested-by tags from folks having 
> 8350/8450/8550/sc8280x,qcm2290?
> 
> I am only owning the visual validation on sc7280 atm.

I'm not quite sure what is your intent here. Are there any SoCs after 
845 that do not have SmartDMA 2.5? Or do you propose to enable SmartDMA 
only for the chipsets that we can visually test? That sounds strange.

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-04  2:29       ` Dmitry Baryshkov
@ 2023-02-04  2:43         ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-04  2:43 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> 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.
>>>
>>
>> While reviewing this patch, I had a first hand experience of how we 
>> are reusing SSPP bitmasks for so many chipsets but I think overall you 
>> got them right here :)
>>
>>> 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 cf053e8f081e..fc818b0273e7 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>> @@ -21,13 +21,16 @@
>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>> @@ -42,6 +45,7 @@
>>>   #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 \
>>
>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other chipsets 
>> like 8250, 8450, 8550.
>>
>> At the moment, for visual validation of this series, I only have 
>> sc7180/sc7280. We are leaving the rest for CI.
>>
>> Was that an intentional approach?
>>
>> If so, we will need tested-by tags from folks having 
>> 8350/8450/8550/sc8280x,qcm2290?
>>
>> I am only owning the visual validation on sc7280 atm.
> 
> I'm not quite sure what is your intent here. Are there any SoCs after 
> 845 that do not have SmartDMA 2.5? Or do you propose to enable SmartDMA 
> only for the chipsets that we can visually test? That sounds strange.
> 

Yes I was thinking to enable smartDMA at the moment on chipsets which we 
can validate visually that display comes up. But I am not sure if thats 
entirely practical.

But the intent was I just want to make sure basic display does come up 
with smartDMA enabled if we are enabling it for all chipsets.

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-04  2:43         ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-04  2:43 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> 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.
>>>
>>
>> While reviewing this patch, I had a first hand experience of how we 
>> are reusing SSPP bitmasks for so many chipsets but I think overall you 
>> got them right here :)
>>
>>> 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 cf053e8f081e..fc818b0273e7 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>> @@ -21,13 +21,16 @@
>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>> @@ -42,6 +45,7 @@
>>>   #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 \
>>
>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other chipsets 
>> like 8250, 8450, 8550.
>>
>> At the moment, for visual validation of this series, I only have 
>> sc7180/sc7280. We are leaving the rest for CI.
>>
>> Was that an intentional approach?
>>
>> If so, we will need tested-by tags from folks having 
>> 8350/8450/8550/sc8280x,qcm2290?
>>
>> I am only owning the visual validation on sc7280 atm.
> 
> I'm not quite sure what is your intent here. Are there any SoCs after 
> 845 that do not have SmartDMA 2.5? Or do you propose to enable SmartDMA 
> only for the chipsets that we can visually test? That sounds strange.
> 

Yes I was thinking to enable smartDMA at the moment on chipsets which we 
can validate visually that display comes up. But I am not sure if thats 
entirely practical.

But the intent was I just want to make sure basic display does come up 
with smartDMA enabled if we are enabling it for all chipsets.

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-04  2:43         ` Abhinav Kumar
@ 2023-02-04  4:10           ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-04  4:10 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 04/02/2023 04:43, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>> 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.
>>>>
>>>
>>> While reviewing this patch, I had a first hand experience of how we 
>>> are reusing SSPP bitmasks for so many chipsets but I think overall 
>>> you got them right here :)
>>>
>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>> @@ -21,13 +21,16 @@
>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>> @@ -42,6 +45,7 @@
>>>>   #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 \
>>>
>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other chipsets 
>>> like 8250, 8450, 8550.
>>>
>>> At the moment, for visual validation of this series, I only have 
>>> sc7180/sc7280. We are leaving the rest for CI.
>>>
>>> Was that an intentional approach?
>>>
>>> If so, we will need tested-by tags from folks having 
>>> 8350/8450/8550/sc8280x,qcm2290?
>>>
>>> I am only owning the visual validation on sc7280 atm.
>>
>> I'm not quite sure what is your intent here. Are there any SoCs after 
>> 845 that do not have SmartDMA 2.5? Or do you propose to enable 
>> SmartDMA only for the chipsets that we can visually test? That sounds 
>> strange.
>>
> 
> Yes I was thinking to enable smartDMA at the moment on chipsets which we 
> can validate visually that display comes up. But I am not sure if thats 
> entirely practical.
> 
> But the intent was I just want to make sure basic display does come up 
> with smartDMA enabled if we are enabling it for all chipsets.

I don't think it is practical or logical. We don't require validating 
other changes on all possible chipsets, so what is so different with 
this one?

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-04  4:10           ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-04  4:10 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 04/02/2023 04:43, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>> 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.
>>>>
>>>
>>> While reviewing this patch, I had a first hand experience of how we 
>>> are reusing SSPP bitmasks for so many chipsets but I think overall 
>>> you got them right here :)
>>>
>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>> @@ -21,13 +21,16 @@
>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>> @@ -42,6 +45,7 @@
>>>>   #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 \
>>>
>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other chipsets 
>>> like 8250, 8450, 8550.
>>>
>>> At the moment, for visual validation of this series, I only have 
>>> sc7180/sc7280. We are leaving the rest for CI.
>>>
>>> Was that an intentional approach?
>>>
>>> If so, we will need tested-by tags from folks having 
>>> 8350/8450/8550/sc8280x,qcm2290?
>>>
>>> I am only owning the visual validation on sc7280 atm.
>>
>> I'm not quite sure what is your intent here. Are there any SoCs after 
>> 845 that do not have SmartDMA 2.5? Or do you propose to enable 
>> SmartDMA only for the chipsets that we can visually test? That sounds 
>> strange.
>>
> 
> Yes I was thinking to enable smartDMA at the moment on chipsets which we 
> can validate visually that display comes up. But I am not sure if thats 
> entirely practical.
> 
> But the intent was I just want to make sure basic display does come up 
> with smartDMA enabled if we are enabling it for all chipsets.

I don't think it is practical or logical. We don't require validating 
other changes on all possible chipsets, so what is so different with 
this one?

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-04  4:10           ` Dmitry Baryshkov
@ 2023-02-04  5:10             ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-04  5:10 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>> 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.
>>>>>
>>>>
>>>> While reviewing this patch, I had a first hand experience of how we 
>>>> are reusing SSPP bitmasks for so many chipsets but I think overall 
>>>> you got them right here :)
>>>>
>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>> @@ -21,13 +21,16 @@
>>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>> @@ -42,6 +45,7 @@
>>>>>   #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 \
>>>>
>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other chipsets 
>>>> like 8250, 8450, 8550.
>>>>
>>>> At the moment, for visual validation of this series, I only have 
>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>
>>>> Was that an intentional approach?
>>>>
>>>> If so, we will need tested-by tags from folks having 
>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>
>>>> I am only owning the visual validation on sc7280 atm.
>>>
>>> I'm not quite sure what is your intent here. Are there any SoCs after 
>>> 845 that do not have SmartDMA 2.5? Or do you propose to enable 
>>> SmartDMA only for the chipsets that we can visually test? That sounds 
>>> strange.
>>>
>>
>> Yes I was thinking to enable smartDMA at the moment on chipsets which 
>> we can validate visually that display comes up. But I am not sure if 
>> thats entirely practical.
>>
>> But the intent was I just want to make sure basic display does come up 
>> with smartDMA enabled if we are enabling it for all chipsets.
> 
> I don't think it is practical or logical. We don't require validating 
> other changes on all possible chipsets, so what is so different with 
> this one?
> 

Thats because with smartDMA if the programming of stages goes wrong we 
could potentially just see a blank screen. Its not about other changes, 
this change in particular controls enabling a feature.

But thats just my thought. I am not going to request to ensure this or 
block this for this.

You can still have my

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

But think of the validations that have to be done before we merge it.

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-04  5:10             ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-04  5:10 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>> 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.
>>>>>
>>>>
>>>> While reviewing this patch, I had a first hand experience of how we 
>>>> are reusing SSPP bitmasks for so many chipsets but I think overall 
>>>> you got them right here :)
>>>>
>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>> @@ -21,13 +21,16 @@
>>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>> @@ -42,6 +45,7 @@
>>>>>   #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 \
>>>>
>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other chipsets 
>>>> like 8250, 8450, 8550.
>>>>
>>>> At the moment, for visual validation of this series, I only have 
>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>
>>>> Was that an intentional approach?
>>>>
>>>> If so, we will need tested-by tags from folks having 
>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>
>>>> I am only owning the visual validation on sc7280 atm.
>>>
>>> I'm not quite sure what is your intent here. Are there any SoCs after 
>>> 845 that do not have SmartDMA 2.5? Or do you propose to enable 
>>> SmartDMA only for the chipsets that we can visually test? That sounds 
>>> strange.
>>>
>>
>> Yes I was thinking to enable smartDMA at the moment on chipsets which 
>> we can validate visually that display comes up. But I am not sure if 
>> thats entirely practical.
>>
>> But the intent was I just want to make sure basic display does come up 
>> with smartDMA enabled if we are enabling it for all chipsets.
> 
> I don't think it is practical or logical. We don't require validating 
> other changes on all possible chipsets, so what is so different with 
> this one?
> 

Thats because with smartDMA if the programming of stages goes wrong we 
could potentially just see a blank screen. Its not about other changes, 
this change in particular controls enabling a feature.

But thats just my thought. I am not going to request to ensure this or 
block this for this.

You can still have my

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

But think of the validations that have to be done before we merge it.

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-04  5:10             ` Abhinav Kumar
@ 2023-02-04 10:43               ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-04 10:43 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 04/02/2023 07:10, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
>> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>>
>>>>>
>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>> 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.
>>>>>>
>>>>>
>>>>> While reviewing this patch, I had a first hand experience of how we 
>>>>> are reusing SSPP bitmasks for so many chipsets but I think overall 
>>>>> you got them right here :)
>>>>>
>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>> @@ -21,13 +21,16 @@
>>>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>>> @@ -42,6 +45,7 @@
>>>>>>   #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 \
>>>>>
>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other 
>>>>> chipsets like 8250, 8450, 8550.
>>>>>
>>>>> At the moment, for visual validation of this series, I only have 
>>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>>
>>>>> Was that an intentional approach?
>>>>>
>>>>> If so, we will need tested-by tags from folks having 
>>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>>
>>>>> I am only owning the visual validation on sc7280 atm.
>>>>
>>>> I'm not quite sure what is your intent here. Are there any SoCs 
>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to enable 
>>>> SmartDMA only for the chipsets that we can visually test? That 
>>>> sounds strange.
>>>>
>>>
>>> Yes I was thinking to enable smartDMA at the moment on chipsets which 
>>> we can validate visually that display comes up. But I am not sure if 
>>> thats entirely practical.
>>>
>>> But the intent was I just want to make sure basic display does come 
>>> up with smartDMA enabled if we are enabling it for all chipsets.
>>
>> I don't think it is practical or logical. We don't require validating 
>> other changes on all possible chipsets, so what is so different with 
>> this one?
>>
> 
> Thats because with smartDMA if the programming of stages goes wrong we 
> could potentially just see a blank screen. Its not about other changes, 
> this change in particular controls enabling a feature.
> 
> But thats just my thought. I am not going to request to ensure this or 
> block this for this.
> 
> You can still have my
> 
> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> 
> But think of the validations that have to be done before we merge it.

The usual way: verify as much as feasible and let anybody else complain 
during the development cycle.

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-04 10:43               ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-04 10:43 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 04/02/2023 07:10, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
>> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>>
>>>>>
>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>> 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.
>>>>>>
>>>>>
>>>>> While reviewing this patch, I had a first hand experience of how we 
>>>>> are reusing SSPP bitmasks for so many chipsets but I think overall 
>>>>> you got them right here :)
>>>>>
>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>> @@ -21,13 +21,16 @@
>>>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>>> @@ -42,6 +45,7 @@
>>>>>>   #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 \
>>>>>
>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other 
>>>>> chipsets like 8250, 8450, 8550.
>>>>>
>>>>> At the moment, for visual validation of this series, I only have 
>>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>>
>>>>> Was that an intentional approach?
>>>>>
>>>>> If so, we will need tested-by tags from folks having 
>>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>>
>>>>> I am only owning the visual validation on sc7280 atm.
>>>>
>>>> I'm not quite sure what is your intent here. Are there any SoCs 
>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to enable 
>>>> SmartDMA only for the chipsets that we can visually test? That 
>>>> sounds strange.
>>>>
>>>
>>> Yes I was thinking to enable smartDMA at the moment on chipsets which 
>>> we can validate visually that display comes up. But I am not sure if 
>>> thats entirely practical.
>>>
>>> But the intent was I just want to make sure basic display does come 
>>> up with smartDMA enabled if we are enabling it for all chipsets.
>>
>> I don't think it is practical or logical. We don't require validating 
>> other changes on all possible chipsets, so what is so different with 
>> this one?
>>
> 
> Thats because with smartDMA if the programming of stages goes wrong we 
> could potentially just see a blank screen. Its not about other changes, 
> this change in particular controls enabling a feature.
> 
> But thats just my thought. I am not going to request to ensure this or 
> block this for this.
> 
> You can still have my
> 
> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> 
> But think of the validations that have to be done before we merge it.

The usual way: verify as much as feasible and let anybody else complain 
during the development cycle.

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-04 10:43               ` Dmitry Baryshkov
@ 2023-02-04 18:35                 ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-04 18:35 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/4/2023 2:43 AM, Dmitry Baryshkov wrote:
> On 04/02/2023 07:10, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
>>> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>>>
>>>>>>
>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>> 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.
>>>>>>>
>>>>>>
>>>>>> While reviewing this patch, I had a first hand experience of how 
>>>>>> we are reusing SSPP bitmasks for so many chipsets but I think 
>>>>>> overall you got them right here :)
>>>>>>
>>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>> @@ -21,13 +21,16 @@
>>>>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>>>> @@ -42,6 +45,7 @@
>>>>>>>   #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 \
>>>>>>
>>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other 
>>>>>> chipsets like 8250, 8450, 8550.
>>>>>>
>>>>>> At the moment, for visual validation of this series, I only have 
>>>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>>>
>>>>>> Was that an intentional approach?
>>>>>>
>>>>>> If so, we will need tested-by tags from folks having 
>>>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>>>
>>>>>> I am only owning the visual validation on sc7280 atm.
>>>>>
>>>>> I'm not quite sure what is your intent here. Are there any SoCs 
>>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to 
>>>>> enable SmartDMA only for the chipsets that we can visually test? 
>>>>> That sounds strange.
>>>>>
>>>>
>>>> Yes I was thinking to enable smartDMA at the moment on chipsets 
>>>> which we can validate visually that display comes up. But I am not 
>>>> sure if thats entirely practical.
>>>>
>>>> But the intent was I just want to make sure basic display does come 
>>>> up with smartDMA enabled if we are enabling it for all chipsets.
>>>
>>> I don't think it is practical or logical. We don't require validating 
>>> other changes on all possible chipsets, so what is so different with 
>>> this one?
>>>
>>
>> Thats because with smartDMA if the programming of stages goes wrong we 
>> could potentially just see a blank screen. Its not about other 
>> changes, this change in particular controls enabling a feature.
>>
>> But thats just my thought. I am not going to request to ensure this or 
>> block this for this.
>>
>> You can still have my
>>
>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>
>> But think of the validations that have to be done before we merge it.
> 
> The usual way: verify as much as feasible and let anybody else complain 
> during the development cycle.
> 

Well, our perspective is to enable the feature on devices on which you 
are able to test and not enable then wait for others to complain.

I did not say test all devices. My point was to enable smartDMA on 
devices which we are able to test.

There are other examples of this, like inline rotation, writeback etc. 
which are at the moment enabled only on devices which QC or others have 
tested on.

So when i said my suggestion was not practical, yes because if you want 
to go ahead with this change in the current form, you would have to 
validate all the chipsets as you are enabling smartDMA on all of them.

If you enable smartDMA only on the chipsets you OR others can validate 
and give Tested-by for like I was planning to do for sc7280, then I am 
not sure why it doesnt sound logical.

But like I said, thats my perspective. I will let you decide as you 
would know how confident you are with this getting enabled for all 
chipsets upstream.

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-04 18:35                 ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-04 18:35 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/4/2023 2:43 AM, Dmitry Baryshkov wrote:
> On 04/02/2023 07:10, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
>>> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>>>
>>>>>>
>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>> 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.
>>>>>>>
>>>>>>
>>>>>> While reviewing this patch, I had a first hand experience of how 
>>>>>> we are reusing SSPP bitmasks for so many chipsets but I think 
>>>>>> overall you got them right here :)
>>>>>>
>>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>> @@ -21,13 +21,16 @@
>>>>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>>>> @@ -42,6 +45,7 @@
>>>>>>>   #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 \
>>>>>>
>>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other 
>>>>>> chipsets like 8250, 8450, 8550.
>>>>>>
>>>>>> At the moment, for visual validation of this series, I only have 
>>>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>>>
>>>>>> Was that an intentional approach?
>>>>>>
>>>>>> If so, we will need tested-by tags from folks having 
>>>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>>>
>>>>>> I am only owning the visual validation on sc7280 atm.
>>>>>
>>>>> I'm not quite sure what is your intent here. Are there any SoCs 
>>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to 
>>>>> enable SmartDMA only for the chipsets that we can visually test? 
>>>>> That sounds strange.
>>>>>
>>>>
>>>> Yes I was thinking to enable smartDMA at the moment on chipsets 
>>>> which we can validate visually that display comes up. But I am not 
>>>> sure if thats entirely practical.
>>>>
>>>> But the intent was I just want to make sure basic display does come 
>>>> up with smartDMA enabled if we are enabling it for all chipsets.
>>>
>>> I don't think it is practical or logical. We don't require validating 
>>> other changes on all possible chipsets, so what is so different with 
>>> this one?
>>>
>>
>> Thats because with smartDMA if the programming of stages goes wrong we 
>> could potentially just see a blank screen. Its not about other 
>> changes, this change in particular controls enabling a feature.
>>
>> But thats just my thought. I am not going to request to ensure this or 
>> block this for this.
>>
>> You can still have my
>>
>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>
>> But think of the validations that have to be done before we merge it.
> 
> The usual way: verify as much as feasible and let anybody else complain 
> during the development cycle.
> 

Well, our perspective is to enable the feature on devices on which you 
are able to test and not enable then wait for others to complain.

I did not say test all devices. My point was to enable smartDMA on 
devices which we are able to test.

There are other examples of this, like inline rotation, writeback etc. 
which are at the moment enabled only on devices which QC or others have 
tested on.

So when i said my suggestion was not practical, yes because if you want 
to go ahead with this change in the current form, you would have to 
validate all the chipsets as you are enabling smartDMA on all of them.

If you enable smartDMA only on the chipsets you OR others can validate 
and give Tested-by for like I was planning to do for sc7280, then I am 
not sure why it doesnt sound logical.

But like I said, thats my perspective. I will let you decide as you 
would know how confident you are with this getting enabled for all 
chipsets upstream.

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-04 18:35                 ` Abhinav Kumar
@ 2023-02-04 21:08                   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-04 21:08 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 04/02/2023 20:35, Abhinav Kumar wrote:
> 
> 
> On 2/4/2023 2:43 AM, Dmitry Baryshkov wrote:
>> On 04/02/2023 07:10, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
>>>> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>>>>
>>>>>
>>>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>>> 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.
>>>>>>>>
>>>>>>>
>>>>>>> While reviewing this patch, I had a first hand experience of how 
>>>>>>> we are reusing SSPP bitmasks for so many chipsets but I think 
>>>>>>> overall you got them right here :)
>>>>>>>
>>>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>> @@ -21,13 +21,16 @@
>>>>>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>>>>> @@ -42,6 +45,7 @@
>>>>>>>>   #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 \
>>>>>>>
>>>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other 
>>>>>>> chipsets like 8250, 8450, 8550.
>>>>>>>
>>>>>>> At the moment, for visual validation of this series, I only have 
>>>>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>>>>
>>>>>>> Was that an intentional approach?
>>>>>>>
>>>>>>> If so, we will need tested-by tags from folks having 
>>>>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>>>>
>>>>>>> I am only owning the visual validation on sc7280 atm.
>>>>>>
>>>>>> I'm not quite sure what is your intent here. Are there any SoCs 
>>>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to 
>>>>>> enable SmartDMA only for the chipsets that we can visually test? 
>>>>>> That sounds strange.
>>>>>>
>>>>>
>>>>> Yes I was thinking to enable smartDMA at the moment on chipsets 
>>>>> which we can validate visually that display comes up. But I am not 
>>>>> sure if thats entirely practical.
>>>>>
>>>>> But the intent was I just want to make sure basic display does come 
>>>>> up with smartDMA enabled if we are enabling it for all chipsets.
>>>>
>>>> I don't think it is practical or logical. We don't require 
>>>> validating other changes on all possible chipsets, so what is so 
>>>> different with this one?
>>>>
>>>
>>> Thats because with smartDMA if the programming of stages goes wrong 
>>> we could potentially just see a blank screen. Its not about other 
>>> changes, this change in particular controls enabling a feature.
>>>
>>> But thats just my thought. I am not going to request to ensure this 
>>> or block this for this.
>>>
>>> You can still have my
>>>
>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>>
>>> But think of the validations that have to be done before we merge it.
>>
>> The usual way: verify as much as feasible and let anybody else 
>> complain during the development cycle.
>>
> 
> Well, our perspective is to enable the feature on devices on which you 
> are able to test and not enable then wait for others to complain.

This would not be really practical. There are plenty of people who can 
test things on obscure platforms, but unfortunately far less amount of 
people who tightly follow the development and can track which new 
feature applies to a particular platform. I hope to be able to fix that 
slightly with the hw catalog rework. However enabling features on other 
platforms definitely requires more knowledge than simply testing the kernel.

> 
> I did not say test all devices. My point was to enable smartDMA on 
> devices which we are able to test.
> 
> There are other examples of this, like inline rotation, writeback etc. 
> which are at the moment enabled only on devices which QC or others have 
> tested on.

But at the time it was added, inline rotation 2.0 could only be 
supported on sc7280. Probably we should expand it not to sc8280xp and 
sm8[345]50.

For WB I don't remember which platforms were supported at the moment it 
was added. But it's also worth expanding support to new platforms.

And, as we speak about testing, is there an easy way to setup the plane 
with UBWC format modifier? Also, did the WB support patches land into 
libdrm?

> So when i said my suggestion was not practical, yes because if you want 
> to go ahead with this change in the current form, you would have to 
> validate all the chipsets as you are enabling smartDMA on all of them.
> 
> If you enable smartDMA only on the chipsets you OR others can validate 
> and give Tested-by for like I was planning to do for sc7280, then I am 
> not sure why it doesnt sound logical.
> 
> But like I said, thats my perspective. I will let you decide as you 
> would know how confident you are with this getting enabled for all 
> chipsets upstream.

I'd say, that once tested on some of the platforms and granted that even 
smalled (qcm2290, sm6115) platforms support smartdma, it will be safe to 
enable smart DMA globablly for every SoC >= sdm845. If I remember 
correctly, msm8998 (and sdm660/630) support smartdma/rect only on DMA 
planes. Is it correct?


-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-04 21:08                   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-04 21:08 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 04/02/2023 20:35, Abhinav Kumar wrote:
> 
> 
> On 2/4/2023 2:43 AM, Dmitry Baryshkov wrote:
>> On 04/02/2023 07:10, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
>>>> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>>>>
>>>>>
>>>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>>> 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.
>>>>>>>>
>>>>>>>
>>>>>>> While reviewing this patch, I had a first hand experience of how 
>>>>>>> we are reusing SSPP bitmasks for so many chipsets but I think 
>>>>>>> overall you got them right here :)
>>>>>>>
>>>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>> @@ -21,13 +21,16 @@
>>>>>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>>>>> @@ -42,6 +45,7 @@
>>>>>>>>   #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 \
>>>>>>>
>>>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other 
>>>>>>> chipsets like 8250, 8450, 8550.
>>>>>>>
>>>>>>> At the moment, for visual validation of this series, I only have 
>>>>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>>>>
>>>>>>> Was that an intentional approach?
>>>>>>>
>>>>>>> If so, we will need tested-by tags from folks having 
>>>>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>>>>
>>>>>>> I am only owning the visual validation on sc7280 atm.
>>>>>>
>>>>>> I'm not quite sure what is your intent here. Are there any SoCs 
>>>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to 
>>>>>> enable SmartDMA only for the chipsets that we can visually test? 
>>>>>> That sounds strange.
>>>>>>
>>>>>
>>>>> Yes I was thinking to enable smartDMA at the moment on chipsets 
>>>>> which we can validate visually that display comes up. But I am not 
>>>>> sure if thats entirely practical.
>>>>>
>>>>> But the intent was I just want to make sure basic display does come 
>>>>> up with smartDMA enabled if we are enabling it for all chipsets.
>>>>
>>>> I don't think it is practical or logical. We don't require 
>>>> validating other changes on all possible chipsets, so what is so 
>>>> different with this one?
>>>>
>>>
>>> Thats because with smartDMA if the programming of stages goes wrong 
>>> we could potentially just see a blank screen. Its not about other 
>>> changes, this change in particular controls enabling a feature.
>>>
>>> But thats just my thought. I am not going to request to ensure this 
>>> or block this for this.
>>>
>>> You can still have my
>>>
>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>>
>>> But think of the validations that have to be done before we merge it.
>>
>> The usual way: verify as much as feasible and let anybody else 
>> complain during the development cycle.
>>
> 
> Well, our perspective is to enable the feature on devices on which you 
> are able to test and not enable then wait for others to complain.

This would not be really practical. There are plenty of people who can 
test things on obscure platforms, but unfortunately far less amount of 
people who tightly follow the development and can track which new 
feature applies to a particular platform. I hope to be able to fix that 
slightly with the hw catalog rework. However enabling features on other 
platforms definitely requires more knowledge than simply testing the kernel.

> 
> I did not say test all devices. My point was to enable smartDMA on 
> devices which we are able to test.
> 
> There are other examples of this, like inline rotation, writeback etc. 
> which are at the moment enabled only on devices which QC or others have 
> tested on.

But at the time it was added, inline rotation 2.0 could only be 
supported on sc7280. Probably we should expand it not to sc8280xp and 
sm8[345]50.

For WB I don't remember which platforms were supported at the moment it 
was added. But it's also worth expanding support to new platforms.

And, as we speak about testing, is there an easy way to setup the plane 
with UBWC format modifier? Also, did the WB support patches land into 
libdrm?

> So when i said my suggestion was not practical, yes because if you want 
> to go ahead with this change in the current form, you would have to 
> validate all the chipsets as you are enabling smartDMA on all of them.
> 
> If you enable smartDMA only on the chipsets you OR others can validate 
> and give Tested-by for like I was planning to do for sc7280, then I am 
> not sure why it doesnt sound logical.
> 
> But like I said, thats my perspective. I will let you decide as you 
> would know how confident you are with this getting enabled for all 
> chipsets upstream.

I'd say, that once tested on some of the platforms and granted that even 
smalled (qcm2290, sm6115) platforms support smartdma, it will be safe to 
enable smart DMA globablly for every SoC >= sdm845. If I remember 
correctly, msm8998 (and sdm660/630) support smartdma/rect only on DMA 
planes. Is it correct?


-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-04 21:08                   ` Dmitry Baryshkov
@ 2023-02-04 23:20                     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-04 23:20 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/4/2023 1:08 PM, Dmitry Baryshkov wrote:
> On 04/02/2023 20:35, Abhinav Kumar wrote:
>>
>>
>> On 2/4/2023 2:43 AM, Dmitry Baryshkov wrote:
>>> On 04/02/2023 07:10, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
>>>>> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>>>>>
>>>>>>
>>>>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>>>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>>>> 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.
>>>>>>>>>
>>>>>>>>
>>>>>>>> While reviewing this patch, I had a first hand experience of how 
>>>>>>>> we are reusing SSPP bitmasks for so many chipsets but I think 
>>>>>>>> overall you got them right here :)
>>>>>>>>
>>>>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>> @@ -21,13 +21,16 @@
>>>>>>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>>>>>> @@ -42,6 +45,7 @@
>>>>>>>>>   #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 \
>>>>>>>>
>>>>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other 
>>>>>>>> chipsets like 8250, 8450, 8550.
>>>>>>>>
>>>>>>>> At the moment, for visual validation of this series, I only have 
>>>>>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>>>>>
>>>>>>>> Was that an intentional approach?
>>>>>>>>
>>>>>>>> If so, we will need tested-by tags from folks having 
>>>>>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>>>>>
>>>>>>>> I am only owning the visual validation on sc7280 atm.
>>>>>>>
>>>>>>> I'm not quite sure what is your intent here. Are there any SoCs 
>>>>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to 
>>>>>>> enable SmartDMA only for the chipsets that we can visually test? 
>>>>>>> That sounds strange.
>>>>>>>
>>>>>>
>>>>>> Yes I was thinking to enable smartDMA at the moment on chipsets 
>>>>>> which we can validate visually that display comes up. But I am not 
>>>>>> sure if thats entirely practical.
>>>>>>
>>>>>> But the intent was I just want to make sure basic display does 
>>>>>> come up with smartDMA enabled if we are enabling it for all chipsets.
>>>>>
>>>>> I don't think it is practical or logical. We don't require 
>>>>> validating other changes on all possible chipsets, so what is so 
>>>>> different with this one?
>>>>>
>>>>
>>>> Thats because with smartDMA if the programming of stages goes wrong 
>>>> we could potentially just see a blank screen. Its not about other 
>>>> changes, this change in particular controls enabling a feature.
>>>>
>>>> But thats just my thought. I am not going to request to ensure this 
>>>> or block this for this.
>>>>
>>>> You can still have my
>>>>
>>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>>>
>>>> But think of the validations that have to be done before we merge it.
>>>
>>> The usual way: verify as much as feasible and let anybody else 
>>> complain during the development cycle.
>>>
>>
>> Well, our perspective is to enable the feature on devices on which you 
>> are able to test and not enable then wait for others to complain.
> 
> This would not be really practical. There are plenty of people who can 
> test things on obscure platforms, but unfortunately far less amount of 
> people who tightly follow the development and can track which new 
> feature applies to a particular platform. I hope to be able to fix that 
> slightly with the hw catalog rework. However enabling features on other 
> platforms definitely requires more knowledge than simply testing the 
> kernel.
> 
>>
>> I did not say test all devices. My point was to enable smartDMA on 
>> devices which we are able to test.
>>
>> There are other examples of this, like inline rotation, writeback etc. 
>> which are at the moment enabled only on devices which QC or others 
>> have tested on.
> 
> But at the time it was added, inline rotation 2.0 could only be 
> supported on sc7280. Probably we should expand it not to sc8280xp and 
> sm8[345]50.
> 
> For WB I don't remember which platforms were supported at the moment it 
> was added. But it's also worth expanding support to new platforms.
> 
> And, as we speak about testing, is there an easy way to setup the plane 
> with UBWC format modifier? Also, did the WB support patches land into 
> libdrm?
> 

I will check the compositor code and update you on the UWBC format 
modifier as I am not too familiar with it.

libdrm always supported virtual encoder 
https://github.com/grate-driver/libdrm/blob/master/include/drm/drm_mode.h#L352

What other support patches are needed? Right now we only use IGT to 
validate writeback.

>> So when i said my suggestion was not practical, yes because if you 
>> want to go ahead with this change in the current form, you would have 
>> to validate all the chipsets as you are enabling smartDMA on all of them.
>>
>> If you enable smartDMA only on the chipsets you OR others can validate 
>> and give Tested-by for like I was planning to do for sc7280, then I am 
>> not sure why it doesnt sound logical.
>>
>> But like I said, thats my perspective. I will let you decide as you 
>> would know how confident you are with this getting enabled for all 
>> chipsets upstream.
> 
> I'd say, that once tested on some of the platforms and granted that even 
> smalled (qcm2290, sm6115) platforms support smartdma, it will be safe to 
> enable smart DMA globablly for every SoC >= sdm845. If I remember 
> correctly, msm8998 (and sdm660/630) support smartdma/rect only on DMA 
> planes. Is it correct?
> 
> 
Yes thats right msm8998 supports smartdma only on DMA sspps.

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-04 23:20                     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-04 23:20 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/4/2023 1:08 PM, Dmitry Baryshkov wrote:
> On 04/02/2023 20:35, Abhinav Kumar wrote:
>>
>>
>> On 2/4/2023 2:43 AM, Dmitry Baryshkov wrote:
>>> On 04/02/2023 07:10, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
>>>>> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>>>>>
>>>>>>
>>>>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>>>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>>>> 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.
>>>>>>>>>
>>>>>>>>
>>>>>>>> While reviewing this patch, I had a first hand experience of how 
>>>>>>>> we are reusing SSPP bitmasks for so many chipsets but I think 
>>>>>>>> overall you got them right here :)
>>>>>>>>
>>>>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>> @@ -21,13 +21,16 @@
>>>>>>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>>>>>> @@ -42,6 +45,7 @@
>>>>>>>>>   #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 \
>>>>>>>>
>>>>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other 
>>>>>>>> chipsets like 8250, 8450, 8550.
>>>>>>>>
>>>>>>>> At the moment, for visual validation of this series, I only have 
>>>>>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>>>>>
>>>>>>>> Was that an intentional approach?
>>>>>>>>
>>>>>>>> If so, we will need tested-by tags from folks having 
>>>>>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>>>>>
>>>>>>>> I am only owning the visual validation on sc7280 atm.
>>>>>>>
>>>>>>> I'm not quite sure what is your intent here. Are there any SoCs 
>>>>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to 
>>>>>>> enable SmartDMA only for the chipsets that we can visually test? 
>>>>>>> That sounds strange.
>>>>>>>
>>>>>>
>>>>>> Yes I was thinking to enable smartDMA at the moment on chipsets 
>>>>>> which we can validate visually that display comes up. But I am not 
>>>>>> sure if thats entirely practical.
>>>>>>
>>>>>> But the intent was I just want to make sure basic display does 
>>>>>> come up with smartDMA enabled if we are enabling it for all chipsets.
>>>>>
>>>>> I don't think it is practical or logical. We don't require 
>>>>> validating other changes on all possible chipsets, so what is so 
>>>>> different with this one?
>>>>>
>>>>
>>>> Thats because with smartDMA if the programming of stages goes wrong 
>>>> we could potentially just see a blank screen. Its not about other 
>>>> changes, this change in particular controls enabling a feature.
>>>>
>>>> But thats just my thought. I am not going to request to ensure this 
>>>> or block this for this.
>>>>
>>>> You can still have my
>>>>
>>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>>>
>>>> But think of the validations that have to be done before we merge it.
>>>
>>> The usual way: verify as much as feasible and let anybody else 
>>> complain during the development cycle.
>>>
>>
>> Well, our perspective is to enable the feature on devices on which you 
>> are able to test and not enable then wait for others to complain.
> 
> This would not be really practical. There are plenty of people who can 
> test things on obscure platforms, but unfortunately far less amount of 
> people who tightly follow the development and can track which new 
> feature applies to a particular platform. I hope to be able to fix that 
> slightly with the hw catalog rework. However enabling features on other 
> platforms definitely requires more knowledge than simply testing the 
> kernel.
> 
>>
>> I did not say test all devices. My point was to enable smartDMA on 
>> devices which we are able to test.
>>
>> There are other examples of this, like inline rotation, writeback etc. 
>> which are at the moment enabled only on devices which QC or others 
>> have tested on.
> 
> But at the time it was added, inline rotation 2.0 could only be 
> supported on sc7280. Probably we should expand it not to sc8280xp and 
> sm8[345]50.
> 
> For WB I don't remember which platforms were supported at the moment it 
> was added. But it's also worth expanding support to new platforms.
> 
> And, as we speak about testing, is there an easy way to setup the plane 
> with UBWC format modifier? Also, did the WB support patches land into 
> libdrm?
> 

I will check the compositor code and update you on the UWBC format 
modifier as I am not too familiar with it.

libdrm always supported virtual encoder 
https://github.com/grate-driver/libdrm/blob/master/include/drm/drm_mode.h#L352

What other support patches are needed? Right now we only use IGT to 
validate writeback.

>> So when i said my suggestion was not practical, yes because if you 
>> want to go ahead with this change in the current form, you would have 
>> to validate all the chipsets as you are enabling smartDMA on all of them.
>>
>> If you enable smartDMA only on the chipsets you OR others can validate 
>> and give Tested-by for like I was planning to do for sc7280, then I am 
>> not sure why it doesnt sound logical.
>>
>> But like I said, thats my perspective. I will let you decide as you 
>> would know how confident you are with this getting enabled for all 
>> chipsets upstream.
> 
> I'd say, that once tested on some of the platforms and granted that even 
> smalled (qcm2290, sm6115) platforms support smartdma, it will be safe to 
> enable smart DMA globablly for every SoC >= sdm845. If I remember 
> correctly, msm8998 (and sdm660/630) support smartdma/rect only on DMA 
> planes. Is it correct?
> 
> 
Yes thats right msm8998 supports smartdma only on DMA sspps.

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-04 23:20                     ` Abhinav Kumar
@ 2023-02-05  0:29                       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-05  0:29 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Stephen Boyd, David Airlie, Daniel Vetter,
	Bjorn Andersson, linux-arm-msm, dri-devel, freedreno

On Sun, 5 Feb 2023 at 01:20, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/4/2023 1:08 PM, Dmitry Baryshkov wrote:
> > On 04/02/2023 20:35, Abhinav Kumar wrote:
> >>
> >>
> >> On 2/4/2023 2:43 AM, Dmitry Baryshkov wrote:
> >>> On 04/02/2023 07:10, Abhinav Kumar wrote:
> >>>>
> >>>>
> >>>> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
> >>>>> On 04/02/2023 04:43, Abhinav Kumar wrote:
> >>>>>>
> >>>>>>
> >>>>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
> >>>>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> >>>>>>>>> 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.
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>> While reviewing this patch, I had a first hand experience of how
> >>>>>>>> we are reusing SSPP bitmasks for so many chipsets but I think
> >>>>>>>> overall you got them right here :)
> >>>>>>>>
> >>>>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
> >>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >>>>>>>>> @@ -21,13 +21,16 @@
> >>>>>>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
> >>>>>>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
> >>>>>>>>> @@ -42,6 +45,7 @@
> >>>>>>>>>   #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 \
> >>>>>>>>
> >>>>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other
> >>>>>>>> chipsets like 8250, 8450, 8550.
> >>>>>>>>
> >>>>>>>> At the moment, for visual validation of this series, I only have
> >>>>>>>> sc7180/sc7280. We are leaving the rest for CI.
> >>>>>>>>
> >>>>>>>> Was that an intentional approach?
> >>>>>>>>
> >>>>>>>> If so, we will need tested-by tags from folks having
> >>>>>>>> 8350/8450/8550/sc8280x,qcm2290?
> >>>>>>>>
> >>>>>>>> I am only owning the visual validation on sc7280 atm.
> >>>>>>>
> >>>>>>> I'm not quite sure what is your intent here. Are there any SoCs
> >>>>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to
> >>>>>>> enable SmartDMA only for the chipsets that we can visually test?
> >>>>>>> That sounds strange.
> >>>>>>>
> >>>>>>
> >>>>>> Yes I was thinking to enable smartDMA at the moment on chipsets
> >>>>>> which we can validate visually that display comes up. But I am not
> >>>>>> sure if thats entirely practical.
> >>>>>>
> >>>>>> But the intent was I just want to make sure basic display does
> >>>>>> come up with smartDMA enabled if we are enabling it for all chipsets.
> >>>>>
> >>>>> I don't think it is practical or logical. We don't require
> >>>>> validating other changes on all possible chipsets, so what is so
> >>>>> different with this one?
> >>>>>
> >>>>
> >>>> Thats because with smartDMA if the programming of stages goes wrong
> >>>> we could potentially just see a blank screen. Its not about other
> >>>> changes, this change in particular controls enabling a feature.
> >>>>
> >>>> But thats just my thought. I am not going to request to ensure this
> >>>> or block this for this.
> >>>>
> >>>> You can still have my
> >>>>
> >>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> >>>>
> >>>> But think of the validations that have to be done before we merge it.
> >>>
> >>> The usual way: verify as much as feasible and let anybody else
> >>> complain during the development cycle.
> >>>
> >>
> >> Well, our perspective is to enable the feature on devices on which you
> >> are able to test and not enable then wait for others to complain.
> >
> > This would not be really practical. There are plenty of people who can
> > test things on obscure platforms, but unfortunately far less amount of
> > people who tightly follow the development and can track which new
> > feature applies to a particular platform. I hope to be able to fix that
> > slightly with the hw catalog rework. However enabling features on other
> > platforms definitely requires more knowledge than simply testing the
> > kernel.
> >
> >>
> >> I did not say test all devices. My point was to enable smartDMA on
> >> devices which we are able to test.
> >>
> >> There are other examples of this, like inline rotation, writeback etc.
> >> which are at the moment enabled only on devices which QC or others
> >> have tested on.
> >
> > But at the time it was added, inline rotation 2.0 could only be
> > supported on sc7280. Probably we should expand it not to sc8280xp and
> > sm8[345]50.
> >
> > For WB I don't remember which platforms were supported at the moment it
> > was added. But it's also worth expanding support to new platforms.
> >
> > And, as we speak about testing, is there an easy way to setup the plane
> > with UBWC format modifier? Also, did the WB support patches land into
> > libdrm?
> >
>
> I will check the compositor code and update you on the UWBC format
> modifier as I am not too familiar with it.

Ideally it would be nice to support ubwc planes in some simple tool,
e.g. modetest.

>
> libdrm always supported virtual encoder
> https://github.com/grate-driver/libdrm/blob/master/include/drm/drm_mode.h#L352
>
> What other support patches are needed? Right now we only use IGT to
> validate writeback.

I remember there was a patchset to make modeset to support using
writeback. What was its fate?

>
> >> So when i said my suggestion was not practical, yes because if you
> >> want to go ahead with this change in the current form, you would have
> >> to validate all the chipsets as you are enabling smartDMA on all of them.
> >>
> >> If you enable smartDMA only on the chipsets you OR others can validate
> >> and give Tested-by for like I was planning to do for sc7280, then I am
> >> not sure why it doesnt sound logical.
> >>
> >> But like I said, thats my perspective. I will let you decide as you
> >> would know how confident you are with this getting enabled for all
> >> chipsets upstream.
> >
> > I'd say, that once tested on some of the platforms and granted that even
> > smalled (qcm2290, sm6115) platforms support smartdma, it will be safe to
> > enable smart DMA globablly for every SoC >= sdm845. If I remember
> > correctly, msm8998 (and sdm660/630) support smartdma/rect only on DMA
> > planes. Is it correct?
> >
> >
> Yes thats right msm8998 supports smartdma only on DMA sspps.

Good

-- 
With best wishes
Dmitry

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-05  0:29                       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-05  0:29 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: freedreno, Sean Paul, Bjorn Andersson, dri-devel, Stephen Boyd,
	linux-arm-msm

On Sun, 5 Feb 2023 at 01:20, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/4/2023 1:08 PM, Dmitry Baryshkov wrote:
> > On 04/02/2023 20:35, Abhinav Kumar wrote:
> >>
> >>
> >> On 2/4/2023 2:43 AM, Dmitry Baryshkov wrote:
> >>> On 04/02/2023 07:10, Abhinav Kumar wrote:
> >>>>
> >>>>
> >>>> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
> >>>>> On 04/02/2023 04:43, Abhinav Kumar wrote:
> >>>>>>
> >>>>>>
> >>>>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
> >>>>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
> >>>>>>>>
> >>>>>>>>
> >>>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> >>>>>>>>> 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.
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>> While reviewing this patch, I had a first hand experience of how
> >>>>>>>> we are reusing SSPP bitmasks for so many chipsets but I think
> >>>>>>>> overall you got them right here :)
> >>>>>>>>
> >>>>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
> >>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >>>>>>>>> @@ -21,13 +21,16 @@
> >>>>>>>>>       (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
> >>>>>>>>>   #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
> >>>>>>>>> @@ -42,6 +45,7 @@
> >>>>>>>>>   #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 \
> >>>>>>>>
> >>>>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other
> >>>>>>>> chipsets like 8250, 8450, 8550.
> >>>>>>>>
> >>>>>>>> At the moment, for visual validation of this series, I only have
> >>>>>>>> sc7180/sc7280. We are leaving the rest for CI.
> >>>>>>>>
> >>>>>>>> Was that an intentional approach?
> >>>>>>>>
> >>>>>>>> If so, we will need tested-by tags from folks having
> >>>>>>>> 8350/8450/8550/sc8280x,qcm2290?
> >>>>>>>>
> >>>>>>>> I am only owning the visual validation on sc7280 atm.
> >>>>>>>
> >>>>>>> I'm not quite sure what is your intent here. Are there any SoCs
> >>>>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to
> >>>>>>> enable SmartDMA only for the chipsets that we can visually test?
> >>>>>>> That sounds strange.
> >>>>>>>
> >>>>>>
> >>>>>> Yes I was thinking to enable smartDMA at the moment on chipsets
> >>>>>> which we can validate visually that display comes up. But I am not
> >>>>>> sure if thats entirely practical.
> >>>>>>
> >>>>>> But the intent was I just want to make sure basic display does
> >>>>>> come up with smartDMA enabled if we are enabling it for all chipsets.
> >>>>>
> >>>>> I don't think it is practical or logical. We don't require
> >>>>> validating other changes on all possible chipsets, so what is so
> >>>>> different with this one?
> >>>>>
> >>>>
> >>>> Thats because with smartDMA if the programming of stages goes wrong
> >>>> we could potentially just see a blank screen. Its not about other
> >>>> changes, this change in particular controls enabling a feature.
> >>>>
> >>>> But thats just my thought. I am not going to request to ensure this
> >>>> or block this for this.
> >>>>
> >>>> You can still have my
> >>>>
> >>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
> >>>>
> >>>> But think of the validations that have to be done before we merge it.
> >>>
> >>> The usual way: verify as much as feasible and let anybody else
> >>> complain during the development cycle.
> >>>
> >>
> >> Well, our perspective is to enable the feature on devices on which you
> >> are able to test and not enable then wait for others to complain.
> >
> > This would not be really practical. There are plenty of people who can
> > test things on obscure platforms, but unfortunately far less amount of
> > people who tightly follow the development and can track which new
> > feature applies to a particular platform. I hope to be able to fix that
> > slightly with the hw catalog rework. However enabling features on other
> > platforms definitely requires more knowledge than simply testing the
> > kernel.
> >
> >>
> >> I did not say test all devices. My point was to enable smartDMA on
> >> devices which we are able to test.
> >>
> >> There are other examples of this, like inline rotation, writeback etc.
> >> which are at the moment enabled only on devices which QC or others
> >> have tested on.
> >
> > But at the time it was added, inline rotation 2.0 could only be
> > supported on sc7280. Probably we should expand it not to sc8280xp and
> > sm8[345]50.
> >
> > For WB I don't remember which platforms were supported at the moment it
> > was added. But it's also worth expanding support to new platforms.
> >
> > And, as we speak about testing, is there an easy way to setup the plane
> > with UBWC format modifier? Also, did the WB support patches land into
> > libdrm?
> >
>
> I will check the compositor code and update you on the UWBC format
> modifier as I am not too familiar with it.

Ideally it would be nice to support ubwc planes in some simple tool,
e.g. modetest.

>
> libdrm always supported virtual encoder
> https://github.com/grate-driver/libdrm/blob/master/include/drm/drm_mode.h#L352
>
> What other support patches are needed? Right now we only use IGT to
> validate writeback.

I remember there was a patchset to make modeset to support using
writeback. What was its fate?

>
> >> So when i said my suggestion was not practical, yes because if you
> >> want to go ahead with this change in the current form, you would have
> >> to validate all the chipsets as you are enabling smartDMA on all of them.
> >>
> >> If you enable smartDMA only on the chipsets you OR others can validate
> >> and give Tested-by for like I was planning to do for sc7280, then I am
> >> not sure why it doesnt sound logical.
> >>
> >> But like I said, thats my perspective. I will let you decide as you
> >> would know how confident you are with this getting enabled for all
> >> chipsets upstream.
> >
> > I'd say, that once tested on some of the platforms and granted that even
> > smalled (qcm2290, sm6115) platforms support smartdma, it will be safe to
> > enable smart DMA globablly for every SoC >= sdm845. If I remember
> > correctly, msm8998 (and sdm660/630) support smartdma/rect only on DMA
> > planes. Is it correct?
> >
> >
> Yes thats right msm8998 supports smartdma only on DMA sspps.

Good

-- 
With best wishes
Dmitry

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-05  0:29                       ` Dmitry Baryshkov
@ 2023-02-05  0:36                         ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-05  0:36 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Stephen Boyd, David Airlie, Daniel Vetter,
	Bjorn Andersson, linux-arm-msm, dri-devel, freedreno



On 2/4/2023 4:29 PM, Dmitry Baryshkov wrote:
> On Sun, 5 Feb 2023 at 01:20, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/4/2023 1:08 PM, Dmitry Baryshkov wrote:
>>> On 04/02/2023 20:35, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/4/2023 2:43 AM, Dmitry Baryshkov wrote:
>>>>> On 04/02/2023 07:10, Abhinav Kumar wrote:
>>>>>>
>>>>>>
>>>>>> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
>>>>>>> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>>>>>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>>>>>> 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.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> While reviewing this patch, I had a first hand experience of how
>>>>>>>>>> we are reusing SSPP bitmasks for so many chipsets but I think
>>>>>>>>>> overall you got them right here :)
>>>>>>>>>>
>>>>>>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>>>> @@ -21,13 +21,16 @@
>>>>>>>>>>>        (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>>>>>>>    #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>>>>>>>> @@ -42,6 +45,7 @@
>>>>>>>>>>>    #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 \
>>>>>>>>>>
>>>>>>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other
>>>>>>>>>> chipsets like 8250, 8450, 8550.
>>>>>>>>>>
>>>>>>>>>> At the moment, for visual validation of this series, I only have
>>>>>>>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>>>>>>>
>>>>>>>>>> Was that an intentional approach?
>>>>>>>>>>
>>>>>>>>>> If so, we will need tested-by tags from folks having
>>>>>>>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>>>>>>>
>>>>>>>>>> I am only owning the visual validation on sc7280 atm.
>>>>>>>>>
>>>>>>>>> I'm not quite sure what is your intent here. Are there any SoCs
>>>>>>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to
>>>>>>>>> enable SmartDMA only for the chipsets that we can visually test?
>>>>>>>>> That sounds strange.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Yes I was thinking to enable smartDMA at the moment on chipsets
>>>>>>>> which we can validate visually that display comes up. But I am not
>>>>>>>> sure if thats entirely practical.
>>>>>>>>
>>>>>>>> But the intent was I just want to make sure basic display does
>>>>>>>> come up with smartDMA enabled if we are enabling it for all chipsets.
>>>>>>>
>>>>>>> I don't think it is practical or logical. We don't require
>>>>>>> validating other changes on all possible chipsets, so what is so
>>>>>>> different with this one?
>>>>>>>
>>>>>>
>>>>>> Thats because with smartDMA if the programming of stages goes wrong
>>>>>> we could potentially just see a blank screen. Its not about other
>>>>>> changes, this change in particular controls enabling a feature.
>>>>>>
>>>>>> But thats just my thought. I am not going to request to ensure this
>>>>>> or block this for this.
>>>>>>
>>>>>> You can still have my
>>>>>>
>>>>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>>>>>
>>>>>> But think of the validations that have to be done before we merge it.
>>>>>
>>>>> The usual way: verify as much as feasible and let anybody else
>>>>> complain during the development cycle.
>>>>>
>>>>
>>>> Well, our perspective is to enable the feature on devices on which you
>>>> are able to test and not enable then wait for others to complain.
>>>
>>> This would not be really practical. There are plenty of people who can
>>> test things on obscure platforms, but unfortunately far less amount of
>>> people who tightly follow the development and can track which new
>>> feature applies to a particular platform. I hope to be able to fix that
>>> slightly with the hw catalog rework. However enabling features on other
>>> platforms definitely requires more knowledge than simply testing the
>>> kernel.
>>>
>>>>
>>>> I did not say test all devices. My point was to enable smartDMA on
>>>> devices which we are able to test.
>>>>
>>>> There are other examples of this, like inline rotation, writeback etc.
>>>> which are at the moment enabled only on devices which QC or others
>>>> have tested on.
>>>
>>> But at the time it was added, inline rotation 2.0 could only be
>>> supported on sc7280. Probably we should expand it not to sc8280xp and
>>> sm8[345]50.
>>>
>>> For WB I don't remember which platforms were supported at the moment it
>>> was added. But it's also worth expanding support to new platforms.
>>>
>>> And, as we speak about testing, is there an easy way to setup the plane
>>> with UBWC format modifier? Also, did the WB support patches land into
>>> libdrm?
>>>
>>
>> I will check the compositor code and update you on the UWBC format
>> modifier as I am not too familiar with it.
> 
> Ideally it would be nice to support ubwc planes in some simple tool,
> e.g. modetest.
> 
>>
>> libdrm always supported virtual encoder
>> https://github.com/grate-driver/libdrm/blob/master/include/drm/drm_mode.h#L352
>>
>> What other support patches are needed? Right now we only use IGT to
>> validate writeback.
> 
> I remember there was a patchset to make modeset to support using
> writeback. What was its fate?
> 

Once our intern finished his internship, noone could take up the pending 
review comments after that so its yet to be merged.

https://patchwork.kernel.org/project/dri-devel/list/?series=667290&archive=both

Once more item to the to-do list.

>>
>>>> So when i said my suggestion was not practical, yes because if you
>>>> want to go ahead with this change in the current form, you would have
>>>> to validate all the chipsets as you are enabling smartDMA on all of them.
>>>>
>>>> If you enable smartDMA only on the chipsets you OR others can validate
>>>> and give Tested-by for like I was planning to do for sc7280, then I am
>>>> not sure why it doesnt sound logical.
>>>>
>>>> But like I said, thats my perspective. I will let you decide as you
>>>> would know how confident you are with this getting enabled for all
>>>> chipsets upstream.
>>>
>>> I'd say, that once tested on some of the platforms and granted that even
>>> smalled (qcm2290, sm6115) platforms support smartdma, it will be safe to
>>> enable smart DMA globablly for every SoC >= sdm845. If I remember
>>> correctly, msm8998 (and sdm660/630) support smartdma/rect only on DMA
>>> planes. Is it correct?
>>>
>>>
>> Yes thats right msm8998 supports smartdma only on DMA sspps.
> 
> Good
> 

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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-05  0:36                         ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-05  0:36 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, Sean Paul, Bjorn Andersson, dri-devel, Stephen Boyd,
	linux-arm-msm



On 2/4/2023 4:29 PM, Dmitry Baryshkov wrote:
> On Sun, 5 Feb 2023 at 01:20, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/4/2023 1:08 PM, Dmitry Baryshkov wrote:
>>> On 04/02/2023 20:35, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/4/2023 2:43 AM, Dmitry Baryshkov wrote:
>>>>> On 04/02/2023 07:10, Abhinav Kumar wrote:
>>>>>>
>>>>>>
>>>>>> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
>>>>>>> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>>>>>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>>>>>> 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.
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> While reviewing this patch, I had a first hand experience of how
>>>>>>>>>> we are reusing SSPP bitmasks for so many chipsets but I think
>>>>>>>>>> overall you got them right here :)
>>>>>>>>>>
>>>>>>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>>>> @@ -21,13 +21,16 @@
>>>>>>>>>>>        (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>>>>>>>    #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>>>>>>>> @@ -42,6 +45,7 @@
>>>>>>>>>>>    #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 \
>>>>>>>>>>
>>>>>>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other
>>>>>>>>>> chipsets like 8250, 8450, 8550.
>>>>>>>>>>
>>>>>>>>>> At the moment, for visual validation of this series, I only have
>>>>>>>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>>>>>>>
>>>>>>>>>> Was that an intentional approach?
>>>>>>>>>>
>>>>>>>>>> If so, we will need tested-by tags from folks having
>>>>>>>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>>>>>>>
>>>>>>>>>> I am only owning the visual validation on sc7280 atm.
>>>>>>>>>
>>>>>>>>> I'm not quite sure what is your intent here. Are there any SoCs
>>>>>>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to
>>>>>>>>> enable SmartDMA only for the chipsets that we can visually test?
>>>>>>>>> That sounds strange.
>>>>>>>>>
>>>>>>>>
>>>>>>>> Yes I was thinking to enable smartDMA at the moment on chipsets
>>>>>>>> which we can validate visually that display comes up. But I am not
>>>>>>>> sure if thats entirely practical.
>>>>>>>>
>>>>>>>> But the intent was I just want to make sure basic display does
>>>>>>>> come up with smartDMA enabled if we are enabling it for all chipsets.
>>>>>>>
>>>>>>> I don't think it is practical or logical. We don't require
>>>>>>> validating other changes on all possible chipsets, so what is so
>>>>>>> different with this one?
>>>>>>>
>>>>>>
>>>>>> Thats because with smartDMA if the programming of stages goes wrong
>>>>>> we could potentially just see a blank screen. Its not about other
>>>>>> changes, this change in particular controls enabling a feature.
>>>>>>
>>>>>> But thats just my thought. I am not going to request to ensure this
>>>>>> or block this for this.
>>>>>>
>>>>>> You can still have my
>>>>>>
>>>>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>>>>>
>>>>>> But think of the validations that have to be done before we merge it.
>>>>>
>>>>> The usual way: verify as much as feasible and let anybody else
>>>>> complain during the development cycle.
>>>>>
>>>>
>>>> Well, our perspective is to enable the feature on devices on which you
>>>> are able to test and not enable then wait for others to complain.
>>>
>>> This would not be really practical. There are plenty of people who can
>>> test things on obscure platforms, but unfortunately far less amount of
>>> people who tightly follow the development and can track which new
>>> feature applies to a particular platform. I hope to be able to fix that
>>> slightly with the hw catalog rework. However enabling features on other
>>> platforms definitely requires more knowledge than simply testing the
>>> kernel.
>>>
>>>>
>>>> I did not say test all devices. My point was to enable smartDMA on
>>>> devices which we are able to test.
>>>>
>>>> There are other examples of this, like inline rotation, writeback etc.
>>>> which are at the moment enabled only on devices which QC or others
>>>> have tested on.
>>>
>>> But at the time it was added, inline rotation 2.0 could only be
>>> supported on sc7280. Probably we should expand it not to sc8280xp and
>>> sm8[345]50.
>>>
>>> For WB I don't remember which platforms were supported at the moment it
>>> was added. But it's also worth expanding support to new platforms.
>>>
>>> And, as we speak about testing, is there an easy way to setup the plane
>>> with UBWC format modifier? Also, did the WB support patches land into
>>> libdrm?
>>>
>>
>> I will check the compositor code and update you on the UWBC format
>> modifier as I am not too familiar with it.
> 
> Ideally it would be nice to support ubwc planes in some simple tool,
> e.g. modetest.
> 
>>
>> libdrm always supported virtual encoder
>> https://github.com/grate-driver/libdrm/blob/master/include/drm/drm_mode.h#L352
>>
>> What other support patches are needed? Right now we only use IGT to
>> validate writeback.
> 
> I remember there was a patchset to make modeset to support using
> writeback. What was its fate?
> 

Once our intern finished his internship, noone could take up the pending 
review comments after that so its yet to be merged.

https://patchwork.kernel.org/project/dri-devel/list/?series=667290&archive=both

Once more item to the to-do list.

>>
>>>> So when i said my suggestion was not practical, yes because if you
>>>> want to go ahead with this change in the current form, you would have
>>>> to validate all the chipsets as you are enabling smartDMA on all of them.
>>>>
>>>> If you enable smartDMA only on the chipsets you OR others can validate
>>>> and give Tested-by for like I was planning to do for sc7280, then I am
>>>> not sure why it doesnt sound logical.
>>>>
>>>> But like I said, thats my perspective. I will let you decide as you
>>>> would know how confident you are with this getting enabled for all
>>>> chipsets upstream.
>>>
>>> I'd say, that once tested on some of the platforms and granted that even
>>> smalled (qcm2290, sm6115) platforms support smartdma, it will be safe to
>>> enable smart DMA globablly for every SoC >= sdm845. If I remember
>>> correctly, msm8998 (and sdm660/630) support smartdma/rect only on DMA
>>> planes. Is it correct?
>>>
>>>
>> Yes thats right msm8998 supports smartdma only on DMA sspps.
> 
> Good
> 

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

* Re: [PATCH v3 19/27] drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-06 18:48     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-06 18:48 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Rework bandwidth/clock calculation functions to use mode directly rather
> than fetching it through the plane data.
> 
> 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 | 39 ++++++++++-------------
>   1 file changed, 17 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index ee261a591d45..09a3fde1c910 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -127,20 +127,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_sspp_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;
> @@ -148,9 +147,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);
> @@ -158,7 +154,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;
>   
> @@ -178,37 +174,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_sspp_cfg *pipe_cfg)
> +static u64 _dpu_plane_calc_clk(const struct drm_display_mode *mode,
> +		struct dpu_hw_sspp_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;
>   }
>   
>   /**
> @@ -1219,9 +1214,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   		_dpu_plane_set_qos_remap(plane, pipe);
>   	}
>   
> -	_dpu_plane_calc_bw(plane, fmt, &pipe_cfg);
> +	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pipe_cfg);
>   
> -	_dpu_plane_calc_clk(plane, &pipe_cfg);
> +	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &pipe_cfg);
>   }
>   
>   static void _dpu_plane_atomic_disable(struct drm_plane *plane)

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

* Re: [PATCH v3 19/27] drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly
@ 2023-02-06 18:48     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-06 18:48 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Rework bandwidth/clock calculation functions to use mode directly rather
> than fetching it through the plane data.
> 
> 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 | 39 ++++++++++-------------
>   1 file changed, 17 insertions(+), 22 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index ee261a591d45..09a3fde1c910 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -127,20 +127,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_sspp_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;
> @@ -148,9 +147,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);
> @@ -158,7 +154,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;
>   
> @@ -178,37 +174,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_sspp_cfg *pipe_cfg)
> +static u64 _dpu_plane_calc_clk(const struct drm_display_mode *mode,
> +		struct dpu_hw_sspp_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;
>   }
>   
>   /**
> @@ -1219,9 +1214,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   		_dpu_plane_set_qos_remap(plane, pipe);
>   	}
>   
> -	_dpu_plane_calc_bw(plane, fmt, &pipe_cfg);
> +	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pipe_cfg);
>   
> -	_dpu_plane_calc_clk(plane, &pipe_cfg);
> +	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &pipe_cfg);
>   }
>   
>   static void _dpu_plane_atomic_disable(struct drm_plane *plane)

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

* Re: [PATCH v3 20/27] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-06 19:07     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-06 19:07 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> 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()).
> 
The title of the patch should now say "add dpu_hw_sspp_cfg"

I have a question on the commit text, why does it say "re-add" and not 
"add".

dpu_hw_pipe_cfg/dpu_hw_sspp_cfg was not a part of dpu_plane_state even 
before and I dont recall it was removed in this series and then added back.

> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 64 ++++++++++-------------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  2 +
>   2 files changed, 30 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 09a3fde1c910..ecf5402ab61a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -951,7 +951,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
>   	const struct drm_crtc_state *crtc_state = NULL;
>   	const struct dpu_format *fmt;
> -	struct drm_rect src, dst, fb_rect = { 0 };
> +	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> +	struct drm_rect fb_rect = { 0 };
>   	uint32_t min_src_size, max_linewidth;
>   	unsigned int rotation;
>   	uint32_t supported_rotations;
> @@ -984,12 +985,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;
> @@ -1008,30 +1012,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;
>   	}
>   
> @@ -1045,7 +1049,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   
>   	if ((pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) &&
>   		(rotation & DRM_MODE_ROTATE_90)) {
> -		ret = dpu_plane_check_inline_rotation(pdpu, sblk, src, fmt);
> +		ret = dpu_plane_check_inline_rotation(pdpu, sblk, pipe_cfg->src_rect, fmt);
>   		if (ret)
>   			return ret;
>   	}
> @@ -1120,9 +1124,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	bool is_rt_pipe;
>   	const struct dpu_format *fmt =
>   		to_dpu_format(msm_framebuffer_format(fb));
> -	struct dpu_hw_sspp_cfg pipe_cfg;
> -
> -	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_sspp_cfg));
> +	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>   
>   	_dpu_plane_set_scanout(plane, pstate, fb);
>   
> @@ -1139,16 +1141,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 */
> @@ -1157,10 +1149,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, pstate->rotation);
> +	_dpu_plane_setup_scaler(pipe, fmt, false, pipe_cfg, pstate->rotation);
>   
>   	if (pipe->sspp->ops.setup_multirect)
>   		pipe->sspp->ops.setup_multirect(
> @@ -1201,12 +1193,12 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   		}
>   	}
>   
> -	_dpu_plane_set_qos_lut(plane, pipe, fmt, &pipe_cfg);
> +	_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, pipe, true, DPU_PLANE_QOS_PANIC_CTRL);
> -		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pipe_cfg);
> +		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pstate->pipe_cfg);
>   	}
>   
>   	if (pstate->needs_qos_remap) {
> @@ -1214,9 +1206,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   		_dpu_plane_set_qos_remap(plane, pipe);
>   	}
>   
> -	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pipe_cfg);
> +	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pstate->pipe_cfg);
>   
> -	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &pipe_cfg);
> +	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &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 a08b0539513b..079dad83eb37 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -19,6 +19,7 @@
>    * @base:	base drm plane state object
>    * @aspace:	pointer to address space for input/output buffers
>    * @pipe:	software pipe description
> + * @pipe_cfg:	software pipe configuration
>    * @stage:	assigned by crtc blender
>    * @needs_qos_remap: qos remap settings need to be updated
>    * @multirect_index: index of the rectangle of SSPP
> @@ -33,6 +34,7 @@ struct dpu_plane_state {
>   	struct drm_plane_state base;
>   	struct msm_gem_address_space *aspace;
>   	struct dpu_sw_pipe pipe;
> +	struct dpu_hw_sspp_cfg pipe_cfg;
>   	enum dpu_stage stage;
>   	bool needs_qos_remap;
>   	bool pending;

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

* Re: [PATCH v3 20/27] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
@ 2023-02-06 19:07     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-06 19:07 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> 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()).
> 
The title of the patch should now say "add dpu_hw_sspp_cfg"

I have a question on the commit text, why does it say "re-add" and not 
"add".

dpu_hw_pipe_cfg/dpu_hw_sspp_cfg was not a part of dpu_plane_state even 
before and I dont recall it was removed in this series and then added back.

> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 64 ++++++++++-------------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  2 +
>   2 files changed, 30 insertions(+), 36 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 09a3fde1c910..ecf5402ab61a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -951,7 +951,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
>   	const struct drm_crtc_state *crtc_state = NULL;
>   	const struct dpu_format *fmt;
> -	struct drm_rect src, dst, fb_rect = { 0 };
> +	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> +	struct drm_rect fb_rect = { 0 };
>   	uint32_t min_src_size, max_linewidth;
>   	unsigned int rotation;
>   	uint32_t supported_rotations;
> @@ -984,12 +985,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;
> @@ -1008,30 +1012,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;
>   	}
>   
> @@ -1045,7 +1049,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   
>   	if ((pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION)) &&
>   		(rotation & DRM_MODE_ROTATE_90)) {
> -		ret = dpu_plane_check_inline_rotation(pdpu, sblk, src, fmt);
> +		ret = dpu_plane_check_inline_rotation(pdpu, sblk, pipe_cfg->src_rect, fmt);
>   		if (ret)
>   			return ret;
>   	}
> @@ -1120,9 +1124,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   	bool is_rt_pipe;
>   	const struct dpu_format *fmt =
>   		to_dpu_format(msm_framebuffer_format(fb));
> -	struct dpu_hw_sspp_cfg pipe_cfg;
> -
> -	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_sspp_cfg));
> +	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>   
>   	_dpu_plane_set_scanout(plane, pstate, fb);
>   
> @@ -1139,16 +1141,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 */
> @@ -1157,10 +1149,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, pstate->rotation);
> +	_dpu_plane_setup_scaler(pipe, fmt, false, pipe_cfg, pstate->rotation);
>   
>   	if (pipe->sspp->ops.setup_multirect)
>   		pipe->sspp->ops.setup_multirect(
> @@ -1201,12 +1193,12 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   		}
>   	}
>   
> -	_dpu_plane_set_qos_lut(plane, pipe, fmt, &pipe_cfg);
> +	_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, pipe, true, DPU_PLANE_QOS_PANIC_CTRL);
> -		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pipe_cfg);
> +		_dpu_plane_set_ot_limit(plane, pipe, crtc, &pstate->pipe_cfg);
>   	}
>   
>   	if (pstate->needs_qos_remap) {
> @@ -1214,9 +1206,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   		_dpu_plane_set_qos_remap(plane, pipe);
>   	}
>   
> -	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pipe_cfg);
> +	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pstate->pipe_cfg);
>   
> -	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &pipe_cfg);
> +	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &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 a08b0539513b..079dad83eb37 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -19,6 +19,7 @@
>    * @base:	base drm plane state object
>    * @aspace:	pointer to address space for input/output buffers
>    * @pipe:	software pipe description
> + * @pipe_cfg:	software pipe configuration
>    * @stage:	assigned by crtc blender
>    * @needs_qos_remap: qos remap settings need to be updated
>    * @multirect_index: index of the rectangle of SSPP
> @@ -33,6 +34,7 @@ struct dpu_plane_state {
>   	struct drm_plane_state base;
>   	struct msm_gem_address_space *aspace;
>   	struct dpu_sw_pipe pipe;
> +	struct dpu_hw_sspp_cfg pipe_cfg;
>   	enum dpu_stage stage;
>   	bool needs_qos_remap;
>   	bool pending;

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

* Re: [PATCH v3 21/27] drm/msm/dpu: simplify dpu_plane_validate_src()
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-06 22:40     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-06 22:40 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> 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>

Can you please explain how the clipping in 
drm_atomic_helper_check_plane_state() can allow us to remove checking 
the fb co-ordinates?

The clipping is done using the mode parameters.

So lets say the FB being used is smaller than the source buffer by an 
incorrect usermode setting.

Then the src sspp shall try to fetch the full image of src rectangle 
size from a FB which isnt that big leading to a fault.

How does the clipping avoid such a case?

> ---
>   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 ecf5402ab61a..0986e740b978 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
>   				old_pstate->needs_dirtyfb);
>   }
>   
> -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_check_inline_rotation(struct dpu_plane *pdpu,
>   						const struct dpu_sspp_sub_blks *sblk,
>   						struct drm_rect src, const struct dpu_format *fmt)
> @@ -998,6 +979,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));
> @@ -1012,7 +1001,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;

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

* Re: [PATCH v3 21/27] drm/msm/dpu: simplify dpu_plane_validate_src()
@ 2023-02-06 22:40     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-06 22:40 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> 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>

Can you please explain how the clipping in 
drm_atomic_helper_check_plane_state() can allow us to remove checking 
the fb co-ordinates?

The clipping is done using the mode parameters.

So lets say the FB being used is smaller than the source buffer by an 
incorrect usermode setting.

Then the src sspp shall try to fetch the full image of src rectangle 
size from a FB which isnt that big leading to a fault.

How does the clipping avoid such a case?

> ---
>   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 ecf5402ab61a..0986e740b978 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
>   				old_pstate->needs_dirtyfb);
>   }
>   
> -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_check_inline_rotation(struct dpu_plane *pdpu,
>   						const struct dpu_sspp_sub_blks *sblk,
>   						struct drm_rect src, const struct dpu_format *fmt)
> @@ -998,6 +979,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));
> @@ -1012,7 +1001,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;

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

* Re: [PATCH v3 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-07  0:22     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07  0:22 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the

sspp-dependent?

> separate function dpu_plane_sspp_update_pipe(). This is one of
> preparational steps to add r_pipe support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Just a couple of minor comments below but otherwise this split up lgtm

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 113 ++++++++++++----------
>   1 file changed, 63 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 0986e740b978..f94e132733f3 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -404,12 +404,13 @@ 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
>    * @pipe:		Pointer to software pipe
> - * @crtc:		Pointer to drm crtc
>    * @pipe_cfg:		Pointer to pipe configuration
> + * @frame_rate:		CRTC's frame rate

Can you please check the spacing here. There seems to be an extra tab 
before the CRTC's frame rate

>    */
>   static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
>   		struct dpu_sw_pipe *pipe,
> -		struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
> +		struct dpu_hw_sspp_cfg *pipe_cfg,
> +		int frame_rate)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
>   	struct dpu_vbif_set_ot_params ot_params;
> @@ -421,7 +422,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 = frame_rate;
>   	ot_params.vbif_idx = VBIF_RT;
>   	ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
>   	ot_params.rd = true;
> @@ -457,26 +458,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 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;
> -	struct dpu_hw_fmt_layout layout;
> -	int ret;
> -
> -	ret = dpu_format_populate_layout(aspace, fb, &layout);
> -	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,
> -					    &layout);
> -		pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, &layout);
> -	}
> -}
> -
>   static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *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,
> @@ -1102,35 +1083,25 @@ 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_sspp_update_pipe(struct drm_plane *plane,
> +				       struct dpu_sw_pipe *pipe,
> +				       struct dpu_hw_sspp_cfg *pipe_cfg,

You can call this parameter sspp_cfg instead of pipe_cfg?

> +				       const struct dpu_format *fmt,
> +				       int frame_rate,
> +				       struct dpu_hw_fmt_layout *layout)
>   {
>   	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;
> -	const struct dpu_format *fmt =
> -		to_dpu_format(msm_framebuffer_format(fb));
> -	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>   
> -	_dpu_plane_set_scanout(plane, pstate, fb);
> -
> -	pstate->pending = true;
> -
> -	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
> -	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
> -	pdpu->is_rt_pipe = is_rt_pipe;
> +	if (layout && pipe->sspp->ops.setup_sourceaddress) {
> +		trace_dpu_plane_set_scanout(pipe, layout);
> +		pipe->sspp->ops.setup_sourceaddress(pipe, layout);
> +	}
>   
>   	_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 */
> @@ -1183,22 +1154,64 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   		}
>   	}
>   
> -	_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, frame_rate);
>   	}
>   
> -	if (pstate->needs_qos_remap) {
> -		pstate->needs_qos_remap = false;
> +	if (pstate->needs_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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> +
> +	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> +	struct msm_gem_address_space *aspace = kms->base.aspace;
> +	struct dpu_hw_fmt_layout layout;
> +	bool layout_valid = false;
> +	int ret;
> +
> +	ret = dpu_format_populate_layout(aspace, fb, &layout);
> +	if (ret)
> +		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> +	else
> +		layout_valid = true;
> +
> +	pstate->pending = true;
> +
> +	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
> +	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
> +	pdpu->is_rt_pipe = is_rt_pipe;
> +
> +	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));
> +
> +	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
> +				   drm_mode_vrefresh(&crtc->mode),
> +				   layout_valid ? &layout: NULL);
> +
> +	if (pstate->needs_qos_remap)
> +		pstate->needs_qos_remap = false;
>   
> -	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pstate->pipe_cfg);
> +	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, pipe_cfg);
>   
> -	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &pstate->pipe_cfg);
> +	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, pipe_cfg);
>   }
>   
>   static void _dpu_plane_atomic_disable(struct drm_plane *plane)

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

* Re: [PATCH v3 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
@ 2023-02-07  0:22     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07  0:22 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the

sspp-dependent?

> separate function dpu_plane_sspp_update_pipe(). This is one of
> preparational steps to add r_pipe support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Just a couple of minor comments below but otherwise this split up lgtm

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 113 ++++++++++++----------
>   1 file changed, 63 insertions(+), 50 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 0986e740b978..f94e132733f3 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -404,12 +404,13 @@ 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
>    * @pipe:		Pointer to software pipe
> - * @crtc:		Pointer to drm crtc
>    * @pipe_cfg:		Pointer to pipe configuration
> + * @frame_rate:		CRTC's frame rate

Can you please check the spacing here. There seems to be an extra tab 
before the CRTC's frame rate

>    */
>   static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
>   		struct dpu_sw_pipe *pipe,
> -		struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
> +		struct dpu_hw_sspp_cfg *pipe_cfg,
> +		int frame_rate)
>   {
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
>   	struct dpu_vbif_set_ot_params ot_params;
> @@ -421,7 +422,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 = frame_rate;
>   	ot_params.vbif_idx = VBIF_RT;
>   	ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
>   	ot_params.rd = true;
> @@ -457,26 +458,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 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;
> -	struct dpu_hw_fmt_layout layout;
> -	int ret;
> -
> -	ret = dpu_format_populate_layout(aspace, fb, &layout);
> -	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,
> -					    &layout);
> -		pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, &layout);
> -	}
> -}
> -
>   static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *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,
> @@ -1102,35 +1083,25 @@ 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_sspp_update_pipe(struct drm_plane *plane,
> +				       struct dpu_sw_pipe *pipe,
> +				       struct dpu_hw_sspp_cfg *pipe_cfg,

You can call this parameter sspp_cfg instead of pipe_cfg?

> +				       const struct dpu_format *fmt,
> +				       int frame_rate,
> +				       struct dpu_hw_fmt_layout *layout)
>   {
>   	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;
> -	const struct dpu_format *fmt =
> -		to_dpu_format(msm_framebuffer_format(fb));
> -	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>   
> -	_dpu_plane_set_scanout(plane, pstate, fb);
> -
> -	pstate->pending = true;
> -
> -	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
> -	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
> -	pdpu->is_rt_pipe = is_rt_pipe;
> +	if (layout && pipe->sspp->ops.setup_sourceaddress) {
> +		trace_dpu_plane_set_scanout(pipe, layout);
> +		pipe->sspp->ops.setup_sourceaddress(pipe, layout);
> +	}
>   
>   	_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 */
> @@ -1183,22 +1154,64 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   		}
>   	}
>   
> -	_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, frame_rate);
>   	}
>   
> -	if (pstate->needs_qos_remap) {
> -		pstate->needs_qos_remap = false;
> +	if (pstate->needs_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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> +
> +	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> +	struct msm_gem_address_space *aspace = kms->base.aspace;
> +	struct dpu_hw_fmt_layout layout;
> +	bool layout_valid = false;
> +	int ret;
> +
> +	ret = dpu_format_populate_layout(aspace, fb, &layout);
> +	if (ret)
> +		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
> +	else
> +		layout_valid = true;
> +
> +	pstate->pending = true;
> +
> +	is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
> +	pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
> +	pdpu->is_rt_pipe = is_rt_pipe;
> +
> +	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));
> +
> +	dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
> +				   drm_mode_vrefresh(&crtc->mode),
> +				   layout_valid ? &layout: NULL);
> +
> +	if (pstate->needs_qos_remap)
> +		pstate->needs_qos_remap = false;
>   
> -	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, &pstate->pipe_cfg);
> +	pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, &crtc->mode, pipe_cfg);
>   
> -	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, &pstate->pipe_cfg);
> +	pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, pipe_cfg);
>   }
>   
>   static void _dpu_plane_atomic_disable(struct drm_plane *plane)

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

* Re: [PATCH v3 21/27] drm/msm/dpu: simplify dpu_plane_validate_src()
  2023-02-06 22:40     ` Abhinav Kumar
@ 2023-02-07  0:27       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-07  0:27 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 07/02/2023 00:40, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> 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>
> 
> Can you please explain how the clipping in 
> drm_atomic_helper_check_plane_state() can allow us to remove checking 
> the fb co-ordinates?
> 
> The clipping is done using the mode parameters.
> 
> So lets say the FB being used is smaller than the source buffer by an 
> incorrect usermode setting.
> 
> Then the src sspp shall try to fetch the full image of src rectangle 
> size from a FB which isnt that big leading to a fault.

This case is checked by the drm_atomic_plane_check().

> 
> How does the clipping avoid such a case?

clipping itself does not. However using clipped coordinates from 
plane_state->src ensures that they already were validated against the FB 
dimensions. I'll see if I can change the commit message to make it more 
obvious.

> 
>> ---
>>   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 ecf5402ab61a..0986e740b978 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane 
>> *plane,
>>                   old_pstate->needs_dirtyfb);
>>   }
>> -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_check_inline_rotation(struct dpu_plane *pdpu,
>>                           const struct dpu_sspp_sub_blks *sblk,
>>                           struct drm_rect src, const struct dpu_format 
>> *fmt)
>> @@ -998,6 +979,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));
>> @@ -1012,7 +1001,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;

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 21/27] drm/msm/dpu: simplify dpu_plane_validate_src()
@ 2023-02-07  0:27       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-07  0:27 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 07/02/2023 00:40, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> 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>
> 
> Can you please explain how the clipping in 
> drm_atomic_helper_check_plane_state() can allow us to remove checking 
> the fb co-ordinates?
> 
> The clipping is done using the mode parameters.
> 
> So lets say the FB being used is smaller than the source buffer by an 
> incorrect usermode setting.
> 
> Then the src sspp shall try to fetch the full image of src rectangle 
> size from a FB which isnt that big leading to a fault.

This case is checked by the drm_atomic_plane_check().

> 
> How does the clipping avoid such a case?

clipping itself does not. However using clipped coordinates from 
plane_state->src ensures that they already were validated against the FB 
dimensions. I'll see if I can change the commit message to make it more 
obvious.

> 
>> ---
>>   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 ecf5402ab61a..0986e740b978 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct drm_plane 
>> *plane,
>>                   old_pstate->needs_dirtyfb);
>>   }
>> -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_check_inline_rotation(struct dpu_plane *pdpu,
>>                           const struct dpu_sspp_sub_blks *sblk,
>>                           struct drm_rect src, const struct dpu_format 
>> *fmt)
>> @@ -998,6 +979,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));
>> @@ -1012,7 +1001,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;

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 21/27] drm/msm/dpu: simplify dpu_plane_validate_src()
  2023-02-07  0:27       ` Dmitry Baryshkov
@ 2023-02-07  0:42         ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07  0:42 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/6/2023 4:27 PM, Dmitry Baryshkov wrote:
> On 07/02/2023 00:40, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> 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>
>>
>> Can you please explain how the clipping in 
>> drm_atomic_helper_check_plane_state() can allow us to remove checking 
>> the fb co-ordinates?
>>
>> The clipping is done using the mode parameters.
>>
>> So lets say the FB being used is smaller than the source buffer by an 
>> incorrect usermode setting.
>>
>> Then the src sspp shall try to fetch the full image of src rectangle 
>> size from a FB which isnt that big leading to a fault.
> 
> This case is checked by the drm_atomic_plane_check().
> 
>>
>> How does the clipping avoid such a case?
> 
> clipping itself does not. However using clipped coordinates from 
> plane_state->src ensures that they already were validated against the FB 
> dimensions. I'll see if I can change the commit message to make it more 
> obvious.
> 

Ah okay, yeah the commit text confused me a bit to look at the clipping 
code in drm_atomic_helper_check_plane_state().

Yes, please change it to point to the helper which addresses this.

>>
>>> ---
>>>   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 ecf5402ab61a..0986e740b978 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct 
>>> drm_plane *plane,
>>>                   old_pstate->needs_dirtyfb);
>>>   }
>>> -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_check_inline_rotation(struct dpu_plane *pdpu,
>>>                           const struct dpu_sspp_sub_blks *sblk,
>>>                           struct drm_rect src, const struct 
>>> dpu_format *fmt)
>>> @@ -998,6 +979,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));
>>> @@ -1012,7 +1001,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;
> 

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

* Re: [PATCH v3 21/27] drm/msm/dpu: simplify dpu_plane_validate_src()
@ 2023-02-07  0:42         ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07  0:42 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/6/2023 4:27 PM, Dmitry Baryshkov wrote:
> On 07/02/2023 00:40, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> 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>
>>
>> Can you please explain how the clipping in 
>> drm_atomic_helper_check_plane_state() can allow us to remove checking 
>> the fb co-ordinates?
>>
>> The clipping is done using the mode parameters.
>>
>> So lets say the FB being used is smaller than the source buffer by an 
>> incorrect usermode setting.
>>
>> Then the src sspp shall try to fetch the full image of src rectangle 
>> size from a FB which isnt that big leading to a fault.
> 
> This case is checked by the drm_atomic_plane_check().
> 
>>
>> How does the clipping avoid such a case?
> 
> clipping itself does not. However using clipped coordinates from 
> plane_state->src ensures that they already were validated against the FB 
> dimensions. I'll see if I can change the commit message to make it more 
> obvious.
> 

Ah okay, yeah the commit text confused me a bit to look at the clipping 
code in drm_atomic_helper_check_plane_state().

Yes, please change it to point to the helper which addresses this.

>>
>>> ---
>>>   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 ecf5402ab61a..0986e740b978 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -894,25 +894,6 @@ static void dpu_plane_cleanup_fb(struct 
>>> drm_plane *plane,
>>>                   old_pstate->needs_dirtyfb);
>>>   }
>>> -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_check_inline_rotation(struct dpu_plane *pdpu,
>>>                           const struct dpu_sspp_sub_blks *sblk,
>>>                           struct drm_rect src, const struct 
>>> dpu_format *fmt)
>>> @@ -998,6 +979,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));
>>> @@ -1012,7 +1001,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;
> 

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

* Re: [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-07 17:49     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07 17:49 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Split pipe-dependent code from dpu_plane_atomic_check() into the
> separate function dpu_plane_atomic_check_pipe(). This is one of

Same comment as prev patch, dpu_plane_atomic_check_pipe() ---> 
dpu_plane_atomic_check_sspp()

> preparational steps to add r_pipe support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 ++++++++++++++---------
>   1 file changed, 53 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 f94e132733f3..e69499490d39 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -903,6 +903,51 @@ static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
>   	return 0;
>   }
>   
> +static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
> +		struct dpu_sw_pipe *pipe,
> +		struct dpu_hw_sspp_cfg *pipe_cfg,

pipe_cfg --> sspp_cfg

Also, had a question. For function parameters spreading across multiple 
lines do we want to align to one guideline? Is it going to be two tabs 
more than the prev line or aligning it with the opening brace of prev line?

I am seeing a mix in the prev patch of the series and this one.

> +		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 */
> +	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 */
> +	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 */
> +	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;
> +	}
> +
> +	return 0;
> +}
> +
>   static int dpu_plane_atomic_check(struct drm_plane *plane,
>   				  struct drm_atomic_state *state)
>   {
> @@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	const struct dpu_format *fmt;
>   	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>   	struct drm_rect fb_rect = { 0 };
> -	uint32_t min_src_size, max_linewidth;
> +	uint32_t max_linewidth;
>   	unsigned int rotation;
>   	uint32_t supported_rotations;
>   	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
> @@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   
>   	max_linewidth = pdpu->catalog->caps->max_linewidth;
>   
> -	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_hw_caps->features & DPU_SSPP_SCALER) ||
> -		 !(pipe_hw_caps->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) {
> +	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;
>   	}
>   
> +	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> +
> +	ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
> +	if (ret)
> +		return ret;
> +
>   	supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
>   
>   	if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))

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

* Re: [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
@ 2023-02-07 17:49     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07 17:49 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Split pipe-dependent code from dpu_plane_atomic_check() into the
> separate function dpu_plane_atomic_check_pipe(). This is one of

Same comment as prev patch, dpu_plane_atomic_check_pipe() ---> 
dpu_plane_atomic_check_sspp()

> preparational steps to add r_pipe support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 ++++++++++++++---------
>   1 file changed, 53 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 f94e132733f3..e69499490d39 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -903,6 +903,51 @@ static int dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
>   	return 0;
>   }
>   
> +static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
> +		struct dpu_sw_pipe *pipe,
> +		struct dpu_hw_sspp_cfg *pipe_cfg,

pipe_cfg --> sspp_cfg

Also, had a question. For function parameters spreading across multiple 
lines do we want to align to one guideline? Is it going to be two tabs 
more than the prev line or aligning it with the opening brace of prev line?

I am seeing a mix in the prev patch of the series and this one.

> +		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 */
> +	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 */
> +	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 */
> +	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;
> +	}
> +
> +	return 0;
> +}
> +
>   static int dpu_plane_atomic_check(struct drm_plane *plane,
>   				  struct drm_atomic_state *state)
>   {
> @@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	const struct dpu_format *fmt;
>   	struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>   	struct drm_rect fb_rect = { 0 };
> -	uint32_t min_src_size, max_linewidth;
> +	uint32_t max_linewidth;
>   	unsigned int rotation;
>   	uint32_t supported_rotations;
>   	const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
> @@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   
>   	max_linewidth = pdpu->catalog->caps->max_linewidth;
>   
> -	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_hw_caps->features & DPU_SSPP_SCALER) ||
> -		 !(pipe_hw_caps->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) {
> +	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;
>   	}
>   
> +	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> +
> +	ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
> +	if (ret)
> +		return ret;
> +
>   	supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
>   
>   	if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))

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

* Re: [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
  2023-02-07 17:49     ` Abhinav Kumar
@ 2023-02-07 17:51       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-07 17:51 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 07/02/2023 19:49, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Split pipe-dependent code from dpu_plane_atomic_check() into the
>> separate function dpu_plane_atomic_check_pipe(). This is one of
> 
> Same comment as prev patch, dpu_plane_atomic_check_pipe() ---> 
> dpu_plane_atomic_check_sspp()

No, it does what it does: it checks one software pipe configuration.

> 
>> preparational steps to add r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 ++++++++++++++---------
>>   1 file changed, 53 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 f94e132733f3..e69499490d39 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -903,6 +903,51 @@ static int dpu_plane_check_inline_rotation(struct 
>> dpu_plane *pdpu,
>>       return 0;
>>   }
>> +static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>> +        struct dpu_sw_pipe *pipe,
>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
> 
> pipe_cfg --> sspp_cfg
> 
> Also, had a question. For function parameters spreading across multiple 
> lines do we want to align to one guideline? Is it going to be two tabs 
> more than the prev line or aligning it with the opening brace of prev line?
> 
> I am seeing a mix in the prev patch of the series and this one.

I usually tend to keep the existing indent when adding new args and 
shifting to open brace when adding new functions. Maybe I failed a 
question in this patch, I'll doublecheck it.

> 
>> +        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 */
>> +    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 */
>> +    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 */
>> +    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;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>   static int dpu_plane_atomic_check(struct drm_plane *plane,
>>                     struct drm_atomic_state *state)
>>   {
>> @@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct drm_plane 
>> *plane,
>>       const struct dpu_format *fmt;
>>       struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>       struct drm_rect fb_rect = { 0 };
>> -    uint32_t min_src_size, max_linewidth;
>> +    uint32_t max_linewidth;
>>       unsigned int rotation;
>>       uint32_t supported_rotations;
>>       const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
>> @@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct 
>> drm_plane *plane,
>>       max_linewidth = pdpu->catalog->caps->max_linewidth;
>> -    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_hw_caps->features & DPU_SSPP_SCALER) ||
>> -         !(pipe_hw_caps->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) {
>> +    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;
>>       }
>> +    fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>> +
>> +    ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, 
>> fmt);
>> +    if (ret)
>> +        return ret;
>> +
>>       supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
>>       if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
@ 2023-02-07 17:51       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-07 17:51 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 07/02/2023 19:49, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Split pipe-dependent code from dpu_plane_atomic_check() into the
>> separate function dpu_plane_atomic_check_pipe(). This is one of
> 
> Same comment as prev patch, dpu_plane_atomic_check_pipe() ---> 
> dpu_plane_atomic_check_sspp()

No, it does what it does: it checks one software pipe configuration.

> 
>> preparational steps to add r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 ++++++++++++++---------
>>   1 file changed, 53 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 f94e132733f3..e69499490d39 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -903,6 +903,51 @@ static int dpu_plane_check_inline_rotation(struct 
>> dpu_plane *pdpu,
>>       return 0;
>>   }
>> +static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>> +        struct dpu_sw_pipe *pipe,
>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
> 
> pipe_cfg --> sspp_cfg
> 
> Also, had a question. For function parameters spreading across multiple 
> lines do we want to align to one guideline? Is it going to be two tabs 
> more than the prev line or aligning it with the opening brace of prev line?
> 
> I am seeing a mix in the prev patch of the series and this one.

I usually tend to keep the existing indent when adding new args and 
shifting to open brace when adding new functions. Maybe I failed a 
question in this patch, I'll doublecheck it.

> 
>> +        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 */
>> +    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 */
>> +    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 */
>> +    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;
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>   static int dpu_plane_atomic_check(struct drm_plane *plane,
>>                     struct drm_atomic_state *state)
>>   {
>> @@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct drm_plane 
>> *plane,
>>       const struct dpu_format *fmt;
>>       struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>       struct drm_rect fb_rect = { 0 };
>> -    uint32_t min_src_size, max_linewidth;
>> +    uint32_t max_linewidth;
>>       unsigned int rotation;
>>       uint32_t supported_rotations;
>>       const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
>> @@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct 
>> drm_plane *plane,
>>       max_linewidth = pdpu->catalog->caps->max_linewidth;
>> -    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_hw_caps->features & DPU_SSPP_SCALER) ||
>> -         !(pipe_hw_caps->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) {
>> +    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;
>>       }
>> +    fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>> +
>> +    ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, 
>> fmt);
>> +    if (ret)
>> +        return ret;
>> +
>>       supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
>>       if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
  2023-02-07 17:51       ` Dmitry Baryshkov
@ 2023-02-07 17:57         ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07 17:57 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/7/2023 9:51 AM, Dmitry Baryshkov wrote:
> On 07/02/2023 19:49, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> Split pipe-dependent code from dpu_plane_atomic_check() into the
>>> separate function dpu_plane_atomic_check_pipe(). This is one of
>>
>> Same comment as prev patch, dpu_plane_atomic_check_pipe() ---> 
>> dpu_plane_atomic_check_sspp()
> 
> No, it does what it does: it checks one software pipe configuration.

The concept of software pipe is only to encapsulate the hw_sspp along 
with its params

+struct dpu_sw_pipe {
+	struct dpu_hw_sspp *sspp;
+	enum dpu_sspp_multirect_index multirect_index;
+	enum dpu_sspp_multirect_mode multirect_mode;
+};

So its a very thin differentiation there.

> 
>>
>>> preparational steps to add r_pipe support.
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 ++++++++++++++---------
>>>   1 file changed, 53 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 f94e132733f3..e69499490d39 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -903,6 +903,51 @@ static int 
>>> dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
>>>       return 0;
>>>   }
>>> +static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>> +        struct dpu_sw_pipe *pipe,
>>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
>>
>> pipe_cfg --> sspp_cfg
>>
>> Also, had a question. For function parameters spreading across 
>> multiple lines do we want to align to one guideline? Is it going to be 
>> two tabs more than the prev line or aligning it with the opening brace 
>> of prev line?
>>
>> I am seeing a mix in the prev patch of the series and this one.
> 
> I usually tend to keep the existing indent when adding new args and 
> shifting to open brace when adding new functions. Maybe I failed a 
> question in this patch, I'll doublecheck it.
> 
>>
>>> +        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 */
>>> +    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 */
>>> +    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 */
>>> +    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;
>>> +    }
>>> +
>>> +    return 0;
>>> +}
>>> +
>>>   static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>                     struct drm_atomic_state *state)
>>>   {
>>> @@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct 
>>> drm_plane *plane,
>>>       const struct dpu_format *fmt;
>>>       struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>       struct drm_rect fb_rect = { 0 };
>>> -    uint32_t min_src_size, max_linewidth;
>>> +    uint32_t max_linewidth;
>>>       unsigned int rotation;
>>>       uint32_t supported_rotations;
>>>       const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
>>> @@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct 
>>> drm_plane *plane,
>>>       max_linewidth = pdpu->catalog->caps->max_linewidth;
>>> -    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_hw_caps->features & DPU_SSPP_SCALER) ||
>>> -         !(pipe_hw_caps->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) {
>>> +    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;
>>>       }
>>> +    fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>> +
>>> +    ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, 
>>> fmt);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>>       supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
>>>       if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
> 

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

* Re: [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
@ 2023-02-07 17:57         ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07 17:57 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/7/2023 9:51 AM, Dmitry Baryshkov wrote:
> On 07/02/2023 19:49, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> Split pipe-dependent code from dpu_plane_atomic_check() into the
>>> separate function dpu_plane_atomic_check_pipe(). This is one of
>>
>> Same comment as prev patch, dpu_plane_atomic_check_pipe() ---> 
>> dpu_plane_atomic_check_sspp()
> 
> No, it does what it does: it checks one software pipe configuration.

The concept of software pipe is only to encapsulate the hw_sspp along 
with its params

+struct dpu_sw_pipe {
+	struct dpu_hw_sspp *sspp;
+	enum dpu_sspp_multirect_index multirect_index;
+	enum dpu_sspp_multirect_mode multirect_mode;
+};

So its a very thin differentiation there.

> 
>>
>>> preparational steps to add r_pipe support.
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 ++++++++++++++---------
>>>   1 file changed, 53 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 f94e132733f3..e69499490d39 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -903,6 +903,51 @@ static int 
>>> dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
>>>       return 0;
>>>   }
>>> +static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>> +        struct dpu_sw_pipe *pipe,
>>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
>>
>> pipe_cfg --> sspp_cfg
>>
>> Also, had a question. For function parameters spreading across 
>> multiple lines do we want to align to one guideline? Is it going to be 
>> two tabs more than the prev line or aligning it with the opening brace 
>> of prev line?
>>
>> I am seeing a mix in the prev patch of the series and this one.
> 
> I usually tend to keep the existing indent when adding new args and 
> shifting to open brace when adding new functions. Maybe I failed a 
> question in this patch, I'll doublecheck it.
> 
>>
>>> +        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 */
>>> +    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 */
>>> +    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 */
>>> +    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;
>>> +    }
>>> +
>>> +    return 0;
>>> +}
>>> +
>>>   static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>                     struct drm_atomic_state *state)
>>>   {
>>> @@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct 
>>> drm_plane *plane,
>>>       const struct dpu_format *fmt;
>>>       struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>       struct drm_rect fb_rect = { 0 };
>>> -    uint32_t min_src_size, max_linewidth;
>>> +    uint32_t max_linewidth;
>>>       unsigned int rotation;
>>>       uint32_t supported_rotations;
>>>       const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
>>> @@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct 
>>> drm_plane *plane,
>>>       max_linewidth = pdpu->catalog->caps->max_linewidth;
>>> -    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_hw_caps->features & DPU_SSPP_SCALER) ||
>>> -         !(pipe_hw_caps->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) {
>>> +    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;
>>>       }
>>> +    fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>> +
>>> +    ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, 
>>> fmt);
>>> +    if (ret)
>>> +        return ret;
>>> +
>>>       supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
>>>       if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
> 

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

* Re: [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
  2023-02-07 17:57         ` Abhinav Kumar
@ 2023-02-07 17:59           ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-07 17:59 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 07/02/2023 19:57, Abhinav Kumar wrote:
> 
> 
> On 2/7/2023 9:51 AM, Dmitry Baryshkov wrote:
>> On 07/02/2023 19:49, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>> Split pipe-dependent code from dpu_plane_atomic_check() into the
>>>> separate function dpu_plane_atomic_check_pipe(). This is one of
>>>
>>> Same comment as prev patch, dpu_plane_atomic_check_pipe() ---> 
>>> dpu_plane_atomic_check_sspp()
>>
>> No, it does what it does: it checks one software pipe configuration.
> 
> The concept of software pipe is only to encapsulate the hw_sspp along 
> with its params
> 
> +struct dpu_sw_pipe {
> +    struct dpu_hw_sspp *sspp;
> +    enum dpu_sspp_multirect_index multirect_index;
> +    enum dpu_sspp_multirect_mode multirect_mode;
> +};
> 
> So its a very thin differentiation there.

SSPP is a hardware thing, while the sw_pipe is a software instance. It 
can employ an SSPP or a half of SSPP. And if it employs a half of SSPP 
(rec1) than the name dpu_plane_atomic_check_sspp() doesn't make sense: 
we are not checking the SSPP itself (or its configuration). We are 
checking the parameters of SW pipe.

> 
>>
>>>
>>>> preparational steps to add r_pipe support.
>>>>
>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>> ---
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 
>>>> ++++++++++++++---------
>>>>   1 file changed, 53 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 f94e132733f3..e69499490d39 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> @@ -903,6 +903,51 @@ static int 
>>>> dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
>>>>       return 0;
>>>>   }
>>>> +static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>> +        struct dpu_sw_pipe *pipe,
>>>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
>>>
>>> pipe_cfg --> sspp_cfg
>>>
>>> Also, had a question. For function parameters spreading across 
>>> multiple lines do we want to align to one guideline? Is it going to 
>>> be two tabs more than the prev line or aligning it with the opening 
>>> brace of prev line?
>>>
>>> I am seeing a mix in the prev patch of the series and this one.
>>
>> I usually tend to keep the existing indent when adding new args and 
>> shifting to open brace when adding new functions. Maybe I failed a 
>> question in this patch, I'll doublecheck it.
>>
>>>
>>>> +        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 */
>>>> +    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 */
>>>> +    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 */
>>>> +    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;
>>>> +    }
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>>   static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>>                     struct drm_atomic_state *state)
>>>>   {
>>>> @@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct 
>>>> drm_plane *plane,
>>>>       const struct dpu_format *fmt;
>>>>       struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>       struct drm_rect fb_rect = { 0 };
>>>> -    uint32_t min_src_size, max_linewidth;
>>>> +    uint32_t max_linewidth;
>>>>       unsigned int rotation;
>>>>       uint32_t supported_rotations;
>>>>       const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
>>>> @@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct 
>>>> drm_plane *plane,
>>>>       max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>> -    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_hw_caps->features & DPU_SSPP_SCALER) ||
>>>> -         !(pipe_hw_caps->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) {
>>>> +    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;
>>>>       }
>>>> +    fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>>> +
>>>> +    ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, 
>>>> pipe_cfg, fmt);
>>>> +    if (ret)
>>>> +        return ret;
>>>> +
>>>>       supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
>>>>       if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
>>

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
@ 2023-02-07 17:59           ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-07 17:59 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 07/02/2023 19:57, Abhinav Kumar wrote:
> 
> 
> On 2/7/2023 9:51 AM, Dmitry Baryshkov wrote:
>> On 07/02/2023 19:49, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>> Split pipe-dependent code from dpu_plane_atomic_check() into the
>>>> separate function dpu_plane_atomic_check_pipe(). This is one of
>>>
>>> Same comment as prev patch, dpu_plane_atomic_check_pipe() ---> 
>>> dpu_plane_atomic_check_sspp()
>>
>> No, it does what it does: it checks one software pipe configuration.
> 
> The concept of software pipe is only to encapsulate the hw_sspp along 
> with its params
> 
> +struct dpu_sw_pipe {
> +    struct dpu_hw_sspp *sspp;
> +    enum dpu_sspp_multirect_index multirect_index;
> +    enum dpu_sspp_multirect_mode multirect_mode;
> +};
> 
> So its a very thin differentiation there.

SSPP is a hardware thing, while the sw_pipe is a software instance. It 
can employ an SSPP or a half of SSPP. And if it employs a half of SSPP 
(rec1) than the name dpu_plane_atomic_check_sspp() doesn't make sense: 
we are not checking the SSPP itself (or its configuration). We are 
checking the parameters of SW pipe.

> 
>>
>>>
>>>> preparational steps to add r_pipe support.
>>>>
>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>> ---
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 
>>>> ++++++++++++++---------
>>>>   1 file changed, 53 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 f94e132733f3..e69499490d39 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> @@ -903,6 +903,51 @@ static int 
>>>> dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
>>>>       return 0;
>>>>   }
>>>> +static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>> +        struct dpu_sw_pipe *pipe,
>>>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
>>>
>>> pipe_cfg --> sspp_cfg
>>>
>>> Also, had a question. For function parameters spreading across 
>>> multiple lines do we want to align to one guideline? Is it going to 
>>> be two tabs more than the prev line or aligning it with the opening 
>>> brace of prev line?
>>>
>>> I am seeing a mix in the prev patch of the series and this one.
>>
>> I usually tend to keep the existing indent when adding new args and 
>> shifting to open brace when adding new functions. Maybe I failed a 
>> question in this patch, I'll doublecheck it.
>>
>>>
>>>> +        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 */
>>>> +    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 */
>>>> +    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 */
>>>> +    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;
>>>> +    }
>>>> +
>>>> +    return 0;
>>>> +}
>>>> +
>>>>   static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>>                     struct drm_atomic_state *state)
>>>>   {
>>>> @@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct 
>>>> drm_plane *plane,
>>>>       const struct dpu_format *fmt;
>>>>       struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>       struct drm_rect fb_rect = { 0 };
>>>> -    uint32_t min_src_size, max_linewidth;
>>>> +    uint32_t max_linewidth;
>>>>       unsigned int rotation;
>>>>       uint32_t supported_rotations;
>>>>       const struct dpu_sspp_cfg *pipe_hw_caps = pstate->pipe.sspp->cap;
>>>> @@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct 
>>>> drm_plane *plane,
>>>>       max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>> -    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_hw_caps->features & DPU_SSPP_SCALER) ||
>>>> -         !(pipe_hw_caps->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) {
>>>> +    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;
>>>>       }
>>>> +    fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>>> +
>>>> +    ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, 
>>>> pipe_cfg, fmt);
>>>> +    if (ret)
>>>> +        return ret;
>>>> +
>>>>       supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
>>>>       if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
>>

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
  2023-02-07 17:59           ` Dmitry Baryshkov
@ 2023-02-07 18:08             ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07 18:08 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/7/2023 9:59 AM, Dmitry Baryshkov wrote:
> On 07/02/2023 19:57, Abhinav Kumar wrote:
>>
>>
>> On 2/7/2023 9:51 AM, Dmitry Baryshkov wrote:
>>> On 07/02/2023 19:49, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>> Split pipe-dependent code from dpu_plane_atomic_check() into the
>>>>> separate function dpu_plane_atomic_check_pipe(). This is one of
>>>>
>>>> Same comment as prev patch, dpu_plane_atomic_check_pipe() ---> 
>>>> dpu_plane_atomic_check_sspp()
>>>
>>> No, it does what it does: it checks one software pipe configuration.
>>
>> The concept of software pipe is only to encapsulate the hw_sspp along 
>> with its params
>>
>> +struct dpu_sw_pipe {
>> +    struct dpu_hw_sspp *sspp;
>> +    enum dpu_sspp_multirect_index multirect_index;
>> +    enum dpu_sspp_multirect_mode multirect_mode;
>> +};
>>
>> So its a very thin differentiation there.
> 
> SSPP is a hardware thing, while the sw_pipe is a software instance. It 
> can employ an SSPP or a half of SSPP. And if it employs a half of SSPP 
> (rec1) than the name dpu_plane_atomic_check_sspp() doesn't make sense: 
> we are not checking the SSPP itself (or its configuration). We are 
> checking the parameters of SW pipe.
> 

Ok, I need to check in the next couple of patches how you are handling 
the same dpu_sw_pipe for different rects of the same sspp.

  struct dpu_plane_state {
  	struct drm_plane_state base;
  	struct msm_gem_address_space *aspace;
-	struct dpu_hw_sspp *hw_sspp;
+	struct dpu_sw_pipe pipe;
  	enum dpu_stage stage;
  	bool needs_qos_remap;
-	uint32_t multirect_index;

So far what I saw was dpu_plane_state ---> dpu_sw_pipe ---> dpu_hw_sppp

In this chain, I couldnt get how the two rects of the DMA SSPP are 
differentiated, perhaps there is something in the next few changes.

>>
>>>
>>>>
>>>>> preparational steps to add r_pipe support.
>>>>>
>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>> ---
>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 
>>>>> ++++++++++++++---------
>>>>>   1 file changed, 53 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 f94e132733f3..e69499490d39 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> @@ -903,6 +903,51 @@ static int 
>>>>> dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
>>>>>       return 0;
>>>>>   }
>>>>> +static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>>> +        struct dpu_sw_pipe *pipe,
>>>>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
>>>>
>>>> pipe_cfg --> sspp_cfg
>>>>
>>>> Also, had a question. For function parameters spreading across 
>>>> multiple lines do we want to align to one guideline? Is it going to 
>>>> be two tabs more than the prev line or aligning it with the opening 
>>>> brace of prev line?
>>>>
>>>> I am seeing a mix in the prev patch of the series and this one.
>>>
>>> I usually tend to keep the existing indent when adding new args and 
>>> shifting to open brace when adding new functions. Maybe I failed a 
>>> question in this patch, I'll doublecheck it.
>>>
>>>>
>>>>> +        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 */
>>>>> +    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 */
>>>>> +    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 */
>>>>> +    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;
>>>>> +    }
>>>>> +
>>>>> +    return 0;
>>>>> +}
>>>>> +
>>>>>   static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>>>                     struct drm_atomic_state *state)
>>>>>   {
>>>>> @@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct 
>>>>> drm_plane *plane,
>>>>>       const struct dpu_format *fmt;
>>>>>       struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>>       struct drm_rect fb_rect = { 0 };
>>>>> -    uint32_t min_src_size, max_linewidth;
>>>>> +    uint32_t max_linewidth;
>>>>>       unsigned int rotation;
>>>>>       uint32_t supported_rotations;
>>>>>       const struct dpu_sspp_cfg *pipe_hw_caps = 
>>>>> pstate->pipe.sspp->cap;
>>>>> @@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct 
>>>>> drm_plane *plane,
>>>>>       max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>>> -    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_hw_caps->features & DPU_SSPP_SCALER) ||
>>>>> -         !(pipe_hw_caps->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) {
>>>>> +    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;
>>>>>       }
>>>>> +    fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>>>> +
>>>>> +    ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, 
>>>>> pipe_cfg, fmt);
>>>>> +    if (ret)
>>>>> +        return ret;
>>>>> +
>>>>>       supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
>>>>>       if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
>>>
> 

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

* Re: [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
@ 2023-02-07 18:08             ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07 18:08 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/7/2023 9:59 AM, Dmitry Baryshkov wrote:
> On 07/02/2023 19:57, Abhinav Kumar wrote:
>>
>>
>> On 2/7/2023 9:51 AM, Dmitry Baryshkov wrote:
>>> On 07/02/2023 19:49, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>> Split pipe-dependent code from dpu_plane_atomic_check() into the
>>>>> separate function dpu_plane_atomic_check_pipe(). This is one of
>>>>
>>>> Same comment as prev patch, dpu_plane_atomic_check_pipe() ---> 
>>>> dpu_plane_atomic_check_sspp()
>>>
>>> No, it does what it does: it checks one software pipe configuration.
>>
>> The concept of software pipe is only to encapsulate the hw_sspp along 
>> with its params
>>
>> +struct dpu_sw_pipe {
>> +    struct dpu_hw_sspp *sspp;
>> +    enum dpu_sspp_multirect_index multirect_index;
>> +    enum dpu_sspp_multirect_mode multirect_mode;
>> +};
>>
>> So its a very thin differentiation there.
> 
> SSPP is a hardware thing, while the sw_pipe is a software instance. It 
> can employ an SSPP or a half of SSPP. And if it employs a half of SSPP 
> (rec1) than the name dpu_plane_atomic_check_sspp() doesn't make sense: 
> we are not checking the SSPP itself (or its configuration). We are 
> checking the parameters of SW pipe.
> 

Ok, I need to check in the next couple of patches how you are handling 
the same dpu_sw_pipe for different rects of the same sspp.

  struct dpu_plane_state {
  	struct drm_plane_state base;
  	struct msm_gem_address_space *aspace;
-	struct dpu_hw_sspp *hw_sspp;
+	struct dpu_sw_pipe pipe;
  	enum dpu_stage stage;
  	bool needs_qos_remap;
-	uint32_t multirect_index;

So far what I saw was dpu_plane_state ---> dpu_sw_pipe ---> dpu_hw_sppp

In this chain, I couldnt get how the two rects of the DMA SSPP are 
differentiated, perhaps there is something in the next few changes.

>>
>>>
>>>>
>>>>> preparational steps to add r_pipe support.
>>>>>
>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>> ---
>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 
>>>>> ++++++++++++++---------
>>>>>   1 file changed, 53 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 f94e132733f3..e69499490d39 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> @@ -903,6 +903,51 @@ static int 
>>>>> dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
>>>>>       return 0;
>>>>>   }
>>>>> +static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>>> +        struct dpu_sw_pipe *pipe,
>>>>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
>>>>
>>>> pipe_cfg --> sspp_cfg
>>>>
>>>> Also, had a question. For function parameters spreading across 
>>>> multiple lines do we want to align to one guideline? Is it going to 
>>>> be two tabs more than the prev line or aligning it with the opening 
>>>> brace of prev line?
>>>>
>>>> I am seeing a mix in the prev patch of the series and this one.
>>>
>>> I usually tend to keep the existing indent when adding new args and 
>>> shifting to open brace when adding new functions. Maybe I failed a 
>>> question in this patch, I'll doublecheck it.
>>>
>>>>
>>>>> +        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 */
>>>>> +    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 */
>>>>> +    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 */
>>>>> +    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;
>>>>> +    }
>>>>> +
>>>>> +    return 0;
>>>>> +}
>>>>> +
>>>>>   static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>>>                     struct drm_atomic_state *state)
>>>>>   {
>>>>> @@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct 
>>>>> drm_plane *plane,
>>>>>       const struct dpu_format *fmt;
>>>>>       struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>>       struct drm_rect fb_rect = { 0 };
>>>>> -    uint32_t min_src_size, max_linewidth;
>>>>> +    uint32_t max_linewidth;
>>>>>       unsigned int rotation;
>>>>>       uint32_t supported_rotations;
>>>>>       const struct dpu_sspp_cfg *pipe_hw_caps = 
>>>>> pstate->pipe.sspp->cap;
>>>>> @@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct 
>>>>> drm_plane *plane,
>>>>>       max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>>> -    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_hw_caps->features & DPU_SSPP_SCALER) ||
>>>>> -         !(pipe_hw_caps->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) {
>>>>> +    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;
>>>>>       }
>>>>> +    fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>>>> +
>>>>> +    ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, 
>>>>> pipe_cfg, fmt);
>>>>> +    if (ret)
>>>>> +        return ret;
>>>>> +
>>>>>       supported_rotations = DRM_MODE_REFLECT_MASK | DRM_MODE_ROTATE_0;
>>>>>       if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
>>>
> 

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

* Re: [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
  2023-02-07 18:08             ` Abhinav Kumar
@ 2023-02-07 19:51               ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-07 19:51 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 07/02/2023 20:08, Abhinav Kumar wrote:
> 
> 
> On 2/7/2023 9:59 AM, Dmitry Baryshkov wrote:
>> On 07/02/2023 19:57, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/7/2023 9:51 AM, Dmitry Baryshkov wrote:
>>>> On 07/02/2023 19:49, Abhinav Kumar wrote:
>>>>>
>>>>>
>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>> Split pipe-dependent code from dpu_plane_atomic_check() into the
>>>>>> separate function dpu_plane_atomic_check_pipe(). This is one of
>>>>>
>>>>> Same comment as prev patch, dpu_plane_atomic_check_pipe() ---> 
>>>>> dpu_plane_atomic_check_sspp()
>>>>
>>>> No, it does what it does: it checks one software pipe configuration.
>>>
>>> The concept of software pipe is only to encapsulate the hw_sspp along 
>>> with its params
>>>
>>> +struct dpu_sw_pipe {
>>> +    struct dpu_hw_sspp *sspp;
>>> +    enum dpu_sspp_multirect_index multirect_index;
>>> +    enum dpu_sspp_multirect_mode multirect_mode;
>>> +};
>>>
>>> So its a very thin differentiation there.
>>
>> SSPP is a hardware thing, while the sw_pipe is a software instance. It 
>> can employ an SSPP or a half of SSPP. And if it employs a half of SSPP 
>> (rec1) than the name dpu_plane_atomic_check_sspp() doesn't make sense: 
>> we are not checking the SSPP itself (or its configuration). We are 
>> checking the parameters of SW pipe.
>>
> 
> Ok, I need to check in the next couple of patches how you are handling 
> the same dpu_sw_pipe for different rects of the same sspp.

rec0 and rec1 are two different instances of dpu_sw_pipe

> 
>   struct dpu_plane_state {
>       struct drm_plane_state base;
>       struct msm_gem_address_space *aspace;
> -    struct dpu_hw_sspp *hw_sspp;
> +    struct dpu_sw_pipe pipe;
>       enum dpu_stage stage;
>       bool needs_qos_remap;
> -    uint32_t multirect_index;
> 
> So far what I saw was dpu_plane_state ---> dpu_sw_pipe ---> dpu_hw_sppp
> 
> In this chain, I couldnt get how the two rects of the DMA SSPP are 
> differentiated, perhaps there is something in the next few changes.
> 
>>>
>>>>
>>>>>
>>>>>> preparational steps to add r_pipe support.
>>>>>>
>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>>> ---
>>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 
>>>>>> ++++++++++++++---------
>>>>>>   1 file changed, 53 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 f94e132733f3..e69499490d39 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>> @@ -903,6 +903,51 @@ static int 
>>>>>> dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
>>>>>>       return 0;
>>>>>>   }
>>>>>> +static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>>>> +        struct dpu_sw_pipe *pipe,
>>>>>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
>>>>>
>>>>> pipe_cfg --> sspp_cfg
>>>>>
>>>>> Also, had a question. For function parameters spreading across 
>>>>> multiple lines do we want to align to one guideline? Is it going to 
>>>>> be two tabs more than the prev line or aligning it with the opening 
>>>>> brace of prev line?
>>>>>
>>>>> I am seeing a mix in the prev patch of the series and this one.
>>>>
>>>> I usually tend to keep the existing indent when adding new args and 
>>>> shifting to open brace when adding new functions. Maybe I failed a 
>>>> question in this patch, I'll doublecheck it.
>>>>
>>>>>
>>>>>> +        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 */
>>>>>> +    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 */
>>>>>> +    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 */
>>>>>> +    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;
>>>>>> +    }
>>>>>> +
>>>>>> +    return 0;
>>>>>> +}
>>>>>> +
>>>>>>   static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>>>>                     struct drm_atomic_state *state)
>>>>>>   {
>>>>>> @@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct 
>>>>>> drm_plane *plane,
>>>>>>       const struct dpu_format *fmt;
>>>>>>       struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>>>       struct drm_rect fb_rect = { 0 };
>>>>>> -    uint32_t min_src_size, max_linewidth;
>>>>>> +    uint32_t max_linewidth;
>>>>>>       unsigned int rotation;
>>>>>>       uint32_t supported_rotations;
>>>>>>       const struct dpu_sspp_cfg *pipe_hw_caps = 
>>>>>> pstate->pipe.sspp->cap;
>>>>>> @@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct 
>>>>>> drm_plane *plane,
>>>>>>       max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>>>> -    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_hw_caps->features & DPU_SSPP_SCALER) ||
>>>>>> -         !(pipe_hw_caps->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) {
>>>>>> +    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;
>>>>>>       }
>>>>>> +    fmt = 
>>>>>> to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>>>>> +
>>>>>> +    ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, 
>>>>>> pipe_cfg, fmt);
>>>>>> +    if (ret)
>>>>>> +        return ret;
>>>>>> +
>>>>>>       supported_rotations = DRM_MODE_REFLECT_MASK | 
>>>>>> DRM_MODE_ROTATE_0;
>>>>>>       if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
>>>>
>>

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check()
@ 2023-02-07 19:51               ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-07 19:51 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 07/02/2023 20:08, Abhinav Kumar wrote:
> 
> 
> On 2/7/2023 9:59 AM, Dmitry Baryshkov wrote:
>> On 07/02/2023 19:57, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/7/2023 9:51 AM, Dmitry Baryshkov wrote:
>>>> On 07/02/2023 19:49, Abhinav Kumar wrote:
>>>>>
>>>>>
>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>> Split pipe-dependent code from dpu_plane_atomic_check() into the
>>>>>> separate function dpu_plane_atomic_check_pipe(). This is one of
>>>>>
>>>>> Same comment as prev patch, dpu_plane_atomic_check_pipe() ---> 
>>>>> dpu_plane_atomic_check_sspp()
>>>>
>>>> No, it does what it does: it checks one software pipe configuration.
>>>
>>> The concept of software pipe is only to encapsulate the hw_sspp along 
>>> with its params
>>>
>>> +struct dpu_sw_pipe {
>>> +    struct dpu_hw_sspp *sspp;
>>> +    enum dpu_sspp_multirect_index multirect_index;
>>> +    enum dpu_sspp_multirect_mode multirect_mode;
>>> +};
>>>
>>> So its a very thin differentiation there.
>>
>> SSPP is a hardware thing, while the sw_pipe is a software instance. It 
>> can employ an SSPP or a half of SSPP. And if it employs a half of SSPP 
>> (rec1) than the name dpu_plane_atomic_check_sspp() doesn't make sense: 
>> we are not checking the SSPP itself (or its configuration). We are 
>> checking the parameters of SW pipe.
>>
> 
> Ok, I need to check in the next couple of patches how you are handling 
> the same dpu_sw_pipe for different rects of the same sspp.

rec0 and rec1 are two different instances of dpu_sw_pipe

> 
>   struct dpu_plane_state {
>       struct drm_plane_state base;
>       struct msm_gem_address_space *aspace;
> -    struct dpu_hw_sspp *hw_sspp;
> +    struct dpu_sw_pipe pipe;
>       enum dpu_stage stage;
>       bool needs_qos_remap;
> -    uint32_t multirect_index;
> 
> So far what I saw was dpu_plane_state ---> dpu_sw_pipe ---> dpu_hw_sppp
> 
> In this chain, I couldnt get how the two rects of the DMA SSPP are 
> differentiated, perhaps there is something in the next few changes.
> 
>>>
>>>>
>>>>>
>>>>>> preparational steps to add r_pipe support.
>>>>>>
>>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>>> ---
>>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 88 
>>>>>> ++++++++++++++---------
>>>>>>   1 file changed, 53 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 f94e132733f3..e69499490d39 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>> @@ -903,6 +903,51 @@ static int 
>>>>>> dpu_plane_check_inline_rotation(struct dpu_plane *pdpu,
>>>>>>       return 0;
>>>>>>   }
>>>>>> +static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>>>> +        struct dpu_sw_pipe *pipe,
>>>>>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
>>>>>
>>>>> pipe_cfg --> sspp_cfg
>>>>>
>>>>> Also, had a question. For function parameters spreading across 
>>>>> multiple lines do we want to align to one guideline? Is it going to 
>>>>> be two tabs more than the prev line or aligning it with the opening 
>>>>> brace of prev line?
>>>>>
>>>>> I am seeing a mix in the prev patch of the series and this one.
>>>>
>>>> I usually tend to keep the existing indent when adding new args and 
>>>> shifting to open brace when adding new functions. Maybe I failed a 
>>>> question in this patch, I'll doublecheck it.
>>>>
>>>>>
>>>>>> +        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 */
>>>>>> +    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 */
>>>>>> +    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 */
>>>>>> +    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;
>>>>>> +    }
>>>>>> +
>>>>>> +    return 0;
>>>>>> +}
>>>>>> +
>>>>>>   static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>>>>                     struct drm_atomic_state *state)
>>>>>>   {
>>>>>> @@ -915,7 +960,7 @@ static int dpu_plane_atomic_check(struct 
>>>>>> drm_plane *plane,
>>>>>>       const struct dpu_format *fmt;
>>>>>>       struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>>>       struct drm_rect fb_rect = { 0 };
>>>>>> -    uint32_t min_src_size, max_linewidth;
>>>>>> +    uint32_t max_linewidth;
>>>>>>       unsigned int rotation;
>>>>>>       uint32_t supported_rotations;
>>>>>>       const struct dpu_sspp_cfg *pipe_hw_caps = 
>>>>>> pstate->pipe.sspp->cap;
>>>>>> @@ -970,46 +1015,19 @@ static int dpu_plane_atomic_check(struct 
>>>>>> drm_plane *plane,
>>>>>>       max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>>>> -    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_hw_caps->features & DPU_SSPP_SCALER) ||
>>>>>> -         !(pipe_hw_caps->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) {
>>>>>> +    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;
>>>>>>       }
>>>>>> +    fmt = 
>>>>>> to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>>>>> +
>>>>>> +    ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, 
>>>>>> pipe_cfg, fmt);
>>>>>> +    if (ret)
>>>>>> +        return ret;
>>>>>> +
>>>>>>       supported_rotations = DRM_MODE_REFLECT_MASK | 
>>>>>> DRM_MODE_ROTATE_0;
>>>>>>       if (pipe_hw_caps->features & BIT(DPU_SSPP_INLINE_ROTATION))
>>>>
>>

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 24/27] drm/msm/dpu: rework plane CSC setting
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-07 20:05     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07 20:05 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Rework the code flushing CSC settings for the plane. Separate out the
> pipe and pipe_cfg as a preparation for r_pipe support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++----------
>   1 file changed, 25 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 e69499490d39..05047192cb37 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -576,29 +576,18 @@ 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_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) {
> -		DPU_ERROR("invalid plane\n");
> -		return NULL;
> -	}
> -
>   	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;
>   
> -	DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
> -			csc_ptr->csc_mv[0],
> -			csc_ptr->csc_mv[1],
> -			csc_ptr->csc_mv[2]);
> -
>   	return csc_ptr;
>   }
>   
> @@ -1049,6 +1038,27 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	return 0;
>   }
>   
> +static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe)
> +{
> +	const struct dpu_format *format = to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
> +	const struct dpu_csc_cfg *csc_ptr;
> +
> +	if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
> +		return;
> +
> +	csc_ptr = _dpu_plane_get_csc(pipe, format);
> +	if (!csc_ptr)
> +		return;
> +
> +	DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
> +			csc_ptr->csc_mv[0],
> +			csc_ptr->csc_mv[1],
> +			csc_ptr->csc_mv[2]);
> +
> +	pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
> +
> +}
> +
>   void dpu_plane_flush(struct drm_plane *plane)
>   {
>   	struct dpu_plane *pdpu;
> @@ -1072,13 +1082,8 @@ 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) {
> -		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);
> -	}

Do we need to check for pipe being valid too (pstate->pipe) && 
(pstate->pipe.sspp) && pstate->pipe.sspp->ops.setup_csc) ?

Before moving the pipe_hw/sw pipe to the state the code used to check 
for pdpu->pipe_hw to be valid. Since dpu_plane_flush() can be called 
from other files too , dont we need to check for (pstate->pipe)?

> +	else
> +		dpu_plane_flush_csc(pdpu, &pstate->pipe);
>   
>   	/* flag h/w flush complete */
>   	if (plane->state)

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

* Re: [PATCH v3 24/27] drm/msm/dpu: rework plane CSC setting
@ 2023-02-07 20:05     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07 20:05 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Rework the code flushing CSC settings for the plane. Separate out the
> pipe and pipe_cfg as a preparation for r_pipe support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++----------
>   1 file changed, 25 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 e69499490d39..05047192cb37 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -576,29 +576,18 @@ 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_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) {
> -		DPU_ERROR("invalid plane\n");
> -		return NULL;
> -	}
> -
>   	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;
>   
> -	DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
> -			csc_ptr->csc_mv[0],
> -			csc_ptr->csc_mv[1],
> -			csc_ptr->csc_mv[2]);
> -
>   	return csc_ptr;
>   }
>   
> @@ -1049,6 +1038,27 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   	return 0;
>   }
>   
> +static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe)
> +{
> +	const struct dpu_format *format = to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
> +	const struct dpu_csc_cfg *csc_ptr;
> +
> +	if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
> +		return;
> +
> +	csc_ptr = _dpu_plane_get_csc(pipe, format);
> +	if (!csc_ptr)
> +		return;
> +
> +	DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
> +			csc_ptr->csc_mv[0],
> +			csc_ptr->csc_mv[1],
> +			csc_ptr->csc_mv[2]);
> +
> +	pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
> +
> +}
> +
>   void dpu_plane_flush(struct drm_plane *plane)
>   {
>   	struct dpu_plane *pdpu;
> @@ -1072,13 +1082,8 @@ 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) {
> -		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);
> -	}

Do we need to check for pipe being valid too (pstate->pipe) && 
(pstate->pipe.sspp) && pstate->pipe.sspp->ops.setup_csc) ?

Before moving the pipe_hw/sw pipe to the state the code used to check 
for pdpu->pipe_hw to be valid. Since dpu_plane_flush() can be called 
from other files too , dont we need to check for (pstate->pipe)?

> +	else
> +		dpu_plane_flush_csc(pdpu, &pstate->pipe);
>   
>   	/* flag h/w flush complete */
>   	if (plane->state)

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

* Re: [PATCH v3 24/27] drm/msm/dpu: rework plane CSC setting
  2023-02-07 20:05     ` Abhinav Kumar
@ 2023-02-07 20:44       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-07 20:44 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: freedreno, Sean Paul, Bjorn Andersson, dri-devel, Stephen Boyd,
	linux-arm-msm

On Tue, 7 Feb 2023 at 22:05, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> > Rework the code flushing CSC settings for the plane. Separate out the
> > pipe and pipe_cfg as a preparation for r_pipe support.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++----------
> >   1 file changed, 25 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 e69499490d39..05047192cb37 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -576,29 +576,18 @@ 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_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) {
> > -             DPU_ERROR("invalid plane\n");
> > -             return NULL;
> > -     }
> > -
> >       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;
> >
> > -     DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
> > -                     csc_ptr->csc_mv[0],
> > -                     csc_ptr->csc_mv[1],
> > -                     csc_ptr->csc_mv[2]);
> > -
> >       return csc_ptr;
> >   }
> >
> > @@ -1049,6 +1038,27 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> >       return 0;
> >   }
> >
> > +static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe)
> > +{
> > +     const struct dpu_format *format = to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
> > +     const struct dpu_csc_cfg *csc_ptr;
> > +
> > +     if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
> > +             return;
> > +
> > +     csc_ptr = _dpu_plane_get_csc(pipe, format);
> > +     if (!csc_ptr)
> > +             return;
> > +
> > +     DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
> > +                     csc_ptr->csc_mv[0],
> > +                     csc_ptr->csc_mv[1],
> > +                     csc_ptr->csc_mv[2]);
> > +
> > +     pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
> > +
> > +}
> > +
> >   void dpu_plane_flush(struct drm_plane *plane)
> >   {
> >       struct dpu_plane *pdpu;
> > @@ -1072,13 +1082,8 @@ 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) {
> > -             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);
> > -     }
>
> Do we need to check for pipe being valid too (pstate->pipe) &&
> (pstate->pipe.sspp) && pstate->pipe.sspp->ops.setup_csc) ?
>
> Before moving the pipe_hw/sw pipe to the state the code used to check
> for pdpu->pipe_hw to be valid. Since dpu_plane_flush() can be called
> from other files too , dont we need to check for (pstate->pipe)?

pstate->pipe is not a pointer, there is nothing to check.

>
> > +     else
> > +             dpu_plane_flush_csc(pdpu, &pstate->pipe);
> >
> >       /* flag h/w flush complete */
> >       if (plane->state)



-- 
With best wishes
Dmitry

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

* Re: [PATCH v3 24/27] drm/msm/dpu: rework plane CSC setting
@ 2023-02-07 20:44       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-07 20:44 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Stephen Boyd, David Airlie, Daniel Vetter,
	Bjorn Andersson, linux-arm-msm, dri-devel, freedreno

On Tue, 7 Feb 2023 at 22:05, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> > Rework the code flushing CSC settings for the plane. Separate out the
> > pipe and pipe_cfg as a preparation for r_pipe support.
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++----------
> >   1 file changed, 25 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 e69499490d39..05047192cb37 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -576,29 +576,18 @@ 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_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) {
> > -             DPU_ERROR("invalid plane\n");
> > -             return NULL;
> > -     }
> > -
> >       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;
> >
> > -     DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
> > -                     csc_ptr->csc_mv[0],
> > -                     csc_ptr->csc_mv[1],
> > -                     csc_ptr->csc_mv[2]);
> > -
> >       return csc_ptr;
> >   }
> >
> > @@ -1049,6 +1038,27 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> >       return 0;
> >   }
> >
> > +static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe)
> > +{
> > +     const struct dpu_format *format = to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
> > +     const struct dpu_csc_cfg *csc_ptr;
> > +
> > +     if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
> > +             return;
> > +
> > +     csc_ptr = _dpu_plane_get_csc(pipe, format);
> > +     if (!csc_ptr)
> > +             return;
> > +
> > +     DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
> > +                     csc_ptr->csc_mv[0],
> > +                     csc_ptr->csc_mv[1],
> > +                     csc_ptr->csc_mv[2]);
> > +
> > +     pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
> > +
> > +}
> > +
> >   void dpu_plane_flush(struct drm_plane *plane)
> >   {
> >       struct dpu_plane *pdpu;
> > @@ -1072,13 +1082,8 @@ 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) {
> > -             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);
> > -     }
>
> Do we need to check for pipe being valid too (pstate->pipe) &&
> (pstate->pipe.sspp) && pstate->pipe.sspp->ops.setup_csc) ?
>
> Before moving the pipe_hw/sw pipe to the state the code used to check
> for pdpu->pipe_hw to be valid. Since dpu_plane_flush() can be called
> from other files too , dont we need to check for (pstate->pipe)?

pstate->pipe is not a pointer, there is nothing to check.

>
> > +     else
> > +             dpu_plane_flush_csc(pdpu, &pstate->pipe);
> >
> >       /* flag h/w flush complete */
> >       if (plane->state)



-- 
With best wishes
Dmitry

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

* Re: [PATCH v3 24/27] drm/msm/dpu: rework plane CSC setting
  2023-02-07 20:44       ` Dmitry Baryshkov
@ 2023-02-07 20:57         ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07 20:57 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Stephen Boyd, David Airlie, Daniel Vetter,
	Bjorn Andersson, linux-arm-msm, dri-devel, freedreno



On 2/7/2023 12:44 PM, Dmitry Baryshkov wrote:
> On Tue, 7 Feb 2023 at 22:05, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> Rework the code flushing CSC settings for the plane. Separate out the
>>> pipe and pipe_cfg as a preparation for r_pipe support.
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++----------
>>>    1 file changed, 25 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 e69499490d39..05047192cb37 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -576,29 +576,18 @@ 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_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) {
>>> -             DPU_ERROR("invalid plane\n");
>>> -             return NULL;
>>> -     }
>>> -
>>>        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;
>>>
>>> -     DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
>>> -                     csc_ptr->csc_mv[0],
>>> -                     csc_ptr->csc_mv[1],
>>> -                     csc_ptr->csc_mv[2]);
>>> -
>>>        return csc_ptr;
>>>    }
>>>
>>> @@ -1049,6 +1038,27 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>        return 0;
>>>    }
>>>
>>> +static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe)
>>> +{
>>> +     const struct dpu_format *format = to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
>>> +     const struct dpu_csc_cfg *csc_ptr;
>>> +
>>> +     if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
>>> +             return;
>>> +
>>> +     csc_ptr = _dpu_plane_get_csc(pipe, format);
>>> +     if (!csc_ptr)
>>> +             return;
>>> +
>>> +     DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
>>> +                     csc_ptr->csc_mv[0],
>>> +                     csc_ptr->csc_mv[1],
>>> +                     csc_ptr->csc_mv[2]);
>>> +
>>> +     pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
>>> +
>>> +}
>>> +
>>>    void dpu_plane_flush(struct drm_plane *plane)
>>>    {
>>>        struct dpu_plane *pdpu;
>>> @@ -1072,13 +1082,8 @@ 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) {
>>> -             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);
>>> -     }
>>
>> Do we need to check for pipe being valid too (pstate->pipe) &&
>> (pstate->pipe.sspp) && pstate->pipe.sspp->ops.setup_csc) ?
>>
>> Before moving the pipe_hw/sw pipe to the state the code used to check
>> for pdpu->pipe_hw to be valid. Since dpu_plane_flush() can be called
>> from other files too , dont we need to check for (pstate->pipe)?
> 
> pstate->pipe is not a pointer, there is nothing to check.

Ah my bad. Only pipe.sspp is a pointer which you are already checking. 
In that case,

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

> 
>>
>>> +     else
>>> +             dpu_plane_flush_csc(pdpu, &pstate->pipe);
>>>
>>>        /* flag h/w flush complete */
>>>        if (plane->state)
> 
> 
> 

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

* Re: [PATCH v3 24/27] drm/msm/dpu: rework plane CSC setting
@ 2023-02-07 20:57         ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-07 20:57 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, Sean Paul, Bjorn Andersson, dri-devel, Stephen Boyd,
	linux-arm-msm



On 2/7/2023 12:44 PM, Dmitry Baryshkov wrote:
> On Tue, 7 Feb 2023 at 22:05, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> Rework the code flushing CSC settings for the plane. Separate out the
>>> pipe and pipe_cfg as a preparation for r_pipe support.
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 45 +++++++++++++----------
>>>    1 file changed, 25 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 e69499490d39..05047192cb37 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -576,29 +576,18 @@ 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_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) {
>>> -             DPU_ERROR("invalid plane\n");
>>> -             return NULL;
>>> -     }
>>> -
>>>        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;
>>>
>>> -     DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
>>> -                     csc_ptr->csc_mv[0],
>>> -                     csc_ptr->csc_mv[1],
>>> -                     csc_ptr->csc_mv[2]);
>>> -
>>>        return csc_ptr;
>>>    }
>>>
>>> @@ -1049,6 +1038,27 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>        return 0;
>>>    }
>>>
>>> +static void dpu_plane_flush_csc(struct dpu_plane *pdpu, struct dpu_sw_pipe *pipe)
>>> +{
>>> +     const struct dpu_format *format = to_dpu_format(msm_framebuffer_format(pdpu->base.state->fb));
>>> +     const struct dpu_csc_cfg *csc_ptr;
>>> +
>>> +     if (!pipe->sspp || !pipe->sspp->ops.setup_csc)
>>> +             return;
>>> +
>>> +     csc_ptr = _dpu_plane_get_csc(pipe, format);
>>> +     if (!csc_ptr)
>>> +             return;
>>> +
>>> +     DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
>>> +                     csc_ptr->csc_mv[0],
>>> +                     csc_ptr->csc_mv[1],
>>> +                     csc_ptr->csc_mv[2]);
>>> +
>>> +     pipe->sspp->ops.setup_csc(pipe->sspp, csc_ptr);
>>> +
>>> +}
>>> +
>>>    void dpu_plane_flush(struct drm_plane *plane)
>>>    {
>>>        struct dpu_plane *pdpu;
>>> @@ -1072,13 +1082,8 @@ 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) {
>>> -             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);
>>> -     }
>>
>> Do we need to check for pipe being valid too (pstate->pipe) &&
>> (pstate->pipe.sspp) && pstate->pipe.sspp->ops.setup_csc) ?
>>
>> Before moving the pipe_hw/sw pipe to the state the code used to check
>> for pdpu->pipe_hw to be valid. Since dpu_plane_flush() can be called
>> from other files too , dont we need to check for (pstate->pipe)?
> 
> pstate->pipe is not a pointer, there is nothing to check.

Ah my bad. Only pipe.sspp is a pointer which you are already checking. 
In that case,

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

> 
>>
>>> +     else
>>> +             dpu_plane_flush_csc(pdpu, &pstate->pipe);
>>>
>>>        /* flag h/w flush complete */
>>>        if (plane->state)
> 
> 
> 

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

* Re: [PATCH v3 25/27] drm/msm/dpu: rework static color fill code
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-08 22:34     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-08 22:34 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Rework static color fill code to separate the pipe / pipe_cfg handling.
> This is a preparation for the r_pipe support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 70 +++++++++++++----------
>   1 file changed, 41 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 05047192cb37..e2e85688ed3c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -639,20 +639,54 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe,
>   				fmt);
>   }
>   
> +static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
> +		struct dpu_sw_pipe *pipe,
> +		struct dpu_hw_sspp_cfg *old_pipe_cfg,

Why is this called old_pipe_cfg instead of just pipe_cfg?


> +		u32 fill_color,
> +		const struct dpu_format *fmt)
> +{
> +	struct dpu_hw_sspp_cfg pipe_cfg;
> +
> +	/* update sspp */
> +	if (!pipe->sspp->ops.setup_solidfill)
> +		return 0;

You can just return from here and make this function void?

> +
> +	pipe->sspp->ops.setup_solidfill(pipe, fill_color);
> +
> +	/* override scaler/decimation if solid fill */
> +	pipe_cfg.dst_rect = old_pipe_cfg->dst_rect;
> +
> +	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);
> +
> +	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, pstate->rotation);
> +
> +	return 0;
> +}
> +
>   /**
>    * _dpu_plane_color_fill - enables color fill on plane
>    * @pdpu:   Pointer to DPU plane object
>    * @color:  RGB fill color value, [23..16] Blue, [15..8] Green, [7..0] Red
>    * @alpha:  8-bit fill alpha value, 255 selects 100% alpha
> - * Returns: 0 on success
>    */
> -static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
> +static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   		uint32_t color, uint32_t alpha)
>   {
>   	const struct dpu_format *fmt;
>   	const struct drm_plane *plane = &pdpu->base;
>   	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
> -	struct dpu_hw_sspp_cfg pipe_cfg;
> +	u32 fill_color = (color & 0xFFFFFF) | ((alpha & 0xFF) << 24);
>   
>   	DPU_DEBUG_PLANE(pdpu, "\n");
>   
> @@ -661,34 +695,12 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   	 * h/w only supports RGB variants
>   	 */
>   	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
> +	/* should not happen ever */
> +	if (!fmt)
> +		return;
>   
>   	/* update sspp */
> -	if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
> -		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;
> -
> -		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);
> -
> -		if (pstate->pipe.sspp->ops.setup_format)
> -			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,
> -					&pipe_cfg);
> -
> -		_dpu_plane_setup_scaler(&pstate->pipe, fmt, true, &pipe_cfg, pstate->rotation);
> -	}
> -
> -	return 0;
> +	_dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
>   }
>   
>   int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)

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

* Re: [PATCH v3 25/27] drm/msm/dpu: rework static color fill code
@ 2023-02-08 22:34     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-08 22:34 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Rework static color fill code to separate the pipe / pipe_cfg handling.
> This is a preparation for the r_pipe support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 70 +++++++++++++----------
>   1 file changed, 41 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 05047192cb37..e2e85688ed3c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -639,20 +639,54 @@ static void _dpu_plane_setup_scaler(struct dpu_sw_pipe *pipe,
>   				fmt);
>   }
>   
> +static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
> +		struct dpu_sw_pipe *pipe,
> +		struct dpu_hw_sspp_cfg *old_pipe_cfg,

Why is this called old_pipe_cfg instead of just pipe_cfg?


> +		u32 fill_color,
> +		const struct dpu_format *fmt)
> +{
> +	struct dpu_hw_sspp_cfg pipe_cfg;
> +
> +	/* update sspp */
> +	if (!pipe->sspp->ops.setup_solidfill)
> +		return 0;

You can just return from here and make this function void?

> +
> +	pipe->sspp->ops.setup_solidfill(pipe, fill_color);
> +
> +	/* override scaler/decimation if solid fill */
> +	pipe_cfg.dst_rect = old_pipe_cfg->dst_rect;
> +
> +	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);
> +
> +	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, pstate->rotation);
> +
> +	return 0;
> +}
> +
>   /**
>    * _dpu_plane_color_fill - enables color fill on plane
>    * @pdpu:   Pointer to DPU plane object
>    * @color:  RGB fill color value, [23..16] Blue, [15..8] Green, [7..0] Red
>    * @alpha:  8-bit fill alpha value, 255 selects 100% alpha
> - * Returns: 0 on success
>    */
> -static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
> +static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   		uint32_t color, uint32_t alpha)
>   {
>   	const struct dpu_format *fmt;
>   	const struct drm_plane *plane = &pdpu->base;
>   	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
> -	struct dpu_hw_sspp_cfg pipe_cfg;
> +	u32 fill_color = (color & 0xFFFFFF) | ((alpha & 0xFF) << 24);
>   
>   	DPU_DEBUG_PLANE(pdpu, "\n");
>   
> @@ -661,34 +695,12 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   	 * h/w only supports RGB variants
>   	 */
>   	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
> +	/* should not happen ever */
> +	if (!fmt)
> +		return;
>   
>   	/* update sspp */
> -	if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
> -		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;
> -
> -		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);
> -
> -		if (pstate->pipe.sspp->ops.setup_format)
> -			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,
> -					&pipe_cfg);
> -
> -		_dpu_plane_setup_scaler(&pstate->pipe, fmt, true, &pipe_cfg, pstate->rotation);
> -	}
> -
> -	return 0;
> +	_dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
>   }
>   
>   int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)

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

* Re: [PATCH v3 17/27] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format
  2023-02-03 23:20       ` Dmitry Baryshkov
@ 2023-02-08 23:09         ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-08 23:09 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 3:20 PM, Dmitry Baryshkov wrote:
> On 04/02/2023 01:07, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> 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>
>>
>> Nothing wrong with the change as such but why is this needed?
>> I looked through tne next patches in the series briefly and unless I 
>> am missing something, I am not able to see how this rewrite is helping 
>> or needed for the remaining patches.
> 
> Having a separate pipe argument eases adding support for r_pipe. After 
> all these changes only upper level functions access pstate->pipe. Then 
> it becomes natural to do:
> 
> dpu_plane_do_something(plane->pipe);
> if (plane->r_pipe)
>      dpu_plane_do_something(plane->r_pipe);

Understood,

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

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

* Re: [PATCH v3 17/27] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format
@ 2023-02-08 23:09         ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-08 23:09 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 3:20 PM, Dmitry Baryshkov wrote:
> On 04/02/2023 01:07, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> 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>
>>
>> Nothing wrong with the change as such but why is this needed?
>> I looked through tne next patches in the series briefly and unless I 
>> am missing something, I am not able to see how this rewrite is helping 
>> or needed for the remaining patches.
> 
> Having a separate pipe argument eases adding support for r_pipe. After 
> all these changes only upper level functions access pstate->pipe. Then 
> it becomes natural to do:
> 
> dpu_plane_do_something(plane->pipe);
> if (plane->r_pipe)
>      dpu_plane_do_something(plane->r_pipe);

Understood,

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

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

* Re: [PATCH v3 26/27] drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-08 23:44     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-08 23:44 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Rework _dpu_crtc_blend_setup_mixer() to split away pipe handling to a
> separate functon. This is a preparation for the r_pipe support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 86 ++++++++++++++++-------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 ++-
>   2 files changed, 63 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 73e1a8c69ef0..0ca3bc38ff7e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -400,6 +400,47 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
>   	}
>   }
>   
> +static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
> +				       struct drm_plane *plane,
> +				       struct dpu_crtc_mixer *mixer,
> +				       u32 num_mixers,
> +				       struct dpu_hw_stage_cfg *stage_cfg,
> +				       enum dpu_stage stage,
> +				       unsigned int stage_idx,
> +				       unsigned long *fetch_active,
> +				       struct dpu_sw_pipe *pipe
> +				      )
> +{
> +	uint32_t lm_idx;
> +	enum dpu_sspp sspp_idx;
> +	struct drm_plane_state *state;
> +
> +	if (!pipe->sspp)
> +		return;
> +
> +	sspp_idx = pipe->sspp->idx;
> +
> +	state = plane->state;
> +
> +	DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
> +			 crtc->base.id,
> +			 stage,
> +			 plane->base.id,
> +			 sspp_idx - SSPP_NONE,
> +			 state->fb ? state->fb->base.id : -1);
> +
> +	set_bit(sspp_idx, fetch_active);
> +
> +	stage_cfg->stage[stage][stage_idx] = sspp_idx;
> +	stage_cfg->multirect_index[stage][stage_idx] =
> +				pipe->multirect_index;
> +
> +	/* blend config update */
> +	for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
> +		mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl,
> +								    sspp_idx);

If you just pass the format to this function you can move rest of the 
for loop also to this function.

Also, you will be able to add the trace_dpu_crtc_setup_mixer() with 
complete information.

trace_dpu_crtc_setup_mixer is currently missing te stage_idx which is 
important to debug blend issues.

> +}
> +
>   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)
> @@ -412,15 +453,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   	struct dpu_format *format;
>   	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>   
> -	uint32_t stage_idx, lm_idx;
> -	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
> +	uint32_t lm_idx;
>   	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;
> -
>   		state = plane->state;
>   		if (!state)
>   			continue;
> @@ -431,39 +469,25 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   		pstate = to_dpu_plane_state(state);
>   		fb = state->fb;
>   
> -		sspp_idx = pstate->pipe.sspp->idx;
> -		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,
> -				sspp_idx - SSPP_VIG0,
> -				state->fb ? state->fb->base.id : -1);
> -
>   		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
>   
>   		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->pipe.multirect_index;
> -
>   		trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
> -					   state, pstate, stage_idx,
> +					   state, pstate,
>   					   format->base.pixel_format,
>   					   fb ? fb->modifier : 0);
>   
> +		_dpu_crtc_blend_setup_pipe(crtc, plane,
> +					   mixer, cstate->num_mixers,
> +					   stage_cfg, pstate->stage, 0,
> +					   fetch_active,
> +					   &pstate->pipe);
> +
>   		/* blend config update */
>   		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
> -			_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);
> +			_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
>   
>   			if (bg_alpha_enable && !format->alpha_enable)
>   				mixer[lm_idx].mixer_op_mode = 0;
> @@ -1297,8 +1321,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, "\tmultirect: mode: %d index: %d\n",
> +		seq_printf(s, "\tsspp[0]:%d\n",
> +			   pstate->pipe.sspp->idx - SSPP_NONE);
> +		seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
>   			pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
> +		if (pstate->r_pipe.sspp) {
> +			seq_printf(s, "\tsspp[1]:%d\n",
> +				   pstate->r_pipe.sspp->idx - SSPP_NONE);
> +			seq_printf(s, "\tmultirect[1]: 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_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> index 0ad148cc2fb8..5ec4f89e8814 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> @@ -633,9 +633,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, uint32_t pixel_format,
> +		 uint32_t pixel_format,
>   		 uint64_t modifier),
> -	TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
> +	TP_ARGS(crtc_id, plane_id, state, pstate,
>   		pixel_format, modifier),
>   	TP_STRUCT__entry(
>   		__field(	uint32_t,		crtc_id		)
> @@ -643,7 +643,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>   		__field(	uint32_t,		fb_id		)
>   		__field_struct(	struct drm_rect,	src_rect	)
>   		__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	)
> @@ -657,7 +656,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>   		__entry->fb_id = state ? state->fb->base.id : 0;
>   		__entry->src_rect = drm_plane_state_src(state);
>   		__entry->dst_rect = drm_plane_state_dest(state);
> -		__entry->stage_idx = stage_idx;
>   		__entry->stage = pstate->stage;
>   		__entry->sspp = pstate->pipe.sspp->idx;
>   		__entry->multirect_idx = pstate->pipe.multirect_index;
> @@ -666,13 +664,13 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>   		__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:%d, sspp:%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, __entry->sspp,
>   		  __entry->multirect_idx, __entry->multirect_mode,
>   		  __entry->pixel_format, __entry->modifier)
>   );

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

* Re: [PATCH v3 26/27] drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
@ 2023-02-08 23:44     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-08 23:44 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Rework _dpu_crtc_blend_setup_mixer() to split away pipe handling to a
> separate functon. This is a preparation for the r_pipe support.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 86 ++++++++++++++++-------
>   drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 ++-
>   2 files changed, 63 insertions(+), 33 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 73e1a8c69ef0..0ca3bc38ff7e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -400,6 +400,47 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
>   	}
>   }
>   
> +static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
> +				       struct drm_plane *plane,
> +				       struct dpu_crtc_mixer *mixer,
> +				       u32 num_mixers,
> +				       struct dpu_hw_stage_cfg *stage_cfg,
> +				       enum dpu_stage stage,
> +				       unsigned int stage_idx,
> +				       unsigned long *fetch_active,
> +				       struct dpu_sw_pipe *pipe
> +				      )
> +{
> +	uint32_t lm_idx;
> +	enum dpu_sspp sspp_idx;
> +	struct drm_plane_state *state;
> +
> +	if (!pipe->sspp)
> +		return;
> +
> +	sspp_idx = pipe->sspp->idx;
> +
> +	state = plane->state;
> +
> +	DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
> +			 crtc->base.id,
> +			 stage,
> +			 plane->base.id,
> +			 sspp_idx - SSPP_NONE,
> +			 state->fb ? state->fb->base.id : -1);
> +
> +	set_bit(sspp_idx, fetch_active);
> +
> +	stage_cfg->stage[stage][stage_idx] = sspp_idx;
> +	stage_cfg->multirect_index[stage][stage_idx] =
> +				pipe->multirect_index;
> +
> +	/* blend config update */
> +	for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
> +		mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl,
> +								    sspp_idx);

If you just pass the format to this function you can move rest of the 
for loop also to this function.

Also, you will be able to add the trace_dpu_crtc_setup_mixer() with 
complete information.

trace_dpu_crtc_setup_mixer is currently missing te stage_idx which is 
important to debug blend issues.

> +}
> +
>   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)
> @@ -412,15 +453,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   	struct dpu_format *format;
>   	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>   
> -	uint32_t stage_idx, lm_idx;
> -	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
> +	uint32_t lm_idx;
>   	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;
> -
>   		state = plane->state;
>   		if (!state)
>   			continue;
> @@ -431,39 +469,25 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   		pstate = to_dpu_plane_state(state);
>   		fb = state->fb;
>   
> -		sspp_idx = pstate->pipe.sspp->idx;
> -		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,
> -				sspp_idx - SSPP_VIG0,
> -				state->fb ? state->fb->base.id : -1);
> -
>   		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
>   
>   		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->pipe.multirect_index;
> -
>   		trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
> -					   state, pstate, stage_idx,
> +					   state, pstate,
>   					   format->base.pixel_format,
>   					   fb ? fb->modifier : 0);
>   
> +		_dpu_crtc_blend_setup_pipe(crtc, plane,
> +					   mixer, cstate->num_mixers,
> +					   stage_cfg, pstate->stage, 0,
> +					   fetch_active,
> +					   &pstate->pipe);
> +
>   		/* blend config update */
>   		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
> -			_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);
> +			_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
>   
>   			if (bg_alpha_enable && !format->alpha_enable)
>   				mixer[lm_idx].mixer_op_mode = 0;
> @@ -1297,8 +1321,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, "\tmultirect: mode: %d index: %d\n",
> +		seq_printf(s, "\tsspp[0]:%d\n",
> +			   pstate->pipe.sspp->idx - SSPP_NONE);
> +		seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
>   			pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
> +		if (pstate->r_pipe.sspp) {
> +			seq_printf(s, "\tsspp[1]:%d\n",
> +				   pstate->r_pipe.sspp->idx - SSPP_NONE);
> +			seq_printf(s, "\tmultirect[1]: 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_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> index 0ad148cc2fb8..5ec4f89e8814 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
> @@ -633,9 +633,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, uint32_t pixel_format,
> +		 uint32_t pixel_format,
>   		 uint64_t modifier),
> -	TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
> +	TP_ARGS(crtc_id, plane_id, state, pstate,
>   		pixel_format, modifier),
>   	TP_STRUCT__entry(
>   		__field(	uint32_t,		crtc_id		)
> @@ -643,7 +643,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>   		__field(	uint32_t,		fb_id		)
>   		__field_struct(	struct drm_rect,	src_rect	)
>   		__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	)
> @@ -657,7 +656,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>   		__entry->fb_id = state ? state->fb->base.id : 0;
>   		__entry->src_rect = drm_plane_state_src(state);
>   		__entry->dst_rect = drm_plane_state_dest(state);
> -		__entry->stage_idx = stage_idx;
>   		__entry->stage = pstate->stage;
>   		__entry->sspp = pstate->pipe.sspp->idx;
>   		__entry->multirect_idx = pstate->pipe.multirect_index;
> @@ -666,13 +664,13 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>   		__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:%d, sspp:%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, __entry->sspp,
>   		  __entry->multirect_idx, __entry->multirect_mode,
>   		  __entry->pixel_format, __entry->modifier)
>   );

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

* Re: [PATCH v3 26/27] drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
  2023-02-08 23:44     ` Abhinav Kumar
@ 2023-02-08 23:47       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-08 23:47 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 09/02/2023 01:44, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Rework _dpu_crtc_blend_setup_mixer() to split away pipe handling to a
>> separate functon. This is a preparation for the r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 86 ++++++++++++++++-------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 ++-
>>   2 files changed, 63 insertions(+), 33 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> index 73e1a8c69ef0..0ca3bc38ff7e 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> @@ -400,6 +400,47 @@ static void 
>> _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
>>       }
>>   }
>> +static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
>> +                       struct drm_plane *plane,
>> +                       struct dpu_crtc_mixer *mixer,
>> +                       u32 num_mixers,
>> +                       struct dpu_hw_stage_cfg *stage_cfg,
>> +                       enum dpu_stage stage,
>> +                       unsigned int stage_idx,
>> +                       unsigned long *fetch_active,
>> +                       struct dpu_sw_pipe *pipe
>> +                      )
>> +{
>> +    uint32_t lm_idx;
>> +    enum dpu_sspp sspp_idx;
>> +    struct drm_plane_state *state;
>> +
>> +    if (!pipe->sspp)
>> +        return;
>> +
>> +    sspp_idx = pipe->sspp->idx;
>> +
>> +    state = plane->state;
>> +
>> +    DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
>> +             crtc->base.id,
>> +             stage,
>> +             plane->base.id,
>> +             sspp_idx - SSPP_NONE,
>> +             state->fb ? state->fb->base.id : -1);
>> +
>> +    set_bit(sspp_idx, fetch_active);
>> +
>> +    stage_cfg->stage[stage][stage_idx] = sspp_idx;
>> +    stage_cfg->multirect_index[stage][stage_idx] =
>> +                pipe->multirect_index;
>> +
>> +    /* blend config update */
>> +    for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
>> +        
>> mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl,
>> +                                    sspp_idx);
> 
> If you just pass the format to this function you can move rest of the 
> for loop also to this function.
> 
> Also, you will be able to add the trace_dpu_crtc_setup_mixer() with 
> complete information.
> 
> trace_dpu_crtc_setup_mixer is currently missing te stage_idx which is 
> important to debug blend issues.

Ack, I'll add it back, thanks for the note.

> 
>> +}
>> +
>>   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)
>> @@ -412,15 +453,12 @@ static void _dpu_crtc_blend_setup_mixer(struct 
>> drm_crtc *crtc,
>>       struct dpu_format *format;
>>       struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>> -    uint32_t stage_idx, lm_idx;
>> -    int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
>> +    uint32_t lm_idx;
>>       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;
>> -
>>           state = plane->state;
>>           if (!state)
>>               continue;
>> @@ -431,39 +469,25 @@ static void _dpu_crtc_blend_setup_mixer(struct 
>> drm_crtc *crtc,
>>           pstate = to_dpu_plane_state(state);
>>           fb = state->fb;
>> -        sspp_idx = pstate->pipe.sspp->idx;
>> -        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,
>> -                sspp_idx - SSPP_VIG0,
>> -                state->fb ? state->fb->base.id : -1);
>> -
>>           format = 
>> to_dpu_format(msm_framebuffer_format(pstate->base.fb));
>>           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->pipe.multirect_index;
>> -
>>           trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
>> -                       state, pstate, stage_idx,
>> +                       state, pstate,
>>                          format->base.pixel_format,
>>                          fb ? fb->modifier : 0);
>> +        _dpu_crtc_blend_setup_pipe(crtc, plane,
>> +                       mixer, cstate->num_mixers,
>> +                       stage_cfg, pstate->stage, 0,
>> +                       fetch_active,
>> +                       &pstate->pipe);
>> +
>>           /* blend config update */
>>           for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
>> -            _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);
>> +            _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
>>               if (bg_alpha_enable && !format->alpha_enable)
>>                   mixer[lm_idx].mixer_op_mode = 0;
>> @@ -1297,8 +1321,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, "\tmultirect: mode: %d index: %d\n",
>> +        seq_printf(s, "\tsspp[0]:%d\n",
>> +               pstate->pipe.sspp->idx - SSPP_NONE);
>> +        seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
>>               pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
>> +        if (pstate->r_pipe.sspp) {
>> +            seq_printf(s, "\tsspp[1]:%d\n",
>> +                   pstate->r_pipe.sspp->idx - SSPP_NONE);
>> +            seq_printf(s, "\tmultirect[1]: 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_trace.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> index 0ad148cc2fb8..5ec4f89e8814 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> @@ -633,9 +633,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, uint32_t pixel_format,
>> +         uint32_t pixel_format,
>>            uint64_t modifier),
>> -    TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
>> +    TP_ARGS(crtc_id, plane_id, state, pstate,
>>           pixel_format, modifier),
>>       TP_STRUCT__entry(
>>           __field(    uint32_t,        crtc_id        )
>> @@ -643,7 +643,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __field(    uint32_t,        fb_id        )
>>           __field_struct(    struct drm_rect,    src_rect    )
>>           __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    )
>> @@ -657,7 +656,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __entry->fb_id = state ? state->fb->base.id : 0;
>>           __entry->src_rect = drm_plane_state_src(state);
>>           __entry->dst_rect = drm_plane_state_dest(state);
>> -        __entry->stage_idx = stage_idx;
>>           __entry->stage = pstate->stage;
>>           __entry->sspp = pstate->pipe.sspp->idx;
>>           __entry->multirect_idx = pstate->pipe.multirect_index;
>> @@ -666,13 +664,13 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __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:%d, sspp:%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, __entry->sspp,
>>             __entry->multirect_idx, __entry->multirect_mode,
>>             __entry->pixel_format, __entry->modifier)
>>   );

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 26/27] drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
@ 2023-02-08 23:47       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-08 23:47 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 09/02/2023 01:44, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Rework _dpu_crtc_blend_setup_mixer() to split away pipe handling to a
>> separate functon. This is a preparation for the r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 86 ++++++++++++++++-------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 ++-
>>   2 files changed, 63 insertions(+), 33 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> index 73e1a8c69ef0..0ca3bc38ff7e 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> @@ -400,6 +400,47 @@ static void 
>> _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
>>       }
>>   }
>> +static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
>> +                       struct drm_plane *plane,
>> +                       struct dpu_crtc_mixer *mixer,
>> +                       u32 num_mixers,
>> +                       struct dpu_hw_stage_cfg *stage_cfg,
>> +                       enum dpu_stage stage,
>> +                       unsigned int stage_idx,
>> +                       unsigned long *fetch_active,
>> +                       struct dpu_sw_pipe *pipe
>> +                      )
>> +{
>> +    uint32_t lm_idx;
>> +    enum dpu_sspp sspp_idx;
>> +    struct drm_plane_state *state;
>> +
>> +    if (!pipe->sspp)
>> +        return;
>> +
>> +    sspp_idx = pipe->sspp->idx;
>> +
>> +    state = plane->state;
>> +
>> +    DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
>> +             crtc->base.id,
>> +             stage,
>> +             plane->base.id,
>> +             sspp_idx - SSPP_NONE,
>> +             state->fb ? state->fb->base.id : -1);
>> +
>> +    set_bit(sspp_idx, fetch_active);
>> +
>> +    stage_cfg->stage[stage][stage_idx] = sspp_idx;
>> +    stage_cfg->multirect_index[stage][stage_idx] =
>> +                pipe->multirect_index;
>> +
>> +    /* blend config update */
>> +    for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
>> +        
>> mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl,
>> +                                    sspp_idx);
> 
> If you just pass the format to this function you can move rest of the 
> for loop also to this function.
> 
> Also, you will be able to add the trace_dpu_crtc_setup_mixer() with 
> complete information.
> 
> trace_dpu_crtc_setup_mixer is currently missing te stage_idx which is 
> important to debug blend issues.

Ack, I'll add it back, thanks for the note.

> 
>> +}
>> +
>>   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)
>> @@ -412,15 +453,12 @@ static void _dpu_crtc_blend_setup_mixer(struct 
>> drm_crtc *crtc,
>>       struct dpu_format *format;
>>       struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>> -    uint32_t stage_idx, lm_idx;
>> -    int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
>> +    uint32_t lm_idx;
>>       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;
>> -
>>           state = plane->state;
>>           if (!state)
>>               continue;
>> @@ -431,39 +469,25 @@ static void _dpu_crtc_blend_setup_mixer(struct 
>> drm_crtc *crtc,
>>           pstate = to_dpu_plane_state(state);
>>           fb = state->fb;
>> -        sspp_idx = pstate->pipe.sspp->idx;
>> -        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,
>> -                sspp_idx - SSPP_VIG0,
>> -                state->fb ? state->fb->base.id : -1);
>> -
>>           format = 
>> to_dpu_format(msm_framebuffer_format(pstate->base.fb));
>>           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->pipe.multirect_index;
>> -
>>           trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
>> -                       state, pstate, stage_idx,
>> +                       state, pstate,
>>                          format->base.pixel_format,
>>                          fb ? fb->modifier : 0);
>> +        _dpu_crtc_blend_setup_pipe(crtc, plane,
>> +                       mixer, cstate->num_mixers,
>> +                       stage_cfg, pstate->stage, 0,
>> +                       fetch_active,
>> +                       &pstate->pipe);
>> +
>>           /* blend config update */
>>           for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
>> -            _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);
>> +            _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
>>               if (bg_alpha_enable && !format->alpha_enable)
>>                   mixer[lm_idx].mixer_op_mode = 0;
>> @@ -1297,8 +1321,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, "\tmultirect: mode: %d index: %d\n",
>> +        seq_printf(s, "\tsspp[0]:%d\n",
>> +               pstate->pipe.sspp->idx - SSPP_NONE);
>> +        seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
>>               pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
>> +        if (pstate->r_pipe.sspp) {
>> +            seq_printf(s, "\tsspp[1]:%d\n",
>> +                   pstate->r_pipe.sspp->idx - SSPP_NONE);
>> +            seq_printf(s, "\tmultirect[1]: 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_trace.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> index 0ad148cc2fb8..5ec4f89e8814 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> @@ -633,9 +633,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, uint32_t pixel_format,
>> +         uint32_t pixel_format,
>>            uint64_t modifier),
>> -    TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
>> +    TP_ARGS(crtc_id, plane_id, state, pstate,
>>           pixel_format, modifier),
>>       TP_STRUCT__entry(
>>           __field(    uint32_t,        crtc_id        )
>> @@ -643,7 +643,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __field(    uint32_t,        fb_id        )
>>           __field_struct(    struct drm_rect,    src_rect    )
>>           __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    )
>> @@ -657,7 +656,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __entry->fb_id = state ? state->fb->base.id : 0;
>>           __entry->src_rect = drm_plane_state_src(state);
>>           __entry->dst_rect = drm_plane_state_dest(state);
>> -        __entry->stage_idx = stage_idx;
>>           __entry->stage = pstate->stage;
>>           __entry->sspp = pstate->pipe.sspp->idx;
>>           __entry->multirect_idx = pstate->pipe.multirect_index;
>> @@ -666,13 +664,13 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __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:%d, sspp:%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, __entry->sspp,
>>             __entry->multirect_idx, __entry->multirect_mode,
>>             __entry->pixel_format, __entry->modifier)
>>   );

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
  2023-02-05  0:36                         ` Abhinav Kumar
@ 2023-02-08 23:53                           ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-08 23:53 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Stephen Boyd, David Airlie, Daniel Vetter,
	Bjorn Andersson, linux-arm-msm, dri-devel, freedreno

On 05/02/2023 02:36, Abhinav Kumar wrote:
> 
> 
> On 2/4/2023 4:29 PM, Dmitry Baryshkov wrote:
>> On Sun, 5 Feb 2023 at 01:20, Abhinav Kumar <quic_abhinavk@quicinc.com> 
>> wrote:
>>>
>>>
>>>
>>> On 2/4/2023 1:08 PM, Dmitry Baryshkov wrote:
>>>> On 04/02/2023 20:35, Abhinav Kumar wrote:
>>>>>
>>>>>
>>>>> On 2/4/2023 2:43 AM, Dmitry Baryshkov wrote:
>>>>>> On 04/02/2023 07:10, Abhinav Kumar wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
>>>>>>>> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>>>>>>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>>>>>>> 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.
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> While reviewing this patch, I had a first hand experience of how
>>>>>>>>>>> we are reusing SSPP bitmasks for so many chipsets but I think
>>>>>>>>>>> overall you got them right here :)
>>>>>>>>>>>
>>>>>>>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>>>>> @@ -21,13 +21,16 @@
>>>>>>>>>>>>        (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>>>>>>>>    #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>>>>>>>>> @@ -42,6 +45,7 @@
>>>>>>>>>>>>    #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 \
>>>>>>>>>>>
>>>>>>>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other
>>>>>>>>>>> chipsets like 8250, 8450, 8550.
>>>>>>>>>>>
>>>>>>>>>>> At the moment, for visual validation of this series, I only have
>>>>>>>>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>>>>>>>>
>>>>>>>>>>> Was that an intentional approach?
>>>>>>>>>>>
>>>>>>>>>>> If so, we will need tested-by tags from folks having
>>>>>>>>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>>>>>>>>
>>>>>>>>>>> I am only owning the visual validation on sc7280 atm.
>>>>>>>>>>
>>>>>>>>>> I'm not quite sure what is your intent here. Are there any SoCs
>>>>>>>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to
>>>>>>>>>> enable SmartDMA only for the chipsets that we can visually test?
>>>>>>>>>> That sounds strange.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Yes I was thinking to enable smartDMA at the moment on chipsets
>>>>>>>>> which we can validate visually that display comes up. But I am not
>>>>>>>>> sure if thats entirely practical.
>>>>>>>>>
>>>>>>>>> But the intent was I just want to make sure basic display does
>>>>>>>>> come up with smartDMA enabled if we are enabling it for all 
>>>>>>>>> chipsets.
>>>>>>>>
>>>>>>>> I don't think it is practical or logical. We don't require
>>>>>>>> validating other changes on all possible chipsets, so what is so
>>>>>>>> different with this one?
>>>>>>>>
>>>>>>>
>>>>>>> Thats because with smartDMA if the programming of stages goes wrong
>>>>>>> we could potentially just see a blank screen. Its not about other
>>>>>>> changes, this change in particular controls enabling a feature.
>>>>>>>
>>>>>>> But thats just my thought. I am not going to request to ensure this
>>>>>>> or block this for this.
>>>>>>>
>>>>>>> You can still have my
>>>>>>>
>>>>>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>>>>>>
>>>>>>> But think of the validations that have to be done before we merge 
>>>>>>> it.
>>>>>>
>>>>>> The usual way: verify as much as feasible and let anybody else
>>>>>> complain during the development cycle.
>>>>>>
>>>>>
>>>>> Well, our perspective is to enable the feature on devices on which you
>>>>> are able to test and not enable then wait for others to complain.
>>>>
>>>> This would not be really practical. There are plenty of people who can
>>>> test things on obscure platforms, but unfortunately far less amount of
>>>> people who tightly follow the development and can track which new
>>>> feature applies to a particular platform. I hope to be able to fix that
>>>> slightly with the hw catalog rework. However enabling features on other
>>>> platforms definitely requires more knowledge than simply testing the
>>>> kernel.
>>>>
>>>>>
>>>>> I did not say test all devices. My point was to enable smartDMA on
>>>>> devices which we are able to test.
>>>>>
>>>>> There are other examples of this, like inline rotation, writeback etc.
>>>>> which are at the moment enabled only on devices which QC or others
>>>>> have tested on.
>>>>
>>>> But at the time it was added, inline rotation 2.0 could only be
>>>> supported on sc7280. Probably we should expand it not to sc8280xp and
>>>> sm8[345]50.
>>>>
>>>> For WB I don't remember which platforms were supported at the moment it
>>>> was added. But it's also worth expanding support to new platforms.
>>>>
>>>> And, as we speak about testing, is there an easy way to setup the plane
>>>> with UBWC format modifier? Also, did the WB support patches land into
>>>> libdrm?
>>>>
>>>
>>> I will check the compositor code and update you on the UWBC format
>>> modifier as I am not too familiar with it.
>>
>> Ideally it would be nice to support ubwc planes in some simple tool,
>> e.g. modetest.
>>
>>>
>>> libdrm always supported virtual encoder
>>> https://github.com/grate-driver/libdrm/blob/master/include/drm/drm_mode.h#L352
>>>
>>> What other support patches are needed? Right now we only use IGT to
>>> validate writeback.
>>
>> I remember there was a patchset to make modeset to support using
>> writeback. What was its fate?
>>
> 
> Once our intern finished his internship, noone could take up the pending 
> review comments after that so its yet to be merged.
> 
> https://patchwork.kernel.org/project/dri-devel/list/?series=667290&archive=both
> 
> Once more item to the to-do list.

Oh. Quite a pity :-(
I hope somebody can pick it up on either of our sides.

> 
>>>
>>>>> So when i said my suggestion was not practical, yes because if you
>>>>> want to go ahead with this change in the current form, you would have
>>>>> to validate all the chipsets as you are enabling smartDMA on all of 
>>>>> them.
>>>>>
>>>>> If you enable smartDMA only on the chipsets you OR others can validate
>>>>> and give Tested-by for like I was planning to do for sc7280, then I am
>>>>> not sure why it doesnt sound logical.
>>>>>
>>>>> But like I said, thats my perspective. I will let you decide as you
>>>>> would know how confident you are with this getting enabled for all
>>>>> chipsets upstream.
>>>>
>>>> I'd say, that once tested on some of the platforms and granted that 
>>>> even
>>>> smalled (qcm2290, sm6115) platforms support smartdma, it will be 
>>>> safe to
>>>> enable smart DMA globablly for every SoC >= sdm845. If I remember
>>>> correctly, msm8998 (and sdm660/630) support smartdma/rect only on DMA
>>>> planes. Is it correct?
>>>>
>>>>
>>> Yes thats right msm8998 supports smartdma only on DMA sspps.
>>
>> Good
>>

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog
@ 2023-02-08 23:53                           ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-08 23:53 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: freedreno, Sean Paul, Bjorn Andersson, dri-devel, Stephen Boyd,
	linux-arm-msm

On 05/02/2023 02:36, Abhinav Kumar wrote:
> 
> 
> On 2/4/2023 4:29 PM, Dmitry Baryshkov wrote:
>> On Sun, 5 Feb 2023 at 01:20, Abhinav Kumar <quic_abhinavk@quicinc.com> 
>> wrote:
>>>
>>>
>>>
>>> On 2/4/2023 1:08 PM, Dmitry Baryshkov wrote:
>>>> On 04/02/2023 20:35, Abhinav Kumar wrote:
>>>>>
>>>>>
>>>>> On 2/4/2023 2:43 AM, Dmitry Baryshkov wrote:
>>>>>> On 04/02/2023 07:10, Abhinav Kumar wrote:
>>>>>>>
>>>>>>>
>>>>>>> On 2/3/2023 8:10 PM, Dmitry Baryshkov wrote:
>>>>>>>> On 04/02/2023 04:43, Abhinav Kumar wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 2/3/2023 6:29 PM, Dmitry Baryshkov wrote:
>>>>>>>>>> On 04/02/2023 01:35, Abhinav Kumar wrote:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>>>>>>> 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.
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> While reviewing this patch, I had a first hand experience of how
>>>>>>>>>>> we are reusing SSPP bitmasks for so many chipsets but I think
>>>>>>>>>>> overall you got them right here :)
>>>>>>>>>>>
>>>>>>>>>>>> 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 cf053e8f081e..fc818b0273e7 100644
>>>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>>>>> @@ -21,13 +21,16 @@
>>>>>>>>>>>>        (VIG_MASK | BIT(DPU_SSPP_SCALER_QSEED3))
>>>>>>>>>>>>    #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 VIG_QCM2290_MASK (VIG_MASK | BIT(DPU_SSPP_QOS_8LVL))
>>>>>>>>>>>> @@ -42,6 +45,7 @@
>>>>>>>>>>>>    #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 \
>>>>>>>>>>>
>>>>>>>>>>> VIG_SDM845_MASK and DMA_SDM845_MASK are used for many other
>>>>>>>>>>> chipsets like 8250, 8450, 8550.
>>>>>>>>>>>
>>>>>>>>>>> At the moment, for visual validation of this series, I only have
>>>>>>>>>>> sc7180/sc7280. We are leaving the rest for CI.
>>>>>>>>>>>
>>>>>>>>>>> Was that an intentional approach?
>>>>>>>>>>>
>>>>>>>>>>> If so, we will need tested-by tags from folks having
>>>>>>>>>>> 8350/8450/8550/sc8280x,qcm2290?
>>>>>>>>>>>
>>>>>>>>>>> I am only owning the visual validation on sc7280 atm.
>>>>>>>>>>
>>>>>>>>>> I'm not quite sure what is your intent here. Are there any SoCs
>>>>>>>>>> after 845 that do not have SmartDMA 2.5? Or do you propose to
>>>>>>>>>> enable SmartDMA only for the chipsets that we can visually test?
>>>>>>>>>> That sounds strange.
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Yes I was thinking to enable smartDMA at the moment on chipsets
>>>>>>>>> which we can validate visually that display comes up. But I am not
>>>>>>>>> sure if thats entirely practical.
>>>>>>>>>
>>>>>>>>> But the intent was I just want to make sure basic display does
>>>>>>>>> come up with smartDMA enabled if we are enabling it for all 
>>>>>>>>> chipsets.
>>>>>>>>
>>>>>>>> I don't think it is practical or logical. We don't require
>>>>>>>> validating other changes on all possible chipsets, so what is so
>>>>>>>> different with this one?
>>>>>>>>
>>>>>>>
>>>>>>> Thats because with smartDMA if the programming of stages goes wrong
>>>>>>> we could potentially just see a blank screen. Its not about other
>>>>>>> changes, this change in particular controls enabling a feature.
>>>>>>>
>>>>>>> But thats just my thought. I am not going to request to ensure this
>>>>>>> or block this for this.
>>>>>>>
>>>>>>> You can still have my
>>>>>>>
>>>>>>> Reviewed-by: Abhinav Kumar <quic_abhinavk@quicinc.com>
>>>>>>>
>>>>>>> But think of the validations that have to be done before we merge 
>>>>>>> it.
>>>>>>
>>>>>> The usual way: verify as much as feasible and let anybody else
>>>>>> complain during the development cycle.
>>>>>>
>>>>>
>>>>> Well, our perspective is to enable the feature on devices on which you
>>>>> are able to test and not enable then wait for others to complain.
>>>>
>>>> This would not be really practical. There are plenty of people who can
>>>> test things on obscure platforms, but unfortunately far less amount of
>>>> people who tightly follow the development and can track which new
>>>> feature applies to a particular platform. I hope to be able to fix that
>>>> slightly with the hw catalog rework. However enabling features on other
>>>> platforms definitely requires more knowledge than simply testing the
>>>> kernel.
>>>>
>>>>>
>>>>> I did not say test all devices. My point was to enable smartDMA on
>>>>> devices which we are able to test.
>>>>>
>>>>> There are other examples of this, like inline rotation, writeback etc.
>>>>> which are at the moment enabled only on devices which QC or others
>>>>> have tested on.
>>>>
>>>> But at the time it was added, inline rotation 2.0 could only be
>>>> supported on sc7280. Probably we should expand it not to sc8280xp and
>>>> sm8[345]50.
>>>>
>>>> For WB I don't remember which platforms were supported at the moment it
>>>> was added. But it's also worth expanding support to new platforms.
>>>>
>>>> And, as we speak about testing, is there an easy way to setup the plane
>>>> with UBWC format modifier? Also, did the WB support patches land into
>>>> libdrm?
>>>>
>>>
>>> I will check the compositor code and update you on the UWBC format
>>> modifier as I am not too familiar with it.
>>
>> Ideally it would be nice to support ubwc planes in some simple tool,
>> e.g. modetest.
>>
>>>
>>> libdrm always supported virtual encoder
>>> https://github.com/grate-driver/libdrm/blob/master/include/drm/drm_mode.h#L352
>>>
>>> What other support patches are needed? Right now we only use IGT to
>>> validate writeback.
>>
>> I remember there was a patchset to make modeset to support using
>> writeback. What was its fate?
>>
> 
> Once our intern finished his internship, noone could take up the pending 
> review comments after that so its yet to be merged.
> 
> https://patchwork.kernel.org/project/dri-devel/list/?series=667290&archive=both
> 
> Once more item to the to-do list.

Oh. Quite a pity :-(
I hope somebody can pick it up on either of our sides.

> 
>>>
>>>>> So when i said my suggestion was not practical, yes because if you
>>>>> want to go ahead with this change in the current form, you would have
>>>>> to validate all the chipsets as you are enabling smartDMA on all of 
>>>>> them.
>>>>>
>>>>> If you enable smartDMA only on the chipsets you OR others can validate
>>>>> and give Tested-by for like I was planning to do for sc7280, then I am
>>>>> not sure why it doesnt sound logical.
>>>>>
>>>>> But like I said, thats my perspective. I will let you decide as you
>>>>> would know how confident you are with this getting enabled for all
>>>>> chipsets upstream.
>>>>
>>>> I'd say, that once tested on some of the platforms and granted that 
>>>> even
>>>> smalled (qcm2290, sm6115) platforms support smartdma, it will be 
>>>> safe to
>>>> enable smart DMA globablly for every SoC >= sdm845. If I remember
>>>> correctly, msm8998 (and sdm660/630) support smartdma/rect only on DMA
>>>> planes. Is it correct?
>>>>
>>>>
>>> Yes thats right msm8998 supports smartdma only on DMA sspps.
>>
>> Good
>>

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
  2023-02-07  0:22     ` Abhinav Kumar
@ 2023-02-09  0:49       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-09  0:49 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 07/02/2023 02:22, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the
> 
> sspp-dependent?
> 
>> separate function dpu_plane_sspp_update_pipe(). This is one of
>> preparational steps to add r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> Just a couple of minor comments below but otherwise this split up lgtm
> 
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 113 ++++++++++++----------
>>   1 file changed, 63 insertions(+), 50 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 0986e740b978..f94e132733f3 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -404,12 +404,13 @@ 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
>>    * @pipe:        Pointer to software pipe
>> - * @crtc:        Pointer to drm crtc
>>    * @pipe_cfg:        Pointer to pipe configuration
>> + * @frame_rate:        CRTC's frame rate
> 
> Can you please check the spacing here. There seems to be an extra tab 
> before the CRTC's frame rate
> 
>>    */
>>   static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
>>           struct dpu_sw_pipe *pipe,
>> -        struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
>> +        int frame_rate)
>>   {
>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>       struct dpu_vbif_set_ot_params ot_params;
>> @@ -421,7 +422,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 = frame_rate;
>>       ot_params.vbif_idx = VBIF_RT;
>>       ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
>>       ot_params.rd = true;
>> @@ -457,26 +458,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 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;
>> -    struct dpu_hw_fmt_layout layout;
>> -    int ret;
>> -
>> -    ret = dpu_format_populate_layout(aspace, fb, &layout);
>> -    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,
>> -                        &layout);
>> -        pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, 
>> &layout);
>> -    }
>> -}
>> -
>>   static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *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,
>> @@ -1102,35 +1083,25 @@ 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_sspp_update_pipe(struct drm_plane *plane,
>> +                       struct dpu_sw_pipe *pipe,
>> +                       struct dpu_hw_sspp_cfg *pipe_cfg,
> 
> You can call this parameter sspp_cfg instead of pipe_cfg?

I think, I'll add a commit renaming dpu_hw_sspp_cfg to dpu_sw_pipe_cfg, 
it would be simmetrical to dpu_sw_pipe then.

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
@ 2023-02-09  0:49       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-09  0:49 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 07/02/2023 02:22, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the
> 
> sspp-dependent?
> 
>> separate function dpu_plane_sspp_update_pipe(). This is one of
>> preparational steps to add r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> Just a couple of minor comments below but otherwise this split up lgtm
> 
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 113 ++++++++++++----------
>>   1 file changed, 63 insertions(+), 50 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 0986e740b978..f94e132733f3 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -404,12 +404,13 @@ 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
>>    * @pipe:        Pointer to software pipe
>> - * @crtc:        Pointer to drm crtc
>>    * @pipe_cfg:        Pointer to pipe configuration
>> + * @frame_rate:        CRTC's frame rate
> 
> Can you please check the spacing here. There seems to be an extra tab 
> before the CRTC's frame rate
> 
>>    */
>>   static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
>>           struct dpu_sw_pipe *pipe,
>> -        struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
>> +        int frame_rate)
>>   {
>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>       struct dpu_vbif_set_ot_params ot_params;
>> @@ -421,7 +422,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 = frame_rate;
>>       ot_params.vbif_idx = VBIF_RT;
>>       ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
>>       ot_params.rd = true;
>> @@ -457,26 +458,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 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;
>> -    struct dpu_hw_fmt_layout layout;
>> -    int ret;
>> -
>> -    ret = dpu_format_populate_layout(aspace, fb, &layout);
>> -    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,
>> -                        &layout);
>> -        pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, 
>> &layout);
>> -    }
>> -}
>> -
>>   static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *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,
>> @@ -1102,35 +1083,25 @@ 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_sspp_update_pipe(struct drm_plane *plane,
>> +                       struct dpu_sw_pipe *pipe,
>> +                       struct dpu_hw_sspp_cfg *pipe_cfg,
> 
> You can call this parameter sspp_cfg instead of pipe_cfg?

I think, I'll add a commit renaming dpu_hw_sspp_cfg to dpu_sw_pipe_cfg, 
it would be simmetrical to dpu_sw_pipe then.

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
  2023-02-07  0:22     ` Abhinav Kumar
@ 2023-02-09  0:51       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-09  0:51 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 07/02/2023 02:22, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the
> 
> sspp-dependent?

No, this is really pipe-dependent. It takes dpu_sw_pipe and 
dpu_sw_pipe_cfg arguments.

> 
>> separate function dpu_plane_sspp_update_pipe(). This is one of
>> preparational steps to add r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
@ 2023-02-09  0:51       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-09  0:51 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 07/02/2023 02:22, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the
> 
> sspp-dependent?

No, this is really pipe-dependent. It takes dpu_sw_pipe and 
dpu_sw_pipe_cfg arguments.

> 
>> separate function dpu_plane_sspp_update_pipe(). This is one of
>> preparational steps to add r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 25/27] drm/msm/dpu: rework static color fill code
  2023-02-08 22:34     ` Abhinav Kumar
@ 2023-02-09  0:53       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-09  0:53 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 09/02/2023 00:34, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Rework static color fill code to separate the pipe / pipe_cfg handling.
>> This is a preparation for the r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 70 +++++++++++++----------
>>   1 file changed, 41 insertions(+), 29 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 05047192cb37..e2e85688ed3c 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -639,20 +639,54 @@ static void _dpu_plane_setup_scaler(struct 
>> dpu_sw_pipe *pipe,
>>                   fmt);
>>   }
>> +static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>> +        struct dpu_sw_pipe *pipe,
>> +        struct dpu_hw_sspp_cfg *old_pipe_cfg,
> 
> Why is this called old_pipe_cfg instead of just pipe_cfg?

Ack. Probably got that wrong during mass-renaming and then missed to fix it.

> 
> 
>> +        u32 fill_color,
>> +        const struct dpu_format *fmt)
>> +{
>> +    struct dpu_hw_sspp_cfg pipe_cfg;
>> +
>> +    /* update sspp */
>> +    if (!pipe->sspp->ops.setup_solidfill)
>> +        return 0;
> 
> You can just return from here and make this function void?

Of course.

> 
>> +
>> +    pipe->sspp->ops.setup_solidfill(pipe, fill_color);
>> +
>> +    /* override scaler/decimation if solid fill */
>> +    pipe_cfg.dst_rect = old_pipe_cfg->dst_rect;
>> +
>> +    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);
>> +
>> +    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, 
>> pstate->rotation);
>> +
>> +    return 0;
>> +}
>> +
>>   /**
>>    * _dpu_plane_color_fill - enables color fill on plane
>>    * @pdpu:   Pointer to DPU plane object
>>    * @color:  RGB fill color value, [23..16] Blue, [15..8] Green, 
>> [7..0] Red
>>    * @alpha:  8-bit fill alpha value, 255 selects 100% alpha
>> - * Returns: 0 on success
>>    */
>> -static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>> +static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
>>           uint32_t color, uint32_t alpha)
>>   {
>>       const struct dpu_format *fmt;
>>       const struct drm_plane *plane = &pdpu->base;
>>       struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>> -    struct dpu_hw_sspp_cfg pipe_cfg;
>> +    u32 fill_color = (color & 0xFFFFFF) | ((alpha & 0xFF) << 24);
>>       DPU_DEBUG_PLANE(pdpu, "\n");
>> @@ -661,34 +695,12 @@ static int _dpu_plane_color_fill(struct 
>> dpu_plane *pdpu,
>>        * h/w only supports RGB variants
>>        */
>>       fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>> +    /* should not happen ever */
>> +    if (!fmt)
>> +        return;
>>       /* update sspp */
>> -    if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
>> -        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;
>> -
>> -        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);
>> -
>> -        if (pstate->pipe.sspp->ops.setup_format)
>> -            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,
>> -                    &pipe_cfg);
>> -
>> -        _dpu_plane_setup_scaler(&pstate->pipe, fmt, true, &pipe_cfg, 
>> pstate->rotation);
>> -    }
>> -
>> -    return 0;
>> +    _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, 
>> &pstate->pipe_cfg, fill_color, fmt);
>>   }
>>   int dpu_plane_validate_multirect_v2(struct 
>> dpu_multirect_plane_states *plane)

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 25/27] drm/msm/dpu: rework static color fill code
@ 2023-02-09  0:53       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-09  0:53 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 09/02/2023 00:34, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Rework static color fill code to separate the pipe / pipe_cfg handling.
>> This is a preparation for the r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 70 +++++++++++++----------
>>   1 file changed, 41 insertions(+), 29 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 05047192cb37..e2e85688ed3c 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -639,20 +639,54 @@ static void _dpu_plane_setup_scaler(struct 
>> dpu_sw_pipe *pipe,
>>                   fmt);
>>   }
>> +static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>> +        struct dpu_sw_pipe *pipe,
>> +        struct dpu_hw_sspp_cfg *old_pipe_cfg,
> 
> Why is this called old_pipe_cfg instead of just pipe_cfg?

Ack. Probably got that wrong during mass-renaming and then missed to fix it.

> 
> 
>> +        u32 fill_color,
>> +        const struct dpu_format *fmt)
>> +{
>> +    struct dpu_hw_sspp_cfg pipe_cfg;
>> +
>> +    /* update sspp */
>> +    if (!pipe->sspp->ops.setup_solidfill)
>> +        return 0;
> 
> You can just return from here and make this function void?

Of course.

> 
>> +
>> +    pipe->sspp->ops.setup_solidfill(pipe, fill_color);
>> +
>> +    /* override scaler/decimation if solid fill */
>> +    pipe_cfg.dst_rect = old_pipe_cfg->dst_rect;
>> +
>> +    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);
>> +
>> +    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, 
>> pstate->rotation);
>> +
>> +    return 0;
>> +}
>> +
>>   /**
>>    * _dpu_plane_color_fill - enables color fill on plane
>>    * @pdpu:   Pointer to DPU plane object
>>    * @color:  RGB fill color value, [23..16] Blue, [15..8] Green, 
>> [7..0] Red
>>    * @alpha:  8-bit fill alpha value, 255 selects 100% alpha
>> - * Returns: 0 on success
>>    */
>> -static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
>> +static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
>>           uint32_t color, uint32_t alpha)
>>   {
>>       const struct dpu_format *fmt;
>>       const struct drm_plane *plane = &pdpu->base;
>>       struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
>> -    struct dpu_hw_sspp_cfg pipe_cfg;
>> +    u32 fill_color = (color & 0xFFFFFF) | ((alpha & 0xFF) << 24);
>>       DPU_DEBUG_PLANE(pdpu, "\n");
>> @@ -661,34 +695,12 @@ static int _dpu_plane_color_fill(struct 
>> dpu_plane *pdpu,
>>        * h/w only supports RGB variants
>>        */
>>       fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
>> +    /* should not happen ever */
>> +    if (!fmt)
>> +        return;
>>       /* update sspp */
>> -    if (fmt && pstate->pipe.sspp->ops.setup_solidfill) {
>> -        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;
>> -
>> -        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);
>> -
>> -        if (pstate->pipe.sspp->ops.setup_format)
>> -            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,
>> -                    &pipe_cfg);
>> -
>> -        _dpu_plane_setup_scaler(&pstate->pipe, fmt, true, &pipe_cfg, 
>> pstate->rotation);
>> -    }
>> -
>> -    return 0;
>> +    _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, 
>> &pstate->pipe_cfg, fill_color, fmt);
>>   }
>>   int dpu_plane_validate_multirect_v2(struct 
>> dpu_multirect_plane_states *plane)

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
  2023-02-03 18:21   ` Dmitry Baryshkov
@ 2023-02-09  2:19     ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-09  2:19 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno, Kalyan Thota



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Typically SSPP can support rectangle with width up to 2560. However it's

Not always 2560. Depends on the chipset.

> 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  |   6 ++
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
>   3 files changed, 114 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 0ca3bc38ff7e..867832a752b2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   					   fetch_active,
>   					   &pstate->pipe);
>   
> +		_dpu_crtc_blend_setup_pipe(crtc, plane,
> +					   mixer, cstate->num_mixers,
> +					   stage_cfg, pstate->stage, 1,
> +					   fetch_active,
> +					   &pstate->r_pipe);
> +
>   		/* blend config update */
>   		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
>   			_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index e2e85688ed3c..401ead64c6bd 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
>   	struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>   
> +	if (!pipe->sspp)
> +		return;
> +
>   	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>   
>   	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>   {
>   	struct dpu_hw_sspp_cfg pipe_cfg;
>   
> +	if (!pipe->sspp)
> +		return 0;

instead of checking if sspp was present, is it not better for the caller 
to check if the rpipe is valid before calling this?

> +
>   	/* update sspp */
>   	if (!pipe->sspp->ops.setup_solidfill)
>   		return 0;
> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   
>   	/* update sspp */
>   	_dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
> +
> +	_dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
>   }

So cant we do

if (pstate->r_pipe.sspp)
	_dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, 		
		&pstate->r_pipe_cfg, fill_color, fmt);

It just seems better to me as the caller would already know if the sspp 
was assigned.

>   
>   int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
> @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>   {
>   	uint32_t min_src_size;
>   
> +	if (!pipe->sspp)
> +		return 0;
> +
>   	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>   
>   	if (DPU_FORMAT_IS_YUV(fmt) &&
> @@ -957,9 +968,12 @@ 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;
> +	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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> +	struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>   	struct drm_rect fb_rect = { 0 };
>   	uint32_t max_linewidth;
>   	unsigned int rotation;
> @@ -983,8 +997,11 @@ 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;
> +	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) {
> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   
>   	max_linewidth = pdpu->catalog->caps->max_linewidth;
>   
> -	/* check decimated source width */
>   	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;
> +		/* 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;
> +		}

This is where I am a bit concerned enabling it for all chipsets in one go.

As you are aware,  we have an open bug today that we do not filter out 
the modes which we do not support.

https://gitlab.freedesktop.org/drm/msm/-/issues/21

Due to this, on all chipsets we will end up trying to do a 4K on 
external display which we dont know what bugs it will expose.

So lets say if we test it on sc7280 fully but not on sc7180, we will 
still hit this condition on sc7180 too but on that chipset we did not 
advertise 4K as a capability in the product spec.

With the max_linewidth check relaxed nothing prevents us from doing 4K 
on a chipset which doesnt support 4K.

> +
> +		/*
> +		 * FIXME: it's not possible to check if sourcesplit is supported,
> +		 * LMs is not assigned yet. It happens in dpu_encoder_virt_mode_set
> +		 */
> +		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;
>   	}
>   

As you requested just wanted to summarize the condition in the email.

In parallel fetch mode, the downstream driver for UBWC formats, we check 
whether the src width of each rectangle is > maxlinewidth/2

https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/DISPLAY.LA.2.0.r3-00500-WAIPIO.0/msm/sde/sde_plane.c#L1835

For sc7280, maxlinewidth is 2400

static const struct dpu_caps sc7280_dpu_caps = {
         .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
         .max_mixer_blendstages = 0x7,
         .qseed_type = DPU_SSPP_SCALER_QSEED4,
         .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
         .ubwc_version = DPU_HW_UBWC_VER_30,
         .has_dim_layer = true,
         .has_idle_pc = true,
         .max_linewidth = 2400,
         .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
};

Hence for UBWC formats which are by default used on the sc7280 
chromebook, each rectangle should be < 1200

SmartDMA is therefore not enough to support 4K on sc7280 and we need 
true virtual planes ( using two SSPPs to display the 4K layer )

Also, probably worth commenting that time multiplex mode support is not 
added in this series.

>   	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>   
> -	ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
> +	ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
> +	if (ret)
> +		return ret;
> +
> +	ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
>   	if (ret)
>   		return ret;
>   
> @@ -1094,8 +1148,10 @@ 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
> +	else {
>   		dpu_plane_flush_csc(pdpu, &pstate->pipe);
> +		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> +	}
>   
>   	/* flag h/w flush complete */
>   	if (plane->state)
> @@ -1130,6 +1186,9 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
>   	struct drm_plane_state *state = plane->state;
>   	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>   
> +	if (!pipe->sspp)
> +		return;
> +
>   	if (layout && pipe->sspp->ops.setup_sourceaddress) {
>   		trace_dpu_plane_set_scanout(pipe, layout);
>   		pipe->sspp->ops.setup_sourceaddress(pipe, layout);
> @@ -1207,13 +1266,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> -
> +	struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>   	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>   	struct msm_gem_address_space *aspace = kms->base.aspace;
>   	struct dpu_hw_fmt_layout layout;
> @@ -1241,12 +1301,22 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   				   drm_mode_vrefresh(&crtc->mode),
>   				   layout_valid ? &layout: NULL);
>   
> +	dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
> +				   drm_mode_vrefresh(&crtc->mode),
> +				   layout_valid ? &layout: NULL);
> +
>   	if (pstate->needs_qos_remap)
>   		pstate->needs_qos_remap = false;
>   
>   	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) {
> +		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)
> @@ -1289,6 +1359,8 @@ 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);
>   
> +		_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 */
> @@ -1369,11 +1441,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> +	const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
> +	const struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_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));
> +
> +	if (r_pipe->sspp) {
> +		drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
> +		drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(r_pipe->multirect_mode));
> +		drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(r_pipe->multirect_index));
> +		drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
> +		drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
> +	}
>   }

Do you think that changing the atomic_print_state to print the r_pipe 
sspp can be moved to a separate patch? So that way we only keep the core 
logic of atomic check of smartDMA in this patch.

>   
>   static void dpu_plane_reset(struct drm_plane *plane)
> @@ -1407,6 +1494,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
>   	 * This is the place where the state is allocated, so fill it fully.
>   	 */
>   	pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
> +	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);
>   }
> @@ -1423,6 +1514,7 @@ 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);
> +	_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 079dad83eb37..183c95949885 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -19,7 +19,9 @@
>    * @base:	base drm plane state object
>    * @aspace:	pointer to address space for input/output buffers
>    * @pipe:	software pipe description
> + * @r_pipe:	software pipe description of the second pipe
>    * @pipe_cfg:	software pipe configuration
> + * @r_pipe_cfg:	software pipe configuration for the second pipe
>    * @stage:	assigned by crtc blender
>    * @needs_qos_remap: qos remap settings need to be updated
>    * @multirect_index: index of the rectangle of SSPP
> @@ -34,7 +36,9 @@ struct dpu_plane_state {
>   	struct drm_plane_state base;
>   	struct msm_gem_address_space *aspace;
>   	struct dpu_sw_pipe pipe;
> +	struct dpu_sw_pipe r_pipe;
>   	struct dpu_hw_sspp_cfg pipe_cfg;
> +	struct dpu_hw_sspp_cfg r_pipe_cfg;
>   	enum dpu_stage stage;
>   	bool needs_qos_remap;
>   	bool pending;

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

* Re: [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
@ 2023-02-09  2:19     ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-09  2:19 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: Kalyan Thota, freedreno, linux-arm-msm, Bjorn Andersson,
	dri-devel, Stephen Boyd



On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> Typically SSPP can support rectangle with width up to 2560. However it's

Not always 2560. Depends on the chipset.

> 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  |   6 ++
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
>   3 files changed, 114 insertions(+), 12 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 0ca3bc38ff7e..867832a752b2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>   					   fetch_active,
>   					   &pstate->pipe);
>   
> +		_dpu_crtc_blend_setup_pipe(crtc, plane,
> +					   mixer, cstate->num_mixers,
> +					   stage_cfg, pstate->stage, 1,
> +					   fetch_active,
> +					   &pstate->r_pipe);
> +
>   		/* blend config update */
>   		for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
>   			_dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index e2e85688ed3c..401ead64c6bd 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>   	struct dpu_plane *pdpu = to_dpu_plane(plane);
>   	struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>   
> +	if (!pipe->sspp)
> +		return;
> +
>   	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>   
>   	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>   {
>   	struct dpu_hw_sspp_cfg pipe_cfg;
>   
> +	if (!pipe->sspp)
> +		return 0;

instead of checking if sspp was present, is it not better for the caller 
to check if the rpipe is valid before calling this?

> +
>   	/* update sspp */
>   	if (!pipe->sspp->ops.setup_solidfill)
>   		return 0;
> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
>   
>   	/* update sspp */
>   	_dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
> +
> +	_dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
>   }

So cant we do

if (pstate->r_pipe.sspp)
	_dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, 		
		&pstate->r_pipe_cfg, fill_color, fmt);

It just seems better to me as the caller would already know if the sspp 
was assigned.

>   
>   int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
> @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>   {
>   	uint32_t min_src_size;
>   
> +	if (!pipe->sspp)
> +		return 0;
> +
>   	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>   
>   	if (DPU_FORMAT_IS_YUV(fmt) &&
> @@ -957,9 +968,12 @@ 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;
> +	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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> +	struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>   	struct drm_rect fb_rect = { 0 };
>   	uint32_t max_linewidth;
>   	unsigned int rotation;
> @@ -983,8 +997,11 @@ 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;
> +	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) {
> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>   
>   	max_linewidth = pdpu->catalog->caps->max_linewidth;
>   
> -	/* check decimated source width */
>   	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;
> +		/* 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;
> +		}

This is where I am a bit concerned enabling it for all chipsets in one go.

As you are aware,  we have an open bug today that we do not filter out 
the modes which we do not support.

https://gitlab.freedesktop.org/drm/msm/-/issues/21

Due to this, on all chipsets we will end up trying to do a 4K on 
external display which we dont know what bugs it will expose.

So lets say if we test it on sc7280 fully but not on sc7180, we will 
still hit this condition on sc7180 too but on that chipset we did not 
advertise 4K as a capability in the product spec.

With the max_linewidth check relaxed nothing prevents us from doing 4K 
on a chipset which doesnt support 4K.

> +
> +		/*
> +		 * FIXME: it's not possible to check if sourcesplit is supported,
> +		 * LMs is not assigned yet. It happens in dpu_encoder_virt_mode_set
> +		 */
> +		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;
>   	}
>   

As you requested just wanted to summarize the condition in the email.

In parallel fetch mode, the downstream driver for UBWC formats, we check 
whether the src width of each rectangle is > maxlinewidth/2

https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/DISPLAY.LA.2.0.r3-00500-WAIPIO.0/msm/sde/sde_plane.c#L1835

For sc7280, maxlinewidth is 2400

static const struct dpu_caps sc7280_dpu_caps = {
         .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
         .max_mixer_blendstages = 0x7,
         .qseed_type = DPU_SSPP_SCALER_QSEED4,
         .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
         .ubwc_version = DPU_HW_UBWC_VER_30,
         .has_dim_layer = true,
         .has_idle_pc = true,
         .max_linewidth = 2400,
         .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
};

Hence for UBWC formats which are by default used on the sc7280 
chromebook, each rectangle should be < 1200

SmartDMA is therefore not enough to support 4K on sc7280 and we need 
true virtual planes ( using two SSPPs to display the 4K layer )

Also, probably worth commenting that time multiplex mode support is not 
added in this series.

>   	fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>   
> -	ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
> +	ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
> +	if (ret)
> +		return ret;
> +
> +	ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
>   	if (ret)
>   		return ret;
>   
> @@ -1094,8 +1148,10 @@ 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
> +	else {
>   		dpu_plane_flush_csc(pdpu, &pstate->pipe);
> +		dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> +	}
>   
>   	/* flag h/w flush complete */
>   	if (plane->state)
> @@ -1130,6 +1186,9 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
>   	struct drm_plane_state *state = plane->state;
>   	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>   
> +	if (!pipe->sspp)
> +		return;
> +
>   	if (layout && pipe->sspp->ops.setup_sourceaddress) {
>   		trace_dpu_plane_set_scanout(pipe, layout);
>   		pipe->sspp->ops.setup_sourceaddress(pipe, layout);
> @@ -1207,13 +1266,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> -
> +	struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>   	struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>   	struct msm_gem_address_space *aspace = kms->base.aspace;
>   	struct dpu_hw_fmt_layout layout;
> @@ -1241,12 +1301,22 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>   				   drm_mode_vrefresh(&crtc->mode),
>   				   layout_valid ? &layout: NULL);
>   
> +	dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
> +				   drm_mode_vrefresh(&crtc->mode),
> +				   layout_valid ? &layout: NULL);
> +
>   	if (pstate->needs_qos_remap)
>   		pstate->needs_qos_remap = false;
>   
>   	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) {
> +		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)
> @@ -1289,6 +1359,8 @@ 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);
>   
> +		_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 */
> @@ -1369,11 +1441,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> +	const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
> +	const struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_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));
> +
> +	if (r_pipe->sspp) {
> +		drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
> +		drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(r_pipe->multirect_mode));
> +		drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(r_pipe->multirect_index));
> +		drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
> +		drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
> +	}
>   }

Do you think that changing the atomic_print_state to print the r_pipe 
sspp can be moved to a separate patch? So that way we only keep the core 
logic of atomic check of smartDMA in this patch.

>   
>   static void dpu_plane_reset(struct drm_plane *plane)
> @@ -1407,6 +1494,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
>   	 * This is the place where the state is allocated, so fill it fully.
>   	 */
>   	pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
> +	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);
>   }
> @@ -1423,6 +1514,7 @@ 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);
> +	_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 079dad83eb37..183c95949885 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -19,7 +19,9 @@
>    * @base:	base drm plane state object
>    * @aspace:	pointer to address space for input/output buffers
>    * @pipe:	software pipe description
> + * @r_pipe:	software pipe description of the second pipe
>    * @pipe_cfg:	software pipe configuration
> + * @r_pipe_cfg:	software pipe configuration for the second pipe
>    * @stage:	assigned by crtc blender
>    * @needs_qos_remap: qos remap settings need to be updated
>    * @multirect_index: index of the rectangle of SSPP
> @@ -34,7 +36,9 @@ struct dpu_plane_state {
>   	struct drm_plane_state base;
>   	struct msm_gem_address_space *aspace;
>   	struct dpu_sw_pipe pipe;
> +	struct dpu_sw_pipe r_pipe;
>   	struct dpu_hw_sspp_cfg pipe_cfg;
> +	struct dpu_hw_sspp_cfg r_pipe_cfg;
>   	enum dpu_stage stage;
>   	bool needs_qos_remap;
>   	bool pending;

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

* Re: [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
  2023-02-09  2:19     ` Abhinav Kumar
@ 2023-02-09 11:45       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-09 11:45 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Kalyan Thota, freedreno, Sean Paul, Bjorn Andersson, dri-devel,
	Stephen Boyd, linux-arm-msm

On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> > Typically SSPP can support rectangle with width up to 2560. However it's
>
> Not always 2560. Depends on the chipset.

_typically_

>
> > 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  |   6 ++
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
> >   3 files changed, 114 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > index 0ca3bc38ff7e..867832a752b2 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> >                                          fetch_active,
> >                                          &pstate->pipe);
> >
> > +             _dpu_crtc_blend_setup_pipe(crtc, plane,
> > +                                        mixer, cstate->num_mixers,
> > +                                        stage_cfg, pstate->stage, 1,
> > +                                        fetch_active,
> > +                                        &pstate->r_pipe);
> > +
> >               /* blend config update */
> >               for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
> >                       _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > index e2e85688ed3c..401ead64c6bd 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
> >       struct dpu_plane *pdpu = to_dpu_plane(plane);
> >       struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
> >
> > +     if (!pipe->sspp)
> > +             return;
> > +
> >       memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
> >
> >       if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
> > @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
> >   {
> >       struct dpu_hw_sspp_cfg pipe_cfg;
> >
> > +     if (!pipe->sspp)
> > +             return 0;
>
> instead of checking if sspp was present, is it not better for the caller
> to check if the rpipe is valid before calling this?
>
> > +
> >       /* update sspp */
> >       if (!pipe->sspp->ops.setup_solidfill)
> >               return 0;
> > @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
> >
> >       /* update sspp */
> >       _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
> > +
> > +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
> >   }
>
> So cant we do
>
> if (pstate->r_pipe.sspp)
>         _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
>                 &pstate->r_pipe_cfg, fill_color, fmt);
>
> It just seems better to me as the caller would already know if the sspp
> was assigned.

 I think I had this kind of code earlier, but then I found it more
logical to move the check to the called function. I'll move it back.

>
> >
> >   int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
> > @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
> >   {
> >       uint32_t min_src_size;
> >
> > +     if (!pipe->sspp)
> > +             return 0;
> > +
> >       min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
> >
> >       if (DPU_FORMAT_IS_YUV(fmt) &&
> > @@ -957,9 +968,12 @@ 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;
> > +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> > +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> >       struct drm_rect fb_rect = { 0 };
> >       uint32_t max_linewidth;
> >       unsigned int rotation;
> > @@ -983,8 +997,11 @@ 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;
> > +     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) {
> > @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> >
> >       max_linewidth = pdpu->catalog->caps->max_linewidth;
> >
> > -     /* check decimated source width */
> >       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;
> > +             /* 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;
> > +             }
>
> This is where I am a bit concerned enabling it for all chipsets in one go.

As I wrote earlier, I'd prefer the opt-out rather than opt-in here. It
is much easier to handle the reports "I have a device with sm6543,
where the display worked before 6.4, but started failing afterwards"
rather than trying to find a person with sm6543 and asking him if he
can enable this and that on his device. And even a lower chance of a
person with sm6543 coming up with a patch 'hey, I enabled this for my
phone and it works!'.

If we find any issues during or close to the end of the development
cycle, we can add a 'don't enable wide plane here' switch and enable
it for failing platforms. But each enablement of this switch should
come with a reason (wide planes not working here because ....). In the
end this switch should be gone and transformed into proper HW
limitation checks.

> As you are aware,  we have an open bug today that we do not filter out
> the modes which we do not support.
>
> https://gitlab.freedesktop.org/drm/msm/-/issues/21

I thought that with the link-frequencies in place and with the DSI
checking the OPP tables this issue is mostly handled. Isn't it?
Is a mode check in the DPU driver itself the last missing piece?

>
> Due to this, on all chipsets we will end up trying to do a 4K on
> external display which we dont know what bugs it will expose.

If we do not expose bugs, we do not have a way to fix them. And I
definitely think that all the bugs should be listed as early as
possible, while both of us still remember the code under the question.

>
> So lets say if we test it on sc7280 fully but not on sc7180, we will
> still hit this condition on sc7180 too but on that chipset we did not
> advertise 4K as a capability in the product spec.

Is it 'not advertised' or 'not supported by hw'?

>
> With the max_linewidth check relaxed nothing prevents us from doing 4K
> on a chipset which doesnt support 4K.

What prevents sc7180 from supporting 4k? Does it support Smart DMA?
Does it support having two LMs per INTF/CRTC? Is there a limitation on
the linewidth of two LMs or two SSPPs?

I see that sm7125 (which has the same DPU revision) even contains
"qcom,sde-vig-sspp-linewidth = <4096>;" in the DTS, despite official
'product brief' advertising only 2520x1080 output resolution.

>
> > +
> > +             /*
> > +              * FIXME: it's not possible to check if sourcesplit is supported,
> > +              * LMs is not assigned yet. It happens in dpu_encoder_virt_mode_set
> > +              */
> > +             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;
> >       }
> >
>
> As you requested just wanted to summarize the condition in the email.
>
> In parallel fetch mode, the downstream driver for UBWC formats, we check
> whether the src width of each rectangle is > maxlinewidth/2
>
> https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/DISPLAY.LA.2.0.r3-00500-WAIPIO.0/msm/sde/sde_plane.c#L1835

Thanks. Please double check my understanding: If the rectangle is used
for the tiled format, then it's max_linewidth is effectively halved.
So we can use rect_solo with full width, but for rect_0/rect_1 we
should halve it, even if two rectangles are used in the time split?

>
> For sc7280, maxlinewidth is 2400
>
> static const struct dpu_caps sc7280_dpu_caps = {
>          .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>          .max_mixer_blendstages = 0x7,
>          .qseed_type = DPU_SSPP_SCALER_QSEED4,
>          .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
>          .ubwc_version = DPU_HW_UBWC_VER_30,
>          .has_dim_layer = true,
>          .has_idle_pc = true,
>          .max_linewidth = 2400,
>          .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
> };
>
> Hence for UBWC formats which are by default used on the sc7280
> chromebook, each rectangle should be < 1200
>
> SmartDMA is therefore not enough to support 4K on sc7280 and we need
> true virtual planes ( using two SSPPs to display the 4K layer )
>
> Also, probably worth commenting that time multiplex mode support is not
> added in this series.

Ack.

>
> >       fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> >
> > -     ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
> > +     ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
> >       if (ret)
> >               return ret;
> >
> > @@ -1094,8 +1148,10 @@ 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
> > +     else {
> >               dpu_plane_flush_csc(pdpu, &pstate->pipe);
> > +             dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> > +     }
> >
> >       /* flag h/w flush complete */
> >       if (plane->state)
> > @@ -1130,6 +1186,9 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
> >       struct drm_plane_state *state = plane->state;
> >       struct dpu_plane_state *pstate = to_dpu_plane_state(state);
> >
> > +     if (!pipe->sspp)
> > +             return;
> > +
> >       if (layout && pipe->sspp->ops.setup_sourceaddress) {
> >               trace_dpu_plane_set_scanout(pipe, layout);
> >               pipe->sspp->ops.setup_sourceaddress(pipe, layout);
> > @@ -1207,13 +1266,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> > -
> > +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> >       struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> >       struct msm_gem_address_space *aspace = kms->base.aspace;
> >       struct dpu_hw_fmt_layout layout;
> > @@ -1241,12 +1301,22 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
> >                                  drm_mode_vrefresh(&crtc->mode),
> >                                  layout_valid ? &layout: NULL);
> >
> > +     dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
> > +                                drm_mode_vrefresh(&crtc->mode),
> > +                                layout_valid ? &layout: NULL);
> > +
> >       if (pstate->needs_qos_remap)
> >               pstate->needs_qos_remap = false;
> >
> >       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) {
> > +             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)
> > @@ -1289,6 +1359,8 @@ 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);
> >
> > +             _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 */
> > @@ -1369,11 +1441,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> > +     const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
> > +     const struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_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));
> > +
> > +     if (r_pipe->sspp) {
> > +             drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
> > +             drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(r_pipe->multirect_mode));
> > +             drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(r_pipe->multirect_index));
> > +             drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
> > +             drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
> > +     }
> >   }
>
> Do you think that changing the atomic_print_state to print the r_pipe
> sspp can be moved to a separate patch? So that way we only keep the core
> logic of atomic check of smartDMA in this patch.
>
> >
> >   static void dpu_plane_reset(struct drm_plane *plane)
> > @@ -1407,6 +1494,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
> >        * This is the place where the state is allocated, so fill it fully.
> >        */
> >       pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
> > +     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);
> >   }
> > @@ -1423,6 +1514,7 @@ 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);
> > +     _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 079dad83eb37..183c95949885 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> > @@ -19,7 +19,9 @@
> >    * @base:   base drm plane state object
> >    * @aspace: pointer to address space for input/output buffers
> >    * @pipe:   software pipe description
> > + * @r_pipe:  software pipe description of the second pipe
> >    * @pipe_cfg:       software pipe configuration
> > + * @r_pipe_cfg:      software pipe configuration for the second pipe
> >    * @stage:  assigned by crtc blender
> >    * @needs_qos_remap: qos remap settings need to be updated
> >    * @multirect_index: index of the rectangle of SSPP
> > @@ -34,7 +36,9 @@ struct dpu_plane_state {
> >       struct drm_plane_state base;
> >       struct msm_gem_address_space *aspace;
> >       struct dpu_sw_pipe pipe;
> > +     struct dpu_sw_pipe r_pipe;
> >       struct dpu_hw_sspp_cfg pipe_cfg;
> > +     struct dpu_hw_sspp_cfg r_pipe_cfg;
> >       enum dpu_stage stage;
> >       bool needs_qos_remap;
> >       bool pending;



-- 
With best wishes
Dmitry

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

* Re: [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
@ 2023-02-09 11:45       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-09 11:45 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Stephen Boyd, David Airlie, Daniel Vetter,
	Bjorn Andersson, linux-arm-msm, dri-devel, freedreno,
	Kalyan Thota

On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> > Typically SSPP can support rectangle with width up to 2560. However it's
>
> Not always 2560. Depends on the chipset.

_typically_

>
> > 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  |   6 ++
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
> >   3 files changed, 114 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > index 0ca3bc38ff7e..867832a752b2 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> > @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> >                                          fetch_active,
> >                                          &pstate->pipe);
> >
> > +             _dpu_crtc_blend_setup_pipe(crtc, plane,
> > +                                        mixer, cstate->num_mixers,
> > +                                        stage_cfg, pstate->stage, 1,
> > +                                        fetch_active,
> > +                                        &pstate->r_pipe);
> > +
> >               /* blend config update */
> >               for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
> >                       _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > index e2e85688ed3c..401ead64c6bd 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
> >       struct dpu_plane *pdpu = to_dpu_plane(plane);
> >       struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
> >
> > +     if (!pipe->sspp)
> > +             return;
> > +
> >       memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
> >
> >       if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
> > @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
> >   {
> >       struct dpu_hw_sspp_cfg pipe_cfg;
> >
> > +     if (!pipe->sspp)
> > +             return 0;
>
> instead of checking if sspp was present, is it not better for the caller
> to check if the rpipe is valid before calling this?
>
> > +
> >       /* update sspp */
> >       if (!pipe->sspp->ops.setup_solidfill)
> >               return 0;
> > @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
> >
> >       /* update sspp */
> >       _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
> > +
> > +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
> >   }
>
> So cant we do
>
> if (pstate->r_pipe.sspp)
>         _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
>                 &pstate->r_pipe_cfg, fill_color, fmt);
>
> It just seems better to me as the caller would already know if the sspp
> was assigned.

 I think I had this kind of code earlier, but then I found it more
logical to move the check to the called function. I'll move it back.

>
> >
> >   int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
> > @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
> >   {
> >       uint32_t min_src_size;
> >
> > +     if (!pipe->sspp)
> > +             return 0;
> > +
> >       min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
> >
> >       if (DPU_FORMAT_IS_YUV(fmt) &&
> > @@ -957,9 +968,12 @@ 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;
> > +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> > +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> >       struct drm_rect fb_rect = { 0 };
> >       uint32_t max_linewidth;
> >       unsigned int rotation;
> > @@ -983,8 +997,11 @@ 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;
> > +     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) {
> > @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> >
> >       max_linewidth = pdpu->catalog->caps->max_linewidth;
> >
> > -     /* check decimated source width */
> >       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;
> > +             /* 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;
> > +             }
>
> This is where I am a bit concerned enabling it for all chipsets in one go.

As I wrote earlier, I'd prefer the opt-out rather than opt-in here. It
is much easier to handle the reports "I have a device with sm6543,
where the display worked before 6.4, but started failing afterwards"
rather than trying to find a person with sm6543 and asking him if he
can enable this and that on his device. And even a lower chance of a
person with sm6543 coming up with a patch 'hey, I enabled this for my
phone and it works!'.

If we find any issues during or close to the end of the development
cycle, we can add a 'don't enable wide plane here' switch and enable
it for failing platforms. But each enablement of this switch should
come with a reason (wide planes not working here because ....). In the
end this switch should be gone and transformed into proper HW
limitation checks.

> As you are aware,  we have an open bug today that we do not filter out
> the modes which we do not support.
>
> https://gitlab.freedesktop.org/drm/msm/-/issues/21

I thought that with the link-frequencies in place and with the DSI
checking the OPP tables this issue is mostly handled. Isn't it?
Is a mode check in the DPU driver itself the last missing piece?

>
> Due to this, on all chipsets we will end up trying to do a 4K on
> external display which we dont know what bugs it will expose.

If we do not expose bugs, we do not have a way to fix them. And I
definitely think that all the bugs should be listed as early as
possible, while both of us still remember the code under the question.

>
> So lets say if we test it on sc7280 fully but not on sc7180, we will
> still hit this condition on sc7180 too but on that chipset we did not
> advertise 4K as a capability in the product spec.

Is it 'not advertised' or 'not supported by hw'?

>
> With the max_linewidth check relaxed nothing prevents us from doing 4K
> on a chipset which doesnt support 4K.

What prevents sc7180 from supporting 4k? Does it support Smart DMA?
Does it support having two LMs per INTF/CRTC? Is there a limitation on
the linewidth of two LMs or two SSPPs?

I see that sm7125 (which has the same DPU revision) even contains
"qcom,sde-vig-sspp-linewidth = <4096>;" in the DTS, despite official
'product brief' advertising only 2520x1080 output resolution.

>
> > +
> > +             /*
> > +              * FIXME: it's not possible to check if sourcesplit is supported,
> > +              * LMs is not assigned yet. It happens in dpu_encoder_virt_mode_set
> > +              */
> > +             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;
> >       }
> >
>
> As you requested just wanted to summarize the condition in the email.
>
> In parallel fetch mode, the downstream driver for UBWC formats, we check
> whether the src width of each rectangle is > maxlinewidth/2
>
> https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/DISPLAY.LA.2.0.r3-00500-WAIPIO.0/msm/sde/sde_plane.c#L1835

Thanks. Please double check my understanding: If the rectangle is used
for the tiled format, then it's max_linewidth is effectively halved.
So we can use rect_solo with full width, but for rect_0/rect_1 we
should halve it, even if two rectangles are used in the time split?

>
> For sc7280, maxlinewidth is 2400
>
> static const struct dpu_caps sc7280_dpu_caps = {
>          .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>          .max_mixer_blendstages = 0x7,
>          .qseed_type = DPU_SSPP_SCALER_QSEED4,
>          .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
>          .ubwc_version = DPU_HW_UBWC_VER_30,
>          .has_dim_layer = true,
>          .has_idle_pc = true,
>          .max_linewidth = 2400,
>          .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
> };
>
> Hence for UBWC formats which are by default used on the sc7280
> chromebook, each rectangle should be < 1200
>
> SmartDMA is therefore not enough to support 4K on sc7280 and we need
> true virtual planes ( using two SSPPs to display the 4K layer )
>
> Also, probably worth commenting that time multiplex mode support is not
> added in this series.

Ack.

>
> >       fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> >
> > -     ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
> > +     ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
> > +     if (ret)
> > +             return ret;
> > +
> > +     ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
> >       if (ret)
> >               return ret;
> >
> > @@ -1094,8 +1148,10 @@ 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
> > +     else {
> >               dpu_plane_flush_csc(pdpu, &pstate->pipe);
> > +             dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> > +     }
> >
> >       /* flag h/w flush complete */
> >       if (plane->state)
> > @@ -1130,6 +1186,9 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
> >       struct drm_plane_state *state = plane->state;
> >       struct dpu_plane_state *pstate = to_dpu_plane_state(state);
> >
> > +     if (!pipe->sspp)
> > +             return;
> > +
> >       if (layout && pipe->sspp->ops.setup_sourceaddress) {
> >               trace_dpu_plane_set_scanout(pipe, layout);
> >               pipe->sspp->ops.setup_sourceaddress(pipe, layout);
> > @@ -1207,13 +1266,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> > -
> > +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> >       struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> >       struct msm_gem_address_space *aspace = kms->base.aspace;
> >       struct dpu_hw_fmt_layout layout;
> > @@ -1241,12 +1301,22 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
> >                                  drm_mode_vrefresh(&crtc->mode),
> >                                  layout_valid ? &layout: NULL);
> >
> > +     dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
> > +                                drm_mode_vrefresh(&crtc->mode),
> > +                                layout_valid ? &layout: NULL);
> > +
> >       if (pstate->needs_qos_remap)
> >               pstate->needs_qos_remap = false;
> >
> >       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) {
> > +             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)
> > @@ -1289,6 +1359,8 @@ 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);
> >
> > +             _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 */
> > @@ -1369,11 +1441,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> > +     const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
> > +     const struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_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));
> > +
> > +     if (r_pipe->sspp) {
> > +             drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
> > +             drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(r_pipe->multirect_mode));
> > +             drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(r_pipe->multirect_index));
> > +             drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
> > +             drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
> > +     }
> >   }
>
> Do you think that changing the atomic_print_state to print the r_pipe
> sspp can be moved to a separate patch? So that way we only keep the core
> logic of atomic check of smartDMA in this patch.
>
> >
> >   static void dpu_plane_reset(struct drm_plane *plane)
> > @@ -1407,6 +1494,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
> >        * This is the place where the state is allocated, so fill it fully.
> >        */
> >       pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
> > +     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);
> >   }
> > @@ -1423,6 +1514,7 @@ 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);
> > +     _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 079dad83eb37..183c95949885 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> > @@ -19,7 +19,9 @@
> >    * @base:   base drm plane state object
> >    * @aspace: pointer to address space for input/output buffers
> >    * @pipe:   software pipe description
> > + * @r_pipe:  software pipe description of the second pipe
> >    * @pipe_cfg:       software pipe configuration
> > + * @r_pipe_cfg:      software pipe configuration for the second pipe
> >    * @stage:  assigned by crtc blender
> >    * @needs_qos_remap: qos remap settings need to be updated
> >    * @multirect_index: index of the rectangle of SSPP
> > @@ -34,7 +36,9 @@ struct dpu_plane_state {
> >       struct drm_plane_state base;
> >       struct msm_gem_address_space *aspace;
> >       struct dpu_sw_pipe pipe;
> > +     struct dpu_sw_pipe r_pipe;
> >       struct dpu_hw_sspp_cfg pipe_cfg;
> > +     struct dpu_hw_sspp_cfg r_pipe_cfg;
> >       enum dpu_stage stage;
> >       bool needs_qos_remap;
> >       bool pending;



-- 
With best wishes
Dmitry

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

* Re: [PATCH v3 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
  2023-02-07  0:22     ` Abhinav Kumar
@ 2023-02-09 11:46       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-09 11:46 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 07/02/2023 02:22, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the
> 
> sspp-dependent?
> 
>> separate function dpu_plane_sspp_update_pipe(). This is one of
>> preparational steps to add r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> Just a couple of minor comments below but otherwise this split up lgtm
> 
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 113 ++++++++++++----------
>>   1 file changed, 63 insertions(+), 50 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 0986e740b978..f94e132733f3 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -404,12 +404,13 @@ 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
>>    * @pipe:        Pointer to software pipe
>> - * @crtc:        Pointer to drm crtc
>>    * @pipe_cfg:        Pointer to pipe configuration
>> + * @frame_rate:        CRTC's frame rate
> 
> Can you please check the spacing here. There seems to be an extra tab 
> before the CRTC's frame rate

I checked, the ident is correct here. It uses tabs, maybe that confuses 
your mailer.

> 
>>    */
>>   static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
>>           struct dpu_sw_pipe *pipe,
>> -        struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
>> +        int frame_rate)
>>   {
>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>       struct dpu_vbif_set_ot_params ot_params;
>> @@ -421,7 +422,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 = frame_rate;
>>       ot_params.vbif_idx = VBIF_RT;
>>       ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
>>       ot_params.rd = true;
>> @@ -457,26 +458,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 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;
>> -    struct dpu_hw_fmt_layout layout;
>> -    int ret;
>> -
>> -    ret = dpu_format_populate_layout(aspace, fb, &layout);
>> -    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,
>> -                        &layout);
>> -        pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, 
>> &layout);
>> -    }
>> -}
>> -
>>   static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *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,
>> @@ -1102,35 +1083,25 @@ 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_sspp_update_pipe(struct drm_plane *plane,
>> +                       struct dpu_sw_pipe *pipe,
>> +                       struct dpu_hw_sspp_cfg *pipe_cfg,
> 
> You can call this parameter sspp_cfg instead of pipe_cfg?
> 
>> +                       const struct dpu_format *fmt,
>> +                       int frame_rate,
>> +                       struct dpu_hw_fmt_layout *layout)
>>   {
>>       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;
>> -    const struct dpu_format *fmt =
>> -        to_dpu_format(msm_framebuffer_format(fb));
>> -    struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>> -    _dpu_plane_set_scanout(plane, pstate, fb);
>> -
>> -    pstate->pending = true;
>> -
>> -    is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
>> -    pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
>> -    pdpu->is_rt_pipe = is_rt_pipe;
>> +    if (layout && pipe->sspp->ops.setup_sourceaddress) {
>> +        trace_dpu_plane_set_scanout(pipe, layout);
>> +        pipe->sspp->ops.setup_sourceaddress(pipe, layout);
>> +    }
>>       _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 */
>> @@ -1183,22 +1154,64 @@ static void 
>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>           }
>>       }
>> -    _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, frame_rate);
>>       }
>> -    if (pstate->needs_qos_remap) {
>> -        pstate->needs_qos_remap = false;
>> +    if (pstate->needs_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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>> +
>> +    struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>> +    struct msm_gem_address_space *aspace = kms->base.aspace;
>> +    struct dpu_hw_fmt_layout layout;
>> +    bool layout_valid = false;
>> +    int ret;
>> +
>> +    ret = dpu_format_populate_layout(aspace, fb, &layout);
>> +    if (ret)
>> +        DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
>> +    else
>> +        layout_valid = true;
>> +
>> +    pstate->pending = true;
>> +
>> +    is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
>> +    pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
>> +    pdpu->is_rt_pipe = is_rt_pipe;
>> +
>> +    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));
>> +
>> +    dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
>> +                   drm_mode_vrefresh(&crtc->mode),
>> +                   layout_valid ? &layout: NULL);
>> +
>> +    if (pstate->needs_qos_remap)
>> +        pstate->needs_qos_remap = false;
>> -    pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, 
>> &crtc->mode, &pstate->pipe_cfg);
>> +    pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, 
>> &crtc->mode, pipe_cfg);
>> -    pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, 
>> &pstate->pipe_cfg);
>> +    pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, pipe_cfg);
>>   }
>>   static void _dpu_plane_atomic_disable(struct drm_plane *plane)

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update()
@ 2023-02-09 11:46       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-09 11:46 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 07/02/2023 02:22, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Split pipe-dependent code from dpu_plane_sspp_atomic_update() into the
> 
> sspp-dependent?
> 
>> separate function dpu_plane_sspp_update_pipe(). This is one of
>> preparational steps to add r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> 
> Just a couple of minor comments below but otherwise this split up lgtm
> 
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 113 ++++++++++++----------
>>   1 file changed, 63 insertions(+), 50 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> index 0986e740b978..f94e132733f3 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> @@ -404,12 +404,13 @@ 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
>>    * @pipe:        Pointer to software pipe
>> - * @crtc:        Pointer to drm crtc
>>    * @pipe_cfg:        Pointer to pipe configuration
>> + * @frame_rate:        CRTC's frame rate
> 
> Can you please check the spacing here. There seems to be an extra tab 
> before the CRTC's frame rate

I checked, the ident is correct here. It uses tabs, maybe that confuses 
your mailer.

> 
>>    */
>>   static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
>>           struct dpu_sw_pipe *pipe,
>> -        struct drm_crtc *crtc, struct dpu_hw_sspp_cfg *pipe_cfg)
>> +        struct dpu_hw_sspp_cfg *pipe_cfg,
>> +        int frame_rate)
>>   {
>>       struct dpu_plane *pdpu = to_dpu_plane(plane);
>>       struct dpu_vbif_set_ot_params ot_params;
>> @@ -421,7 +422,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 = frame_rate;
>>       ot_params.vbif_idx = VBIF_RT;
>>       ot_params.clk_ctrl = pipe->sspp->cap->clk_ctrl;
>>       ot_params.rd = true;
>> @@ -457,26 +458,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 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;
>> -    struct dpu_hw_fmt_layout layout;
>> -    int ret;
>> -
>> -    ret = dpu_format_populate_layout(aspace, fb, &layout);
>> -    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,
>> -                        &layout);
>> -        pstate->pipe.sspp->ops.setup_sourceaddress(&pstate->pipe, 
>> &layout);
>> -    }
>> -}
>> -
>>   static void _dpu_plane_setup_scaler3(struct dpu_hw_sspp *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,
>> @@ -1102,35 +1083,25 @@ 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_sspp_update_pipe(struct drm_plane *plane,
>> +                       struct dpu_sw_pipe *pipe,
>> +                       struct dpu_hw_sspp_cfg *pipe_cfg,
> 
> You can call this parameter sspp_cfg instead of pipe_cfg?
> 
>> +                       const struct dpu_format *fmt,
>> +                       int frame_rate,
>> +                       struct dpu_hw_fmt_layout *layout)
>>   {
>>       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;
>> -    const struct dpu_format *fmt =
>> -        to_dpu_format(msm_framebuffer_format(fb));
>> -    struct dpu_hw_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>> -    _dpu_plane_set_scanout(plane, pstate, fb);
>> -
>> -    pstate->pending = true;
>> -
>> -    is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
>> -    pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
>> -    pdpu->is_rt_pipe = is_rt_pipe;
>> +    if (layout && pipe->sspp->ops.setup_sourceaddress) {
>> +        trace_dpu_plane_set_scanout(pipe, layout);
>> +        pipe->sspp->ops.setup_sourceaddress(pipe, layout);
>> +    }
>>       _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 */
>> @@ -1183,22 +1154,64 @@ static void 
>> dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>           }
>>       }
>> -    _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, frame_rate);
>>       }
>> -    if (pstate->needs_qos_remap) {
>> -        pstate->needs_qos_remap = false;
>> +    if (pstate->needs_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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>> +
>> +    struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>> +    struct msm_gem_address_space *aspace = kms->base.aspace;
>> +    struct dpu_hw_fmt_layout layout;
>> +    bool layout_valid = false;
>> +    int ret;
>> +
>> +    ret = dpu_format_populate_layout(aspace, fb, &layout);
>> +    if (ret)
>> +        DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
>> +    else
>> +        layout_valid = true;
>> +
>> +    pstate->pending = true;
>> +
>> +    is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
>> +    pstate->needs_qos_remap |= (is_rt_pipe != pdpu->is_rt_pipe);
>> +    pdpu->is_rt_pipe = is_rt_pipe;
>> +
>> +    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));
>> +
>> +    dpu_plane_sspp_update_pipe(plane, pipe, pipe_cfg, fmt,
>> +                   drm_mode_vrefresh(&crtc->mode),
>> +                   layout_valid ? &layout: NULL);
>> +
>> +    if (pstate->needs_qos_remap)
>> +        pstate->needs_qos_remap = false;
>> -    pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, 
>> &crtc->mode, &pstate->pipe_cfg);
>> +    pstate->plane_fetch_bw = _dpu_plane_calc_bw(pdpu->catalog, fmt, 
>> &crtc->mode, pipe_cfg);
>> -    pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, 
>> &pstate->pipe_cfg);
>> +    pstate->plane_clk = _dpu_plane_calc_clk(&crtc->mode, pipe_cfg);
>>   }
>>   static void _dpu_plane_atomic_disable(struct drm_plane *plane)

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
  2023-02-09 11:45       ` Dmitry Baryshkov
@ 2023-02-09 19:25         ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-09 19:25 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Rob Clark, Sean Paul, Stephen Boyd, David Airlie, Daniel Vetter,
	Bjorn Andersson, linux-arm-msm, dri-devel, freedreno,
	Kalyan Thota



On 2/9/2023 3:45 AM, Dmitry Baryshkov wrote:
> On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> Typically SSPP can support rectangle with width up to 2560. However it's
>>
>> Not always 2560. Depends on the chipset.
> 
> _typically_
> 

Would just say maxlinewidth of SSPP instead of giving some hardcoded number.

>>
>>> 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  |   6 ++
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
>>>    3 files changed, 114 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> index 0ca3bc38ff7e..867832a752b2 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>>>                                           fetch_active,
>>>                                           &pstate->pipe);
>>>
>>> +             _dpu_crtc_blend_setup_pipe(crtc, plane,
>>> +                                        mixer, cstate->num_mixers,
>>> +                                        stage_cfg, pstate->stage, 1,
>>> +                                        fetch_active,
>>> +                                        &pstate->r_pipe);
>>> +
>>>                /* blend config update */
>>>                for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
>>>                        _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> index e2e85688ed3c..401ead64c6bd 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>>>        struct dpu_plane *pdpu = to_dpu_plane(plane);
>>>        struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>>>
>>> +     if (!pipe->sspp)
>>> +             return;
>>> +
>>>        memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>>
>>>        if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>>> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>>>    {
>>>        struct dpu_hw_sspp_cfg pipe_cfg;
>>>
>>> +     if (!pipe->sspp)
>>> +             return 0;
>>
>> instead of checking if sspp was present, is it not better for the caller
>> to check if the rpipe is valid before calling this?
>>
>>> +
>>>        /* update sspp */
>>>        if (!pipe->sspp->ops.setup_solidfill)
>>>                return 0;
>>> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
>>>
>>>        /* update sspp */
>>>        _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
>>> +
>>> +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
>>>    }
>>
>> So cant we do
>>
>> if (pstate->r_pipe.sspp)
>>          _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
>>                  &pstate->r_pipe_cfg, fill_color, fmt);
>>
>> It just seems better to me as the caller would already know if the sspp
>> was assigned.
> 
>   I think I had this kind of code earlier, but then I found it more
> logical to move the check to the called function. I'll move it back.
> 
>>
>>>
>>>    int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
>>> @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>    {
>>>        uint32_t min_src_size;
>>>
>>> +     if (!pipe->sspp)
>>> +             return 0;
>>> +
>>>        min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>>
>>>        if (DPU_FORMAT_IS_YUV(fmt) &&
>>> @@ -957,9 +968,12 @@ 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;
>>> +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>        struct drm_rect fb_rect = { 0 };
>>>        uint32_t max_linewidth;
>>>        unsigned int rotation;
>>> @@ -983,8 +997,11 @@ 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;
>>> +     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) {
>>> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>
>>>        max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>
>>> -     /* check decimated source width */
>>>        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;
>>> +             /* 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;
>>> +             }
>>
>> This is where I am a bit concerned enabling it for all chipsets in one go.
> 
> As I wrote earlier, I'd prefer the opt-out rather than opt-in here. It
> is much easier to handle the reports "I have a device with sm6543,
> where the display worked before 6.4, but started failing afterwards"
> rather than trying to find a person with sm6543 and asking him if he
> can enable this and that on his device. And even a lower chance of a
> person with sm6543 coming up with a patch 'hey, I enabled this for my
> phone and it works!'.
> 
> If we find any issues during or close to the end of the development
> cycle, we can add a 'don't enable wide plane here' switch and enable
> it for failing platforms. But each enablement of this switch should
> come with a reason (wide planes not working here because ....). In the
> end this switch should be gone and transformed into proper HW
> limitation checks.
> 

As it has become clear that with this patch series 4K with UBWC cannot 
be supported without true virtual planes (with two SSPPs), why do you 
need to relax this check right now?

You can relax this when you add the support for virtual planes till then 
let it be this way.

Its not going to break smartDMA as such. You can still use it for layers 
< 2560.

That way we stay true to the purpose of the feature. I think originally 
you wanted to get this in for smartDMA and not to support wide plane and 
that purpose will still be achieved even with keeping this check intact.

You can relax it in the virtual plane series.

Regarding issues, this is where it gets tricky. We should be aligning 
with what the product supports. QC will not support issues arising with 
4K on chipsets on which 4K is not advertized.

>> As you are aware,  we have an open bug today that we do not filter out
>> the modes which we do not support.
>>
>> https://gitlab.freedesktop.org/drm/msm/-/issues/21
> 
> I thought that with the link-frequencies in place and with the DSI
> checking the OPP tables this issue is mostly handled. Isn't it?
> Is a mode check in the DPU driver itself the last missing piece?
> 

opp based checking was implemented only for DSI. That one is byte clk based.

DP uses link rate for opp table.

Even with a 5.4G link rate (the one in sc7180 chromebook) 4k@30 would 
still be possible but it was not advertized

https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf

These docs are available in public domain.

As we synced up last time on 
https://patchwork.freedesktop.org/series/107917/, even with these limits 
in place, its not matching the advertized limits.

>>
>> Due to this, on all chipsets we will end up trying to do a 4K on
>> external display which we dont know what bugs it will expose.
> 
> If we do not expose bugs, we do not have a way to fix them. And I
> definitely think that all the bugs should be listed as early as
> possible, while both of us still remember the code under the question.
> 

Yes but on chipsets where 4K is supported ( and hence needed ).

>>
>> So lets say if we test it on sc7280 fully but not on sc7180, we will
>> still hit this condition on sc7180 too but on that chipset we did not
>> advertise 4K as a capability in the product spec.
> 
> Is it 'not advertised' or 'not supported by hw'?
> 

The document 
https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf 
is made from inputs from not just display team but overall system 
limits. So even though you could argue that this falls within the 
display capabilities, all I can say at the moment is we have to stick to 
the advertized limits as its compiled with inputs from all the teams 
(system/performance etc).

>>
>> With the max_linewidth check relaxed nothing prevents us from doing 4K
>> on a chipset which doesnt support 4K.
> 
> What prevents sc7180 from supporting 4k? Does it support Smart DMA?
> Does it support having two LMs per INTF/CRTC? Is there a limitation on
> the linewidth of two LMs or two SSPPs?
> 
> I see that sm7125 (which has the same DPU revision) even contains
> "qcom,sde-vig-sspp-linewidth = <4096>;" in the DTS, despite official
> 'product brief' advertising only 2520x1080 output resolution.
> 

My previous response should have answered this.

>>
>>> +
>>> +             /*
>>> +              * FIXME: it's not possible to check if sourcesplit is supported,
>>> +              * LMs is not assigned yet. It happens in dpu_encoder_virt_mode_set
>>> +              */
>>> +             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;
>>>        }
>>>
>>
>> As you requested just wanted to summarize the condition in the email.
>>
>> In parallel fetch mode, the downstream driver for UBWC formats, we check
>> whether the src width of each rectangle is > maxlinewidth/2
>>
>> https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/DISPLAY.LA.2.0.r3-00500-WAIPIO.0/msm/sde/sde_plane.c#L1835
> 
> Thanks. Please double check my understanding: If the rectangle is used
> for the tiled format, then it's max_linewidth is effectively halved.
> So we can use rect_solo with full width, but for rect_0/rect_1 we
> should halve it, even if two rectangles are used in the time split?
> 

Not in time split mode. Only in parallel fetch mode which is being used 
here. Rest of your understanding is correct.

>>
>> For sc7280, maxlinewidth is 2400
>>
>> static const struct dpu_caps sc7280_dpu_caps = {
>>           .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>>           .max_mixer_blendstages = 0x7,
>>           .qseed_type = DPU_SSPP_SCALER_QSEED4,
>>           .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
>>           .ubwc_version = DPU_HW_UBWC_VER_30,
>>           .has_dim_layer = true,
>>           .has_idle_pc = true,
>>           .max_linewidth = 2400,
>>           .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
>> };
>>
>> Hence for UBWC formats which are by default used on the sc7280
>> chromebook, each rectangle should be < 1200
>>
>> SmartDMA is therefore not enough to support 4K on sc7280 and we need
>> true virtual planes ( using two SSPPs to display the 4K layer )
>>
>> Also, probably worth commenting that time multiplex mode support is not
>> added in this series.
> 
> Ack.
> 
>>
>>>        fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>>
>>> -     ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
>>> +     ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
>>> +     if (ret)
>>> +             return ret;
>>> +
>>> +     ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
>>>        if (ret)
>>>                return ret;
>>>
>>> @@ -1094,8 +1148,10 @@ 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
>>> +     else {
>>>                dpu_plane_flush_csc(pdpu, &pstate->pipe);
>>> +             dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
>>> +     }
>>>
>>>        /* flag h/w flush complete */
>>>        if (plane->state)
>>> @@ -1130,6 +1186,9 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
>>>        struct drm_plane_state *state = plane->state;
>>>        struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>>
>>> +     if (!pipe->sspp)
>>> +             return;
>>> +
>>>        if (layout && pipe->sspp->ops.setup_sourceaddress) {
>>>                trace_dpu_plane_set_scanout(pipe, layout);
>>>                pipe->sspp->ops.setup_sourceaddress(pipe, layout);
>>> @@ -1207,13 +1266,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>> -
>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>        struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>>>        struct msm_gem_address_space *aspace = kms->base.aspace;
>>>        struct dpu_hw_fmt_layout layout;
>>> @@ -1241,12 +1301,22 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>                                   drm_mode_vrefresh(&crtc->mode),
>>>                                   layout_valid ? &layout: NULL);
>>>
>>> +     dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
>>> +                                drm_mode_vrefresh(&crtc->mode),
>>> +                                layout_valid ? &layout: NULL);
>>> +
>>>        if (pstate->needs_qos_remap)
>>>                pstate->needs_qos_remap = false;
>>>
>>>        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) {
>>> +             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)
>>> @@ -1289,6 +1359,8 @@ 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);
>>>
>>> +             _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 */
>>> @@ -1369,11 +1441,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>> +     const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
>>> +     const struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_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));
>>> +
>>> +     if (r_pipe->sspp) {
>>> +             drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
>>> +             drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(r_pipe->multirect_mode));
>>> +             drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(r_pipe->multirect_index));
>>> +             drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
>>> +             drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
>>> +     }
>>>    }
>>
>> Do you think that changing the atomic_print_state to print the r_pipe
>> sspp can be moved to a separate patch? So that way we only keep the core
>> logic of atomic check of smartDMA in this patch.
>>
>>>
>>>    static void dpu_plane_reset(struct drm_plane *plane)
>>> @@ -1407,6 +1494,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
>>>         * This is the place where the state is allocated, so fill it fully.
>>>         */
>>>        pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
>>> +     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);
>>>    }
>>> @@ -1423,6 +1514,7 @@ 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);
>>> +     _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 079dad83eb37..183c95949885 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> @@ -19,7 +19,9 @@
>>>     * @base:   base drm plane state object
>>>     * @aspace: pointer to address space for input/output buffers
>>>     * @pipe:   software pipe description
>>> + * @r_pipe:  software pipe description of the second pipe
>>>     * @pipe_cfg:       software pipe configuration
>>> + * @r_pipe_cfg:      software pipe configuration for the second pipe
>>>     * @stage:  assigned by crtc blender
>>>     * @needs_qos_remap: qos remap settings need to be updated
>>>     * @multirect_index: index of the rectangle of SSPP
>>> @@ -34,7 +36,9 @@ struct dpu_plane_state {
>>>        struct drm_plane_state base;
>>>        struct msm_gem_address_space *aspace;
>>>        struct dpu_sw_pipe pipe;
>>> +     struct dpu_sw_pipe r_pipe;
>>>        struct dpu_hw_sspp_cfg pipe_cfg;
>>> +     struct dpu_hw_sspp_cfg r_pipe_cfg;
>>>        enum dpu_stage stage;
>>>        bool needs_qos_remap;
>>>        bool pending;
> 
> 
> 

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

* Re: [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
@ 2023-02-09 19:25         ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-09 19:25 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Kalyan Thota, freedreno, Sean Paul, Bjorn Andersson, dri-devel,
	Stephen Boyd, linux-arm-msm



On 2/9/2023 3:45 AM, Dmitry Baryshkov wrote:
> On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> Typically SSPP can support rectangle with width up to 2560. However it's
>>
>> Not always 2560. Depends on the chipset.
> 
> _typically_
> 

Would just say maxlinewidth of SSPP instead of giving some hardcoded number.

>>
>>> 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  |   6 ++
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
>>>    3 files changed, 114 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> index 0ca3bc38ff7e..867832a752b2 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>>>                                           fetch_active,
>>>                                           &pstate->pipe);
>>>
>>> +             _dpu_crtc_blend_setup_pipe(crtc, plane,
>>> +                                        mixer, cstate->num_mixers,
>>> +                                        stage_cfg, pstate->stage, 1,
>>> +                                        fetch_active,
>>> +                                        &pstate->r_pipe);
>>> +
>>>                /* blend config update */
>>>                for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
>>>                        _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> index e2e85688ed3c..401ead64c6bd 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>>>        struct dpu_plane *pdpu = to_dpu_plane(plane);
>>>        struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>>>
>>> +     if (!pipe->sspp)
>>> +             return;
>>> +
>>>        memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>>
>>>        if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>>> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>>>    {
>>>        struct dpu_hw_sspp_cfg pipe_cfg;
>>>
>>> +     if (!pipe->sspp)
>>> +             return 0;
>>
>> instead of checking if sspp was present, is it not better for the caller
>> to check if the rpipe is valid before calling this?
>>
>>> +
>>>        /* update sspp */
>>>        if (!pipe->sspp->ops.setup_solidfill)
>>>                return 0;
>>> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
>>>
>>>        /* update sspp */
>>>        _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
>>> +
>>> +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
>>>    }
>>
>> So cant we do
>>
>> if (pstate->r_pipe.sspp)
>>          _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
>>                  &pstate->r_pipe_cfg, fill_color, fmt);
>>
>> It just seems better to me as the caller would already know if the sspp
>> was assigned.
> 
>   I think I had this kind of code earlier, but then I found it more
> logical to move the check to the called function. I'll move it back.
> 
>>
>>>
>>>    int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
>>> @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>    {
>>>        uint32_t min_src_size;
>>>
>>> +     if (!pipe->sspp)
>>> +             return 0;
>>> +
>>>        min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>>
>>>        if (DPU_FORMAT_IS_YUV(fmt) &&
>>> @@ -957,9 +968,12 @@ 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;
>>> +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>        struct drm_rect fb_rect = { 0 };
>>>        uint32_t max_linewidth;
>>>        unsigned int rotation;
>>> @@ -983,8 +997,11 @@ 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;
>>> +     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) {
>>> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>
>>>        max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>
>>> -     /* check decimated source width */
>>>        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;
>>> +             /* 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;
>>> +             }
>>
>> This is where I am a bit concerned enabling it for all chipsets in one go.
> 
> As I wrote earlier, I'd prefer the opt-out rather than opt-in here. It
> is much easier to handle the reports "I have a device with sm6543,
> where the display worked before 6.4, but started failing afterwards"
> rather than trying to find a person with sm6543 and asking him if he
> can enable this and that on his device. And even a lower chance of a
> person with sm6543 coming up with a patch 'hey, I enabled this for my
> phone and it works!'.
> 
> If we find any issues during or close to the end of the development
> cycle, we can add a 'don't enable wide plane here' switch and enable
> it for failing platforms. But each enablement of this switch should
> come with a reason (wide planes not working here because ....). In the
> end this switch should be gone and transformed into proper HW
> limitation checks.
> 

As it has become clear that with this patch series 4K with UBWC cannot 
be supported without true virtual planes (with two SSPPs), why do you 
need to relax this check right now?

You can relax this when you add the support for virtual planes till then 
let it be this way.

Its not going to break smartDMA as such. You can still use it for layers 
< 2560.

That way we stay true to the purpose of the feature. I think originally 
you wanted to get this in for smartDMA and not to support wide plane and 
that purpose will still be achieved even with keeping this check intact.

You can relax it in the virtual plane series.

Regarding issues, this is where it gets tricky. We should be aligning 
with what the product supports. QC will not support issues arising with 
4K on chipsets on which 4K is not advertized.

>> As you are aware,  we have an open bug today that we do not filter out
>> the modes which we do not support.
>>
>> https://gitlab.freedesktop.org/drm/msm/-/issues/21
> 
> I thought that with the link-frequencies in place and with the DSI
> checking the OPP tables this issue is mostly handled. Isn't it?
> Is a mode check in the DPU driver itself the last missing piece?
> 

opp based checking was implemented only for DSI. That one is byte clk based.

DP uses link rate for opp table.

Even with a 5.4G link rate (the one in sc7180 chromebook) 4k@30 would 
still be possible but it was not advertized

https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf

These docs are available in public domain.

As we synced up last time on 
https://patchwork.freedesktop.org/series/107917/, even with these limits 
in place, its not matching the advertized limits.

>>
>> Due to this, on all chipsets we will end up trying to do a 4K on
>> external display which we dont know what bugs it will expose.
> 
> If we do not expose bugs, we do not have a way to fix them. And I
> definitely think that all the bugs should be listed as early as
> possible, while both of us still remember the code under the question.
> 

Yes but on chipsets where 4K is supported ( and hence needed ).

>>
>> So lets say if we test it on sc7280 fully but not on sc7180, we will
>> still hit this condition on sc7180 too but on that chipset we did not
>> advertise 4K as a capability in the product spec.
> 
> Is it 'not advertised' or 'not supported by hw'?
> 

The document 
https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf 
is made from inputs from not just display team but overall system 
limits. So even though you could argue that this falls within the 
display capabilities, all I can say at the moment is we have to stick to 
the advertized limits as its compiled with inputs from all the teams 
(system/performance etc).

>>
>> With the max_linewidth check relaxed nothing prevents us from doing 4K
>> on a chipset which doesnt support 4K.
> 
> What prevents sc7180 from supporting 4k? Does it support Smart DMA?
> Does it support having two LMs per INTF/CRTC? Is there a limitation on
> the linewidth of two LMs or two SSPPs?
> 
> I see that sm7125 (which has the same DPU revision) even contains
> "qcom,sde-vig-sspp-linewidth = <4096>;" in the DTS, despite official
> 'product brief' advertising only 2520x1080 output resolution.
> 

My previous response should have answered this.

>>
>>> +
>>> +             /*
>>> +              * FIXME: it's not possible to check if sourcesplit is supported,
>>> +              * LMs is not assigned yet. It happens in dpu_encoder_virt_mode_set
>>> +              */
>>> +             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;
>>>        }
>>>
>>
>> As you requested just wanted to summarize the condition in the email.
>>
>> In parallel fetch mode, the downstream driver for UBWC formats, we check
>> whether the src width of each rectangle is > maxlinewidth/2
>>
>> https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/DISPLAY.LA.2.0.r3-00500-WAIPIO.0/msm/sde/sde_plane.c#L1835
> 
> Thanks. Please double check my understanding: If the rectangle is used
> for the tiled format, then it's max_linewidth is effectively halved.
> So we can use rect_solo with full width, but for rect_0/rect_1 we
> should halve it, even if two rectangles are used in the time split?
> 

Not in time split mode. Only in parallel fetch mode which is being used 
here. Rest of your understanding is correct.

>>
>> For sc7280, maxlinewidth is 2400
>>
>> static const struct dpu_caps sc7280_dpu_caps = {
>>           .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>>           .max_mixer_blendstages = 0x7,
>>           .qseed_type = DPU_SSPP_SCALER_QSEED4,
>>           .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
>>           .ubwc_version = DPU_HW_UBWC_VER_30,
>>           .has_dim_layer = true,
>>           .has_idle_pc = true,
>>           .max_linewidth = 2400,
>>           .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
>> };
>>
>> Hence for UBWC formats which are by default used on the sc7280
>> chromebook, each rectangle should be < 1200
>>
>> SmartDMA is therefore not enough to support 4K on sc7280 and we need
>> true virtual planes ( using two SSPPs to display the 4K layer )
>>
>> Also, probably worth commenting that time multiplex mode support is not
>> added in this series.
> 
> Ack.
> 
>>
>>>        fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>>
>>> -     ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
>>> +     ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
>>> +     if (ret)
>>> +             return ret;
>>> +
>>> +     ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
>>>        if (ret)
>>>                return ret;
>>>
>>> @@ -1094,8 +1148,10 @@ 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
>>> +     else {
>>>                dpu_plane_flush_csc(pdpu, &pstate->pipe);
>>> +             dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
>>> +     }
>>>
>>>        /* flag h/w flush complete */
>>>        if (plane->state)
>>> @@ -1130,6 +1186,9 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
>>>        struct drm_plane_state *state = plane->state;
>>>        struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>>
>>> +     if (!pipe->sspp)
>>> +             return;
>>> +
>>>        if (layout && pipe->sspp->ops.setup_sourceaddress) {
>>>                trace_dpu_plane_set_scanout(pipe, layout);
>>>                pipe->sspp->ops.setup_sourceaddress(pipe, layout);
>>> @@ -1207,13 +1266,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>> -
>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>        struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>>>        struct msm_gem_address_space *aspace = kms->base.aspace;
>>>        struct dpu_hw_fmt_layout layout;
>>> @@ -1241,12 +1301,22 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>                                   drm_mode_vrefresh(&crtc->mode),
>>>                                   layout_valid ? &layout: NULL);
>>>
>>> +     dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
>>> +                                drm_mode_vrefresh(&crtc->mode),
>>> +                                layout_valid ? &layout: NULL);
>>> +
>>>        if (pstate->needs_qos_remap)
>>>                pstate->needs_qos_remap = false;
>>>
>>>        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) {
>>> +             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)
>>> @@ -1289,6 +1359,8 @@ 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);
>>>
>>> +             _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 */
>>> @@ -1369,11 +1441,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>> +     const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
>>> +     const struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_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));
>>> +
>>> +     if (r_pipe->sspp) {
>>> +             drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
>>> +             drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(r_pipe->multirect_mode));
>>> +             drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(r_pipe->multirect_index));
>>> +             drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
>>> +             drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
>>> +     }
>>>    }
>>
>> Do you think that changing the atomic_print_state to print the r_pipe
>> sspp can be moved to a separate patch? So that way we only keep the core
>> logic of atomic check of smartDMA in this patch.
>>
>>>
>>>    static void dpu_plane_reset(struct drm_plane *plane)
>>> @@ -1407,6 +1494,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
>>>         * This is the place where the state is allocated, so fill it fully.
>>>         */
>>>        pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
>>> +     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);
>>>    }
>>> @@ -1423,6 +1514,7 @@ 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);
>>> +     _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 079dad83eb37..183c95949885 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> @@ -19,7 +19,9 @@
>>>     * @base:   base drm plane state object
>>>     * @aspace: pointer to address space for input/output buffers
>>>     * @pipe:   software pipe description
>>> + * @r_pipe:  software pipe description of the second pipe
>>>     * @pipe_cfg:       software pipe configuration
>>> + * @r_pipe_cfg:      software pipe configuration for the second pipe
>>>     * @stage:  assigned by crtc blender
>>>     * @needs_qos_remap: qos remap settings need to be updated
>>>     * @multirect_index: index of the rectangle of SSPP
>>> @@ -34,7 +36,9 @@ struct dpu_plane_state {
>>>        struct drm_plane_state base;
>>>        struct msm_gem_address_space *aspace;
>>>        struct dpu_sw_pipe pipe;
>>> +     struct dpu_sw_pipe r_pipe;
>>>        struct dpu_hw_sspp_cfg pipe_cfg;
>>> +     struct dpu_hw_sspp_cfg r_pipe_cfg;
>>>        enum dpu_stage stage;
>>>        bool needs_qos_remap;
>>>        bool pending;
> 
> 
> 

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

* Re: [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
  2023-02-09 19:25         ` Abhinav Kumar
@ 2023-02-09 21:23           ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-09 21:23 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Rob Clark, Sean Paul, Stephen Boyd, David Airlie, Daniel Vetter,
	Bjorn Andersson, linux-arm-msm, dri-devel, freedreno,
	Kalyan Thota

Hi Abhinav,

On Thu, 9 Feb 2023 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/9/2023 3:45 AM, Dmitry Baryshkov wrote:
> > On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> >>> Typically SSPP can support rectangle with width up to 2560. However it's
> >>
> >> Not always 2560. Depends on the chipset.
> >
> > _typically_
> >
>
> Would just say maxlinewidth of SSPP instead of giving some hardcoded number.

Ack.

>
> >>
> >>> 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  |   6 ++
> >>>    drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
> >>>    drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
> >>>    3 files changed, 114 insertions(+), 12 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >>> index 0ca3bc38ff7e..867832a752b2 100644
> >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >>> @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> >>>                                           fetch_active,
> >>>                                           &pstate->pipe);
> >>>
> >>> +             _dpu_crtc_blend_setup_pipe(crtc, plane,
> >>> +                                        mixer, cstate->num_mixers,
> >>> +                                        stage_cfg, pstate->stage, 1,
> >>> +                                        fetch_active,
> >>> +                                        &pstate->r_pipe);
> >>> +
> >>>                /* blend config update */
> >>>                for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
> >>>                        _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
> >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >>> index e2e85688ed3c..401ead64c6bd 100644
> >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >>> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
> >>>        struct dpu_plane *pdpu = to_dpu_plane(plane);
> >>>        struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
> >>>
> >>> +     if (!pipe->sspp)
> >>> +             return;
> >>> +
> >>>        memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
> >>>
> >>>        if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
> >>> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
> >>>    {
> >>>        struct dpu_hw_sspp_cfg pipe_cfg;
> >>>
> >>> +     if (!pipe->sspp)
> >>> +             return 0;
> >>
> >> instead of checking if sspp was present, is it not better for the caller
> >> to check if the rpipe is valid before calling this?
> >>
> >>> +
> >>>        /* update sspp */
> >>>        if (!pipe->sspp->ops.setup_solidfill)
> >>>                return 0;
> >>> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
> >>>
> >>>        /* update sspp */
> >>>        _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
> >>> +
> >>> +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
> >>>    }
> >>
> >> So cant we do
> >>
> >> if (pstate->r_pipe.sspp)
> >>          _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
> >>                  &pstate->r_pipe_cfg, fill_color, fmt);
> >>
> >> It just seems better to me as the caller would already know if the sspp
> >> was assigned.
> >
> >   I think I had this kind of code earlier, but then I found it more
> > logical to move the check to the called function. I'll move it back.
> >
> >>
> >>>
> >>>    int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
> >>> @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
> >>>    {
> >>>        uint32_t min_src_size;
> >>>
> >>> +     if (!pipe->sspp)
> >>> +             return 0;
> >>> +
> >>>        min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
> >>>
> >>>        if (DPU_FORMAT_IS_YUV(fmt) &&
> >>> @@ -957,9 +968,12 @@ 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;
> >>> +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> >>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> >>>        struct drm_rect fb_rect = { 0 };
> >>>        uint32_t max_linewidth;
> >>>        unsigned int rotation;
> >>> @@ -983,8 +997,11 @@ 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;
> >>> +     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) {
> >>> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> >>>
> >>>        max_linewidth = pdpu->catalog->caps->max_linewidth;
> >>>
> >>> -     /* check decimated source width */
> >>>        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;
> >>> +             /* 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;
> >>> +             }
> >>
> >> This is where I am a bit concerned enabling it for all chipsets in one go.
> >
> > As I wrote earlier, I'd prefer the opt-out rather than opt-in here. It
> > is much easier to handle the reports "I have a device with sm6543,
> > where the display worked before 6.4, but started failing afterwards"
> > rather than trying to find a person with sm6543 and asking him if he
> > can enable this and that on his device. And even a lower chance of a
> > person with sm6543 coming up with a patch 'hey, I enabled this for my
> > phone and it works!'.
> >
> > If we find any issues during or close to the end of the development
> > cycle, we can add a 'don't enable wide plane here' switch and enable
> > it for failing platforms. But each enablement of this switch should
> > come with a reason (wide planes not working here because ....). In the
> > end this switch should be gone and transformed into proper HW
> > limitation checks.
> >
>
> As it has become clear that with this patch series 4K with UBWC cannot
> be supported without true virtual planes (with two SSPPs), why do you
> need to relax this check right now?

Yes. It enables support for 4k @ linear formats. So my plan for this
series is to land 4k with all the proper applicable restrictions.

> You can relax this when you add the support for virtual planes till then
> let it be this way.
>
> Its not going to break smartDMA as such. You can still use it for layers
> < 2560.
>
> That way we stay true to the purpose of the feature. I think originally
> you wanted to get this in for smartDMA and not to support wide plane and
> that purpose will still be achieved even with keeping this check intact.

Actually, no. With this series I wanted to get 4k. It was developed in
parallel with the 4k enablement for RB3 (posted, bridge patches are
being merged for 6.3) and RB5 (delayed for now, I have other issues
there).

> You can relax it in the virtual plane series.
>
> Regarding issues, this is where it gets tricky. We should be aligning
> with what the product supports. QC will not support issues arising with
> 4K on chipsets on which 4K is not advertized.

So, we have several different items here:
- SmartDMA v2 per se, supporting two rectangles per VIG or DMA plane,
- Source split support,
- Supporting 4k modes.

I think we should tend them one by one. This series concerns SmartDMA
v2. Using SmartDMA it is possible to use two rectangles side by side
to emulate a wide plane. This series doesn't care at all about max
resolutions. These two items are completely orthogonal.

> >> As you are aware,  we have an open bug today that we do not filter out
> >> the modes which we do not support.
> >>
> >> https://gitlab.freedesktop.org/drm/msm/-/issues/21
> >
> > I thought that with the link-frequencies in place and with the DSI
> > checking the OPP tables this issue is mostly handled. Isn't it?
> > Is a mode check in the DPU driver itself the last missing piece?
> >
>
> opp based checking was implemented only for DSI. That one is byte clk based.
>
> DP uses link rate for opp table.
>
> Even with a 5.4G link rate (the one in sc7180 chromebook) 4k@30 would
> still be possible but it was not advertized
>
> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>
> These docs are available in public domain.
>
> As we synced up last time on
> https://patchwork.freedesktop.org/series/107917/, even with these limits
> in place, its not matching the advertized limits.
>
> >>
> >> Due to this, on all chipsets we will end up trying to do a 4K on
> >> external display which we dont know what bugs it will expose.
> >
> > If we do not expose bugs, we do not have a way to fix them. And I
> > definitely think that all the bugs should be listed as early as
> > possible, while both of us still remember the code under the question.
> >
>
> Yes but on chipsets where 4K is supported ( and hence needed ).

4k, SmartDMA, src-split, split-display, etc.


>
> >>
> >> So lets say if we test it on sc7280 fully but not on sc7180, we will
> >> still hit this condition on sc7180 too but on that chipset we did not
> >> advertise 4K as a capability in the product spec.
> >
> > Is it 'not advertised' or 'not supported by hw'?
> >
>
> The document
> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
> is made from inputs from not just display team but overall system
> limits. So even though you could argue that this falls within the
> display capabilities, all I can say at the moment is we have to stick to
> the advertized limits as its compiled with inputs from all the teams
> (system/performance etc).

So, there should be a limiting factor (or a combination of them).
Filter out 4k modes on sc7180. Or modes using fill rate higher than N.
Pixel clock rate higher than M. But it has nothing to do with these
patches enabling SmartDMA support on this platform.

Even if we look at the vendor kernels, we don't see 'maximum external
resolution'. Instead I see a combination of linewidth and bandwidth
limitations. If we can stick to that, that would be great.

>
> >>
> >> With the max_linewidth check relaxed nothing prevents us from doing 4K
> >> on a chipset which doesnt support 4K.
> >
> > What prevents sc7180 from supporting 4k? Does it support Smart DMA?
> > Does it support having two LMs per INTF/CRTC? Is there a limitation on
> > the linewidth of two LMs or two SSPPs?
> >
> > I see that sm7125 (which has the same DPU revision) even contains
> > "qcom,sde-vig-sspp-linewidth = <4096>;" in the DTS, despite official
> > 'product brief' advertising only 2520x1080 output resolution.
> >
>
> My previous response should have answered this.

Up to some point, thanks.

>
> >>
> >>> +
> >>> +             /*
> >>> +              * FIXME: it's not possible to check if sourcesplit is supported,
> >>> +              * LMs is not assigned yet. It happens in dpu_encoder_virt_mode_set
> >>> +              */
> >>> +             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;
> >>>        }
> >>>
> >>
> >> As you requested just wanted to summarize the condition in the email.
> >>
> >> In parallel fetch mode, the downstream driver for UBWC formats, we check
> >> whether the src width of each rectangle is > maxlinewidth/2
> >>
> >> https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/DISPLAY.LA.2.0.r3-00500-WAIPIO.0/msm/sde/sde_plane.c#L1835
> >
> > Thanks. Please double check my understanding: If the rectangle is used
> > for the tiled format, then it's max_linewidth is effectively halved.
> > So we can use rect_solo with full width, but for rect_0/rect_1 we
> > should halve it, even if two rectangles are used in the time split?
> >
>
> Not in time split mode. Only in parallel fetch mode which is being used
> here. Rest of your understanding is correct.

Ack, thanks for the correction. This is important for plane checks.

>
> >>
> >> For sc7280, maxlinewidth is 2400
> >>
> >> static const struct dpu_caps sc7280_dpu_caps = {
> >>           .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
> >>           .max_mixer_blendstages = 0x7,
> >>           .qseed_type = DPU_SSPP_SCALER_QSEED4,
> >>           .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
> >>           .ubwc_version = DPU_HW_UBWC_VER_30,
> >>           .has_dim_layer = true,
> >>           .has_idle_pc = true,
> >>           .max_linewidth = 2400,
> >>           .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
> >> };
> >>
> >> Hence for UBWC formats which are by default used on the sc7280
> >> chromebook, each rectangle should be < 1200
> >>
> >> SmartDMA is therefore not enough to support 4K on sc7280 and we need
> >> true virtual planes ( using two SSPPs to display the 4K layer )
> >>
> >> Also, probably worth commenting that time multiplex mode support is not
> >> added in this series.
> >
> > Ack.
> >
> >>
> >>>        fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> >>>
> >>> -     ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
> >>> +     ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
> >>> +     if (ret)
> >>> +             return ret;
> >>> +
> >>> +     ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
> >>>        if (ret)
> >>>                return ret;
> >>>
> >>> @@ -1094,8 +1148,10 @@ 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
> >>> +     else {
> >>>                dpu_plane_flush_csc(pdpu, &pstate->pipe);
> >>> +             dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> >>> +     }
> >>>
> >>>        /* flag h/w flush complete */
> >>>        if (plane->state)
> >>> @@ -1130,6 +1186,9 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
> >>>        struct drm_plane_state *state = plane->state;
> >>>        struct dpu_plane_state *pstate = to_dpu_plane_state(state);
> >>>
> >>> +     if (!pipe->sspp)
> >>> +             return;
> >>> +
> >>>        if (layout && pipe->sspp->ops.setup_sourceaddress) {
> >>>                trace_dpu_plane_set_scanout(pipe, layout);
> >>>                pipe->sspp->ops.setup_sourceaddress(pipe, layout);
> >>> @@ -1207,13 +1266,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> >>> -
> >>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> >>>        struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> >>>        struct msm_gem_address_space *aspace = kms->base.aspace;
> >>>        struct dpu_hw_fmt_layout layout;
> >>> @@ -1241,12 +1301,22 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
> >>>                                   drm_mode_vrefresh(&crtc->mode),
> >>>                                   layout_valid ? &layout: NULL);
> >>>
> >>> +     dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
> >>> +                                drm_mode_vrefresh(&crtc->mode),
> >>> +                                layout_valid ? &layout: NULL);
> >>> +
> >>>        if (pstate->needs_qos_remap)
> >>>                pstate->needs_qos_remap = false;
> >>>
> >>>        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) {
> >>> +             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)
> >>> @@ -1289,6 +1359,8 @@ 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);
> >>>
> >>> +             _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 */
> >>> @@ -1369,11 +1441,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> >>> +     const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
> >>> +     const struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_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));
> >>> +
> >>> +     if (r_pipe->sspp) {
> >>> +             drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
> >>> +             drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(r_pipe->multirect_mode));
> >>> +             drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(r_pipe->multirect_index));
> >>> +             drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
> >>> +             drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
> >>> +     }
> >>>    }
> >>
> >> Do you think that changing the atomic_print_state to print the r_pipe
> >> sspp can be moved to a separate patch? So that way we only keep the core
> >> logic of atomic check of smartDMA in this patch.
> >>
> >>>
> >>>    static void dpu_plane_reset(struct drm_plane *plane)
> >>> @@ -1407,6 +1494,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
> >>>         * This is the place where the state is allocated, so fill it fully.
> >>>         */
> >>>        pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
> >>> +     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);
> >>>    }
> >>> @@ -1423,6 +1514,7 @@ 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);
> >>> +     _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 079dad83eb37..183c95949885 100644
> >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> >>> @@ -19,7 +19,9 @@
> >>>     * @base:   base drm plane state object
> >>>     * @aspace: pointer to address space for input/output buffers
> >>>     * @pipe:   software pipe description
> >>> + * @r_pipe:  software pipe description of the second pipe
> >>>     * @pipe_cfg:       software pipe configuration
> >>> + * @r_pipe_cfg:      software pipe configuration for the second pipe
> >>>     * @stage:  assigned by crtc blender
> >>>     * @needs_qos_remap: qos remap settings need to be updated
> >>>     * @multirect_index: index of the rectangle of SSPP
> >>> @@ -34,7 +36,9 @@ struct dpu_plane_state {
> >>>        struct drm_plane_state base;
> >>>        struct msm_gem_address_space *aspace;
> >>>        struct dpu_sw_pipe pipe;
> >>> +     struct dpu_sw_pipe r_pipe;
> >>>        struct dpu_hw_sspp_cfg pipe_cfg;
> >>> +     struct dpu_hw_sspp_cfg r_pipe_cfg;
> >>>        enum dpu_stage stage;
> >>>        bool needs_qos_remap;
> >>>        bool pending;
> >
> >
> >



--
With best wishes
Dmitry

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

* Re: [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
@ 2023-02-09 21:23           ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-09 21:23 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Kalyan Thota, freedreno, Sean Paul, Bjorn Andersson, dri-devel,
	Stephen Boyd, linux-arm-msm

Hi Abhinav,

On Thu, 9 Feb 2023 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
>
>
> On 2/9/2023 3:45 AM, Dmitry Baryshkov wrote:
> > On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> >>> Typically SSPP can support rectangle with width up to 2560. However it's
> >>
> >> Not always 2560. Depends on the chipset.
> >
> > _typically_
> >
>
> Would just say maxlinewidth of SSPP instead of giving some hardcoded number.

Ack.

>
> >>
> >>> 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  |   6 ++
> >>>    drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
> >>>    drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
> >>>    3 files changed, 114 insertions(+), 12 deletions(-)
> >>>
> >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >>> index 0ca3bc38ff7e..867832a752b2 100644
> >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >>> @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> >>>                                           fetch_active,
> >>>                                           &pstate->pipe);
> >>>
> >>> +             _dpu_crtc_blend_setup_pipe(crtc, plane,
> >>> +                                        mixer, cstate->num_mixers,
> >>> +                                        stage_cfg, pstate->stage, 1,
> >>> +                                        fetch_active,
> >>> +                                        &pstate->r_pipe);
> >>> +
> >>>                /* blend config update */
> >>>                for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
> >>>                        _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
> >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >>> index e2e85688ed3c..401ead64c6bd 100644
> >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >>> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
> >>>        struct dpu_plane *pdpu = to_dpu_plane(plane);
> >>>        struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
> >>>
> >>> +     if (!pipe->sspp)
> >>> +             return;
> >>> +
> >>>        memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
> >>>
> >>>        if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
> >>> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
> >>>    {
> >>>        struct dpu_hw_sspp_cfg pipe_cfg;
> >>>
> >>> +     if (!pipe->sspp)
> >>> +             return 0;
> >>
> >> instead of checking if sspp was present, is it not better for the caller
> >> to check if the rpipe is valid before calling this?
> >>
> >>> +
> >>>        /* update sspp */
> >>>        if (!pipe->sspp->ops.setup_solidfill)
> >>>                return 0;
> >>> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
> >>>
> >>>        /* update sspp */
> >>>        _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
> >>> +
> >>> +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
> >>>    }
> >>
> >> So cant we do
> >>
> >> if (pstate->r_pipe.sspp)
> >>          _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
> >>                  &pstate->r_pipe_cfg, fill_color, fmt);
> >>
> >> It just seems better to me as the caller would already know if the sspp
> >> was assigned.
> >
> >   I think I had this kind of code earlier, but then I found it more
> > logical to move the check to the called function. I'll move it back.
> >
> >>
> >>>
> >>>    int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
> >>> @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
> >>>    {
> >>>        uint32_t min_src_size;
> >>>
> >>> +     if (!pipe->sspp)
> >>> +             return 0;
> >>> +
> >>>        min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
> >>>
> >>>        if (DPU_FORMAT_IS_YUV(fmt) &&
> >>> @@ -957,9 +968,12 @@ 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;
> >>> +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> >>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> >>>        struct drm_rect fb_rect = { 0 };
> >>>        uint32_t max_linewidth;
> >>>        unsigned int rotation;
> >>> @@ -983,8 +997,11 @@ 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;
> >>> +     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) {
> >>> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> >>>
> >>>        max_linewidth = pdpu->catalog->caps->max_linewidth;
> >>>
> >>> -     /* check decimated source width */
> >>>        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;
> >>> +             /* 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;
> >>> +             }
> >>
> >> This is where I am a bit concerned enabling it for all chipsets in one go.
> >
> > As I wrote earlier, I'd prefer the opt-out rather than opt-in here. It
> > is much easier to handle the reports "I have a device with sm6543,
> > where the display worked before 6.4, but started failing afterwards"
> > rather than trying to find a person with sm6543 and asking him if he
> > can enable this and that on his device. And even a lower chance of a
> > person with sm6543 coming up with a patch 'hey, I enabled this for my
> > phone and it works!'.
> >
> > If we find any issues during or close to the end of the development
> > cycle, we can add a 'don't enable wide plane here' switch and enable
> > it for failing platforms. But each enablement of this switch should
> > come with a reason (wide planes not working here because ....). In the
> > end this switch should be gone and transformed into proper HW
> > limitation checks.
> >
>
> As it has become clear that with this patch series 4K with UBWC cannot
> be supported without true virtual planes (with two SSPPs), why do you
> need to relax this check right now?

Yes. It enables support for 4k @ linear formats. So my plan for this
series is to land 4k with all the proper applicable restrictions.

> You can relax this when you add the support for virtual planes till then
> let it be this way.
>
> Its not going to break smartDMA as such. You can still use it for layers
> < 2560.
>
> That way we stay true to the purpose of the feature. I think originally
> you wanted to get this in for smartDMA and not to support wide plane and
> that purpose will still be achieved even with keeping this check intact.

Actually, no. With this series I wanted to get 4k. It was developed in
parallel with the 4k enablement for RB3 (posted, bridge patches are
being merged for 6.3) and RB5 (delayed for now, I have other issues
there).

> You can relax it in the virtual plane series.
>
> Regarding issues, this is where it gets tricky. We should be aligning
> with what the product supports. QC will not support issues arising with
> 4K on chipsets on which 4K is not advertized.

So, we have several different items here:
- SmartDMA v2 per se, supporting two rectangles per VIG or DMA plane,
- Source split support,
- Supporting 4k modes.

I think we should tend them one by one. This series concerns SmartDMA
v2. Using SmartDMA it is possible to use two rectangles side by side
to emulate a wide plane. This series doesn't care at all about max
resolutions. These two items are completely orthogonal.

> >> As you are aware,  we have an open bug today that we do not filter out
> >> the modes which we do not support.
> >>
> >> https://gitlab.freedesktop.org/drm/msm/-/issues/21
> >
> > I thought that with the link-frequencies in place and with the DSI
> > checking the OPP tables this issue is mostly handled. Isn't it?
> > Is a mode check in the DPU driver itself the last missing piece?
> >
>
> opp based checking was implemented only for DSI. That one is byte clk based.
>
> DP uses link rate for opp table.
>
> Even with a 5.4G link rate (the one in sc7180 chromebook) 4k@30 would
> still be possible but it was not advertized
>
> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>
> These docs are available in public domain.
>
> As we synced up last time on
> https://patchwork.freedesktop.org/series/107917/, even with these limits
> in place, its not matching the advertized limits.
>
> >>
> >> Due to this, on all chipsets we will end up trying to do a 4K on
> >> external display which we dont know what bugs it will expose.
> >
> > If we do not expose bugs, we do not have a way to fix them. And I
> > definitely think that all the bugs should be listed as early as
> > possible, while both of us still remember the code under the question.
> >
>
> Yes but on chipsets where 4K is supported ( and hence needed ).

4k, SmartDMA, src-split, split-display, etc.


>
> >>
> >> So lets say if we test it on sc7280 fully but not on sc7180, we will
> >> still hit this condition on sc7180 too but on that chipset we did not
> >> advertise 4K as a capability in the product spec.
> >
> > Is it 'not advertised' or 'not supported by hw'?
> >
>
> The document
> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
> is made from inputs from not just display team but overall system
> limits. So even though you could argue that this falls within the
> display capabilities, all I can say at the moment is we have to stick to
> the advertized limits as its compiled with inputs from all the teams
> (system/performance etc).

So, there should be a limiting factor (or a combination of them).
Filter out 4k modes on sc7180. Or modes using fill rate higher than N.
Pixel clock rate higher than M. But it has nothing to do with these
patches enabling SmartDMA support on this platform.

Even if we look at the vendor kernels, we don't see 'maximum external
resolution'. Instead I see a combination of linewidth and bandwidth
limitations. If we can stick to that, that would be great.

>
> >>
> >> With the max_linewidth check relaxed nothing prevents us from doing 4K
> >> on a chipset which doesnt support 4K.
> >
> > What prevents sc7180 from supporting 4k? Does it support Smart DMA?
> > Does it support having two LMs per INTF/CRTC? Is there a limitation on
> > the linewidth of two LMs or two SSPPs?
> >
> > I see that sm7125 (which has the same DPU revision) even contains
> > "qcom,sde-vig-sspp-linewidth = <4096>;" in the DTS, despite official
> > 'product brief' advertising only 2520x1080 output resolution.
> >
>
> My previous response should have answered this.

Up to some point, thanks.

>
> >>
> >>> +
> >>> +             /*
> >>> +              * FIXME: it's not possible to check if sourcesplit is supported,
> >>> +              * LMs is not assigned yet. It happens in dpu_encoder_virt_mode_set
> >>> +              */
> >>> +             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;
> >>>        }
> >>>
> >>
> >> As you requested just wanted to summarize the condition in the email.
> >>
> >> In parallel fetch mode, the downstream driver for UBWC formats, we check
> >> whether the src width of each rectangle is > maxlinewidth/2
> >>
> >> https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/DISPLAY.LA.2.0.r3-00500-WAIPIO.0/msm/sde/sde_plane.c#L1835
> >
> > Thanks. Please double check my understanding: If the rectangle is used
> > for the tiled format, then it's max_linewidth is effectively halved.
> > So we can use rect_solo with full width, but for rect_0/rect_1 we
> > should halve it, even if two rectangles are used in the time split?
> >
>
> Not in time split mode. Only in parallel fetch mode which is being used
> here. Rest of your understanding is correct.

Ack, thanks for the correction. This is important for plane checks.

>
> >>
> >> For sc7280, maxlinewidth is 2400
> >>
> >> static const struct dpu_caps sc7280_dpu_caps = {
> >>           .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
> >>           .max_mixer_blendstages = 0x7,
> >>           .qseed_type = DPU_SSPP_SCALER_QSEED4,
> >>           .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
> >>           .ubwc_version = DPU_HW_UBWC_VER_30,
> >>           .has_dim_layer = true,
> >>           .has_idle_pc = true,
> >>           .max_linewidth = 2400,
> >>           .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
> >> };
> >>
> >> Hence for UBWC formats which are by default used on the sc7280
> >> chromebook, each rectangle should be < 1200
> >>
> >> SmartDMA is therefore not enough to support 4K on sc7280 and we need
> >> true virtual planes ( using two SSPPs to display the 4K layer )
> >>
> >> Also, probably worth commenting that time multiplex mode support is not
> >> added in this series.
> >
> > Ack.
> >
> >>
> >>>        fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
> >>>
> >>> -     ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
> >>> +     ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
> >>> +     if (ret)
> >>> +             return ret;
> >>> +
> >>> +     ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
> >>>        if (ret)
> >>>                return ret;
> >>>
> >>> @@ -1094,8 +1148,10 @@ 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
> >>> +     else {
> >>>                dpu_plane_flush_csc(pdpu, &pstate->pipe);
> >>> +             dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
> >>> +     }
> >>>
> >>>        /* flag h/w flush complete */
> >>>        if (plane->state)
> >>> @@ -1130,6 +1186,9 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
> >>>        struct drm_plane_state *state = plane->state;
> >>>        struct dpu_plane_state *pstate = to_dpu_plane_state(state);
> >>>
> >>> +     if (!pipe->sspp)
> >>> +             return;
> >>> +
> >>>        if (layout && pipe->sspp->ops.setup_sourceaddress) {
> >>>                trace_dpu_plane_set_scanout(pipe, layout);
> >>>                pipe->sspp->ops.setup_sourceaddress(pipe, layout);
> >>> @@ -1207,13 +1266,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> >>> -
> >>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> >>>        struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
> >>>        struct msm_gem_address_space *aspace = kms->base.aspace;
> >>>        struct dpu_hw_fmt_layout layout;
> >>> @@ -1241,12 +1301,22 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
> >>>                                   drm_mode_vrefresh(&crtc->mode),
> >>>                                   layout_valid ? &layout: NULL);
> >>>
> >>> +     dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
> >>> +                                drm_mode_vrefresh(&crtc->mode),
> >>> +                                layout_valid ? &layout: NULL);
> >>> +
> >>>        if (pstate->needs_qos_remap)
> >>>                pstate->needs_qos_remap = false;
> >>>
> >>>        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) {
> >>> +             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)
> >>> @@ -1289,6 +1359,8 @@ 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);
> >>>
> >>> +             _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 */
> >>> @@ -1369,11 +1441,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> >>> +     const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
> >>> +     const struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_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));
> >>> +
> >>> +     if (r_pipe->sspp) {
> >>> +             drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
> >>> +             drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(r_pipe->multirect_mode));
> >>> +             drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(r_pipe->multirect_index));
> >>> +             drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
> >>> +             drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
> >>> +     }
> >>>    }
> >>
> >> Do you think that changing the atomic_print_state to print the r_pipe
> >> sspp can be moved to a separate patch? So that way we only keep the core
> >> logic of atomic check of smartDMA in this patch.
> >>
> >>>
> >>>    static void dpu_plane_reset(struct drm_plane *plane)
> >>> @@ -1407,6 +1494,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
> >>>         * This is the place where the state is allocated, so fill it fully.
> >>>         */
> >>>        pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
> >>> +     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);
> >>>    }
> >>> @@ -1423,6 +1514,7 @@ 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);
> >>> +     _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 079dad83eb37..183c95949885 100644
> >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> >>> @@ -19,7 +19,9 @@
> >>>     * @base:   base drm plane state object
> >>>     * @aspace: pointer to address space for input/output buffers
> >>>     * @pipe:   software pipe description
> >>> + * @r_pipe:  software pipe description of the second pipe
> >>>     * @pipe_cfg:       software pipe configuration
> >>> + * @r_pipe_cfg:      software pipe configuration for the second pipe
> >>>     * @stage:  assigned by crtc blender
> >>>     * @needs_qos_remap: qos remap settings need to be updated
> >>>     * @multirect_index: index of the rectangle of SSPP
> >>> @@ -34,7 +36,9 @@ struct dpu_plane_state {
> >>>        struct drm_plane_state base;
> >>>        struct msm_gem_address_space *aspace;
> >>>        struct dpu_sw_pipe pipe;
> >>> +     struct dpu_sw_pipe r_pipe;
> >>>        struct dpu_hw_sspp_cfg pipe_cfg;
> >>> +     struct dpu_hw_sspp_cfg r_pipe_cfg;
> >>>        enum dpu_stage stage;
> >>>        bool needs_qos_remap;
> >>>        bool pending;
> >
> >
> >



--
With best wishes
Dmitry

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

* Re: [Freedreno] [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
  2023-02-09 21:23           ` Dmitry Baryshkov
@ 2023-02-09 22:12             ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-09 22:12 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Kalyan Thota, freedreno, Sean Paul, Bjorn Andersson, dri-devel,
	Stephen Boyd, Rob Clark, Daniel Vetter, linux-arm-msm,
	David Airlie

Hi Dmitry

On 2/9/2023 1:23 PM, Dmitry Baryshkov wrote:
> Hi Abhinav,
> 
> On Thu, 9 Feb 2023 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/9/2023 3:45 AM, Dmitry Baryshkov wrote:
>>> On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>> Typically SSPP can support rectangle with width up to 2560. However it's
>>>>
>>>> Not always 2560. Depends on the chipset.
>>>
>>> _typically_
>>>
>>
>> Would just say maxlinewidth of SSPP instead of giving some hardcoded number.
> 
> Ack.
> 
>>
>>>>
>>>>> 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  |   6 ++
>>>>>     drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
>>>>>     drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
>>>>>     3 files changed, 114 insertions(+), 12 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> index 0ca3bc38ff7e..867832a752b2 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>>>>>                                            fetch_active,
>>>>>                                            &pstate->pipe);
>>>>>
>>>>> +             _dpu_crtc_blend_setup_pipe(crtc, plane,
>>>>> +                                        mixer, cstate->num_mixers,
>>>>> +                                        stage_cfg, pstate->stage, 1,
>>>>> +                                        fetch_active,
>>>>> +                                        &pstate->r_pipe);
>>>>> +
>>>>>                 /* blend config update */
>>>>>                 for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
>>>>>                         _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> index e2e85688ed3c..401ead64c6bd 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>>>>>         struct dpu_plane *pdpu = to_dpu_plane(plane);
>>>>>         struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>>>>>
>>>>> +     if (!pipe->sspp)
>>>>> +             return;
>>>>> +
>>>>>         memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>>>>
>>>>>         if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>>>>> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>>>>>     {
>>>>>         struct dpu_hw_sspp_cfg pipe_cfg;
>>>>>
>>>>> +     if (!pipe->sspp)
>>>>> +             return 0;
>>>>
>>>> instead of checking if sspp was present, is it not better for the caller
>>>> to check if the rpipe is valid before calling this?
>>>>
>>>>> +
>>>>>         /* update sspp */
>>>>>         if (!pipe->sspp->ops.setup_solidfill)
>>>>>                 return 0;
>>>>> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
>>>>>
>>>>>         /* update sspp */
>>>>>         _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
>>>>> +
>>>>> +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
>>>>>     }
>>>>
>>>> So cant we do
>>>>
>>>> if (pstate->r_pipe.sspp)
>>>>           _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
>>>>                   &pstate->r_pipe_cfg, fill_color, fmt);
>>>>
>>>> It just seems better to me as the caller would already know if the sspp
>>>> was assigned.
>>>
>>>    I think I had this kind of code earlier, but then I found it more
>>> logical to move the check to the called function. I'll move it back.
>>>
>>>>
>>>>>
>>>>>     int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
>>>>> @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>>>     {
>>>>>         uint32_t min_src_size;
>>>>>
>>>>> +     if (!pipe->sspp)
>>>>> +             return 0;
>>>>> +
>>>>>         min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>>>>
>>>>>         if (DPU_FORMAT_IS_YUV(fmt) &&
>>>>> @@ -957,9 +968,12 @@ 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;
>>>>> +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>>>         struct drm_rect fb_rect = { 0 };
>>>>>         uint32_t max_linewidth;
>>>>>         unsigned int rotation;
>>>>> @@ -983,8 +997,11 @@ 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;
>>>>> +     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) {
>>>>> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>>>
>>>>>         max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>>>
>>>>> -     /* check decimated source width */
>>>>>         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;
>>>>> +             /* 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;
>>>>> +             }
>>>>
>>>> This is where I am a bit concerned enabling it for all chipsets in one go.
>>>
>>> As I wrote earlier, I'd prefer the opt-out rather than opt-in here. It
>>> is much easier to handle the reports "I have a device with sm6543,
>>> where the display worked before 6.4, but started failing afterwards"
>>> rather than trying to find a person with sm6543 and asking him if he
>>> can enable this and that on his device. And even a lower chance of a
>>> person with sm6543 coming up with a patch 'hey, I enabled this for my
>>> phone and it works!'.
>>>
>>> If we find any issues during or close to the end of the development
>>> cycle, we can add a 'don't enable wide plane here' switch and enable
>>> it for failing platforms. But each enablement of this switch should
>>> come with a reason (wide planes not working here because ....). In the
>>> end this switch should be gone and transformed into proper HW
>>> limitation checks.
>>>
>>
>> As it has become clear that with this patch series 4K with UBWC cannot
>> be supported without true virtual planes (with two SSPPs), why do you
>> need to relax this check right now?
> 
> Yes. It enables support for 4k @ linear formats. So my plan for this
> series is to land 4k with all the proper applicable restrictions.
> 
>> You can relax this when you add the support for virtual planes till then
>> let it be this way.
>>
>> Its not going to break smartDMA as such. You can still use it for layers
>> < 2560.
>>
>> That way we stay true to the purpose of the feature. I think originally
>> you wanted to get this in for smartDMA and not to support wide plane and
>> that purpose will still be achieved even with keeping this check intact.
> 
> Actually, no. With this series I wanted to get 4k. It was developed in
> parallel with the 4k enablement for RB3 (posted, bridge patches are
> being merged for 6.3) and RB5 (delayed for now, I have other issues
> there).
> 

With the UBWC related checks, this wont support 4K for UBWC layers which 
is default on QC chipsets. So I am fine with respect to that. But still 
this does not address the product spec advertized modes. Like I 
mentioned before, relaxing the maxlinewidth check with the added UBWC 
checks is fine from DPU point of view but not from the product POV.

As things stand today, this is the only check failing the 4K modes on 
chipsets which shouldnt support 4k (linear or UBWC doesnt matter).

>> You can relax it in the virtual plane series.
>>
>> Regarding issues, this is where it gets tricky. We should be aligning
>> with what the product supports. QC will not support issues arising with
>> 4K on chipsets on which 4K is not advertized.
> 
> So, we have several different items here:
> - SmartDMA v2 per se, supporting two rectangles per VIG or DMA plane,
> - Source split support,
> - Supporting 4k modes.
> 
> I think we should tend them one by one. This series concerns SmartDMA
> v2. Using SmartDMA it is possible to use two rectangles side by side
> to emulate a wide plane. This series doesn't care at all about max
> resolutions. These two items are completely orthogonal.
> 

No its not orthogonal. Relaxing the maxlinewidth check in the 
atomic_check() will allow 4K layers now even on chipsets where 4K wasnt 
advertized. Linear or UBWC doesnt matter as the spec doesnt go into that.

>>>> As you are aware,  we have an open bug today that we do not filter out
>>>> the modes which we do not support.
>>>>
>>>> https://gitlab.freedesktop.org/drm/msm/-/issues/21
>>>
>>> I thought that with the link-frequencies in place and with the DSI
>>> checking the OPP tables this issue is mostly handled. Isn't it?
>>> Is a mode check in the DPU driver itself the last missing piece?
>>>
>>
>> opp based checking was implemented only for DSI. That one is byte clk based.
>>
>> DP uses link rate for opp table.
>>
>> Even with a 5.4G link rate (the one in sc7180 chromebook) 4k@30 would
>> still be possible but it was not advertized
>>
>> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>>
>> These docs are available in public domain.
>>
>> As we synced up last time on
>> https://patchwork.freedesktop.org/series/107917/, even with these limits
>> in place, its not matching the advertized limits.
>>
>>>>
>>>> Due to this, on all chipsets we will end up trying to do a 4K on
>>>> external display which we dont know what bugs it will expose.
>>>
>>> If we do not expose bugs, we do not have a way to fix them. And I
>>> definitely think that all the bugs should be listed as early as
>>> possible, while both of us still remember the code under the question.
>>>
>>
>> Yes but on chipsets where 4K is supported ( and hence needed ).
> 
> 4k, SmartDMA, src-split, split-display, etc.
> 

The visual issues reported on sdm845 on the other thread are a classic 
example of what I just wrote on that patchset and thats why I was 
emphasizing a visual validation OR in other words enable the feature on 
which you are able to visually validate it.

We can evaluate and enable smartDMA on other chipsets on a need basis.

We discussed this again even today in the team discussion. Our team's 
PoV doesnt change. We would still like to enable smartDMA only on 
chipsets which can be visually validated first to limit the debugging 
effort to one chipset first and then perfect it. Otherwise its too much 
effort on QC side to debug those issues on all chipsets.


> 
>>
>>>>
>>>> So lets say if we test it on sc7280 fully but not on sc7180, we will
>>>> still hit this condition on sc7180 too but on that chipset we did not
>>>> advertise 4K as a capability in the product spec.
>>>
>>> Is it 'not advertised' or 'not supported by hw'?
>>>
>>
>> The document
>> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>> is made from inputs from not just display team but overall system
>> limits. So even though you could argue that this falls within the
>> display capabilities, all I can say at the moment is we have to stick to
>> the advertized limits as its compiled with inputs from all the teams
>> (system/performance etc).
> 
> So, there should be a limiting factor (or a combination of them).
> Filter out 4k modes on sc7180. Or modes using fill rate higher than N.
> Pixel clock rate higher than M. But it has nothing to do with these
> patches enabling SmartDMA support on this platform.
> 
> Even if we look at the vendor kernels, we don't see 'maximum external
> resolution'. Instead I see a combination of linewidth and bandwidth
> limitations. If we can stick to that, that would be great.
> 

Can you please point me to bandwidth limitation checks? How are other 
vendors coming up with this number? It has to be based on some 
resolution too right?

My RFC https://patchwork.freedesktop.org/series/107917/ considered pixel 
clk as the limiting factor which was posted after discussions 
internally. In the absence of another way, that remains the only 
solution to tackle this.

>>
>>>>
>>>> With the max_linewidth check relaxed nothing prevents us from doing 4K
>>>> on a chipset which doesnt support 4K.
>>>
>>> What prevents sc7180 from supporting 4k? Does it support Smart DMA?
>>> Does it support having two LMs per INTF/CRTC? Is there a limitation on
>>> the linewidth of two LMs or two SSPPs?
>>>
>>> I see that sm7125 (which has the same DPU revision) even contains
>>> "qcom,sde-vig-sspp-linewidth = <4096>;" in the DTS, despite official
>>> 'product brief' advertising only 2520x1080 output resolution.
>>>
>>
>> My previous response should have answered this.
> 
> Up to some point, thanks.
> 
>>
>>>>
>>>>> +
>>>>> +             /*
>>>>> +              * FIXME: it's not possible to check if sourcesplit is supported,
>>>>> +              * LMs is not assigned yet. It happens in dpu_encoder_virt_mode_set
>>>>> +              */
>>>>> +             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;
>>>>>         }
>>>>>
>>>>
>>>> As you requested just wanted to summarize the condition in the email.
>>>>
>>>> In parallel fetch mode, the downstream driver for UBWC formats, we check
>>>> whether the src width of each rectangle is > maxlinewidth/2
>>>>
>>>> https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/DISPLAY.LA.2.0.r3-00500-WAIPIO.0/msm/sde/sde_plane.c#L1835
>>>
>>> Thanks. Please double check my understanding: If the rectangle is used
>>> for the tiled format, then it's max_linewidth is effectively halved.
>>> So we can use rect_solo with full width, but for rect_0/rect_1 we
>>> should halve it, even if two rectangles are used in the time split?
>>>
>>
>> Not in time split mode. Only in parallel fetch mode which is being used
>> here. Rest of your understanding is correct.
> 
> Ack, thanks for the correction. This is important for plane checks.
> 
>>
>>>>
>>>> For sc7280, maxlinewidth is 2400
>>>>
>>>> static const struct dpu_caps sc7280_dpu_caps = {
>>>>            .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>>>>            .max_mixer_blendstages = 0x7,
>>>>            .qseed_type = DPU_SSPP_SCALER_QSEED4,
>>>>            .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
>>>>            .ubwc_version = DPU_HW_UBWC_VER_30,
>>>>            .has_dim_layer = true,
>>>>            .has_idle_pc = true,
>>>>            .max_linewidth = 2400,
>>>>            .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
>>>> };
>>>>
>>>> Hence for UBWC formats which are by default used on the sc7280
>>>> chromebook, each rectangle should be < 1200
>>>>
>>>> SmartDMA is therefore not enough to support 4K on sc7280 and we need
>>>> true virtual planes ( using two SSPPs to display the 4K layer )
>>>>
>>>> Also, probably worth commenting that time multiplex mode support is not
>>>> added in this series.
>>>
>>> Ack.
>>>
>>>>
>>>>>         fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>>>>
>>>>> -     ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
>>>>> +     ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
>>>>> +     if (ret)
>>>>> +             return ret;
>>>>> +
>>>>> +     ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
>>>>>         if (ret)
>>>>>                 return ret;
>>>>>
>>>>> @@ -1094,8 +1148,10 @@ 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
>>>>> +     else {
>>>>>                 dpu_plane_flush_csc(pdpu, &pstate->pipe);
>>>>> +             dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
>>>>> +     }
>>>>>
>>>>>         /* flag h/w flush complete */
>>>>>         if (plane->state)
>>>>> @@ -1130,6 +1186,9 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
>>>>>         struct drm_plane_state *state = plane->state;
>>>>>         struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>>>>
>>>>> +     if (!pipe->sspp)
>>>>> +             return;
>>>>> +
>>>>>         if (layout && pipe->sspp->ops.setup_sourceaddress) {
>>>>>                 trace_dpu_plane_set_scanout(pipe, layout);
>>>>>                 pipe->sspp->ops.setup_sourceaddress(pipe, layout);
>>>>> @@ -1207,13 +1266,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>> -
>>>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>>>         struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>>>>>         struct msm_gem_address_space *aspace = kms->base.aspace;
>>>>>         struct dpu_hw_fmt_layout layout;
>>>>> @@ -1241,12 +1301,22 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>>>                                    drm_mode_vrefresh(&crtc->mode),
>>>>>                                    layout_valid ? &layout: NULL);
>>>>>
>>>>> +     dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
>>>>> +                                drm_mode_vrefresh(&crtc->mode),
>>>>> +                                layout_valid ? &layout: NULL);
>>>>> +
>>>>>         if (pstate->needs_qos_remap)
>>>>>                 pstate->needs_qos_remap = false;
>>>>>
>>>>>         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) {
>>>>> +             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)
>>>>> @@ -1289,6 +1359,8 @@ 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);
>>>>>
>>>>> +             _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 */
>>>>> @@ -1369,11 +1441,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>> +     const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
>>>>> +     const struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_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));
>>>>> +
>>>>> +     if (r_pipe->sspp) {
>>>>> +             drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
>>>>> +             drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(r_pipe->multirect_mode));
>>>>> +             drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(r_pipe->multirect_index));
>>>>> +             drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
>>>>> +             drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
>>>>> +     }
>>>>>     }
>>>>
>>>> Do you think that changing the atomic_print_state to print the r_pipe
>>>> sspp can be moved to a separate patch? So that way we only keep the core
>>>> logic of atomic check of smartDMA in this patch.
>>>>
>>>>>
>>>>>     static void dpu_plane_reset(struct drm_plane *plane)
>>>>> @@ -1407,6 +1494,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
>>>>>          * This is the place where the state is allocated, so fill it fully.
>>>>>          */
>>>>>         pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
>>>>> +     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);
>>>>>     }
>>>>> @@ -1423,6 +1514,7 @@ 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);
>>>>> +     _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 079dad83eb37..183c95949885 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>>> @@ -19,7 +19,9 @@
>>>>>      * @base:   base drm plane state object
>>>>>      * @aspace: pointer to address space for input/output buffers
>>>>>      * @pipe:   software pipe description
>>>>> + * @r_pipe:  software pipe description of the second pipe
>>>>>      * @pipe_cfg:       software pipe configuration
>>>>> + * @r_pipe_cfg:      software pipe configuration for the second pipe
>>>>>      * @stage:  assigned by crtc blender
>>>>>      * @needs_qos_remap: qos remap settings need to be updated
>>>>>      * @multirect_index: index of the rectangle of SSPP
>>>>> @@ -34,7 +36,9 @@ struct dpu_plane_state {
>>>>>         struct drm_plane_state base;
>>>>>         struct msm_gem_address_space *aspace;
>>>>>         struct dpu_sw_pipe pipe;
>>>>> +     struct dpu_sw_pipe r_pipe;
>>>>>         struct dpu_hw_sspp_cfg pipe_cfg;
>>>>> +     struct dpu_hw_sspp_cfg r_pipe_cfg;
>>>>>         enum dpu_stage stage;
>>>>>         bool needs_qos_remap;
>>>>>         bool pending;
>>>
>>>
>>>
> 
> 
> 
> --
> With best wishes
> Dmitry

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

* Re: [Freedreno] [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
@ 2023-02-09 22:12             ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-09 22:12 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Kalyan Thota, freedreno, Bjorn Andersson, dri-devel,
	Stephen Boyd, linux-arm-msm, Sean Paul

Hi Dmitry

On 2/9/2023 1:23 PM, Dmitry Baryshkov wrote:
> Hi Abhinav,
> 
> On Thu, 9 Feb 2023 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>>
>>
>> On 2/9/2023 3:45 AM, Dmitry Baryshkov wrote:
>>> On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>> Typically SSPP can support rectangle with width up to 2560. However it's
>>>>
>>>> Not always 2560. Depends on the chipset.
>>>
>>> _typically_
>>>
>>
>> Would just say maxlinewidth of SSPP instead of giving some hardcoded number.
> 
> Ack.
> 
>>
>>>>
>>>>> 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  |   6 ++
>>>>>     drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
>>>>>     drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
>>>>>     3 files changed, 114 insertions(+), 12 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> index 0ca3bc38ff7e..867832a752b2 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>>>>>                                            fetch_active,
>>>>>                                            &pstate->pipe);
>>>>>
>>>>> +             _dpu_crtc_blend_setup_pipe(crtc, plane,
>>>>> +                                        mixer, cstate->num_mixers,
>>>>> +                                        stage_cfg, pstate->stage, 1,
>>>>> +                                        fetch_active,
>>>>> +                                        &pstate->r_pipe);
>>>>> +
>>>>>                 /* blend config update */
>>>>>                 for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
>>>>>                         _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> index e2e85688ed3c..401ead64c6bd 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>>>>>         struct dpu_plane *pdpu = to_dpu_plane(plane);
>>>>>         struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>>>>>
>>>>> +     if (!pipe->sspp)
>>>>> +             return;
>>>>> +
>>>>>         memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>>>>
>>>>>         if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>>>>> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>>>>>     {
>>>>>         struct dpu_hw_sspp_cfg pipe_cfg;
>>>>>
>>>>> +     if (!pipe->sspp)
>>>>> +             return 0;
>>>>
>>>> instead of checking if sspp was present, is it not better for the caller
>>>> to check if the rpipe is valid before calling this?
>>>>
>>>>> +
>>>>>         /* update sspp */
>>>>>         if (!pipe->sspp->ops.setup_solidfill)
>>>>>                 return 0;
>>>>> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
>>>>>
>>>>>         /* update sspp */
>>>>>         _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
>>>>> +
>>>>> +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
>>>>>     }
>>>>
>>>> So cant we do
>>>>
>>>> if (pstate->r_pipe.sspp)
>>>>           _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
>>>>                   &pstate->r_pipe_cfg, fill_color, fmt);
>>>>
>>>> It just seems better to me as the caller would already know if the sspp
>>>> was assigned.
>>>
>>>    I think I had this kind of code earlier, but then I found it more
>>> logical to move the check to the called function. I'll move it back.
>>>
>>>>
>>>>>
>>>>>     int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
>>>>> @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>>>     {
>>>>>         uint32_t min_src_size;
>>>>>
>>>>> +     if (!pipe->sspp)
>>>>> +             return 0;
>>>>> +
>>>>>         min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>>>>
>>>>>         if (DPU_FORMAT_IS_YUV(fmt) &&
>>>>> @@ -957,9 +968,12 @@ 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;
>>>>> +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>>>         struct drm_rect fb_rect = { 0 };
>>>>>         uint32_t max_linewidth;
>>>>>         unsigned int rotation;
>>>>> @@ -983,8 +997,11 @@ 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;
>>>>> +     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) {
>>>>> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>>>
>>>>>         max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>>>
>>>>> -     /* check decimated source width */
>>>>>         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;
>>>>> +             /* 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;
>>>>> +             }
>>>>
>>>> This is where I am a bit concerned enabling it for all chipsets in one go.
>>>
>>> As I wrote earlier, I'd prefer the opt-out rather than opt-in here. It
>>> is much easier to handle the reports "I have a device with sm6543,
>>> where the display worked before 6.4, but started failing afterwards"
>>> rather than trying to find a person with sm6543 and asking him if he
>>> can enable this and that on his device. And even a lower chance of a
>>> person with sm6543 coming up with a patch 'hey, I enabled this for my
>>> phone and it works!'.
>>>
>>> If we find any issues during or close to the end of the development
>>> cycle, we can add a 'don't enable wide plane here' switch and enable
>>> it for failing platforms. But each enablement of this switch should
>>> come with a reason (wide planes not working here because ....). In the
>>> end this switch should be gone and transformed into proper HW
>>> limitation checks.
>>>
>>
>> As it has become clear that with this patch series 4K with UBWC cannot
>> be supported without true virtual planes (with two SSPPs), why do you
>> need to relax this check right now?
> 
> Yes. It enables support for 4k @ linear formats. So my plan for this
> series is to land 4k with all the proper applicable restrictions.
> 
>> You can relax this when you add the support for virtual planes till then
>> let it be this way.
>>
>> Its not going to break smartDMA as such. You can still use it for layers
>> < 2560.
>>
>> That way we stay true to the purpose of the feature. I think originally
>> you wanted to get this in for smartDMA and not to support wide plane and
>> that purpose will still be achieved even with keeping this check intact.
> 
> Actually, no. With this series I wanted to get 4k. It was developed in
> parallel with the 4k enablement for RB3 (posted, bridge patches are
> being merged for 6.3) and RB5 (delayed for now, I have other issues
> there).
> 

With the UBWC related checks, this wont support 4K for UBWC layers which 
is default on QC chipsets. So I am fine with respect to that. But still 
this does not address the product spec advertized modes. Like I 
mentioned before, relaxing the maxlinewidth check with the added UBWC 
checks is fine from DPU point of view but not from the product POV.

As things stand today, this is the only check failing the 4K modes on 
chipsets which shouldnt support 4k (linear or UBWC doesnt matter).

>> You can relax it in the virtual plane series.
>>
>> Regarding issues, this is where it gets tricky. We should be aligning
>> with what the product supports. QC will not support issues arising with
>> 4K on chipsets on which 4K is not advertized.
> 
> So, we have several different items here:
> - SmartDMA v2 per se, supporting two rectangles per VIG or DMA plane,
> - Source split support,
> - Supporting 4k modes.
> 
> I think we should tend them one by one. This series concerns SmartDMA
> v2. Using SmartDMA it is possible to use two rectangles side by side
> to emulate a wide plane. This series doesn't care at all about max
> resolutions. These two items are completely orthogonal.
> 

No its not orthogonal. Relaxing the maxlinewidth check in the 
atomic_check() will allow 4K layers now even on chipsets where 4K wasnt 
advertized. Linear or UBWC doesnt matter as the spec doesnt go into that.

>>>> As you are aware,  we have an open bug today that we do not filter out
>>>> the modes which we do not support.
>>>>
>>>> https://gitlab.freedesktop.org/drm/msm/-/issues/21
>>>
>>> I thought that with the link-frequencies in place and with the DSI
>>> checking the OPP tables this issue is mostly handled. Isn't it?
>>> Is a mode check in the DPU driver itself the last missing piece?
>>>
>>
>> opp based checking was implemented only for DSI. That one is byte clk based.
>>
>> DP uses link rate for opp table.
>>
>> Even with a 5.4G link rate (the one in sc7180 chromebook) 4k@30 would
>> still be possible but it was not advertized
>>
>> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>>
>> These docs are available in public domain.
>>
>> As we synced up last time on
>> https://patchwork.freedesktop.org/series/107917/, even with these limits
>> in place, its not matching the advertized limits.
>>
>>>>
>>>> Due to this, on all chipsets we will end up trying to do a 4K on
>>>> external display which we dont know what bugs it will expose.
>>>
>>> If we do not expose bugs, we do not have a way to fix them. And I
>>> definitely think that all the bugs should be listed as early as
>>> possible, while both of us still remember the code under the question.
>>>
>>
>> Yes but on chipsets where 4K is supported ( and hence needed ).
> 
> 4k, SmartDMA, src-split, split-display, etc.
> 

The visual issues reported on sdm845 on the other thread are a classic 
example of what I just wrote on that patchset and thats why I was 
emphasizing a visual validation OR in other words enable the feature on 
which you are able to visually validate it.

We can evaluate and enable smartDMA on other chipsets on a need basis.

We discussed this again even today in the team discussion. Our team's 
PoV doesnt change. We would still like to enable smartDMA only on 
chipsets which can be visually validated first to limit the debugging 
effort to one chipset first and then perfect it. Otherwise its too much 
effort on QC side to debug those issues on all chipsets.


> 
>>
>>>>
>>>> So lets say if we test it on sc7280 fully but not on sc7180, we will
>>>> still hit this condition on sc7180 too but on that chipset we did not
>>>> advertise 4K as a capability in the product spec.
>>>
>>> Is it 'not advertised' or 'not supported by hw'?
>>>
>>
>> The document
>> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>> is made from inputs from not just display team but overall system
>> limits. So even though you could argue that this falls within the
>> display capabilities, all I can say at the moment is we have to stick to
>> the advertized limits as its compiled with inputs from all the teams
>> (system/performance etc).
> 
> So, there should be a limiting factor (or a combination of them).
> Filter out 4k modes on sc7180. Or modes using fill rate higher than N.
> Pixel clock rate higher than M. But it has nothing to do with these
> patches enabling SmartDMA support on this platform.
> 
> Even if we look at the vendor kernels, we don't see 'maximum external
> resolution'. Instead I see a combination of linewidth and bandwidth
> limitations. If we can stick to that, that would be great.
> 

Can you please point me to bandwidth limitation checks? How are other 
vendors coming up with this number? It has to be based on some 
resolution too right?

My RFC https://patchwork.freedesktop.org/series/107917/ considered pixel 
clk as the limiting factor which was posted after discussions 
internally. In the absence of another way, that remains the only 
solution to tackle this.

>>
>>>>
>>>> With the max_linewidth check relaxed nothing prevents us from doing 4K
>>>> on a chipset which doesnt support 4K.
>>>
>>> What prevents sc7180 from supporting 4k? Does it support Smart DMA?
>>> Does it support having two LMs per INTF/CRTC? Is there a limitation on
>>> the linewidth of two LMs or two SSPPs?
>>>
>>> I see that sm7125 (which has the same DPU revision) even contains
>>> "qcom,sde-vig-sspp-linewidth = <4096>;" in the DTS, despite official
>>> 'product brief' advertising only 2520x1080 output resolution.
>>>
>>
>> My previous response should have answered this.
> 
> Up to some point, thanks.
> 
>>
>>>>
>>>>> +
>>>>> +             /*
>>>>> +              * FIXME: it's not possible to check if sourcesplit is supported,
>>>>> +              * LMs is not assigned yet. It happens in dpu_encoder_virt_mode_set
>>>>> +              */
>>>>> +             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;
>>>>>         }
>>>>>
>>>>
>>>> As you requested just wanted to summarize the condition in the email.
>>>>
>>>> In parallel fetch mode, the downstream driver for UBWC formats, we check
>>>> whether the src width of each rectangle is > maxlinewidth/2
>>>>
>>>> https://git.codelinaro.org/clo/la/platform/vendor/opensource/display-drivers/-/blob/DISPLAY.LA.2.0.r3-00500-WAIPIO.0/msm/sde/sde_plane.c#L1835
>>>
>>> Thanks. Please double check my understanding: If the rectangle is used
>>> for the tiled format, then it's max_linewidth is effectively halved.
>>> So we can use rect_solo with full width, but for rect_0/rect_1 we
>>> should halve it, even if two rectangles are used in the time split?
>>>
>>
>> Not in time split mode. Only in parallel fetch mode which is being used
>> here. Rest of your understanding is correct.
> 
> Ack, thanks for the correction. This is important for plane checks.
> 
>>
>>>>
>>>> For sc7280, maxlinewidth is 2400
>>>>
>>>> static const struct dpu_caps sc7280_dpu_caps = {
>>>>            .max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>>>>            .max_mixer_blendstages = 0x7,
>>>>            .qseed_type = DPU_SSPP_SCALER_QSEED4,
>>>>            .smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
>>>>            .ubwc_version = DPU_HW_UBWC_VER_30,
>>>>            .has_dim_layer = true,
>>>>            .has_idle_pc = true,
>>>>            .max_linewidth = 2400,
>>>>            .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
>>>> };
>>>>
>>>> Hence for UBWC formats which are by default used on the sc7280
>>>> chromebook, each rectangle should be < 1200
>>>>
>>>> SmartDMA is therefore not enough to support 4K on sc7280 and we need
>>>> true virtual planes ( using two SSPPs to display the 4K layer )
>>>>
>>>> Also, probably worth commenting that time multiplex mode support is not
>>>> added in this series.
>>>
>>> Ack.
>>>
>>>>
>>>>>         fmt = to_dpu_format(msm_framebuffer_format(new_plane_state->fb));
>>>>>
>>>>> -     ret = dpu_plane_atomic_check_pipe(pdpu, &pstate->pipe, pipe_cfg, fmt);
>>>>> +     ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt);
>>>>> +     if (ret)
>>>>> +             return ret;
>>>>> +
>>>>> +     ret = dpu_plane_atomic_check_pipe(pdpu, r_pipe, r_pipe_cfg, fmt);
>>>>>         if (ret)
>>>>>                 return ret;
>>>>>
>>>>> @@ -1094,8 +1148,10 @@ 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
>>>>> +     else {
>>>>>                 dpu_plane_flush_csc(pdpu, &pstate->pipe);
>>>>> +             dpu_plane_flush_csc(pdpu, &pstate->r_pipe);
>>>>> +     }
>>>>>
>>>>>         /* flag h/w flush complete */
>>>>>         if (plane->state)
>>>>> @@ -1130,6 +1186,9 @@ static void dpu_plane_sspp_update_pipe(struct drm_plane *plane,
>>>>>         struct drm_plane_state *state = plane->state;
>>>>>         struct dpu_plane_state *pstate = to_dpu_plane_state(state);
>>>>>
>>>>> +     if (!pipe->sspp)
>>>>> +             return;
>>>>> +
>>>>>         if (layout && pipe->sspp->ops.setup_sourceaddress) {
>>>>>                 trace_dpu_plane_set_scanout(pipe, layout);
>>>>>                 pipe->sspp->ops.setup_sourceaddress(pipe, layout);
>>>>> @@ -1207,13 +1266,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>> -
>>>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>>>         struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base);
>>>>>         struct msm_gem_address_space *aspace = kms->base.aspace;
>>>>>         struct dpu_hw_fmt_layout layout;
>>>>> @@ -1241,12 +1301,22 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
>>>>>                                    drm_mode_vrefresh(&crtc->mode),
>>>>>                                    layout_valid ? &layout: NULL);
>>>>>
>>>>> +     dpu_plane_sspp_update_pipe(plane, r_pipe, r_pipe_cfg, fmt,
>>>>> +                                drm_mode_vrefresh(&crtc->mode),
>>>>> +                                layout_valid ? &layout: NULL);
>>>>> +
>>>>>         if (pstate->needs_qos_remap)
>>>>>                 pstate->needs_qos_remap = false;
>>>>>
>>>>>         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) {
>>>>> +             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)
>>>>> @@ -1289,6 +1359,8 @@ 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);
>>>>>
>>>>> +             _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 */
>>>>> @@ -1369,11 +1441,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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>> +     const struct dpu_sw_pipe *r_pipe = &pstate->r_pipe;
>>>>> +     const struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_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));
>>>>> +
>>>>> +     if (r_pipe->sspp) {
>>>>> +             drm_printf(p, "\tsspp[1]=%s\n", r_pipe->sspp->cap->name);
>>>>> +             drm_printf(p, "\tmultirect_mode[1]=%s\n", dpu_get_multirect_mode(r_pipe->multirect_mode));
>>>>> +             drm_printf(p, "\tmultirect_index[1]=%s\n", dpu_get_multirect_index(r_pipe->multirect_index));
>>>>> +             drm_printf(p, "\tsrc[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->src_rect));
>>>>> +             drm_printf(p, "\tdst[1]=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&r_pipe_cfg->dst_rect));
>>>>> +     }
>>>>>     }
>>>>
>>>> Do you think that changing the atomic_print_state to print the r_pipe
>>>> sspp can be moved to a separate patch? So that way we only keep the core
>>>> logic of atomic check of smartDMA in this patch.
>>>>
>>>>>
>>>>>     static void dpu_plane_reset(struct drm_plane *plane)
>>>>> @@ -1407,6 +1494,10 @@ static void dpu_plane_reset(struct drm_plane *plane)
>>>>>          * This is the place where the state is allocated, so fill it fully.
>>>>>          */
>>>>>         pstate->pipe.sspp = dpu_rm_get_sspp(&dpu_kms->rm, pdpu->pipe);
>>>>> +     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);
>>>>>     }
>>>>> @@ -1423,6 +1514,7 @@ 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);
>>>>> +     _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 079dad83eb37..183c95949885 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>>> @@ -19,7 +19,9 @@
>>>>>      * @base:   base drm plane state object
>>>>>      * @aspace: pointer to address space for input/output buffers
>>>>>      * @pipe:   software pipe description
>>>>> + * @r_pipe:  software pipe description of the second pipe
>>>>>      * @pipe_cfg:       software pipe configuration
>>>>> + * @r_pipe_cfg:      software pipe configuration for the second pipe
>>>>>      * @stage:  assigned by crtc blender
>>>>>      * @needs_qos_remap: qos remap settings need to be updated
>>>>>      * @multirect_index: index of the rectangle of SSPP
>>>>> @@ -34,7 +36,9 @@ struct dpu_plane_state {
>>>>>         struct drm_plane_state base;
>>>>>         struct msm_gem_address_space *aspace;
>>>>>         struct dpu_sw_pipe pipe;
>>>>> +     struct dpu_sw_pipe r_pipe;
>>>>>         struct dpu_hw_sspp_cfg pipe_cfg;
>>>>> +     struct dpu_hw_sspp_cfg r_pipe_cfg;
>>>>>         enum dpu_stage stage;
>>>>>         bool needs_qos_remap;
>>>>>         bool pending;
>>>
>>>
>>>
> 
> 
> 
> --
> With best wishes
> Dmitry

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

* Re: [Freedreno] [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
  2023-02-09 22:12             ` Abhinav Kumar
@ 2023-02-10  0:09               ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-10  0:09 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Kalyan Thota, freedreno, Bjorn Andersson, dri-devel,
	Stephen Boyd, linux-arm-msm, Sean Paul

 .

On Fri, 10 Feb 2023 at 00:12, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
> Hi Dmitry
>
> On 2/9/2023 1:23 PM, Dmitry Baryshkov wrote:
> > Hi Abhinav,
> >
> > On Thu, 9 Feb 2023 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 2/9/2023 3:45 AM, Dmitry Baryshkov wrote:
> >>> On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> >>>>> Typically SSPP can support rectangle with width up to 2560. However it's
> >>>>
> >>>> Not always 2560. Depends on the chipset.
> >>>
> >>> _typically_
> >>>
> >>
> >> Would just say maxlinewidth of SSPP instead of giving some hardcoded number.
> >
> > Ack.
> >
> >>
> >>>>
> >>>>> 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  |   6 ++
> >>>>>     drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
> >>>>>     drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
> >>>>>     3 files changed, 114 insertions(+), 12 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >>>>> index 0ca3bc38ff7e..867832a752b2 100644
> >>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >>>>> @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> >>>>>                                            fetch_active,
> >>>>>                                            &pstate->pipe);
> >>>>>
> >>>>> +             _dpu_crtc_blend_setup_pipe(crtc, plane,
> >>>>> +                                        mixer, cstate->num_mixers,
> >>>>> +                                        stage_cfg, pstate->stage, 1,
> >>>>> +                                        fetch_active,
> >>>>> +                                        &pstate->r_pipe);
> >>>>> +
> >>>>>                 /* blend config update */
> >>>>>                 for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
> >>>>>                         _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
> >>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >>>>> index e2e85688ed3c..401ead64c6bd 100644
> >>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >>>>> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
> >>>>>         struct dpu_plane *pdpu = to_dpu_plane(plane);
> >>>>>         struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
> >>>>>
> >>>>> +     if (!pipe->sspp)
> >>>>> +             return;
> >>>>> +
> >>>>>         memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
> >>>>>
> >>>>>         if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
> >>>>> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
> >>>>>     {
> >>>>>         struct dpu_hw_sspp_cfg pipe_cfg;
> >>>>>
> >>>>> +     if (!pipe->sspp)
> >>>>> +             return 0;
> >>>>
> >>>> instead of checking if sspp was present, is it not better for the caller
> >>>> to check if the rpipe is valid before calling this?
> >>>>
> >>>>> +
> >>>>>         /* update sspp */
> >>>>>         if (!pipe->sspp->ops.setup_solidfill)
> >>>>>                 return 0;
> >>>>> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
> >>>>>
> >>>>>         /* update sspp */
> >>>>>         _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
> >>>>> +
> >>>>> +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
> >>>>>     }
> >>>>
> >>>> So cant we do
> >>>>
> >>>> if (pstate->r_pipe.sspp)
> >>>>           _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
> >>>>                   &pstate->r_pipe_cfg, fill_color, fmt);
> >>>>
> >>>> It just seems better to me as the caller would already know if the sspp
> >>>> was assigned.
> >>>
> >>>    I think I had this kind of code earlier, but then I found it more
> >>> logical to move the check to the called function. I'll move it back.
> >>>
> >>>>
> >>>>>
> >>>>>     int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
> >>>>> @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
> >>>>>     {
> >>>>>         uint32_t min_src_size;
> >>>>>
> >>>>> +     if (!pipe->sspp)
> >>>>> +             return 0;
> >>>>> +
> >>>>>         min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
> >>>>>
> >>>>>         if (DPU_FORMAT_IS_YUV(fmt) &&
> >>>>> @@ -957,9 +968,12 @@ 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;
> >>>>> +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> >>>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> >>>>>         struct drm_rect fb_rect = { 0 };
> >>>>>         uint32_t max_linewidth;
> >>>>>         unsigned int rotation;
> >>>>> @@ -983,8 +997,11 @@ 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;
> >>>>> +     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) {
> >>>>> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> >>>>>
> >>>>>         max_linewidth = pdpu->catalog->caps->max_linewidth;
> >>>>>
> >>>>> -     /* check decimated source width */
> >>>>>         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;
> >>>>> +             /* 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;
> >>>>> +             }
> >>>>
> >>>> This is where I am a bit concerned enabling it for all chipsets in one go.
> >>>
> >>> As I wrote earlier, I'd prefer the opt-out rather than opt-in here. It
> >>> is much easier to handle the reports "I have a device with sm6543,
> >>> where the display worked before 6.4, but started failing afterwards"
> >>> rather than trying to find a person with sm6543 and asking him if he
> >>> can enable this and that on his device. And even a lower chance of a
> >>> person with sm6543 coming up with a patch 'hey, I enabled this for my
> >>> phone and it works!'.
> >>>
> >>> If we find any issues during or close to the end of the development
> >>> cycle, we can add a 'don't enable wide plane here' switch and enable
> >>> it for failing platforms. But each enablement of this switch should
> >>> come with a reason (wide planes not working here because ....). In the
> >>> end this switch should be gone and transformed into proper HW
> >>> limitation checks.
> >>>
> >>
> >> As it has become clear that with this patch series 4K with UBWC cannot
> >> be supported without true virtual planes (with two SSPPs), why do you
> >> need to relax this check right now?
> >
> > Yes. It enables support for 4k @ linear formats. So my plan for this
> > series is to land 4k with all the proper applicable restrictions.
> >
> >> You can relax this when you add the support for virtual planes till then
> >> let it be this way.
> >>
> >> Its not going to break smartDMA as such. You can still use it for layers
> >> < 2560.
> >>
> >> That way we stay true to the purpose of the feature. I think originally
> >> you wanted to get this in for smartDMA and not to support wide plane and
> >> that purpose will still be achieved even with keeping this check intact.
> >
> > Actually, no. With this series I wanted to get 4k. It was developed in
> > parallel with the 4k enablement for RB3 (posted, bridge patches are
> > being merged for 6.3) and RB5 (delayed for now, I have other issues
> > there).
> >
>
> With the UBWC related checks, this wont support 4K for UBWC layers which
> is default on QC chipsets. So I am fine with respect to that. But still
> this does not address the product spec advertized modes. Like I
> mentioned before, relaxing the maxlinewidth check with the added UBWC
> checks is fine from DPU point of view but not from the product POV.
>
> As things stand today, this is the only check failing the 4K modes on
> chipsets which shouldnt support 4k (linear or UBWC doesnt matter).
>
> >> You can relax it in the virtual plane series.
> >>
> >> Regarding issues, this is where it gets tricky. We should be aligning
> >> with what the product supports. QC will not support issues arising with
> >> 4K on chipsets on which 4K is not advertized.
> >
> > So, we have several different items here:
> > - SmartDMA v2 per se, supporting two rectangles per VIG or DMA plane,
> > - Source split support,
> > - Supporting 4k modes.
> >
> > I think we should tend them one by one. This series concerns SmartDMA
> > v2. Using SmartDMA it is possible to use two rectangles side by side
> > to emulate a wide plane. This series doesn't care at all about max
> > resolutions. These two items are completely orthogonal.
> >
>
> No its not orthogonal. Relaxing the maxlinewidth check in the
> atomic_check() will allow 4K layers now even on chipsets where 4K wasnt
> advertized. Linear or UBWC doesnt matter as the spec doesnt go into that.

Please correct my answers, if I got something wrong here:

Does sc7180 support SmartDMA? Yes it does.
Can QC or CrOS validate SmartDMA separately on sc7180? I hope you can.
Should the hw-supported feature be enabled? Yes, it should.

Now limiting out 4k by not supporting SmartDMA looks like a misfeature.
I can only suggest sending a change to block 4k on sc7180.

> >>>> As you are aware,  we have an open bug today that we do not filter out
> >>>> the modes which we do not support.
> >>>>
> >>>> https://gitlab.freedesktop.org/drm/msm/-/issues/21
> >>>
> >>> I thought that with the link-frequencies in place and with the DSI
> >>> checking the OPP tables this issue is mostly handled. Isn't it?
> >>> Is a mode check in the DPU driver itself the last missing piece?
> >>>
> >>
> >> opp based checking was implemented only for DSI. That one is byte clk based.
> >>
> >> DP uses link rate for opp table.
> >>
> >> Even with a 5.4G link rate (the one in sc7180 chromebook) 4k@30 would
> >> still be possible but it was not advertized
> >>
> >> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
> >>
> >> These docs are available in public domain.
> >>
> >> As we synced up last time on
> >> https://patchwork.freedesktop.org/series/107917/, even with these limits
> >> in place, its not matching the advertized limits.
> >>
> >>>>
> >>>> Due to this, on all chipsets we will end up trying to do a 4K on
> >>>> external display which we dont know what bugs it will expose.
> >>>
> >>> If we do not expose bugs, we do not have a way to fix them. And I
> >>> definitely think that all the bugs should be listed as early as
> >>> possible, while both of us still remember the code under the question.
> >>>
> >>
> >> Yes but on chipsets where 4K is supported ( and hence needed ).
> >
> > 4k, SmartDMA, src-split, split-display, etc.
> >
>
> The visual issues reported on sdm845 on the other thread are a classic
> example of what I just wrote on that patchset and thats why I was
> emphasizing a visual validation OR in other words enable the feature on
> which you are able to visually validate it.

Yes. And if we did not enable the feature, Amit would not be able to
spot that. I can repeat my suggestion:

- prevalidate these features for the accessible platforms (e.g. I only
have sdm845, sm8250 and sm8350 at hand)
- enable SmartDMA for all chipsets where SmartDMA is supported
- collect possible tested-by and broken-at reports, while the patches
sit in linux-next
- disable SmartDMA basing on the feedback from the previous step (e.g.
select from 'mostly disable', 'disable for the bugged cases', 'do not
disable at all', etc).
  I can promise that if we see a significant validation failure rate I
will not oppose disabling SmartDMA.

As a reminder: if the patchset is ready at the time of 6.3-rc1 (in
three weeks from now), it is going to be merged into linux-next first,
after that it can go into the main Linus'es tree at 6.4-rc1. So we
will have _two_ kernel cycles to collect bug reports and to disable
(or fix) broken cases.

> We can evaluate and enable smartDMA on other chipsets on a need basis.
>
> We discussed this again even today in the team discussion. Our team's
> PoV doesnt change. We would still like to enable smartDMA only on
> chipsets which can be visually validated first to limit the debugging
> effort to one chipset first and then perfect it. Otherwise its too much
> effort on QC side to debug those issues on all chipsets.

I think QC mostly debugs issues on sc7180/sc7280 and sometimes on
sdm845/sm8250 (and now on sm8350). I think we can let people
(somainline, PmOS) test features on other platforms.
And testing happens better if we can say 'please test linux-next'
rather than 'please test linux-next + this patch to enable the feature
+ that patch to enable the second patch of the feature'.

> >>>> So lets say if we test it on sc7280 fully but not on sc7180, we will
> >>>> still hit this condition on sc7180 too but on that chipset we did not
> >>>> advertise 4K as a capability in the product spec.
> >>>
> >>> Is it 'not advertised' or 'not supported by hw'?
> >>>
> >>
> >> The document
> >> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
> >> is made from inputs from not just display team but overall system
> >> limits. So even though you could argue that this falls within the
> >> display capabilities, all I can say at the moment is we have to stick to
> >> the advertized limits as its compiled with inputs from all the teams
> >> (system/performance etc).
> >
> > So, there should be a limiting factor (or a combination of them).
> > Filter out 4k modes on sc7180. Or modes using fill rate higher than N.
> > Pixel clock rate higher than M. But it has nothing to do with these
> > patches enabling SmartDMA support on this platform.
> >
> > Even if we look at the vendor kernels, we don't see 'maximum external
> > resolution'. Instead I see a combination of linewidth and bandwidth
> > limitations. If we can stick to that, that would be great.
> >
>
> Can you please point me to bandwidth limitation checks? How are other
> vendors coming up with this number? It has to be based on some
> resolution too right?

Usually it is considered in the other direction. The SoC can support
this-and-that pixel clock and bandwidth, so put the NxM resolution to
the datasheet as the max supported one.

Can you point out how the vendor kernel limits DP modes? I checked out
several dtsi files. For sm8250 the DP is limited to 1920x1080 (while
PB explicitly mentions 4k@60).
sm7125 is limited to 2560x1600. sm6150 again 1920x1080. From the pile
of the DTS that I have here the rest lists only
qcom,max-pclk-frequency-khz

> My RFC https://patchwork.freedesktop.org/series/107917/ considered pixel
> clk as the limiting factor which was posted after discussions
> internally. In the absence of another way, that remains the only
> solution to tackle this.

If I remember correctly the mentioned patchset used manually crafted
pixel clocks. And for example for sm8250 this clock doesn't correspond
to verifiable source.
Your patchset used 594000 KHz as max ext pclk for sm8250. vendor dtsi
lists 187500 KHz as maximum DP pclk for RB5 and 150000 KHz in all
other cases. And, at the same time, it lists a 3840x2160@60 mode for
the DSI/lt9611uxc with the pixel clock as high as 608040 KHz.

I suggest we stop the discussion at this point, unless there is
anything else wrong with this patchset itself.

I noted the point regarding UBWC & parallel mode. I will handle it in
the next iteration.

I noted your valid point about the visual verification. I proposed a
way to ease validation, allowing it to be enabled for testers and
early adopters for nearly two cycles. I hope you'd agree to this plan.
I on the other side agree to revert to opt-in if the failure rate is
high.

Please stop bringing max resolution issues to this patchserie. It must
be handled separately. I hope to see the mode filter patch targeting
sc7180 & sc7280. With the DSI opp check in place I think we should
concentrate on the DP case. If nothing else, I think even adding the
max PCLK to the msm_dp_desc should be sufficient to your worries. I'd
prefer to be able to override it for the particular board, but I think
this can come later, as it would require an agreement from the DT
schema team.

--
With best wishes
Dmitry

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

* Re: [Freedreno] [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
@ 2023-02-10  0:09               ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-10  0:09 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Kalyan Thota, freedreno, Sean Paul, Bjorn Andersson, dri-devel,
	Stephen Boyd, Rob Clark, Daniel Vetter, linux-arm-msm,
	David Airlie

 .

On Fri, 10 Feb 2023 at 00:12, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>
> Hi Dmitry
>
> On 2/9/2023 1:23 PM, Dmitry Baryshkov wrote:
> > Hi Abhinav,
> >
> > On Thu, 9 Feb 2023 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>
> >>
> >>
> >> On 2/9/2023 3:45 AM, Dmitry Baryshkov wrote:
> >>> On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
> >>>>> Typically SSPP can support rectangle with width up to 2560. However it's
> >>>>
> >>>> Not always 2560. Depends on the chipset.
> >>>
> >>> _typically_
> >>>
> >>
> >> Would just say maxlinewidth of SSPP instead of giving some hardcoded number.
> >
> > Ack.
> >
> >>
> >>>>
> >>>>> 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  |   6 ++
> >>>>>     drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
> >>>>>     drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
> >>>>>     3 files changed, 114 insertions(+), 12 deletions(-)
> >>>>>
> >>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >>>>> index 0ca3bc38ff7e..867832a752b2 100644
> >>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> >>>>> @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
> >>>>>                                            fetch_active,
> >>>>>                                            &pstate->pipe);
> >>>>>
> >>>>> +             _dpu_crtc_blend_setup_pipe(crtc, plane,
> >>>>> +                                        mixer, cstate->num_mixers,
> >>>>> +                                        stage_cfg, pstate->stage, 1,
> >>>>> +                                        fetch_active,
> >>>>> +                                        &pstate->r_pipe);
> >>>>> +
> >>>>>                 /* blend config update */
> >>>>>                 for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
> >>>>>                         _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
> >>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >>>>> index e2e85688ed3c..401ead64c6bd 100644
> >>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >>>>> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
> >>>>>         struct dpu_plane *pdpu = to_dpu_plane(plane);
> >>>>>         struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
> >>>>>
> >>>>> +     if (!pipe->sspp)
> >>>>> +             return;
> >>>>> +
> >>>>>         memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
> >>>>>
> >>>>>         if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
> >>>>> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
> >>>>>     {
> >>>>>         struct dpu_hw_sspp_cfg pipe_cfg;
> >>>>>
> >>>>> +     if (!pipe->sspp)
> >>>>> +             return 0;
> >>>>
> >>>> instead of checking if sspp was present, is it not better for the caller
> >>>> to check if the rpipe is valid before calling this?
> >>>>
> >>>>> +
> >>>>>         /* update sspp */
> >>>>>         if (!pipe->sspp->ops.setup_solidfill)
> >>>>>                 return 0;
> >>>>> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
> >>>>>
> >>>>>         /* update sspp */
> >>>>>         _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
> >>>>> +
> >>>>> +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
> >>>>>     }
> >>>>
> >>>> So cant we do
> >>>>
> >>>> if (pstate->r_pipe.sspp)
> >>>>           _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
> >>>>                   &pstate->r_pipe_cfg, fill_color, fmt);
> >>>>
> >>>> It just seems better to me as the caller would already know if the sspp
> >>>> was assigned.
> >>>
> >>>    I think I had this kind of code earlier, but then I found it more
> >>> logical to move the check to the called function. I'll move it back.
> >>>
> >>>>
> >>>>>
> >>>>>     int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
> >>>>> @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
> >>>>>     {
> >>>>>         uint32_t min_src_size;
> >>>>>
> >>>>> +     if (!pipe->sspp)
> >>>>> +             return 0;
> >>>>> +
> >>>>>         min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
> >>>>>
> >>>>>         if (DPU_FORMAT_IS_YUV(fmt) &&
> >>>>> @@ -957,9 +968,12 @@ 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;
> >>>>> +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
> >>>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
> >>>>>         struct drm_rect fb_rect = { 0 };
> >>>>>         uint32_t max_linewidth;
> >>>>>         unsigned int rotation;
> >>>>> @@ -983,8 +997,11 @@ 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;
> >>>>> +     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) {
> >>>>> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
> >>>>>
> >>>>>         max_linewidth = pdpu->catalog->caps->max_linewidth;
> >>>>>
> >>>>> -     /* check decimated source width */
> >>>>>         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;
> >>>>> +             /* 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;
> >>>>> +             }
> >>>>
> >>>> This is where I am a bit concerned enabling it for all chipsets in one go.
> >>>
> >>> As I wrote earlier, I'd prefer the opt-out rather than opt-in here. It
> >>> is much easier to handle the reports "I have a device with sm6543,
> >>> where the display worked before 6.4, but started failing afterwards"
> >>> rather than trying to find a person with sm6543 and asking him if he
> >>> can enable this and that on his device. And even a lower chance of a
> >>> person with sm6543 coming up with a patch 'hey, I enabled this for my
> >>> phone and it works!'.
> >>>
> >>> If we find any issues during or close to the end of the development
> >>> cycle, we can add a 'don't enable wide plane here' switch and enable
> >>> it for failing platforms. But each enablement of this switch should
> >>> come with a reason (wide planes not working here because ....). In the
> >>> end this switch should be gone and transformed into proper HW
> >>> limitation checks.
> >>>
> >>
> >> As it has become clear that with this patch series 4K with UBWC cannot
> >> be supported without true virtual planes (with two SSPPs), why do you
> >> need to relax this check right now?
> >
> > Yes. It enables support for 4k @ linear formats. So my plan for this
> > series is to land 4k with all the proper applicable restrictions.
> >
> >> You can relax this when you add the support for virtual planes till then
> >> let it be this way.
> >>
> >> Its not going to break smartDMA as such. You can still use it for layers
> >> < 2560.
> >>
> >> That way we stay true to the purpose of the feature. I think originally
> >> you wanted to get this in for smartDMA and not to support wide plane and
> >> that purpose will still be achieved even with keeping this check intact.
> >
> > Actually, no. With this series I wanted to get 4k. It was developed in
> > parallel with the 4k enablement for RB3 (posted, bridge patches are
> > being merged for 6.3) and RB5 (delayed for now, I have other issues
> > there).
> >
>
> With the UBWC related checks, this wont support 4K for UBWC layers which
> is default on QC chipsets. So I am fine with respect to that. But still
> this does not address the product spec advertized modes. Like I
> mentioned before, relaxing the maxlinewidth check with the added UBWC
> checks is fine from DPU point of view but not from the product POV.
>
> As things stand today, this is the only check failing the 4K modes on
> chipsets which shouldnt support 4k (linear or UBWC doesnt matter).
>
> >> You can relax it in the virtual plane series.
> >>
> >> Regarding issues, this is where it gets tricky. We should be aligning
> >> with what the product supports. QC will not support issues arising with
> >> 4K on chipsets on which 4K is not advertized.
> >
> > So, we have several different items here:
> > - SmartDMA v2 per se, supporting two rectangles per VIG or DMA plane,
> > - Source split support,
> > - Supporting 4k modes.
> >
> > I think we should tend them one by one. This series concerns SmartDMA
> > v2. Using SmartDMA it is possible to use two rectangles side by side
> > to emulate a wide plane. This series doesn't care at all about max
> > resolutions. These two items are completely orthogonal.
> >
>
> No its not orthogonal. Relaxing the maxlinewidth check in the
> atomic_check() will allow 4K layers now even on chipsets where 4K wasnt
> advertized. Linear or UBWC doesnt matter as the spec doesnt go into that.

Please correct my answers, if I got something wrong here:

Does sc7180 support SmartDMA? Yes it does.
Can QC or CrOS validate SmartDMA separately on sc7180? I hope you can.
Should the hw-supported feature be enabled? Yes, it should.

Now limiting out 4k by not supporting SmartDMA looks like a misfeature.
I can only suggest sending a change to block 4k on sc7180.

> >>>> As you are aware,  we have an open bug today that we do not filter out
> >>>> the modes which we do not support.
> >>>>
> >>>> https://gitlab.freedesktop.org/drm/msm/-/issues/21
> >>>
> >>> I thought that with the link-frequencies in place and with the DSI
> >>> checking the OPP tables this issue is mostly handled. Isn't it?
> >>> Is a mode check in the DPU driver itself the last missing piece?
> >>>
> >>
> >> opp based checking was implemented only for DSI. That one is byte clk based.
> >>
> >> DP uses link rate for opp table.
> >>
> >> Even with a 5.4G link rate (the one in sc7180 chromebook) 4k@30 would
> >> still be possible but it was not advertized
> >>
> >> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
> >>
> >> These docs are available in public domain.
> >>
> >> As we synced up last time on
> >> https://patchwork.freedesktop.org/series/107917/, even with these limits
> >> in place, its not matching the advertized limits.
> >>
> >>>>
> >>>> Due to this, on all chipsets we will end up trying to do a 4K on
> >>>> external display which we dont know what bugs it will expose.
> >>>
> >>> If we do not expose bugs, we do not have a way to fix them. And I
> >>> definitely think that all the bugs should be listed as early as
> >>> possible, while both of us still remember the code under the question.
> >>>
> >>
> >> Yes but on chipsets where 4K is supported ( and hence needed ).
> >
> > 4k, SmartDMA, src-split, split-display, etc.
> >
>
> The visual issues reported on sdm845 on the other thread are a classic
> example of what I just wrote on that patchset and thats why I was
> emphasizing a visual validation OR in other words enable the feature on
> which you are able to visually validate it.

Yes. And if we did not enable the feature, Amit would not be able to
spot that. I can repeat my suggestion:

- prevalidate these features for the accessible platforms (e.g. I only
have sdm845, sm8250 and sm8350 at hand)
- enable SmartDMA for all chipsets where SmartDMA is supported
- collect possible tested-by and broken-at reports, while the patches
sit in linux-next
- disable SmartDMA basing on the feedback from the previous step (e.g.
select from 'mostly disable', 'disable for the bugged cases', 'do not
disable at all', etc).
  I can promise that if we see a significant validation failure rate I
will not oppose disabling SmartDMA.

As a reminder: if the patchset is ready at the time of 6.3-rc1 (in
three weeks from now), it is going to be merged into linux-next first,
after that it can go into the main Linus'es tree at 6.4-rc1. So we
will have _two_ kernel cycles to collect bug reports and to disable
(or fix) broken cases.

> We can evaluate and enable smartDMA on other chipsets on a need basis.
>
> We discussed this again even today in the team discussion. Our team's
> PoV doesnt change. We would still like to enable smartDMA only on
> chipsets which can be visually validated first to limit the debugging
> effort to one chipset first and then perfect it. Otherwise its too much
> effort on QC side to debug those issues on all chipsets.

I think QC mostly debugs issues on sc7180/sc7280 and sometimes on
sdm845/sm8250 (and now on sm8350). I think we can let people
(somainline, PmOS) test features on other platforms.
And testing happens better if we can say 'please test linux-next'
rather than 'please test linux-next + this patch to enable the feature
+ that patch to enable the second patch of the feature'.

> >>>> So lets say if we test it on sc7280 fully but not on sc7180, we will
> >>>> still hit this condition on sc7180 too but on that chipset we did not
> >>>> advertise 4K as a capability in the product spec.
> >>>
> >>> Is it 'not advertised' or 'not supported by hw'?
> >>>
> >>
> >> The document
> >> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
> >> is made from inputs from not just display team but overall system
> >> limits. So even though you could argue that this falls within the
> >> display capabilities, all I can say at the moment is we have to stick to
> >> the advertized limits as its compiled with inputs from all the teams
> >> (system/performance etc).
> >
> > So, there should be a limiting factor (or a combination of them).
> > Filter out 4k modes on sc7180. Or modes using fill rate higher than N.
> > Pixel clock rate higher than M. But it has nothing to do with these
> > patches enabling SmartDMA support on this platform.
> >
> > Even if we look at the vendor kernels, we don't see 'maximum external
> > resolution'. Instead I see a combination of linewidth and bandwidth
> > limitations. If we can stick to that, that would be great.
> >
>
> Can you please point me to bandwidth limitation checks? How are other
> vendors coming up with this number? It has to be based on some
> resolution too right?

Usually it is considered in the other direction. The SoC can support
this-and-that pixel clock and bandwidth, so put the NxM resolution to
the datasheet as the max supported one.

Can you point out how the vendor kernel limits DP modes? I checked out
several dtsi files. For sm8250 the DP is limited to 1920x1080 (while
PB explicitly mentions 4k@60).
sm7125 is limited to 2560x1600. sm6150 again 1920x1080. From the pile
of the DTS that I have here the rest lists only
qcom,max-pclk-frequency-khz

> My RFC https://patchwork.freedesktop.org/series/107917/ considered pixel
> clk as the limiting factor which was posted after discussions
> internally. In the absence of another way, that remains the only
> solution to tackle this.

If I remember correctly the mentioned patchset used manually crafted
pixel clocks. And for example for sm8250 this clock doesn't correspond
to verifiable source.
Your patchset used 594000 KHz as max ext pclk for sm8250. vendor dtsi
lists 187500 KHz as maximum DP pclk for RB5 and 150000 KHz in all
other cases. And, at the same time, it lists a 3840x2160@60 mode for
the DSI/lt9611uxc with the pixel clock as high as 608040 KHz.

I suggest we stop the discussion at this point, unless there is
anything else wrong with this patchset itself.

I noted the point regarding UBWC & parallel mode. I will handle it in
the next iteration.

I noted your valid point about the visual verification. I proposed a
way to ease validation, allowing it to be enabled for testers and
early adopters for nearly two cycles. I hope you'd agree to this plan.
I on the other side agree to revert to opt-in if the failure rate is
high.

Please stop bringing max resolution issues to this patchserie. It must
be handled separately. I hope to see the mode filter patch targeting
sc7180 & sc7280. With the DSI opp check in place I think we should
concentrate on the DP case. If nothing else, I think even adding the
max PCLK to the msm_dp_desc should be sufficient to your worries. I'd
prefer to be able to override it for the particular board, but I think
this can come later, as it would require an agreement from the DT
schema team.

--
With best wishes
Dmitry

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

* Re: [Freedreno] [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
  2023-02-10  0:09               ` Dmitry Baryshkov
@ 2023-02-10  1:12                 ` Abhinav Kumar
  -1 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-10  1:12 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Kalyan Thota, freedreno, Sean Paul, Bjorn Andersson, dri-devel,
	Stephen Boyd, Rob Clark, Daniel Vetter, linux-arm-msm,
	David Airlie

Hi Dmitry

On 2/9/2023 4:09 PM, Dmitry Baryshkov wrote:
>   .
> 
> On Fri, 10 Feb 2023 at 00:12, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>> Hi Dmitry
>>
>> On 2/9/2023 1:23 PM, Dmitry Baryshkov wrote:
>>> Hi Abhinav,
>>>
>>> On Thu, 9 Feb 2023 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 2/9/2023 3:45 AM, Dmitry Baryshkov wrote:
>>>>> On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>> Typically SSPP can support rectangle with width up to 2560. However it's
>>>>>>
>>>>>> Not always 2560. Depends on the chipset.
>>>>>
>>>>> _typically_
>>>>>
>>>>
>>>> Would just say maxlinewidth of SSPP instead of giving some hardcoded number.
>>>
>>> Ack.
>>>
>>>>
>>>>>>
>>>>>>> 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  |   6 ++
>>>>>>>      drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
>>>>>>>      drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
>>>>>>>      3 files changed, 114 insertions(+), 12 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>>>> index 0ca3bc38ff7e..867832a752b2 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>>>> @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>>>>>>>                                             fetch_active,
>>>>>>>                                             &pstate->pipe);
>>>>>>>
>>>>>>> +             _dpu_crtc_blend_setup_pipe(crtc, plane,
>>>>>>> +                                        mixer, cstate->num_mixers,
>>>>>>> +                                        stage_cfg, pstate->stage, 1,
>>>>>>> +                                        fetch_active,
>>>>>>> +                                        &pstate->r_pipe);
>>>>>>> +
>>>>>>>                  /* blend config update */
>>>>>>>                  for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
>>>>>>>                          _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>>> index e2e85688ed3c..401ead64c6bd 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>>> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>>>>>>>          struct dpu_plane *pdpu = to_dpu_plane(plane);
>>>>>>>          struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>>>>>>>
>>>>>>> +     if (!pipe->sspp)
>>>>>>> +             return;
>>>>>>> +
>>>>>>>          memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>>>>>>
>>>>>>>          if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>>>>>>> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>>>>>>>      {
>>>>>>>          struct dpu_hw_sspp_cfg pipe_cfg;
>>>>>>>
>>>>>>> +     if (!pipe->sspp)
>>>>>>> +             return 0;
>>>>>>
>>>>>> instead of checking if sspp was present, is it not better for the caller
>>>>>> to check if the rpipe is valid before calling this?
>>>>>>
>>>>>>> +
>>>>>>>          /* update sspp */
>>>>>>>          if (!pipe->sspp->ops.setup_solidfill)
>>>>>>>                  return 0;
>>>>>>> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
>>>>>>>
>>>>>>>          /* update sspp */
>>>>>>>          _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
>>>>>>> +
>>>>>>> +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
>>>>>>>      }
>>>>>>
>>>>>> So cant we do
>>>>>>
>>>>>> if (pstate->r_pipe.sspp)
>>>>>>            _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
>>>>>>                    &pstate->r_pipe_cfg, fill_color, fmt);
>>>>>>
>>>>>> It just seems better to me as the caller would already know if the sspp
>>>>>> was assigned.
>>>>>
>>>>>     I think I had this kind of code earlier, but then I found it more
>>>>> logical to move the check to the called function. I'll move it back.
>>>>>
>>>>>>
>>>>>>>
>>>>>>>      int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
>>>>>>> @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>>>>>      {
>>>>>>>          uint32_t min_src_size;
>>>>>>>
>>>>>>> +     if (!pipe->sspp)
>>>>>>> +             return 0;
>>>>>>> +
>>>>>>>          min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>>>>>>
>>>>>>>          if (DPU_FORMAT_IS_YUV(fmt) &&
>>>>>>> @@ -957,9 +968,12 @@ 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;
>>>>>>> +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>>>>>          struct drm_rect fb_rect = { 0 };
>>>>>>>          uint32_t max_linewidth;
>>>>>>>          unsigned int rotation;
>>>>>>> @@ -983,8 +997,11 @@ 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;
>>>>>>> +     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) {
>>>>>>> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>>>>>
>>>>>>>          max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>>>>>
>>>>>>> -     /* check decimated source width */
>>>>>>>          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;
>>>>>>> +             /* 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;
>>>>>>> +             }
>>>>>>
>>>>>> This is where I am a bit concerned enabling it for all chipsets in one go.
>>>>>
>>>>> As I wrote earlier, I'd prefer the opt-out rather than opt-in here. It
>>>>> is much easier to handle the reports "I have a device with sm6543,
>>>>> where the display worked before 6.4, but started failing afterwards"
>>>>> rather than trying to find a person with sm6543 and asking him if he
>>>>> can enable this and that on his device. And even a lower chance of a
>>>>> person with sm6543 coming up with a patch 'hey, I enabled this for my
>>>>> phone and it works!'.
>>>>>
>>>>> If we find any issues during or close to the end of the development
>>>>> cycle, we can add a 'don't enable wide plane here' switch and enable
>>>>> it for failing platforms. But each enablement of this switch should
>>>>> come with a reason (wide planes not working here because ....). In the
>>>>> end this switch should be gone and transformed into proper HW
>>>>> limitation checks.
>>>>>
>>>>
>>>> As it has become clear that with this patch series 4K with UBWC cannot
>>>> be supported without true virtual planes (with two SSPPs), why do you
>>>> need to relax this check right now?
>>>
>>> Yes. It enables support for 4k @ linear formats. So my plan for this
>>> series is to land 4k with all the proper applicable restrictions.
>>>
>>>> You can relax this when you add the support for virtual planes till then
>>>> let it be this way.
>>>>
>>>> Its not going to break smartDMA as such. You can still use it for layers
>>>> < 2560.
>>>>
>>>> That way we stay true to the purpose of the feature. I think originally
>>>> you wanted to get this in for smartDMA and not to support wide plane and
>>>> that purpose will still be achieved even with keeping this check intact.
>>>
>>> Actually, no. With this series I wanted to get 4k. It was developed in
>>> parallel with the 4k enablement for RB3 (posted, bridge patches are
>>> being merged for 6.3) and RB5 (delayed for now, I have other issues
>>> there).
>>>
>>
>> With the UBWC related checks, this wont support 4K for UBWC layers which
>> is default on QC chipsets. So I am fine with respect to that. But still
>> this does not address the product spec advertized modes. Like I
>> mentioned before, relaxing the maxlinewidth check with the added UBWC
>> checks is fine from DPU point of view but not from the product POV.
>>
>> As things stand today, this is the only check failing the 4K modes on
>> chipsets which shouldnt support 4k (linear or UBWC doesnt matter).
>>
>>>> You can relax it in the virtual plane series.
>>>>
>>>> Regarding issues, this is where it gets tricky. We should be aligning
>>>> with what the product supports. QC will not support issues arising with
>>>> 4K on chipsets on which 4K is not advertized.
>>>
>>> So, we have several different items here:
>>> - SmartDMA v2 per se, supporting two rectangles per VIG or DMA plane,
>>> - Source split support,
>>> - Supporting 4k modes.
>>>
>>> I think we should tend them one by one. This series concerns SmartDMA
>>> v2. Using SmartDMA it is possible to use two rectangles side by side
>>> to emulate a wide plane. This series doesn't care at all about max
>>> resolutions. These two items are completely orthogonal.
>>>
>>
>> No its not orthogonal. Relaxing the maxlinewidth check in the
>> atomic_check() will allow 4K layers now even on chipsets where 4K wasnt
>> advertized. Linear or UBWC doesnt matter as the spec doesnt go into that.
> 
> Please correct my answers, if I got something wrong here:
> 
> Does sc7180 support SmartDMA? Yes it does.
> Can QC or CrOS validate SmartDMA separately on sc7180? I hope you can.
> Should the hw-supported feature be enabled? Yes, it should.
> 
> Now limiting out 4k by not supporting SmartDMA looks like a misfeature.
> I can only suggest sending a change to block 4k on sc7180.
> 

Agreed. We should first block 4K on sc7180 and other devices which dont 
advertize 4k. No, it was never a question of limiting out 4K by not 
supporting smartDMA but the other way around. By supporting smartDMA, we 
would have had to support 4K on some chipsets due to this change which I 
didnt want to do.

And yes agreed that we can stop discussing 4K anymore on this patch but 
not smartDMA itself. Please see below.

>>>>>> As you are aware,  we have an open bug today that we do not filter out
>>>>>> the modes which we do not support.
>>>>>>
>>>>>> https://gitlab.freedesktop.org/drm/msm/-/issues/21
>>>>>
>>>>> I thought that with the link-frequencies in place and with the DSI
>>>>> checking the OPP tables this issue is mostly handled. Isn't it?
>>>>> Is a mode check in the DPU driver itself the last missing piece?
>>>>>
>>>>
>>>> opp based checking was implemented only for DSI. That one is byte clk based.
>>>>
>>>> DP uses link rate for opp table.
>>>>
>>>> Even with a 5.4G link rate (the one in sc7180 chromebook) 4k@30 would
>>>> still be possible but it was not advertized
>>>>
>>>> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>>>>
>>>> These docs are available in public domain.
>>>>
>>>> As we synced up last time on
>>>> https://patchwork.freedesktop.org/series/107917/, even with these limits
>>>> in place, its not matching the advertized limits.
>>>>
>>>>>>
>>>>>> Due to this, on all chipsets we will end up trying to do a 4K on
>>>>>> external display which we dont know what bugs it will expose.
>>>>>
>>>>> If we do not expose bugs, we do not have a way to fix them. And I
>>>>> definitely think that all the bugs should be listed as early as
>>>>> possible, while both of us still remember the code under the question.
>>>>>
>>>>
>>>> Yes but on chipsets where 4K is supported ( and hence needed ).
>>>
>>> 4k, SmartDMA, src-split, split-display, etc.
>>>
>>
>> The visual issues reported on sdm845 on the other thread are a classic
>> example of what I just wrote on that patchset and thats why I was
>> emphasizing a visual validation OR in other words enable the feature on
>> which you are able to visually validate it.
> 
> Yes. And if we did not enable the feature, Amit would not be able to
> spot that. I can repeat my suggestion:
> 
> - prevalidate these features for the accessible platforms (e.g. I only
> have sdm845, sm8250 and sm8350 at hand)

How? Your validation is not with a compositor in most cases and just 
with modetest.

> - enable SmartDMA for all chipsets where SmartDMA is supported
> - collect possible tested-by and broken-at reports, while the patches
> sit in linux-next

Question:

1) Who will test these on all the devices for us? This is what I had 
written even before that someone should give Tested-by tags then.

Even if you have them on linux-next, someone has to test them voluntarily.

2) Who will look at these broken-at reports and debug them?

> - disable SmartDMA basing on the feedback from the previous step (e.g.
> select from 'mostly disable', 'disable for the bugged cases', 'do not
> disable at all', etc).
>    I can promise that if we see a significant validation failure rate I
> will not oppose disabling SmartDMA.
> 

Thanks for agreeing on this :)

> As a reminder: if the patchset is ready at the time of 6.3-rc1 (in
> three weeks from now), it is going to be merged into linux-next first,
> after that it can go into the main Linus'es tree at 6.4-rc1. So we
> will have _two_ kernel cycles to collect bug reports and to disable
> (or fix) broken cases.
> 

>> We can evaluate and enable smartDMA on other chipsets on a need basis.
>>
>> We discussed this again even today in the team discussion. Our team's
>> PoV doesnt change. We would still like to enable smartDMA only on
>> chipsets which can be visually validated first to limit the debugging
>> effort to one chipset first and then perfect it. Otherwise its too much
>> effort on QC side to debug those issues on all chipsets.
> 
> I think QC mostly debugs issues on sc7180/sc7280 and sometimes on
> sdm845/sm8250 (and now on sm8350). I think we can let people
> (somainline, PmOS) test features on other platforms.
> And testing happens better if we can say 'please test linux-next'
> rather than 'please test linux-next + this patch to enable the feature
> + that patch to enable the second patch of the feature'.
> 

In this particular case, in the current timeframe QC can only commit to 
validate sc7280 at this point and not sc7180, sdm845, sm8250 and sm8350 
for this feature.

So it will be upto you and others for all other targets.

Yes, I agree, people prefer to test on a branch rather than branch + 
patches.

>>>>>> So lets say if we test it on sc7280 fully but not on sc7180, we will
>>>>>> still hit this condition on sc7180 too but on that chipset we did not
>>>>>> advertise 4K as a capability in the product spec.
>>>>>
>>>>> Is it 'not advertised' or 'not supported by hw'?
>>>>>
>>>>
>>>> The document
>>>> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>>>> is made from inputs from not just display team but overall system
>>>> limits. So even though you could argue that this falls within the
>>>> display capabilities, all I can say at the moment is we have to stick to
>>>> the advertized limits as its compiled with inputs from all the teams
>>>> (system/performance etc).
>>>
>>> So, there should be a limiting factor (or a combination of them).
>>> Filter out 4k modes on sc7180. Or modes using fill rate higher than N.
>>> Pixel clock rate higher than M. But it has nothing to do with these
>>> patches enabling SmartDMA support on this platform.
>>>
>>> Even if we look at the vendor kernels, we don't see 'maximum external
>>> resolution'. Instead I see a combination of linewidth and bandwidth
>>> limitations. If we can stick to that, that would be great.
>>>
>>
>> Can you please point me to bandwidth limitation checks? How are other
>> vendors coming up with this number? It has to be based on some
>> resolution too right?
> 
> Usually it is considered in the other direction. The SoC can support
> this-and-that pixel clock and bandwidth, so put the NxM resolution to
> the datasheet as the max supported one.
>
Our data sheet also gave the resolution so I chose the pixel clk last time.

> Can you point out how the vendor kernel limits DP modes? I checked out
> several dtsi files. For sm8250 the DP is limited to 1920x1080 (while
> PB explicitly mentions 4k@60).

Where do you see 1920x1080? In kona-sde.dtsi I see 675000

> sm7125 is limited to 2560x1600. sm6150 again 1920x1080. From the pile
> of the DTS that I have here the rest lists only
> qcom,max-pclk-frequency-khz

Yes, qcom,max-pclk-frequency-khz is the method they use.

> 
>> My RFC https://patchwork.freedesktop.org/series/107917/ considered pixel
>> clk as the limiting factor which was posted after discussions
>> internally. In the absence of another way, that remains the only
>> solution to tackle this.
> 
> If I remember correctly the mentioned patchset used manually crafted
> pixel clocks. And for example for sm8250 this clock doesn't correspond
> to verifiable source.
> Your patchset used 594000 KHz as max ext pclk for sm8250. vendor dtsi
> lists 187500 KHz as maximum DP pclk for RB5 and 150000 KHz in all

Lets discuss this more when I re-post the patch to limit 4K modes.

> other cases. And, at the same time, it lists a 3840x2160@60 mode for
> the DSI/lt9611uxc with the pixel clock as high as 608040 KHz.
> 
> I suggest we stop the discussion at this point, unless there is
> anything else wrong with this patchset itself.
> 

Agreed but please look at my comments about smartDMA validation above 
and let me know.

> I noted the point regarding UBWC & parallel mode. I will handle it in
> the next iteration.
> 
> I noted your valid point about the visual verification. I proposed a
> way to ease validation, allowing it to be enabled for testers and
> early adopters for nearly two cycles. I hope you'd agree to this plan.
> I on the other side agree to revert to opt-in if the failure rate is
> high.
> 

Agreed but with above concerns.

> Please stop bringing max resolution issues to this patchserie. It must

It got dragged into this patch because this patch relaxed the checks for 
max resolution.

> be handled separately. I hope to see the mode filter patch targeting
> sc7180 & sc7280. With the DSI opp check in place I think we should
> concentrate on the DP case. If nothing else, I think even adding the
> max PCLK to the msm_dp_desc should be sufficient to your worries. I'd
> prefer to be able to override it for the particular board, but I think
> this can come later, as it would require an agreement from the DT
> schema team.
> 

Alright, I can rebase that RFC to cover the DP cases for now and we can 
discuss all the max resolution discussions there.

> --
> With best wishes
> Dmitry

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

* Re: [Freedreno] [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
@ 2023-02-10  1:12                 ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-10  1:12 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Kalyan Thota, freedreno, Bjorn Andersson, dri-devel,
	Stephen Boyd, linux-arm-msm, Sean Paul

Hi Dmitry

On 2/9/2023 4:09 PM, Dmitry Baryshkov wrote:
>   .
> 
> On Fri, 10 Feb 2023 at 00:12, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>
>> Hi Dmitry
>>
>> On 2/9/2023 1:23 PM, Dmitry Baryshkov wrote:
>>> Hi Abhinav,
>>>
>>> On Thu, 9 Feb 2023 at 21:25, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>
>>>>
>>>>
>>>> On 2/9/2023 3:45 AM, Dmitry Baryshkov wrote:
>>>>> On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar <quic_abhinavk@quicinc.com> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>> Typically SSPP can support rectangle with width up to 2560. However it's
>>>>>>
>>>>>> Not always 2560. Depends on the chipset.
>>>>>
>>>>> _typically_
>>>>>
>>>>
>>>> Would just say maxlinewidth of SSPP instead of giving some hardcoded number.
>>>
>>> Ack.
>>>
>>>>
>>>>>>
>>>>>>> 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  |   6 ++
>>>>>>>      drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 +++++++++++++++++++---
>>>>>>>      drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
>>>>>>>      3 files changed, 114 insertions(+), 12 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>>>> index 0ca3bc38ff7e..867832a752b2 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>>>> @@ -485,6 +485,12 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>>>>>>>                                             fetch_active,
>>>>>>>                                             &pstate->pipe);
>>>>>>>
>>>>>>> +             _dpu_crtc_blend_setup_pipe(crtc, plane,
>>>>>>> +                                        mixer, cstate->num_mixers,
>>>>>>> +                                        stage_cfg, pstate->stage, 1,
>>>>>>> +                                        fetch_active,
>>>>>>> +                                        &pstate->r_pipe);
>>>>>>> +
>>>>>>>                  /* blend config update */
>>>>>>>                  for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
>>>>>>>                          _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>>> index e2e85688ed3c..401ead64c6bd 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>>> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
>>>>>>>          struct dpu_plane *pdpu = to_dpu_plane(plane);
>>>>>>>          struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>>>>>>>
>>>>>>> +     if (!pipe->sspp)
>>>>>>> +             return;
>>>>>>> +
>>>>>>>          memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>>>>>>
>>>>>>>          if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>>>>>>> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct dpu_plane_state *pstate,
>>>>>>>      {
>>>>>>>          struct dpu_hw_sspp_cfg pipe_cfg;
>>>>>>>
>>>>>>> +     if (!pipe->sspp)
>>>>>>> +             return 0;
>>>>>>
>>>>>> instead of checking if sspp was present, is it not better for the caller
>>>>>> to check if the rpipe is valid before calling this?
>>>>>>
>>>>>>> +
>>>>>>>          /* update sspp */
>>>>>>>          if (!pipe->sspp->ops.setup_solidfill)
>>>>>>>                  return 0;
>>>>>>> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct dpu_plane *pdpu,
>>>>>>>
>>>>>>>          /* update sspp */
>>>>>>>          _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, &pstate->pipe_cfg, fill_color, fmt);
>>>>>>> +
>>>>>>> +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, &pstate->r_pipe_cfg, fill_color, fmt);
>>>>>>>      }
>>>>>>
>>>>>> So cant we do
>>>>>>
>>>>>> if (pstate->r_pipe.sspp)
>>>>>>            _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
>>>>>>                    &pstate->r_pipe_cfg, fill_color, fmt);
>>>>>>
>>>>>> It just seems better to me as the caller would already know if the sspp
>>>>>> was assigned.
>>>>>
>>>>>     I think I had this kind of code earlier, but then I found it more
>>>>> logical to move the check to the called function. I'll move it back.
>>>>>
>>>>>>
>>>>>>>
>>>>>>>      int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
>>>>>>> @@ -911,6 +919,9 @@ static int dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>>>>>      {
>>>>>>>          uint32_t min_src_size;
>>>>>>>
>>>>>>> +     if (!pipe->sspp)
>>>>>>> +             return 0;
>>>>>>> +
>>>>>>>          min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>>>>>>
>>>>>>>          if (DPU_FORMAT_IS_YUV(fmt) &&
>>>>>>> @@ -957,9 +968,12 @@ 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;
>>>>>>> +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>>>>>          struct drm_rect fb_rect = { 0 };
>>>>>>>          uint32_t max_linewidth;
>>>>>>>          unsigned int rotation;
>>>>>>> @@ -983,8 +997,11 @@ 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;
>>>>>>> +     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) {
>>>>>>> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
>>>>>>>
>>>>>>>          max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>>>>>
>>>>>>> -     /* check decimated source width */
>>>>>>>          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;
>>>>>>> +             /* 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;
>>>>>>> +             }
>>>>>>
>>>>>> This is where I am a bit concerned enabling it for all chipsets in one go.
>>>>>
>>>>> As I wrote earlier, I'd prefer the opt-out rather than opt-in here. It
>>>>> is much easier to handle the reports "I have a device with sm6543,
>>>>> where the display worked before 6.4, but started failing afterwards"
>>>>> rather than trying to find a person with sm6543 and asking him if he
>>>>> can enable this and that on his device. And even a lower chance of a
>>>>> person with sm6543 coming up with a patch 'hey, I enabled this for my
>>>>> phone and it works!'.
>>>>>
>>>>> If we find any issues during or close to the end of the development
>>>>> cycle, we can add a 'don't enable wide plane here' switch and enable
>>>>> it for failing platforms. But each enablement of this switch should
>>>>> come with a reason (wide planes not working here because ....). In the
>>>>> end this switch should be gone and transformed into proper HW
>>>>> limitation checks.
>>>>>
>>>>
>>>> As it has become clear that with this patch series 4K with UBWC cannot
>>>> be supported without true virtual planes (with two SSPPs), why do you
>>>> need to relax this check right now?
>>>
>>> Yes. It enables support for 4k @ linear formats. So my plan for this
>>> series is to land 4k with all the proper applicable restrictions.
>>>
>>>> You can relax this when you add the support for virtual planes till then
>>>> let it be this way.
>>>>
>>>> Its not going to break smartDMA as such. You can still use it for layers
>>>> < 2560.
>>>>
>>>> That way we stay true to the purpose of the feature. I think originally
>>>> you wanted to get this in for smartDMA and not to support wide plane and
>>>> that purpose will still be achieved even with keeping this check intact.
>>>
>>> Actually, no. With this series I wanted to get 4k. It was developed in
>>> parallel with the 4k enablement for RB3 (posted, bridge patches are
>>> being merged for 6.3) and RB5 (delayed for now, I have other issues
>>> there).
>>>
>>
>> With the UBWC related checks, this wont support 4K for UBWC layers which
>> is default on QC chipsets. So I am fine with respect to that. But still
>> this does not address the product spec advertized modes. Like I
>> mentioned before, relaxing the maxlinewidth check with the added UBWC
>> checks is fine from DPU point of view but not from the product POV.
>>
>> As things stand today, this is the only check failing the 4K modes on
>> chipsets which shouldnt support 4k (linear or UBWC doesnt matter).
>>
>>>> You can relax it in the virtual plane series.
>>>>
>>>> Regarding issues, this is where it gets tricky. We should be aligning
>>>> with what the product supports. QC will not support issues arising with
>>>> 4K on chipsets on which 4K is not advertized.
>>>
>>> So, we have several different items here:
>>> - SmartDMA v2 per se, supporting two rectangles per VIG or DMA plane,
>>> - Source split support,
>>> - Supporting 4k modes.
>>>
>>> I think we should tend them one by one. This series concerns SmartDMA
>>> v2. Using SmartDMA it is possible to use two rectangles side by side
>>> to emulate a wide plane. This series doesn't care at all about max
>>> resolutions. These two items are completely orthogonal.
>>>
>>
>> No its not orthogonal. Relaxing the maxlinewidth check in the
>> atomic_check() will allow 4K layers now even on chipsets where 4K wasnt
>> advertized. Linear or UBWC doesnt matter as the spec doesnt go into that.
> 
> Please correct my answers, if I got something wrong here:
> 
> Does sc7180 support SmartDMA? Yes it does.
> Can QC or CrOS validate SmartDMA separately on sc7180? I hope you can.
> Should the hw-supported feature be enabled? Yes, it should.
> 
> Now limiting out 4k by not supporting SmartDMA looks like a misfeature.
> I can only suggest sending a change to block 4k on sc7180.
> 

Agreed. We should first block 4K on sc7180 and other devices which dont 
advertize 4k. No, it was never a question of limiting out 4K by not 
supporting smartDMA but the other way around. By supporting smartDMA, we 
would have had to support 4K on some chipsets due to this change which I 
didnt want to do.

And yes agreed that we can stop discussing 4K anymore on this patch but 
not smartDMA itself. Please see below.

>>>>>> As you are aware,  we have an open bug today that we do not filter out
>>>>>> the modes which we do not support.
>>>>>>
>>>>>> https://gitlab.freedesktop.org/drm/msm/-/issues/21
>>>>>
>>>>> I thought that with the link-frequencies in place and with the DSI
>>>>> checking the OPP tables this issue is mostly handled. Isn't it?
>>>>> Is a mode check in the DPU driver itself the last missing piece?
>>>>>
>>>>
>>>> opp based checking was implemented only for DSI. That one is byte clk based.
>>>>
>>>> DP uses link rate for opp table.
>>>>
>>>> Even with a 5.4G link rate (the one in sc7180 chromebook) 4k@30 would
>>>> still be possible but it was not advertized
>>>>
>>>> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>>>>
>>>> These docs are available in public domain.
>>>>
>>>> As we synced up last time on
>>>> https://patchwork.freedesktop.org/series/107917/, even with these limits
>>>> in place, its not matching the advertized limits.
>>>>
>>>>>>
>>>>>> Due to this, on all chipsets we will end up trying to do a 4K on
>>>>>> external display which we dont know what bugs it will expose.
>>>>>
>>>>> If we do not expose bugs, we do not have a way to fix them. And I
>>>>> definitely think that all the bugs should be listed as early as
>>>>> possible, while both of us still remember the code under the question.
>>>>>
>>>>
>>>> Yes but on chipsets where 4K is supported ( and hence needed ).
>>>
>>> 4k, SmartDMA, src-split, split-display, etc.
>>>
>>
>> The visual issues reported on sdm845 on the other thread are a classic
>> example of what I just wrote on that patchset and thats why I was
>> emphasizing a visual validation OR in other words enable the feature on
>> which you are able to visually validate it.
> 
> Yes. And if we did not enable the feature, Amit would not be able to
> spot that. I can repeat my suggestion:
> 
> - prevalidate these features for the accessible platforms (e.g. I only
> have sdm845, sm8250 and sm8350 at hand)

How? Your validation is not with a compositor in most cases and just 
with modetest.

> - enable SmartDMA for all chipsets where SmartDMA is supported
> - collect possible tested-by and broken-at reports, while the patches
> sit in linux-next

Question:

1) Who will test these on all the devices for us? This is what I had 
written even before that someone should give Tested-by tags then.

Even if you have them on linux-next, someone has to test them voluntarily.

2) Who will look at these broken-at reports and debug them?

> - disable SmartDMA basing on the feedback from the previous step (e.g.
> select from 'mostly disable', 'disable for the bugged cases', 'do not
> disable at all', etc).
>    I can promise that if we see a significant validation failure rate I
> will not oppose disabling SmartDMA.
> 

Thanks for agreeing on this :)

> As a reminder: if the patchset is ready at the time of 6.3-rc1 (in
> three weeks from now), it is going to be merged into linux-next first,
> after that it can go into the main Linus'es tree at 6.4-rc1. So we
> will have _two_ kernel cycles to collect bug reports and to disable
> (or fix) broken cases.
> 

>> We can evaluate and enable smartDMA on other chipsets on a need basis.
>>
>> We discussed this again even today in the team discussion. Our team's
>> PoV doesnt change. We would still like to enable smartDMA only on
>> chipsets which can be visually validated first to limit the debugging
>> effort to one chipset first and then perfect it. Otherwise its too much
>> effort on QC side to debug those issues on all chipsets.
> 
> I think QC mostly debugs issues on sc7180/sc7280 and sometimes on
> sdm845/sm8250 (and now on sm8350). I think we can let people
> (somainline, PmOS) test features on other platforms.
> And testing happens better if we can say 'please test linux-next'
> rather than 'please test linux-next + this patch to enable the feature
> + that patch to enable the second patch of the feature'.
> 

In this particular case, in the current timeframe QC can only commit to 
validate sc7280 at this point and not sc7180, sdm845, sm8250 and sm8350 
for this feature.

So it will be upto you and others for all other targets.

Yes, I agree, people prefer to test on a branch rather than branch + 
patches.

>>>>>> So lets say if we test it on sc7280 fully but not on sc7180, we will
>>>>>> still hit this condition on sc7180 too but on that chipset we did not
>>>>>> advertise 4K as a capability in the product spec.
>>>>>
>>>>> Is it 'not advertised' or 'not supported by hw'?
>>>>>
>>>>
>>>> The document
>>>> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>>>> is made from inputs from not just display team but overall system
>>>> limits. So even though you could argue that this falls within the
>>>> display capabilities, all I can say at the moment is we have to stick to
>>>> the advertized limits as its compiled with inputs from all the teams
>>>> (system/performance etc).
>>>
>>> So, there should be a limiting factor (or a combination of them).
>>> Filter out 4k modes on sc7180. Or modes using fill rate higher than N.
>>> Pixel clock rate higher than M. But it has nothing to do with these
>>> patches enabling SmartDMA support on this platform.
>>>
>>> Even if we look at the vendor kernels, we don't see 'maximum external
>>> resolution'. Instead I see a combination of linewidth and bandwidth
>>> limitations. If we can stick to that, that would be great.
>>>
>>
>> Can you please point me to bandwidth limitation checks? How are other
>> vendors coming up with this number? It has to be based on some
>> resolution too right?
> 
> Usually it is considered in the other direction. The SoC can support
> this-and-that pixel clock and bandwidth, so put the NxM resolution to
> the datasheet as the max supported one.
>
Our data sheet also gave the resolution so I chose the pixel clk last time.

> Can you point out how the vendor kernel limits DP modes? I checked out
> several dtsi files. For sm8250 the DP is limited to 1920x1080 (while
> PB explicitly mentions 4k@60).

Where do you see 1920x1080? In kona-sde.dtsi I see 675000

> sm7125 is limited to 2560x1600. sm6150 again 1920x1080. From the pile
> of the DTS that I have here the rest lists only
> qcom,max-pclk-frequency-khz

Yes, qcom,max-pclk-frequency-khz is the method they use.

> 
>> My RFC https://patchwork.freedesktop.org/series/107917/ considered pixel
>> clk as the limiting factor which was posted after discussions
>> internally. In the absence of another way, that remains the only
>> solution to tackle this.
> 
> If I remember correctly the mentioned patchset used manually crafted
> pixel clocks. And for example for sm8250 this clock doesn't correspond
> to verifiable source.
> Your patchset used 594000 KHz as max ext pclk for sm8250. vendor dtsi
> lists 187500 KHz as maximum DP pclk for RB5 and 150000 KHz in all

Lets discuss this more when I re-post the patch to limit 4K modes.

> other cases. And, at the same time, it lists a 3840x2160@60 mode for
> the DSI/lt9611uxc with the pixel clock as high as 608040 KHz.
> 
> I suggest we stop the discussion at this point, unless there is
> anything else wrong with this patchset itself.
> 

Agreed but please look at my comments about smartDMA validation above 
and let me know.

> I noted the point regarding UBWC & parallel mode. I will handle it in
> the next iteration.
> 
> I noted your valid point about the visual verification. I proposed a
> way to ease validation, allowing it to be enabled for testers and
> early adopters for nearly two cycles. I hope you'd agree to this plan.
> I on the other side agree to revert to opt-in if the failure rate is
> high.
> 

Agreed but with above concerns.

> Please stop bringing max resolution issues to this patchserie. It must

It got dragged into this patch because this patch relaxed the checks for 
max resolution.

> be handled separately. I hope to see the mode filter patch targeting
> sc7180 & sc7280. With the DSI opp check in place I think we should
> concentrate on the DP case. If nothing else, I think even adding the
> max PCLK to the msm_dp_desc should be sufficient to your worries. I'd
> prefer to be able to override it for the particular board, but I think
> this can come later, as it would require an agreement from the DT
> schema team.
> 

Alright, I can rebase that RFC to cover the DP cases for now and we can 
discuss all the max resolution discussions there.

> --
> With best wishes
> Dmitry

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

* Re: [Freedreno] [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
  2023-02-10  1:12                 ` Abhinav Kumar
@ 2023-02-10  2:46                   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-10  2:46 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Kalyan Thota, freedreno, Sean Paul, Bjorn Andersson, dri-devel,
	Stephen Boyd, Rob Clark, Daniel Vetter, linux-arm-msm,
	David Airlie

On 10/02/2023 03:12, Abhinav Kumar wrote:
> Hi Dmitry
> 
> On 2/9/2023 4:09 PM, Dmitry Baryshkov wrote:
>>   .
>>
>> On Fri, 10 Feb 2023 at 00:12, Abhinav Kumar 
>> <quic_abhinavk@quicinc.com> wrote:
>>>
>>> Hi Dmitry
>>>
>>> On 2/9/2023 1:23 PM, Dmitry Baryshkov wrote:
>>>> Hi Abhinav,
>>>>
>>>> On Thu, 9 Feb 2023 at 21:25, Abhinav Kumar 
>>>> <quic_abhinavk@quicinc.com> wrote:
>>>>>
>>>>>
>>>>>
>>>>> On 2/9/2023 3:45 AM, Dmitry Baryshkov wrote:
>>>>>> On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar 
>>>>>> <quic_abhinavk@quicinc.com> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>>> Typically SSPP can support rectangle with width up to 2560. 
>>>>>>>> However it's
>>>>>>>
>>>>>>> Not always 2560. Depends on the chipset.
>>>>>>
>>>>>> _typically_
>>>>>>
>>>>>
>>>>> Would just say maxlinewidth of SSPP instead of giving some 
>>>>> hardcoded number.
>>>>
>>>> Ack.
>>>>
>>>>>
>>>>>>>
>>>>>>>> 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  |   6 ++
>>>>>>>>      drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 
>>>>>>>> +++++++++++++++++++---
>>>>>>>>      drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
>>>>>>>>      3 files changed, 114 insertions(+), 12 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>>>>> index 0ca3bc38ff7e..867832a752b2 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>>>>> @@ -485,6 +485,12 @@ static void 
>>>>>>>> _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>>>>>>>>                                             fetch_active,
>>>>>>>>                                             &pstate->pipe);
>>>>>>>>
>>>>>>>> +             _dpu_crtc_blend_setup_pipe(crtc, plane,
>>>>>>>> +                                        mixer, cstate->num_mixers,
>>>>>>>> +                                        stage_cfg, 
>>>>>>>> pstate->stage, 1,
>>>>>>>> +                                        fetch_active,
>>>>>>>> +                                        &pstate->r_pipe);
>>>>>>>> +
>>>>>>>>                  /* blend config update */
>>>>>>>>                  for (lm_idx = 0; lm_idx < cstate->num_mixers; 
>>>>>>>> lm_idx++) {
>>>>>>>>                          _dpu_crtc_setup_blend_cfg(mixer + 
>>>>>>>> lm_idx, pstate, format);
>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>>>> index e2e85688ed3c..401ead64c6bd 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>>>> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct 
>>>>>>>> drm_plane *plane,
>>>>>>>>          struct dpu_plane *pdpu = to_dpu_plane(plane);
>>>>>>>>          struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>>>>>>>>
>>>>>>>> +     if (!pipe->sspp)
>>>>>>>> +             return;
>>>>>>>> +
>>>>>>>>          memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>>>>>>>
>>>>>>>>          if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>>>>>>>> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct 
>>>>>>>> dpu_plane_state *pstate,
>>>>>>>>      {
>>>>>>>>          struct dpu_hw_sspp_cfg pipe_cfg;
>>>>>>>>
>>>>>>>> +     if (!pipe->sspp)
>>>>>>>> +             return 0;
>>>>>>>
>>>>>>> instead of checking if sspp was present, is it not better for the 
>>>>>>> caller
>>>>>>> to check if the rpipe is valid before calling this?
>>>>>>>
>>>>>>>> +
>>>>>>>>          /* update sspp */
>>>>>>>>          if (!pipe->sspp->ops.setup_solidfill)
>>>>>>>>                  return 0;
>>>>>>>> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct 
>>>>>>>> dpu_plane *pdpu,
>>>>>>>>
>>>>>>>>          /* update sspp */
>>>>>>>>          _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, 
>>>>>>>> &pstate->pipe_cfg, fill_color, fmt);
>>>>>>>> +
>>>>>>>> +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, 
>>>>>>>> &pstate->r_pipe_cfg, fill_color, fmt);
>>>>>>>>      }
>>>>>>>
>>>>>>> So cant we do
>>>>>>>
>>>>>>> if (pstate->r_pipe.sspp)
>>>>>>>            _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
>>>>>>>                    &pstate->r_pipe_cfg, fill_color, fmt);
>>>>>>>
>>>>>>> It just seems better to me as the caller would already know if 
>>>>>>> the sspp
>>>>>>> was assigned.
>>>>>>
>>>>>>     I think I had this kind of code earlier, but then I found it more
>>>>>> logical to move the check to the called function. I'll move it back.
>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>>      int dpu_plane_validate_multirect_v2(struct 
>>>>>>>> dpu_multirect_plane_states *plane)
>>>>>>>> @@ -911,6 +919,9 @@ static int 
>>>>>>>> dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>>>>>>      {
>>>>>>>>          uint32_t min_src_size;
>>>>>>>>
>>>>>>>> +     if (!pipe->sspp)
>>>>>>>> +             return 0;
>>>>>>>> +
>>>>>>>>          min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>>>>>>>
>>>>>>>>          if (DPU_FORMAT_IS_YUV(fmt) &&
>>>>>>>> @@ -957,9 +968,12 @@ 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;
>>>>>>>> +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>>>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>>>>>>          struct drm_rect fb_rect = { 0 };
>>>>>>>>          uint32_t max_linewidth;
>>>>>>>>          unsigned int rotation;
>>>>>>>> @@ -983,8 +997,11 @@ 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;
>>>>>>>> +     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) {
>>>>>>>> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct 
>>>>>>>> drm_plane *plane,
>>>>>>>>
>>>>>>>>          max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>>>>>>
>>>>>>>> -     /* check decimated source width */
>>>>>>>>          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;
>>>>>>>> +             /* 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;
>>>>>>>> +             }
>>>>>>>
>>>>>>> This is where I am a bit concerned enabling it for all chipsets 
>>>>>>> in one go.
>>>>>>
>>>>>> As I wrote earlier, I'd prefer the opt-out rather than opt-in 
>>>>>> here. It
>>>>>> is much easier to handle the reports "I have a device with sm6543,
>>>>>> where the display worked before 6.4, but started failing afterwards"
>>>>>> rather than trying to find a person with sm6543 and asking him if he
>>>>>> can enable this and that on his device. And even a lower chance of a
>>>>>> person with sm6543 coming up with a patch 'hey, I enabled this for my
>>>>>> phone and it works!'.
>>>>>>
>>>>>> If we find any issues during or close to the end of the development
>>>>>> cycle, we can add a 'don't enable wide plane here' switch and enable
>>>>>> it for failing platforms. But each enablement of this switch should
>>>>>> come with a reason (wide planes not working here because ....). In 
>>>>>> the
>>>>>> end this switch should be gone and transformed into proper HW
>>>>>> limitation checks.
>>>>>>
>>>>>
>>>>> As it has become clear that with this patch series 4K with UBWC cannot
>>>>> be supported without true virtual planes (with two SSPPs), why do you
>>>>> need to relax this check right now?
>>>>
>>>> Yes. It enables support for 4k @ linear formats. So my plan for this
>>>> series is to land 4k with all the proper applicable restrictions.
>>>>
>>>>> You can relax this when you add the support for virtual planes till 
>>>>> then
>>>>> let it be this way.
>>>>>
>>>>> Its not going to break smartDMA as such. You can still use it for 
>>>>> layers
>>>>> < 2560.
>>>>>
>>>>> That way we stay true to the purpose of the feature. I think 
>>>>> originally
>>>>> you wanted to get this in for smartDMA and not to support wide 
>>>>> plane and
>>>>> that purpose will still be achieved even with keeping this check 
>>>>> intact.
>>>>
>>>> Actually, no. With this series I wanted to get 4k. It was developed in
>>>> parallel with the 4k enablement for RB3 (posted, bridge patches are
>>>> being merged for 6.3) and RB5 (delayed for now, I have other issues
>>>> there).
>>>>
>>>
>>> With the UBWC related checks, this wont support 4K for UBWC layers which
>>> is default on QC chipsets. So I am fine with respect to that. But still
>>> this does not address the product spec advertized modes. Like I
>>> mentioned before, relaxing the maxlinewidth check with the added UBWC
>>> checks is fine from DPU point of view but not from the product POV.
>>>
>>> As things stand today, this is the only check failing the 4K modes on
>>> chipsets which shouldnt support 4k (linear or UBWC doesnt matter).
>>>
>>>>> You can relax it in the virtual plane series.
>>>>>
>>>>> Regarding issues, this is where it gets tricky. We should be aligning
>>>>> with what the product supports. QC will not support issues arising 
>>>>> with
>>>>> 4K on chipsets on which 4K is not advertized.
>>>>
>>>> So, we have several different items here:
>>>> - SmartDMA v2 per se, supporting two rectangles per VIG or DMA plane,
>>>> - Source split support,
>>>> - Supporting 4k modes.
>>>>
>>>> I think we should tend them one by one. This series concerns SmartDMA
>>>> v2. Using SmartDMA it is possible to use two rectangles side by side
>>>> to emulate a wide plane. This series doesn't care at all about max
>>>> resolutions. These two items are completely orthogonal.
>>>>
>>>
>>> No its not orthogonal. Relaxing the maxlinewidth check in the
>>> atomic_check() will allow 4K layers now even on chipsets where 4K wasnt
>>> advertized. Linear or UBWC doesnt matter as the spec doesnt go into 
>>> that.
>>
>> Please correct my answers, if I got something wrong here:
>>
>> Does sc7180 support SmartDMA? Yes it does.
>> Can QC or CrOS validate SmartDMA separately on sc7180? I hope you can.
>> Should the hw-supported feature be enabled? Yes, it should.
>>
>> Now limiting out 4k by not supporting SmartDMA looks like a misfeature.
>> I can only suggest sending a change to block 4k on sc7180.
>>
> 
> Agreed. We should first block 4K on sc7180 and other devices which dont 
> advertize 4k. No, it was never a question of limiting out 4K by not 
> supporting smartDMA but the other way around. By supporting smartDMA, we 
> would have had to support 4K on some chipsets due to this change which I 
> didnt want to do.
> 
> And yes agreed that we can stop discussing 4K anymore on this patch but 
> not smartDMA itself. Please see below.
> 
>>>>>>> As you are aware,  we have an open bug today that we do not 
>>>>>>> filter out
>>>>>>> the modes which we do not support.
>>>>>>>
>>>>>>> https://gitlab.freedesktop.org/drm/msm/-/issues/21
>>>>>>
>>>>>> I thought that with the link-frequencies in place and with the DSI
>>>>>> checking the OPP tables this issue is mostly handled. Isn't it?
>>>>>> Is a mode check in the DPU driver itself the last missing piece?
>>>>>>
>>>>>
>>>>> opp based checking was implemented only for DSI. That one is byte 
>>>>> clk based.
>>>>>
>>>>> DP uses link rate for opp table.
>>>>>
>>>>> Even with a 5.4G link rate (the one in sc7180 chromebook) 4k@30 would
>>>>> still be possible but it was not advertized
>>>>>
>>>>> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>>>>>
>>>>> These docs are available in public domain.
>>>>>
>>>>> As we synced up last time on
>>>>> https://patchwork.freedesktop.org/series/107917/, even with these 
>>>>> limits
>>>>> in place, its not matching the advertized limits.
>>>>>
>>>>>>>
>>>>>>> Due to this, on all chipsets we will end up trying to do a 4K on
>>>>>>> external display which we dont know what bugs it will expose.
>>>>>>
>>>>>> If we do not expose bugs, we do not have a way to fix them. And I
>>>>>> definitely think that all the bugs should be listed as early as
>>>>>> possible, while both of us still remember the code under the 
>>>>>> question.
>>>>>>
>>>>>
>>>>> Yes but on chipsets where 4K is supported ( and hence needed ).
>>>>
>>>> 4k, SmartDMA, src-split, split-display, etc.
>>>>
>>>
>>> The visual issues reported on sdm845 on the other thread are a classic
>>> example of what I just wrote on that patchset and thats why I was
>>> emphasizing a visual validation OR in other words enable the feature on
>>> which you are able to visually validate it.
>>
>> Yes. And if we did not enable the feature, Amit would not be able to
>> spot that. I can repeat my suggestion:
>>
>> - prevalidate these features for the accessible platforms (e.g. I only
>> have sdm845, sm8250 and sm8350 at hand)
> 
> How? Your validation is not with a compositor in most cases and just 
> with modetest.

Yes, I mostly validated it using the modetest up to now. It was enough 
to spot most of the issues during development.

My plan is to validate it with wayland on C630 (sdm850, DP), X11 on RB3 
(sdm845, DSI) and, once I get back to the office, X11 on RB5 (sm8250, 
DSI). I did not have particular plans for sm8350, but it might also be 
worth giving it a try.

>> - enable SmartDMA for all chipsets where SmartDMA is supported
>> - collect possible tested-by and broken-at reports, while the patches
>> sit in linux-next
> 
> Question:
> 
> 1) Who will test these on all the devices for us? This is what I had 
> written even before that someone should give Tested-by tags then.
> 
> Even if you have them on linux-next, someone has to test them voluntarily.

My plan is to depend on the contributors of the corresponding platforms. 
In other words, Bjorn (for sc8180x/sc8280xp), Neal (sm8450/sm8550) and 
hopefully Marijn or Adam (for sm6115 and maybe other platforms)

> 2) Who will look at these broken-at reports and debug them?

The author of the patchset, me. With the hope that you can help in 
obscure cases.

> 
>> - disable SmartDMA basing on the feedback from the previous step (e.g.
>> select from 'mostly disable', 'disable for the bugged cases', 'do not
>> disable at all', etc).
>>    I can promise that if we see a significant validation failure rate I
>> will not oppose disabling SmartDMA.
>>
> 
> Thanks for agreeing on this :)
> 
>> As a reminder: if the patchset is ready at the time of 6.3-rc1 (in
>> three weeks from now), it is going to be merged into linux-next first,
>> after that it can go into the main Linus'es tree at 6.4-rc1. So we
>> will have _two_ kernel cycles to collect bug reports and to disable
>> (or fix) broken cases.
>>
> 
>>> We can evaluate and enable smartDMA on other chipsets on a need basis.
>>>
>>> We discussed this again even today in the team discussion. Our team's
>>> PoV doesnt change. We would still like to enable smartDMA only on
>>> chipsets which can be visually validated first to limit the debugging
>>> effort to one chipset first and then perfect it. Otherwise its too much
>>> effort on QC side to debug those issues on all chipsets.
>>
>> I think QC mostly debugs issues on sc7180/sc7280 and sometimes on
>> sdm845/sm8250 (and now on sm8350). I think we can let people
>> (somainline, PmOS) test features on other platforms.
>> And testing happens better if we can say 'please test linux-next'
>> rather than 'please test linux-next + this patch to enable the feature
>> + that patch to enable the second patch of the feature'.
>>
> 
> In this particular case, in the current timeframe QC can only commit to 
> validate sc7280 at this point and not sc7180, sdm845, sm8250 and sm8350 
> for this feature.

This is both good and bad. Not being able to test sc7180 sounds 
particularly bad. I still didn't have time to work on my sc7180 laptop. 
It still has WoA.

> 
> So it will be upto you and others for all other targets.
> 
> Yes, I agree, people prefer to test on a branch rather than branch + 
> patches.

Good.

> 
>>>>>>> So lets say if we test it on sc7280 fully but not on sc7180, we will
>>>>>>> still hit this condition on sc7180 too but on that chipset we did 
>>>>>>> not
>>>>>>> advertise 4K as a capability in the product spec.
>>>>>>
>>>>>> Is it 'not advertised' or 'not supported by hw'?
>>>>>>
>>>>>
>>>>> The document
>>>>> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>>>>> is made from inputs from not just display team but overall system
>>>>> limits. So even though you could argue that this falls within the
>>>>> display capabilities, all I can say at the moment is we have to 
>>>>> stick to
>>>>> the advertized limits as its compiled with inputs from all the teams
>>>>> (system/performance etc).
>>>>
>>>> So, there should be a limiting factor (or a combination of them).
>>>> Filter out 4k modes on sc7180. Or modes using fill rate higher than N.
>>>> Pixel clock rate higher than M. But it has nothing to do with these
>>>> patches enabling SmartDMA support on this platform.
>>>>
>>>> Even if we look at the vendor kernels, we don't see 'maximum external
>>>> resolution'. Instead I see a combination of linewidth and bandwidth
>>>> limitations. If we can stick to that, that would be great.
>>>>
>>>
>>> Can you please point me to bandwidth limitation checks? How are other
>>> vendors coming up with this number? It has to be based on some
>>> resolution too right?
>>
>> Usually it is considered in the other direction. The SoC can support
>> this-and-that pixel clock and bandwidth, so put the NxM resolution to
>> the datasheet as the max supported one.
>>
> Our data sheet also gave the resolution so I chose the pixel clk last time.
> 
>> Can you point out how the vendor kernel limits DP modes? I checked out
>> several dtsi files. For sm8250 the DP is limited to 1920x1080 (while
>> PB explicitly mentions 4k@60).
> 
> Where do you see 1920x1080? In kona-sde.dtsi I see 675000

I have been looking at the DTSI files for the RB5 board. See post-CS8 
and post-CS9 releases.

> 
>> sm7125 is limited to 2560x1600. sm6150 again 1920x1080. From the pile
>> of the DTS that I have here the rest lists only
>> qcom,max-pclk-frequency-khz
> 
> Yes, qcom,max-pclk-frequency-khz is the method they use.
> 
>>
>>> My RFC https://patchwork.freedesktop.org/series/107917/ considered pixel
>>> clk as the limiting factor which was posted after discussions
>>> internally. In the absence of another way, that remains the only
>>> solution to tackle this.
>>
>> If I remember correctly the mentioned patchset used manually crafted
>> pixel clocks. And for example for sm8250 this clock doesn't correspond
>> to verifiable source.
>> Your patchset used 594000 KHz as max ext pclk for sm8250. vendor dtsi
>> lists 187500 KHz as maximum DP pclk for RB5 and 150000 KHz in all
> 
> Lets discuss this more when I re-post the patch to limit 4K modes.
> 
>> other cases. And, at the same time, it lists a 3840x2160@60 mode for
>> the DSI/lt9611uxc with the pixel clock as high as 608040 KHz.
>>
>> I suggest we stop the discussion at this point, unless there is
>> anything else wrong with this patchset itself.
>>
> 
> Agreed but please look at my comments about smartDMA validation above 
> and let me know.
> 
>> I noted the point regarding UBWC & parallel mode. I will handle it in
>> the next iteration.
>>
>> I noted your valid point about the visual verification. I proposed a
>> way to ease validation, allowing it to be enabled for testers and
>> early adopters for nearly two cycles. I hope you'd agree to this plan.
>> I on the other side agree to revert to opt-in if the failure rate is
>> high.
>>
> 
> Agreed but with above concerns.

Thanks!

> 
>> Please stop bringing max resolution issues to this patchserie. It must
> 
> It got dragged into this patch because this patch relaxed the checks for 
> max resolution.
> 
>> be handled separately. I hope to see the mode filter patch targeting
>> sc7180 & sc7280. With the DSI opp check in place I think we should
>> concentrate on the DP case. If nothing else, I think even adding the
>> max PCLK to the msm_dp_desc should be sufficient to your worries. I'd
>> prefer to be able to override it for the particular board, but I think
>> this can come later, as it would require an agreement from the DT
>> schema team.
>>
> 
> Alright, I can rebase that RFC to cover the DP cases for now and we can 
> discuss all the max resolution discussions there.

Thanks!

> 
>> -- 
>> With best wishes
>> Dmitry

-- 
With best wishes
Dmitry


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

* Re: [Freedreno] [PATCH v3 27/27] drm/msm/dpu: add support for wide planes
@ 2023-02-10  2:46                   ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-10  2:46 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Kalyan Thota, freedreno, Bjorn Andersson, dri-devel,
	Stephen Boyd, linux-arm-msm, Sean Paul

On 10/02/2023 03:12, Abhinav Kumar wrote:
> Hi Dmitry
> 
> On 2/9/2023 4:09 PM, Dmitry Baryshkov wrote:
>>   .
>>
>> On Fri, 10 Feb 2023 at 00:12, Abhinav Kumar 
>> <quic_abhinavk@quicinc.com> wrote:
>>>
>>> Hi Dmitry
>>>
>>> On 2/9/2023 1:23 PM, Dmitry Baryshkov wrote:
>>>> Hi Abhinav,
>>>>
>>>> On Thu, 9 Feb 2023 at 21:25, Abhinav Kumar 
>>>> <quic_abhinavk@quicinc.com> wrote:
>>>>>
>>>>>
>>>>>
>>>>> On 2/9/2023 3:45 AM, Dmitry Baryshkov wrote:
>>>>>> On Thu, 9 Feb 2023 at 04:19, Abhinav Kumar 
>>>>>> <quic_abhinavk@quicinc.com> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>>>>> Typically SSPP can support rectangle with width up to 2560. 
>>>>>>>> However it's
>>>>>>>
>>>>>>> Not always 2560. Depends on the chipset.
>>>>>>
>>>>>> _typically_
>>>>>>
>>>>>
>>>>> Would just say maxlinewidth of SSPP instead of giving some 
>>>>> hardcoded number.
>>>>
>>>> Ack.
>>>>
>>>>>
>>>>>>>
>>>>>>>> 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  |   6 ++
>>>>>>>>      drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 116 
>>>>>>>> +++++++++++++++++++---
>>>>>>>>      drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   4 +
>>>>>>>>      3 files changed, 114 insertions(+), 12 deletions(-)
>>>>>>>>
>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>>>>> index 0ca3bc38ff7e..867832a752b2 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>>>>> @@ -485,6 +485,12 @@ static void 
>>>>>>>> _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
>>>>>>>>                                             fetch_active,
>>>>>>>>                                             &pstate->pipe);
>>>>>>>>
>>>>>>>> +             _dpu_crtc_blend_setup_pipe(crtc, plane,
>>>>>>>> +                                        mixer, cstate->num_mixers,
>>>>>>>> +                                        stage_cfg, 
>>>>>>>> pstate->stage, 1,
>>>>>>>> +                                        fetch_active,
>>>>>>>> +                                        &pstate->r_pipe);
>>>>>>>> +
>>>>>>>>                  /* blend config update */
>>>>>>>>                  for (lm_idx = 0; lm_idx < cstate->num_mixers; 
>>>>>>>> lm_idx++) {
>>>>>>>>                          _dpu_crtc_setup_blend_cfg(mixer + 
>>>>>>>> lm_idx, pstate, format);
>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>>>> index e2e85688ed3c..401ead64c6bd 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>>>>> @@ -365,6 +365,9 @@ static void _dpu_plane_set_qos_ctrl(struct 
>>>>>>>> drm_plane *plane,
>>>>>>>>          struct dpu_plane *pdpu = to_dpu_plane(plane);
>>>>>>>>          struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
>>>>>>>>
>>>>>>>> +     if (!pipe->sspp)
>>>>>>>> +             return;
>>>>>>>> +
>>>>>>>>          memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
>>>>>>>>
>>>>>>>>          if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
>>>>>>>> @@ -647,6 +650,9 @@ static int _dpu_plane_color_fill_pipe(struct 
>>>>>>>> dpu_plane_state *pstate,
>>>>>>>>      {
>>>>>>>>          struct dpu_hw_sspp_cfg pipe_cfg;
>>>>>>>>
>>>>>>>> +     if (!pipe->sspp)
>>>>>>>> +             return 0;
>>>>>>>
>>>>>>> instead of checking if sspp was present, is it not better for the 
>>>>>>> caller
>>>>>>> to check if the rpipe is valid before calling this?
>>>>>>>
>>>>>>>> +
>>>>>>>>          /* update sspp */
>>>>>>>>          if (!pipe->sspp->ops.setup_solidfill)
>>>>>>>>                  return 0;
>>>>>>>> @@ -701,6 +707,8 @@ static void _dpu_plane_color_fill(struct 
>>>>>>>> dpu_plane *pdpu,
>>>>>>>>
>>>>>>>>          /* update sspp */
>>>>>>>>          _dpu_plane_color_fill_pipe(pstate, &pstate->pipe, 
>>>>>>>> &pstate->pipe_cfg, fill_color, fmt);
>>>>>>>> +
>>>>>>>> +     _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe, 
>>>>>>>> &pstate->r_pipe_cfg, fill_color, fmt);
>>>>>>>>      }
>>>>>>>
>>>>>>> So cant we do
>>>>>>>
>>>>>>> if (pstate->r_pipe.sspp)
>>>>>>>            _dpu_plane_color_fill_pipe(pstate, &pstate->r_pipe,
>>>>>>>                    &pstate->r_pipe_cfg, fill_color, fmt);
>>>>>>>
>>>>>>> It just seems better to me as the caller would already know if 
>>>>>>> the sspp
>>>>>>> was assigned.
>>>>>>
>>>>>>     I think I had this kind of code earlier, but then I found it more
>>>>>> logical to move the check to the called function. I'll move it back.
>>>>>>
>>>>>>>
>>>>>>>>
>>>>>>>>      int dpu_plane_validate_multirect_v2(struct 
>>>>>>>> dpu_multirect_plane_states *plane)
>>>>>>>> @@ -911,6 +919,9 @@ static int 
>>>>>>>> dpu_plane_atomic_check_pipe(struct dpu_plane *pdpu,
>>>>>>>>      {
>>>>>>>>          uint32_t min_src_size;
>>>>>>>>
>>>>>>>> +     if (!pipe->sspp)
>>>>>>>> +             return 0;
>>>>>>>> +
>>>>>>>>          min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
>>>>>>>>
>>>>>>>>          if (DPU_FORMAT_IS_YUV(fmt) &&
>>>>>>>> @@ -957,9 +968,12 @@ 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;
>>>>>>>> +     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_sspp_cfg *pipe_cfg = &pstate->pipe_cfg;
>>>>>>>> +     struct dpu_hw_sspp_cfg *r_pipe_cfg = &pstate->r_pipe_cfg;
>>>>>>>>          struct drm_rect fb_rect = { 0 };
>>>>>>>>          uint32_t max_linewidth;
>>>>>>>>          unsigned int rotation;
>>>>>>>> @@ -983,8 +997,11 @@ 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;
>>>>>>>> +     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) {
>>>>>>>> @@ -1016,16 +1033,53 @@ static int dpu_plane_atomic_check(struct 
>>>>>>>> drm_plane *plane,
>>>>>>>>
>>>>>>>>          max_linewidth = pdpu->catalog->caps->max_linewidth;
>>>>>>>>
>>>>>>>> -     /* check decimated source width */
>>>>>>>>          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;
>>>>>>>> +             /* 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;
>>>>>>>> +             }
>>>>>>>
>>>>>>> This is where I am a bit concerned enabling it for all chipsets 
>>>>>>> in one go.
>>>>>>
>>>>>> As I wrote earlier, I'd prefer the opt-out rather than opt-in 
>>>>>> here. It
>>>>>> is much easier to handle the reports "I have a device with sm6543,
>>>>>> where the display worked before 6.4, but started failing afterwards"
>>>>>> rather than trying to find a person with sm6543 and asking him if he
>>>>>> can enable this and that on his device. And even a lower chance of a
>>>>>> person with sm6543 coming up with a patch 'hey, I enabled this for my
>>>>>> phone and it works!'.
>>>>>>
>>>>>> If we find any issues during or close to the end of the development
>>>>>> cycle, we can add a 'don't enable wide plane here' switch and enable
>>>>>> it for failing platforms. But each enablement of this switch should
>>>>>> come with a reason (wide planes not working here because ....). In 
>>>>>> the
>>>>>> end this switch should be gone and transformed into proper HW
>>>>>> limitation checks.
>>>>>>
>>>>>
>>>>> As it has become clear that with this patch series 4K with UBWC cannot
>>>>> be supported without true virtual planes (with two SSPPs), why do you
>>>>> need to relax this check right now?
>>>>
>>>> Yes. It enables support for 4k @ linear formats. So my plan for this
>>>> series is to land 4k with all the proper applicable restrictions.
>>>>
>>>>> You can relax this when you add the support for virtual planes till 
>>>>> then
>>>>> let it be this way.
>>>>>
>>>>> Its not going to break smartDMA as such. You can still use it for 
>>>>> layers
>>>>> < 2560.
>>>>>
>>>>> That way we stay true to the purpose of the feature. I think 
>>>>> originally
>>>>> you wanted to get this in for smartDMA and not to support wide 
>>>>> plane and
>>>>> that purpose will still be achieved even with keeping this check 
>>>>> intact.
>>>>
>>>> Actually, no. With this series I wanted to get 4k. It was developed in
>>>> parallel with the 4k enablement for RB3 (posted, bridge patches are
>>>> being merged for 6.3) and RB5 (delayed for now, I have other issues
>>>> there).
>>>>
>>>
>>> With the UBWC related checks, this wont support 4K for UBWC layers which
>>> is default on QC chipsets. So I am fine with respect to that. But still
>>> this does not address the product spec advertized modes. Like I
>>> mentioned before, relaxing the maxlinewidth check with the added UBWC
>>> checks is fine from DPU point of view but not from the product POV.
>>>
>>> As things stand today, this is the only check failing the 4K modes on
>>> chipsets which shouldnt support 4k (linear or UBWC doesnt matter).
>>>
>>>>> You can relax it in the virtual plane series.
>>>>>
>>>>> Regarding issues, this is where it gets tricky. We should be aligning
>>>>> with what the product supports. QC will not support issues arising 
>>>>> with
>>>>> 4K on chipsets on which 4K is not advertized.
>>>>
>>>> So, we have several different items here:
>>>> - SmartDMA v2 per se, supporting two rectangles per VIG or DMA plane,
>>>> - Source split support,
>>>> - Supporting 4k modes.
>>>>
>>>> I think we should tend them one by one. This series concerns SmartDMA
>>>> v2. Using SmartDMA it is possible to use two rectangles side by side
>>>> to emulate a wide plane. This series doesn't care at all about max
>>>> resolutions. These two items are completely orthogonal.
>>>>
>>>
>>> No its not orthogonal. Relaxing the maxlinewidth check in the
>>> atomic_check() will allow 4K layers now even on chipsets where 4K wasnt
>>> advertized. Linear or UBWC doesnt matter as the spec doesnt go into 
>>> that.
>>
>> Please correct my answers, if I got something wrong here:
>>
>> Does sc7180 support SmartDMA? Yes it does.
>> Can QC or CrOS validate SmartDMA separately on sc7180? I hope you can.
>> Should the hw-supported feature be enabled? Yes, it should.
>>
>> Now limiting out 4k by not supporting SmartDMA looks like a misfeature.
>> I can only suggest sending a change to block 4k on sc7180.
>>
> 
> Agreed. We should first block 4K on sc7180 and other devices which dont 
> advertize 4k. No, it was never a question of limiting out 4K by not 
> supporting smartDMA but the other way around. By supporting smartDMA, we 
> would have had to support 4K on some chipsets due to this change which I 
> didnt want to do.
> 
> And yes agreed that we can stop discussing 4K anymore on this patch but 
> not smartDMA itself. Please see below.
> 
>>>>>>> As you are aware,  we have an open bug today that we do not 
>>>>>>> filter out
>>>>>>> the modes which we do not support.
>>>>>>>
>>>>>>> https://gitlab.freedesktop.org/drm/msm/-/issues/21
>>>>>>
>>>>>> I thought that with the link-frequencies in place and with the DSI
>>>>>> checking the OPP tables this issue is mostly handled. Isn't it?
>>>>>> Is a mode check in the DPU driver itself the last missing piece?
>>>>>>
>>>>>
>>>>> opp based checking was implemented only for DSI. That one is byte 
>>>>> clk based.
>>>>>
>>>>> DP uses link rate for opp table.
>>>>>
>>>>> Even with a 5.4G link rate (the one in sc7180 chromebook) 4k@30 would
>>>>> still be possible but it was not advertized
>>>>>
>>>>> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>>>>>
>>>>> These docs are available in public domain.
>>>>>
>>>>> As we synced up last time on
>>>>> https://patchwork.freedesktop.org/series/107917/, even with these 
>>>>> limits
>>>>> in place, its not matching the advertized limits.
>>>>>
>>>>>>>
>>>>>>> Due to this, on all chipsets we will end up trying to do a 4K on
>>>>>>> external display which we dont know what bugs it will expose.
>>>>>>
>>>>>> If we do not expose bugs, we do not have a way to fix them. And I
>>>>>> definitely think that all the bugs should be listed as early as
>>>>>> possible, while both of us still remember the code under the 
>>>>>> question.
>>>>>>
>>>>>
>>>>> Yes but on chipsets where 4K is supported ( and hence needed ).
>>>>
>>>> 4k, SmartDMA, src-split, split-display, etc.
>>>>
>>>
>>> The visual issues reported on sdm845 on the other thread are a classic
>>> example of what I just wrote on that patchset and thats why I was
>>> emphasizing a visual validation OR in other words enable the feature on
>>> which you are able to visually validate it.
>>
>> Yes. And if we did not enable the feature, Amit would not be able to
>> spot that. I can repeat my suggestion:
>>
>> - prevalidate these features for the accessible platforms (e.g. I only
>> have sdm845, sm8250 and sm8350 at hand)
> 
> How? Your validation is not with a compositor in most cases and just 
> with modetest.

Yes, I mostly validated it using the modetest up to now. It was enough 
to spot most of the issues during development.

My plan is to validate it with wayland on C630 (sdm850, DP), X11 on RB3 
(sdm845, DSI) and, once I get back to the office, X11 on RB5 (sm8250, 
DSI). I did not have particular plans for sm8350, but it might also be 
worth giving it a try.

>> - enable SmartDMA for all chipsets where SmartDMA is supported
>> - collect possible tested-by and broken-at reports, while the patches
>> sit in linux-next
> 
> Question:
> 
> 1) Who will test these on all the devices for us? This is what I had 
> written even before that someone should give Tested-by tags then.
> 
> Even if you have them on linux-next, someone has to test them voluntarily.

My plan is to depend on the contributors of the corresponding platforms. 
In other words, Bjorn (for sc8180x/sc8280xp), Neal (sm8450/sm8550) and 
hopefully Marijn or Adam (for sm6115 and maybe other platforms)

> 2) Who will look at these broken-at reports and debug them?

The author of the patchset, me. With the hope that you can help in 
obscure cases.

> 
>> - disable SmartDMA basing on the feedback from the previous step (e.g.
>> select from 'mostly disable', 'disable for the bugged cases', 'do not
>> disable at all', etc).
>>    I can promise that if we see a significant validation failure rate I
>> will not oppose disabling SmartDMA.
>>
> 
> Thanks for agreeing on this :)
> 
>> As a reminder: if the patchset is ready at the time of 6.3-rc1 (in
>> three weeks from now), it is going to be merged into linux-next first,
>> after that it can go into the main Linus'es tree at 6.4-rc1. So we
>> will have _two_ kernel cycles to collect bug reports and to disable
>> (or fix) broken cases.
>>
> 
>>> We can evaluate and enable smartDMA on other chipsets on a need basis.
>>>
>>> We discussed this again even today in the team discussion. Our team's
>>> PoV doesnt change. We would still like to enable smartDMA only on
>>> chipsets which can be visually validated first to limit the debugging
>>> effort to one chipset first and then perfect it. Otherwise its too much
>>> effort on QC side to debug those issues on all chipsets.
>>
>> I think QC mostly debugs issues on sc7180/sc7280 and sometimes on
>> sdm845/sm8250 (and now on sm8350). I think we can let people
>> (somainline, PmOS) test features on other platforms.
>> And testing happens better if we can say 'please test linux-next'
>> rather than 'please test linux-next + this patch to enable the feature
>> + that patch to enable the second patch of the feature'.
>>
> 
> In this particular case, in the current timeframe QC can only commit to 
> validate sc7280 at this point and not sc7180, sdm845, sm8250 and sm8350 
> for this feature.

This is both good and bad. Not being able to test sc7180 sounds 
particularly bad. I still didn't have time to work on my sc7180 laptop. 
It still has WoA.

> 
> So it will be upto you and others for all other targets.
> 
> Yes, I agree, people prefer to test on a branch rather than branch + 
> patches.

Good.

> 
>>>>>>> So lets say if we test it on sc7280 fully but not on sc7180, we will
>>>>>>> still hit this condition on sc7180 too but on that chipset we did 
>>>>>>> not
>>>>>>> advertise 4K as a capability in the product spec.
>>>>>>
>>>>>> Is it 'not advertised' or 'not supported by hw'?
>>>>>>
>>>>>
>>>>> The document
>>>>> https://www.qualcomm.com/content/dam/qcomm-martech/dm-assets/documents/prod_brief_qcom_sd7c.pdf
>>>>> is made from inputs from not just display team but overall system
>>>>> limits. So even though you could argue that this falls within the
>>>>> display capabilities, all I can say at the moment is we have to 
>>>>> stick to
>>>>> the advertized limits as its compiled with inputs from all the teams
>>>>> (system/performance etc).
>>>>
>>>> So, there should be a limiting factor (or a combination of them).
>>>> Filter out 4k modes on sc7180. Or modes using fill rate higher than N.
>>>> Pixel clock rate higher than M. But it has nothing to do with these
>>>> patches enabling SmartDMA support on this platform.
>>>>
>>>> Even if we look at the vendor kernels, we don't see 'maximum external
>>>> resolution'. Instead I see a combination of linewidth and bandwidth
>>>> limitations. If we can stick to that, that would be great.
>>>>
>>>
>>> Can you please point me to bandwidth limitation checks? How are other
>>> vendors coming up with this number? It has to be based on some
>>> resolution too right?
>>
>> Usually it is considered in the other direction. The SoC can support
>> this-and-that pixel clock and bandwidth, so put the NxM resolution to
>> the datasheet as the max supported one.
>>
> Our data sheet also gave the resolution so I chose the pixel clk last time.
> 
>> Can you point out how the vendor kernel limits DP modes? I checked out
>> several dtsi files. For sm8250 the DP is limited to 1920x1080 (while
>> PB explicitly mentions 4k@60).
> 
> Where do you see 1920x1080? In kona-sde.dtsi I see 675000

I have been looking at the DTSI files for the RB5 board. See post-CS8 
and post-CS9 releases.

> 
>> sm7125 is limited to 2560x1600. sm6150 again 1920x1080. From the pile
>> of the DTS that I have here the rest lists only
>> qcom,max-pclk-frequency-khz
> 
> Yes, qcom,max-pclk-frequency-khz is the method they use.
> 
>>
>>> My RFC https://patchwork.freedesktop.org/series/107917/ considered pixel
>>> clk as the limiting factor which was posted after discussions
>>> internally. In the absence of another way, that remains the only
>>> solution to tackle this.
>>
>> If I remember correctly the mentioned patchset used manually crafted
>> pixel clocks. And for example for sm8250 this clock doesn't correspond
>> to verifiable source.
>> Your patchset used 594000 KHz as max ext pclk for sm8250. vendor dtsi
>> lists 187500 KHz as maximum DP pclk for RB5 and 150000 KHz in all
> 
> Lets discuss this more when I re-post the patch to limit 4K modes.
> 
>> other cases. And, at the same time, it lists a 3840x2160@60 mode for
>> the DSI/lt9611uxc with the pixel clock as high as 608040 KHz.
>>
>> I suggest we stop the discussion at this point, unless there is
>> anything else wrong with this patchset itself.
>>
> 
> Agreed but please look at my comments about smartDMA validation above 
> and let me know.
> 
>> I noted the point regarding UBWC & parallel mode. I will handle it in
>> the next iteration.
>>
>> I noted your valid point about the visual verification. I proposed a
>> way to ease validation, allowing it to be enabled for testers and
>> early adopters for nearly two cycles. I hope you'd agree to this plan.
>> I on the other side agree to revert to opt-in if the failure rate is
>> high.
>>
> 
> Agreed but with above concerns.

Thanks!

> 
>> Please stop bringing max resolution issues to this patchserie. It must
> 
> It got dragged into this patch because this patch relaxed the checks for 
> max resolution.
> 
>> be handled separately. I hope to see the mode filter patch targeting
>> sc7180 & sc7280. With the DSI opp check in place I think we should
>> concentrate on the DP case. If nothing else, I think even adding the
>> max PCLK to the msm_dp_desc should be sufficient to your worries. I'd
>> prefer to be able to override it for the particular board, but I think
>> this can come later, as it would require an agreement from the DT
>> schema team.
>>
> 
> Alright, I can rebase that RFC to cover the DP cases for now and we can 
> discuss all the max resolution discussions there.

Thanks!

> 
>> -- 
>> With best wishes
>> Dmitry

-- 
With best wishes
Dmitry


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

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

Hi Dmitry

Sorry for the late response on this one.

On 2/3/2023 2:55 PM, Dmitry Baryshkov wrote:
> On 04/02/2023 00:44, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> Move plane state updates from dpu_crtc_atomic_check() to the function
>>> where they belong: to dpu_plane_atomic_check().
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-----------------
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++++++++++--------
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ------
>>>   3 files changed, 11 insertions(+), 31 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> index b485234eefb2..bd09bb319a58 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> @@ -1129,7 +1129,6 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>>>       const struct drm_plane_state *pstate;
>>>       struct drm_plane *plane;
>>> @@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct 
>>> drm_crtc *crtc,
>>>       crtc_rect.x2 = mode->hdisplay;
>>>       crtc_rect.y2 = mode->vdisplay;
>>> -     /* get plane state for all drm planes associated with crtc 
>>> state */
>>> +    /* FIXME: move this to dpu_plane_atomic_check? */
>>>       drm_atomic_crtc_state_for_each_plane_state(plane, pstate, 
>>> crtc_state) {
>>>           struct dpu_plane_state *dpu_pstate = 
>>> to_dpu_plane_state(pstate);
>>>           struct drm_rect dst, clip = crtc_rect;
>>> -        int stage;
>>>           if (IS_ERR_OR_NULL(pstate)) {
>>>               rc = PTR_ERR(pstate);
>>> @@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct 
>>> drm_crtc *crtc,
>>>           dpu_pstate->needs_dirtyfb = needs_dirtyfb;
>>> -        dpu_plane_clear_multirect(pstate);
>>> -
>>>           dst = drm_plane_state_dest(pstate);
>>>           if (!drm_rect_intersect(&clip, &dst)) {
>>>               DPU_ERROR("invalid vertical/horizontal destination\n");
>>> @@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct 
>>> drm_crtc *crtc,
>>>                     DRM_RECT_ARG(&dst));
>>>               return -E2BIG;
>>>           }
>>> -
>>> -        /* verify stage setting before using it */
>>> -        stage = DPU_STAGE_0 + pstate->normalized_zpos;
>>> -        if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
>>> -            DPU_ERROR("> %d plane stages assigned\n",
>>> -                    dpu_kms->catalog->caps->max_mixer_blendstages - 
>>> DPU_STAGE_0);
>>> -            return -EINVAL;
>>> -        }
>>> -
>>> -        to_dpu_plane_state(pstate)->stage = stage;
>>> -        DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
>>> -
>>>       }
>>>       atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> index 1b3033b15bfa..5aabf9694a53 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -733,14 +733,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];
>>> @@ -994,6 +986,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;
>>> +
>>
>> But I am not sure if clearing the multirect belongs here and now I 
>> want to clarify one thing about 
>> https://patchwork.freedesktop.org/patch/521354/?series=99909&rev=4 
>> which was R-bed in the v1 and carried fwd since then.
>>
>> So prior to that change, we were only clearing the multirects of the 
>> planes that were staged to the crtc and we were getting those from the 
>> crtc state. But now we are clearing the multirect of all the planes.
>>
>> Dont we have to keep that in the crtc_atomic_check() since we do that 
>> on all the planes attached to a certain CRTC.
>>
>> In that case shouldnt we keep this in the crtc_atomic_check() and 
>> bring back pipe_staged[] without the multirect and source split cases 
>> ofcourse.
> 
> What for? In other words, what would be the difference?
> 

So, please correct my understanding here. drm_plane's atomic_check() 
will be called for all the planes which are getting updated in this 
atomic commit using for_each_oldnew_plane_in_state() and drm_crtc's 
atomic_check() will be called for all the CRTC's in this atomic update 
using for_each_new_crtc_in_state().

If the plane is not connected to any CRTC, why do we need to clear the 
multirect pstates.

OR in that case would atomic_commit not even be called if the plane is 
not connected to any CRTC?

One case i can think of is the disable commit where the no planes will 
be connected to the CRTC so in that case, before this change we would 
explicitly clear out all the planes connected to the CRTC but now with 
this change is there a possibility that only if the plane state changed 
we would clear it out?

	
>>
>>> +    pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
>>> +    if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
>>> +        DPU_ERROR("> %d plane stages assigned\n",
>>> +                pdpu->catalog->caps->max_mixer_blendstages - 
>>> DPU_STAGE_0);
>>> +        return -EINVAL;
>>> +    }
>>> +
>>
>> I agree that this check belongs to the plane_atomic_check().
>>
>>>       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 228db401e905..a08b0539513b 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> @@ -88,12 +88,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] 176+ messages in thread

* Re: [PATCH v3 15/27] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
@ 2023-02-14 23:25         ` Abhinav Kumar
  0 siblings, 0 replies; 176+ messages in thread
From: Abhinav Kumar @ 2023-02-14 23:25 UTC (permalink / raw)
  To: Dmitry Baryshkov, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

Hi Dmitry

Sorry for the late response on this one.

On 2/3/2023 2:55 PM, Dmitry Baryshkov wrote:
> On 04/02/2023 00:44, Abhinav Kumar wrote:
>>
>>
>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>> Move plane state updates from dpu_crtc_atomic_check() to the function
>>> where they belong: to dpu_plane_atomic_check().
>>>
>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>> ---
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-----------------
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++++++++++--------
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ------
>>>   3 files changed, 11 insertions(+), 31 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> index b485234eefb2..bd09bb319a58 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>> @@ -1129,7 +1129,6 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>>>       const struct drm_plane_state *pstate;
>>>       struct drm_plane *plane;
>>> @@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct 
>>> drm_crtc *crtc,
>>>       crtc_rect.x2 = mode->hdisplay;
>>>       crtc_rect.y2 = mode->vdisplay;
>>> -     /* get plane state for all drm planes associated with crtc 
>>> state */
>>> +    /* FIXME: move this to dpu_plane_atomic_check? */
>>>       drm_atomic_crtc_state_for_each_plane_state(plane, pstate, 
>>> crtc_state) {
>>>           struct dpu_plane_state *dpu_pstate = 
>>> to_dpu_plane_state(pstate);
>>>           struct drm_rect dst, clip = crtc_rect;
>>> -        int stage;
>>>           if (IS_ERR_OR_NULL(pstate)) {
>>>               rc = PTR_ERR(pstate);
>>> @@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct 
>>> drm_crtc *crtc,
>>>           dpu_pstate->needs_dirtyfb = needs_dirtyfb;
>>> -        dpu_plane_clear_multirect(pstate);
>>> -
>>>           dst = drm_plane_state_dest(pstate);
>>>           if (!drm_rect_intersect(&clip, &dst)) {
>>>               DPU_ERROR("invalid vertical/horizontal destination\n");
>>> @@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct 
>>> drm_crtc *crtc,
>>>                     DRM_RECT_ARG(&dst));
>>>               return -E2BIG;
>>>           }
>>> -
>>> -        /* verify stage setting before using it */
>>> -        stage = DPU_STAGE_0 + pstate->normalized_zpos;
>>> -        if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
>>> -            DPU_ERROR("> %d plane stages assigned\n",
>>> -                    dpu_kms->catalog->caps->max_mixer_blendstages - 
>>> DPU_STAGE_0);
>>> -            return -EINVAL;
>>> -        }
>>> -
>>> -        to_dpu_plane_state(pstate)->stage = stage;
>>> -        DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
>>> -
>>>       }
>>>       atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> index 1b3033b15bfa..5aabf9694a53 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>> @@ -733,14 +733,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];
>>> @@ -994,6 +986,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;
>>> +
>>
>> But I am not sure if clearing the multirect belongs here and now I 
>> want to clarify one thing about 
>> https://patchwork.freedesktop.org/patch/521354/?series=99909&rev=4 
>> which was R-bed in the v1 and carried fwd since then.
>>
>> So prior to that change, we were only clearing the multirects of the 
>> planes that were staged to the crtc and we were getting those from the 
>> crtc state. But now we are clearing the multirect of all the planes.
>>
>> Dont we have to keep that in the crtc_atomic_check() since we do that 
>> on all the planes attached to a certain CRTC.
>>
>> In that case shouldnt we keep this in the crtc_atomic_check() and 
>> bring back pipe_staged[] without the multirect and source split cases 
>> ofcourse.
> 
> What for? In other words, what would be the difference?
> 

So, please correct my understanding here. drm_plane's atomic_check() 
will be called for all the planes which are getting updated in this 
atomic commit using for_each_oldnew_plane_in_state() and drm_crtc's 
atomic_check() will be called for all the CRTC's in this atomic update 
using for_each_new_crtc_in_state().

If the plane is not connected to any CRTC, why do we need to clear the 
multirect pstates.

OR in that case would atomic_commit not even be called if the plane is 
not connected to any CRTC?

One case i can think of is the disable commit where the no planes will 
be connected to the CRTC so in that case, before this change we would 
explicitly clear out all the planes connected to the CRTC but now with 
this change is there a possibility that only if the plane state changed 
we would clear it out?

	
>>
>>> +    pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
>>> +    if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
>>> +        DPU_ERROR("> %d plane stages assigned\n",
>>> +                pdpu->catalog->caps->max_mixer_blendstages - 
>>> DPU_STAGE_0);
>>> +        return -EINVAL;
>>> +    }
>>> +
>>
>> I agree that this check belongs to the plane_atomic_check().
>>
>>>       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 228db401e905..a08b0539513b 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>> @@ -88,12 +88,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] 176+ messages in thread

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

On 15/02/2023 01:25, Abhinav Kumar wrote:
> Hi Dmitry
> 
> Sorry for the late response on this one.
> 
> On 2/3/2023 2:55 PM, Dmitry Baryshkov wrote:
>> On 04/02/2023 00:44, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>> Move plane state updates from dpu_crtc_atomic_check() to the function
>>>> where they belong: to dpu_plane_atomic_check().
>>>>
>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>> ---
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-----------------
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++++++++++--------
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ------
>>>>   3 files changed, 11 insertions(+), 31 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> index b485234eefb2..bd09bb319a58 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> @@ -1129,7 +1129,6 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>>>>       const struct drm_plane_state *pstate;
>>>>       struct drm_plane *plane;
>>>> @@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct 
>>>> drm_crtc *crtc,
>>>>       crtc_rect.x2 = mode->hdisplay;
>>>>       crtc_rect.y2 = mode->vdisplay;
>>>> -     /* get plane state for all drm planes associated with crtc 
>>>> state */
>>>> +    /* FIXME: move this to dpu_plane_atomic_check? */
>>>>       drm_atomic_crtc_state_for_each_plane_state(plane, pstate, 
>>>> crtc_state) {
>>>>           struct dpu_plane_state *dpu_pstate = 
>>>> to_dpu_plane_state(pstate);
>>>>           struct drm_rect dst, clip = crtc_rect;
>>>> -        int stage;
>>>>           if (IS_ERR_OR_NULL(pstate)) {
>>>>               rc = PTR_ERR(pstate);
>>>> @@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct 
>>>> drm_crtc *crtc,
>>>>           dpu_pstate->needs_dirtyfb = needs_dirtyfb;
>>>> -        dpu_plane_clear_multirect(pstate);
>>>> -
>>>>           dst = drm_plane_state_dest(pstate);
>>>>           if (!drm_rect_intersect(&clip, &dst)) {
>>>>               DPU_ERROR("invalid vertical/horizontal destination\n");
>>>> @@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct 
>>>> drm_crtc *crtc,
>>>>                     DRM_RECT_ARG(&dst));
>>>>               return -E2BIG;
>>>>           }
>>>> -
>>>> -        /* verify stage setting before using it */
>>>> -        stage = DPU_STAGE_0 + pstate->normalized_zpos;
>>>> -        if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
>>>> -            DPU_ERROR("> %d plane stages assigned\n",
>>>> -                    dpu_kms->catalog->caps->max_mixer_blendstages - 
>>>> DPU_STAGE_0);
>>>> -            return -EINVAL;
>>>> -        }
>>>> -
>>>> -        to_dpu_plane_state(pstate)->stage = stage;
>>>> -        DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
>>>> -
>>>>       }
>>>>       atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> index 1b3033b15bfa..5aabf9694a53 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> @@ -733,14 +733,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];
>>>> @@ -994,6 +986,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;
>>>> +
>>>
>>> But I am not sure if clearing the multirect belongs here and now I 
>>> want to clarify one thing about 
>>> https://patchwork.freedesktop.org/patch/521354/?series=99909&rev=4 
>>> which was R-bed in the v1 and carried fwd since then.
>>>
>>> So prior to that change, we were only clearing the multirects of the 
>>> planes that were staged to the crtc and we were getting those from 
>>> the crtc state. But now we are clearing the multirect of all the planes.
>>>
>>> Dont we have to keep that in the crtc_atomic_check() since we do that 
>>> on all the planes attached to a certain CRTC.
>>>
>>> In that case shouldnt we keep this in the crtc_atomic_check() and 
>>> bring back pipe_staged[] without the multirect and source split cases 
>>> ofcourse.
>>
>> What for? In other words, what would be the difference?
>>
> 
> So, please correct my understanding here. drm_plane's atomic_check() 
> will be called for all the planes which are getting updated in this 
> atomic commit using for_each_oldnew_plane_in_state() and drm_crtc's 
> atomic_check() will be called for all the CRTC's in this atomic update 
> using for_each_new_crtc_in_state() >
> If the plane is not connected to any CRTC, why do we need to clear the 
> multirect pstates.

If the plane is not connected to any CRTC, then we just don't care what 
is there in the multirect state, so we might clear it as well.

> 
> OR in that case would atomic_commit not even be called if the plane is 
> not connected to any CRTC?
> 
> One case i can think of is the disable commit where the no planes will 
> be connected to the CRTC so in that case, before this change we would 
> explicitly clear out all the planes connected to the CRTC but now with 
> this change is there a possibility that only if the plane state changed 
> we would clear it out?

Ah. Maybe I understand your point. I think 
drm_atomic_add_affected_planes() will ensure that all planes attached to 
CRTCs are also a part of the atomic state.

Regarding the change itself. Think about encapsulation. CRTC should not 
care about plane's multirect state. It is a plane implementation detail. 
As we delve upon a path of using rect1 and then even using different 
SSPPs for the plane, these implementation details will change (mostly) 
behind CRTC's back.

> 
> 
>>>
>>>> +    pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
>>>> +    if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
>>>> +        DPU_ERROR("> %d plane stages assigned\n",
>>>> +                pdpu->catalog->caps->max_mixer_blendstages - 
>>>> DPU_STAGE_0);
>>>> +        return -EINVAL;
>>>> +    }
>>>> +
>>>
>>> I agree that this check belongs to the plane_atomic_check().
>>>
>>>>       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 228db401e905..a08b0539513b 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>> @@ -88,12 +88,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
>>

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 15/27] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
@ 2023-02-15  0:08           ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-15  0:08 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 15/02/2023 01:25, Abhinav Kumar wrote:
> Hi Dmitry
> 
> Sorry for the late response on this one.
> 
> On 2/3/2023 2:55 PM, Dmitry Baryshkov wrote:
>> On 04/02/2023 00:44, Abhinav Kumar wrote:
>>>
>>>
>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>> Move plane state updates from dpu_crtc_atomic_check() to the function
>>>> where they belong: to dpu_plane_atomic_check().
>>>>
>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>> ---
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-----------------
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++++++++++--------
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ------
>>>>   3 files changed, 11 insertions(+), 31 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> index b485234eefb2..bd09bb319a58 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>> @@ -1129,7 +1129,6 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>>>>       const struct drm_plane_state *pstate;
>>>>       struct drm_plane *plane;
>>>> @@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct 
>>>> drm_crtc *crtc,
>>>>       crtc_rect.x2 = mode->hdisplay;
>>>>       crtc_rect.y2 = mode->vdisplay;
>>>> -     /* get plane state for all drm planes associated with crtc 
>>>> state */
>>>> +    /* FIXME: move this to dpu_plane_atomic_check? */
>>>>       drm_atomic_crtc_state_for_each_plane_state(plane, pstate, 
>>>> crtc_state) {
>>>>           struct dpu_plane_state *dpu_pstate = 
>>>> to_dpu_plane_state(pstate);
>>>>           struct drm_rect dst, clip = crtc_rect;
>>>> -        int stage;
>>>>           if (IS_ERR_OR_NULL(pstate)) {
>>>>               rc = PTR_ERR(pstate);
>>>> @@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct 
>>>> drm_crtc *crtc,
>>>>           dpu_pstate->needs_dirtyfb = needs_dirtyfb;
>>>> -        dpu_plane_clear_multirect(pstate);
>>>> -
>>>>           dst = drm_plane_state_dest(pstate);
>>>>           if (!drm_rect_intersect(&clip, &dst)) {
>>>>               DPU_ERROR("invalid vertical/horizontal destination\n");
>>>> @@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct 
>>>> drm_crtc *crtc,
>>>>                     DRM_RECT_ARG(&dst));
>>>>               return -E2BIG;
>>>>           }
>>>> -
>>>> -        /* verify stage setting before using it */
>>>> -        stage = DPU_STAGE_0 + pstate->normalized_zpos;
>>>> -        if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
>>>> -            DPU_ERROR("> %d plane stages assigned\n",
>>>> -                    dpu_kms->catalog->caps->max_mixer_blendstages - 
>>>> DPU_STAGE_0);
>>>> -            return -EINVAL;
>>>> -        }
>>>> -
>>>> -        to_dpu_plane_state(pstate)->stage = stage;
>>>> -        DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
>>>> -
>>>>       }
>>>>       atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> index 1b3033b15bfa..5aabf9694a53 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>> @@ -733,14 +733,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];
>>>> @@ -994,6 +986,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;
>>>> +
>>>
>>> But I am not sure if clearing the multirect belongs here and now I 
>>> want to clarify one thing about 
>>> https://patchwork.freedesktop.org/patch/521354/?series=99909&rev=4 
>>> which was R-bed in the v1 and carried fwd since then.
>>>
>>> So prior to that change, we were only clearing the multirects of the 
>>> planes that were staged to the crtc and we were getting those from 
>>> the crtc state. But now we are clearing the multirect of all the planes.
>>>
>>> Dont we have to keep that in the crtc_atomic_check() since we do that 
>>> on all the planes attached to a certain CRTC.
>>>
>>> In that case shouldnt we keep this in the crtc_atomic_check() and 
>>> bring back pipe_staged[] without the multirect and source split cases 
>>> ofcourse.
>>
>> What for? In other words, what would be the difference?
>>
> 
> So, please correct my understanding here. drm_plane's atomic_check() 
> will be called for all the planes which are getting updated in this 
> atomic commit using for_each_oldnew_plane_in_state() and drm_crtc's 
> atomic_check() will be called for all the CRTC's in this atomic update 
> using for_each_new_crtc_in_state() >
> If the plane is not connected to any CRTC, why do we need to clear the 
> multirect pstates.

If the plane is not connected to any CRTC, then we just don't care what 
is there in the multirect state, so we might clear it as well.

> 
> OR in that case would atomic_commit not even be called if the plane is 
> not connected to any CRTC?
> 
> One case i can think of is the disable commit where the no planes will 
> be connected to the CRTC so in that case, before this change we would 
> explicitly clear out all the planes connected to the CRTC but now with 
> this change is there a possibility that only if the plane state changed 
> we would clear it out?

Ah. Maybe I understand your point. I think 
drm_atomic_add_affected_planes() will ensure that all planes attached to 
CRTCs are also a part of the atomic state.

Regarding the change itself. Think about encapsulation. CRTC should not 
care about plane's multirect state. It is a plane implementation detail. 
As we delve upon a path of using rect1 and then even using different 
SSPPs for the plane, these implementation details will change (mostly) 
behind CRTC's back.

> 
> 
>>>
>>>> +    pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
>>>> +    if (pstate->stage >= pdpu->catalog->caps->max_mixer_blendstages) {
>>>> +        DPU_ERROR("> %d plane stages assigned\n",
>>>> +                pdpu->catalog->caps->max_mixer_blendstages - 
>>>> DPU_STAGE_0);
>>>> +        return -EINVAL;
>>>> +    }
>>>> +
>>>
>>> I agree that this check belongs to the plane_atomic_check().
>>>
>>>>       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 228db401e905..a08b0539513b 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>> @@ -88,12 +88,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
>>

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 20/27] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
  2023-02-06 19:07     ` Abhinav Kumar
@ 2023-02-16 16:49       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-16 16:49 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 06/02/2023 21:07, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> 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()).
>>
> The title of the patch should now say "add dpu_hw_sspp_cfg"
> 
> I have a question on the commit text, why does it say "re-add" and not 
> "add".
> 
> dpu_hw_pipe_cfg/dpu_hw_sspp_cfg was not a part of dpu_plane_state even 
> before and I dont recall it was removed in this series and then added back.

Ack, I'll fix both items in v4.

> 
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 64 ++++++++++-------------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  2 +
>>   2 files changed, 30 insertions(+), 36 deletions(-)-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 20/27] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state
@ 2023-02-16 16:49       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-02-16 16:49 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 06/02/2023 21:07, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> 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()).
>>
> The title of the patch should now say "add dpu_hw_sspp_cfg"
> 
> I have a question on the commit text, why does it say "re-add" and not 
> "add".
> 
> dpu_hw_pipe_cfg/dpu_hw_sspp_cfg was not a part of dpu_plane_state even 
> before and I dont recall it was removed in this series and then added back.

Ack, I'll fix both items in v4.

> 
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 64 ++++++++++-------------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  2 +
>>   2 files changed, 30 insertions(+), 36 deletions(-)-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 15/27] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
  2023-02-15  0:08           ` Dmitry Baryshkov
@ 2023-03-03 11:43             ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-03-03 11:43 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 15/02/2023 02:08, Dmitry Baryshkov wrote:
> On 15/02/2023 01:25, Abhinav Kumar wrote:
>> Hi Dmitry
>>
>> Sorry for the late response on this one.
>>
>> On 2/3/2023 2:55 PM, Dmitry Baryshkov wrote:
>>> On 04/02/2023 00:44, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>> Move plane state updates from dpu_crtc_atomic_check() to the function
>>>>> where they belong: to dpu_plane_atomic_check().
>>>>>
>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>> ---
>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-----------------
>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++++++++++--------
>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ------
>>>>>   3 files changed, 11 insertions(+), 31 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> index b485234eefb2..bd09bb319a58 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> @@ -1129,7 +1129,6 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>>>>>       const struct drm_plane_state *pstate;
>>>>>       struct drm_plane *plane;
>>>>> @@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct 
>>>>> drm_crtc *crtc,
>>>>>       crtc_rect.x2 = mode->hdisplay;
>>>>>       crtc_rect.y2 = mode->vdisplay;
>>>>> -     /* get plane state for all drm planes associated with crtc 
>>>>> state */
>>>>> +    /* FIXME: move this to dpu_plane_atomic_check? */
>>>>>       drm_atomic_crtc_state_for_each_plane_state(plane, pstate, 
>>>>> crtc_state) {
>>>>>           struct dpu_plane_state *dpu_pstate = 
>>>>> to_dpu_plane_state(pstate);
>>>>>           struct drm_rect dst, clip = crtc_rect;
>>>>> -        int stage;
>>>>>           if (IS_ERR_OR_NULL(pstate)) {
>>>>>               rc = PTR_ERR(pstate);
>>>>> @@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct 
>>>>> drm_crtc *crtc,
>>>>>           dpu_pstate->needs_dirtyfb = needs_dirtyfb;
>>>>> -        dpu_plane_clear_multirect(pstate);
>>>>> -
>>>>>           dst = drm_plane_state_dest(pstate);
>>>>>           if (!drm_rect_intersect(&clip, &dst)) {
>>>>>               DPU_ERROR("invalid vertical/horizontal destination\n");
>>>>> @@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct 
>>>>> drm_crtc *crtc,
>>>>>                     DRM_RECT_ARG(&dst));
>>>>>               return -E2BIG;
>>>>>           }
>>>>> -
>>>>> -        /* verify stage setting before using it */
>>>>> -        stage = DPU_STAGE_0 + pstate->normalized_zpos;
>>>>> -        if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
>>>>> -            DPU_ERROR("> %d plane stages assigned\n",
>>>>> -                    dpu_kms->catalog->caps->max_mixer_blendstages 
>>>>> - DPU_STAGE_0);
>>>>> -            return -EINVAL;
>>>>> -        }
>>>>> -
>>>>> -        to_dpu_plane_state(pstate)->stage = stage;
>>>>> -        DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
>>>>> -
>>>>>       }
>>>>>       atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> index 1b3033b15bfa..5aabf9694a53 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> @@ -733,14 +733,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];
>>>>> @@ -994,6 +986,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;
>>>>> +
>>>>
>>>> But I am not sure if clearing the multirect belongs here and now I 
>>>> want to clarify one thing about 
>>>> https://patchwork.freedesktop.org/patch/521354/?series=99909&rev=4 
>>>> which was R-bed in the v1 and carried fwd since then.
>>>>
>>>> So prior to that change, we were only clearing the multirects of the 
>>>> planes that were staged to the crtc and we were getting those from 
>>>> the crtc state. But now we are clearing the multirect of all the 
>>>> planes.
>>>>
>>>> Dont we have to keep that in the crtc_atomic_check() since we do 
>>>> that on all the planes attached to a certain CRTC.
>>>>
>>>> In that case shouldnt we keep this in the crtc_atomic_check() and 
>>>> bring back pipe_staged[] without the multirect and source split 
>>>> cases ofcourse.
>>>
>>> What for? In other words, what would be the difference?
>>>
>>
>> So, please correct my understanding here. drm_plane's atomic_check() 
>> will be called for all the planes which are getting updated in this 
>> atomic commit using for_each_oldnew_plane_in_state() and drm_crtc's 
>> atomic_check() will be called for all the CRTC's in this atomic update 
>> using for_each_new_crtc_in_state() >
>> If the plane is not connected to any CRTC, why do we need to clear the 
>> multirect pstates.
> 
> If the plane is not connected to any CRTC, then we just don't care what 
> is there in the multirect state, so we might clear it as well.
> 
>>
>> OR in that case would atomic_commit not even be called if the plane is 
>> not connected to any CRTC?
>>
>> One case i can think of is the disable commit where the no planes will 
>> be connected to the CRTC so in that case, before this change we would 
>> explicitly clear out all the planes connected to the CRTC but now with 
>> this change is there a possibility that only if the plane state 
>> changed we would clear it out?
> 
> Ah. Maybe I understand your point. I think 
> drm_atomic_add_affected_planes() will ensure that all planes attached to 
> CRTCs are also a part of the atomic state.

Checked, it works as expected. But on the other hand, this pointed me to 
a possible issue in dpu_plane_atomic_disable. Probably we should drop 
the multirect setup there.

> 
> Regarding the change itself. Think about encapsulation. CRTC should not 
> care about plane's multirect state. It is a plane implementation detail. 
> As we delve upon a path of using rect1 and then even using different 
> SSPPs for the plane, these implementation details will change (mostly) 
> behind CRTC's back.
> 
>>
>>
>>>>
>>>>> +    pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
>>>>> +    if (pstate->stage >= 
>>>>> pdpu->catalog->caps->max_mixer_blendstages) {
>>>>> +        DPU_ERROR("> %d plane stages assigned\n",
>>>>> +                pdpu->catalog->caps->max_mixer_blendstages - 
>>>>> DPU_STAGE_0);
>>>>> +        return -EINVAL;
>>>>> +    }
>>>>> +
>>>>
>>>> I agree that this check belongs to the plane_atomic_check().
>>>>
>>>>>       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 228db401e905..a08b0539513b 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>>> @@ -88,12 +88,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
>>>
> 

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 15/27] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check()
@ 2023-03-03 11:43             ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-03-03 11:43 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 15/02/2023 02:08, Dmitry Baryshkov wrote:
> On 15/02/2023 01:25, Abhinav Kumar wrote:
>> Hi Dmitry
>>
>> Sorry for the late response on this one.
>>
>> On 2/3/2023 2:55 PM, Dmitry Baryshkov wrote:
>>> On 04/02/2023 00:44, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>>>>> Move plane state updates from dpu_crtc_atomic_check() to the function
>>>>> where they belong: to dpu_plane_atomic_check().
>>>>>
>>>>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>>>>> ---
>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 18 +-----------------
>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 18 ++++++++++--------
>>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  6 ------
>>>>>   3 files changed, 11 insertions(+), 31 deletions(-)
>>>>>
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> index b485234eefb2..bd09bb319a58 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>>>>> @@ -1129,7 +1129,6 @@ 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 dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
>>>>>       const struct drm_plane_state *pstate;
>>>>>       struct drm_plane *plane;
>>>>> @@ -1161,11 +1160,10 @@ static int dpu_crtc_atomic_check(struct 
>>>>> drm_crtc *crtc,
>>>>>       crtc_rect.x2 = mode->hdisplay;
>>>>>       crtc_rect.y2 = mode->vdisplay;
>>>>> -     /* get plane state for all drm planes associated with crtc 
>>>>> state */
>>>>> +    /* FIXME: move this to dpu_plane_atomic_check? */
>>>>>       drm_atomic_crtc_state_for_each_plane_state(plane, pstate, 
>>>>> crtc_state) {
>>>>>           struct dpu_plane_state *dpu_pstate = 
>>>>> to_dpu_plane_state(pstate);
>>>>>           struct drm_rect dst, clip = crtc_rect;
>>>>> -        int stage;
>>>>>           if (IS_ERR_OR_NULL(pstate)) {
>>>>>               rc = PTR_ERR(pstate);
>>>>> @@ -1179,8 +1177,6 @@ static int dpu_crtc_atomic_check(struct 
>>>>> drm_crtc *crtc,
>>>>>           dpu_pstate->needs_dirtyfb = needs_dirtyfb;
>>>>> -        dpu_plane_clear_multirect(pstate);
>>>>> -
>>>>>           dst = drm_plane_state_dest(pstate);
>>>>>           if (!drm_rect_intersect(&clip, &dst)) {
>>>>>               DPU_ERROR("invalid vertical/horizontal destination\n");
>>>>> @@ -1189,18 +1185,6 @@ static int dpu_crtc_atomic_check(struct 
>>>>> drm_crtc *crtc,
>>>>>                     DRM_RECT_ARG(&dst));
>>>>>               return -E2BIG;
>>>>>           }
>>>>> -
>>>>> -        /* verify stage setting before using it */
>>>>> -        stage = DPU_STAGE_0 + pstate->normalized_zpos;
>>>>> -        if (stage >= dpu_kms->catalog->caps->max_mixer_blendstages) {
>>>>> -            DPU_ERROR("> %d plane stages assigned\n",
>>>>> -                    dpu_kms->catalog->caps->max_mixer_blendstages 
>>>>> - DPU_STAGE_0);
>>>>> -            return -EINVAL;
>>>>> -        }
>>>>> -
>>>>> -        to_dpu_plane_state(pstate)->stage = stage;
>>>>> -        DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
>>>>> -
>>>>>       }
>>>>>       atomic_inc(&_dpu_crtc_get_kms(crtc)->bandwidth_ref);
>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c 
>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> index 1b3033b15bfa..5aabf9694a53 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>>>>> @@ -733,14 +733,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];
>>>>> @@ -994,6 +986,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;
>>>>> +
>>>>
>>>> But I am not sure if clearing the multirect belongs here and now I 
>>>> want to clarify one thing about 
>>>> https://patchwork.freedesktop.org/patch/521354/?series=99909&rev=4 
>>>> which was R-bed in the v1 and carried fwd since then.
>>>>
>>>> So prior to that change, we were only clearing the multirects of the 
>>>> planes that were staged to the crtc and we were getting those from 
>>>> the crtc state. But now we are clearing the multirect of all the 
>>>> planes.
>>>>
>>>> Dont we have to keep that in the crtc_atomic_check() since we do 
>>>> that on all the planes attached to a certain CRTC.
>>>>
>>>> In that case shouldnt we keep this in the crtc_atomic_check() and 
>>>> bring back pipe_staged[] without the multirect and source split 
>>>> cases ofcourse.
>>>
>>> What for? In other words, what would be the difference?
>>>
>>
>> So, please correct my understanding here. drm_plane's atomic_check() 
>> will be called for all the planes which are getting updated in this 
>> atomic commit using for_each_oldnew_plane_in_state() and drm_crtc's 
>> atomic_check() will be called for all the CRTC's in this atomic update 
>> using for_each_new_crtc_in_state() >
>> If the plane is not connected to any CRTC, why do we need to clear the 
>> multirect pstates.
> 
> If the plane is not connected to any CRTC, then we just don't care what 
> is there in the multirect state, so we might clear it as well.
> 
>>
>> OR in that case would atomic_commit not even be called if the plane is 
>> not connected to any CRTC?
>>
>> One case i can think of is the disable commit where the no planes will 
>> be connected to the CRTC so in that case, before this change we would 
>> explicitly clear out all the planes connected to the CRTC but now with 
>> this change is there a possibility that only if the plane state 
>> changed we would clear it out?
> 
> Ah. Maybe I understand your point. I think 
> drm_atomic_add_affected_planes() will ensure that all planes attached to 
> CRTCs are also a part of the atomic state.

Checked, it works as expected. But on the other hand, this pointed me to 
a possible issue in dpu_plane_atomic_disable. Probably we should drop 
the multirect setup there.

> 
> Regarding the change itself. Think about encapsulation. CRTC should not 
> care about plane's multirect state. It is a plane implementation detail. 
> As we delve upon a path of using rect1 and then even using different 
> SSPPs for the plane, these implementation details will change (mostly) 
> behind CRTC's back.
> 
>>
>>
>>>>
>>>>> +    pstate->stage = DPU_STAGE_0 + pstate->base.normalized_zpos;
>>>>> +    if (pstate->stage >= 
>>>>> pdpu->catalog->caps->max_mixer_blendstages) {
>>>>> +        DPU_ERROR("> %d plane stages assigned\n",
>>>>> +                pdpu->catalog->caps->max_mixer_blendstages - 
>>>>> DPU_STAGE_0);
>>>>> +        return -EINVAL;
>>>>> +    }
>>>>> +
>>>>
>>>> I agree that this check belongs to the plane_atomic_check().
>>>>
>>>>>       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 228db401e905..a08b0539513b 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
>>>>> @@ -88,12 +88,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
>>>
> 

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 26/27] drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
  2023-02-08 23:44     ` Abhinav Kumar
@ 2023-03-03 12:18       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-03-03 12:18 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: Stephen Boyd, David Airlie, Daniel Vetter, Bjorn Andersson,
	linux-arm-msm, dri-devel, freedreno

On 09/02/2023 01:44, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Rework _dpu_crtc_blend_setup_mixer() to split away pipe handling to a
>> separate functon. This is a preparation for the r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 86 ++++++++++++++++-------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 ++-
>>   2 files changed, 63 insertions(+), 33 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> index 73e1a8c69ef0..0ca3bc38ff7e 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> @@ -400,6 +400,47 @@ static void 
>> _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
>>       }
>>   }
>> +static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
>> +                       struct drm_plane *plane,
>> +                       struct dpu_crtc_mixer *mixer,
>> +                       u32 num_mixers,
>> +                       struct dpu_hw_stage_cfg *stage_cfg,
>> +                       enum dpu_stage stage,
>> +                       unsigned int stage_idx,
>> +                       unsigned long *fetch_active,
>> +                       struct dpu_sw_pipe *pipe
>> +                      )
>> +{
>> +    uint32_t lm_idx;
>> +    enum dpu_sspp sspp_idx;
>> +    struct drm_plane_state *state;
>> +
>> +    if (!pipe->sspp)
>> +        return;
>> +
>> +    sspp_idx = pipe->sspp->idx;
>> +
>> +    state = plane->state;
>> +
>> +    DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
>> +             crtc->base.id,
>> +             stage,
>> +             plane->base.id,
>> +             sspp_idx - SSPP_NONE,
>> +             state->fb ? state->fb->base.id : -1);
>> +
>> +    set_bit(sspp_idx, fetch_active);
>> +
>> +    stage_cfg->stage[stage][stage_idx] = sspp_idx;
>> +    stage_cfg->multirect_index[stage][stage_idx] =
>> +                pipe->multirect_index;
>> +
>> +    /* blend config update */
>> +    for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
>> +        
>> mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl,
>> +                                    sspp_idx);
> 
> If you just pass the format to this function you can move rest of the 
> for loop also to this function.

As a second thought, this would defeat the purpose of the split. We 
don't have to call _dpu_crtc_setup_blend_cfg() or setup mixer_op_mode 
for the second pipe separately. So, I'd leave the loops as is.

> 
> Also, you will be able to add the trace_dpu_crtc_setup_mixer() with 
> complete information.
> 
> trace_dpu_crtc_setup_mixer is currently missing te stage_idx which is 
> important to debug blend issues.
> 
>> +}
>> +
>>   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)
>> @@ -412,15 +453,12 @@ static void _dpu_crtc_blend_setup_mixer(struct 
>> drm_crtc *crtc,
>>       struct dpu_format *format;
>>       struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>> -    uint32_t stage_idx, lm_idx;
>> -    int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
>> +    uint32_t lm_idx;
>>       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;
>> -
>>           state = plane->state;
>>           if (!state)
>>               continue;
>> @@ -431,39 +469,25 @@ static void _dpu_crtc_blend_setup_mixer(struct 
>> drm_crtc *crtc,
>>           pstate = to_dpu_plane_state(state);
>>           fb = state->fb;
>> -        sspp_idx = pstate->pipe.sspp->idx;
>> -        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,
>> -                sspp_idx - SSPP_VIG0,
>> -                state->fb ? state->fb->base.id : -1);
>> -
>>           format = 
>> to_dpu_format(msm_framebuffer_format(pstate->base.fb));
>>           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->pipe.multirect_index;
>> -
>>           trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
>> -                       state, pstate, stage_idx,
>> +                       state, pstate,
>>                          format->base.pixel_format,
>>                          fb ? fb->modifier : 0);
>> +        _dpu_crtc_blend_setup_pipe(crtc, plane,
>> +                       mixer, cstate->num_mixers,
>> +                       stage_cfg, pstate->stage, 0,
>> +                       fetch_active,
>> +                       &pstate->pipe);
>> +
>>           /* blend config update */
>>           for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
>> -            _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);
>> +            _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
>>               if (bg_alpha_enable && !format->alpha_enable)
>>                   mixer[lm_idx].mixer_op_mode = 0;
>> @@ -1297,8 +1321,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, "\tmultirect: mode: %d index: %d\n",
>> +        seq_printf(s, "\tsspp[0]:%d\n",
>> +               pstate->pipe.sspp->idx - SSPP_NONE);
>> +        seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
>>               pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
>> +        if (pstate->r_pipe.sspp) {
>> +            seq_printf(s, "\tsspp[1]:%d\n",
>> +                   pstate->r_pipe.sspp->idx - SSPP_NONE);
>> +            seq_printf(s, "\tmultirect[1]: 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_trace.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> index 0ad148cc2fb8..5ec4f89e8814 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> @@ -633,9 +633,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, uint32_t pixel_format,
>> +         uint32_t pixel_format,
>>            uint64_t modifier),
>> -    TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
>> +    TP_ARGS(crtc_id, plane_id, state, pstate,
>>           pixel_format, modifier),
>>       TP_STRUCT__entry(
>>           __field(    uint32_t,        crtc_id        )
>> @@ -643,7 +643,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __field(    uint32_t,        fb_id        )
>>           __field_struct(    struct drm_rect,    src_rect    )
>>           __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    )
>> @@ -657,7 +656,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __entry->fb_id = state ? state->fb->base.id : 0;
>>           __entry->src_rect = drm_plane_state_src(state);
>>           __entry->dst_rect = drm_plane_state_dest(state);
>> -        __entry->stage_idx = stage_idx;
>>           __entry->stage = pstate->stage;
>>           __entry->sspp = pstate->pipe.sspp->idx;
>>           __entry->multirect_idx = pstate->pipe.multirect_index;
>> @@ -666,13 +664,13 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __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:%d, sspp:%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, __entry->sspp,
>>             __entry->multirect_idx, __entry->multirect_mode,
>>             __entry->pixel_format, __entry->modifier)
>>   );

-- 
With best wishes
Dmitry


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

* Re: [PATCH v3 26/27] drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer
@ 2023-03-03 12:18       ` Dmitry Baryshkov
  0 siblings, 0 replies; 176+ messages in thread
From: Dmitry Baryshkov @ 2023-03-03 12:18 UTC (permalink / raw)
  To: Abhinav Kumar, Rob Clark, Sean Paul
  Cc: freedreno, linux-arm-msm, Bjorn Andersson, dri-devel, Stephen Boyd

On 09/02/2023 01:44, Abhinav Kumar wrote:
> 
> 
> On 2/3/2023 10:21 AM, Dmitry Baryshkov wrote:
>> Rework _dpu_crtc_blend_setup_mixer() to split away pipe handling to a
>> separate functon. This is a preparation for the r_pipe support.
>>
>> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 86 ++++++++++++++++-------
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 10 ++-
>>   2 files changed, 63 insertions(+), 33 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> index 73e1a8c69ef0..0ca3bc38ff7e 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
>> @@ -400,6 +400,47 @@ static void 
>> _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
>>       }
>>   }
>> +static void _dpu_crtc_blend_setup_pipe(struct drm_crtc *crtc,
>> +                       struct drm_plane *plane,
>> +                       struct dpu_crtc_mixer *mixer,
>> +                       u32 num_mixers,
>> +                       struct dpu_hw_stage_cfg *stage_cfg,
>> +                       enum dpu_stage stage,
>> +                       unsigned int stage_idx,
>> +                       unsigned long *fetch_active,
>> +                       struct dpu_sw_pipe *pipe
>> +                      )
>> +{
>> +    uint32_t lm_idx;
>> +    enum dpu_sspp sspp_idx;
>> +    struct drm_plane_state *state;
>> +
>> +    if (!pipe->sspp)
>> +        return;
>> +
>> +    sspp_idx = pipe->sspp->idx;
>> +
>> +    state = plane->state;
>> +
>> +    DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
>> +             crtc->base.id,
>> +             stage,
>> +             plane->base.id,
>> +             sspp_idx - SSPP_NONE,
>> +             state->fb ? state->fb->base.id : -1);
>> +
>> +    set_bit(sspp_idx, fetch_active);
>> +
>> +    stage_cfg->stage[stage][stage_idx] = sspp_idx;
>> +    stage_cfg->multirect_index[stage][stage_idx] =
>> +                pipe->multirect_index;
>> +
>> +    /* blend config update */
>> +    for (lm_idx = 0; lm_idx < num_mixers; lm_idx++)
>> +        
>> mixer[lm_idx].lm_ctl->ops.update_pending_flush_sspp(mixer[lm_idx].lm_ctl,
>> +                                    sspp_idx);
> 
> If you just pass the format to this function you can move rest of the 
> for loop also to this function.

As a second thought, this would defeat the purpose of the split. We 
don't have to call _dpu_crtc_setup_blend_cfg() or setup mixer_op_mode 
for the second pipe separately. So, I'd leave the loops as is.

> 
> Also, you will be able to add the trace_dpu_crtc_setup_mixer() with 
> complete information.
> 
> trace_dpu_crtc_setup_mixer is currently missing te stage_idx which is 
> important to debug blend issues.
> 
>> +}
>> +
>>   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)
>> @@ -412,15 +453,12 @@ static void _dpu_crtc_blend_setup_mixer(struct 
>> drm_crtc *crtc,
>>       struct dpu_format *format;
>>       struct dpu_hw_ctl *ctl = mixer->lm_ctl;
>> -    uint32_t stage_idx, lm_idx;
>> -    int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
>> +    uint32_t lm_idx;
>>       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;
>> -
>>           state = plane->state;
>>           if (!state)
>>               continue;
>> @@ -431,39 +469,25 @@ static void _dpu_crtc_blend_setup_mixer(struct 
>> drm_crtc *crtc,
>>           pstate = to_dpu_plane_state(state);
>>           fb = state->fb;
>> -        sspp_idx = pstate->pipe.sspp->idx;
>> -        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,
>> -                sspp_idx - SSPP_VIG0,
>> -                state->fb ? state->fb->base.id : -1);
>> -
>>           format = 
>> to_dpu_format(msm_framebuffer_format(pstate->base.fb));
>>           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->pipe.multirect_index;
>> -
>>           trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
>> -                       state, pstate, stage_idx,
>> +                       state, pstate,
>>                          format->base.pixel_format,
>>                          fb ? fb->modifier : 0);
>> +        _dpu_crtc_blend_setup_pipe(crtc, plane,
>> +                       mixer, cstate->num_mixers,
>> +                       stage_cfg, pstate->stage, 0,
>> +                       fetch_active,
>> +                       &pstate->pipe);
>> +
>>           /* blend config update */
>>           for (lm_idx = 0; lm_idx < cstate->num_mixers; lm_idx++) {
>> -            _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);
>> +            _dpu_crtc_setup_blend_cfg(mixer + lm_idx, pstate, format);
>>               if (bg_alpha_enable && !format->alpha_enable)
>>                   mixer[lm_idx].mixer_op_mode = 0;
>> @@ -1297,8 +1321,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, "\tmultirect: mode: %d index: %d\n",
>> +        seq_printf(s, "\tsspp[0]:%d\n",
>> +               pstate->pipe.sspp->idx - SSPP_NONE);
>> +        seq_printf(s, "\tmultirect[0]: mode: %d index: %d\n",
>>               pstate->pipe.multirect_mode, pstate->pipe.multirect_index);
>> +        if (pstate->r_pipe.sspp) {
>> +            seq_printf(s, "\tsspp[1]:%d\n",
>> +                   pstate->r_pipe.sspp->idx - SSPP_NONE);
>> +            seq_printf(s, "\tmultirect[1]: 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_trace.h 
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> index 0ad148cc2fb8..5ec4f89e8814 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
>> @@ -633,9 +633,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, uint32_t pixel_format,
>> +         uint32_t pixel_format,
>>            uint64_t modifier),
>> -    TP_ARGS(crtc_id, plane_id, state, pstate, stage_idx,
>> +    TP_ARGS(crtc_id, plane_id, state, pstate,
>>           pixel_format, modifier),
>>       TP_STRUCT__entry(
>>           __field(    uint32_t,        crtc_id        )
>> @@ -643,7 +643,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __field(    uint32_t,        fb_id        )
>>           __field_struct(    struct drm_rect,    src_rect    )
>>           __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    )
>> @@ -657,7 +656,6 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __entry->fb_id = state ? state->fb->base.id : 0;
>>           __entry->src_rect = drm_plane_state_src(state);
>>           __entry->dst_rect = drm_plane_state_dest(state);
>> -        __entry->stage_idx = stage_idx;
>>           __entry->stage = pstate->stage;
>>           __entry->sspp = pstate->pipe.sspp->idx;
>>           __entry->multirect_idx = pstate->pipe.multirect_index;
>> @@ -666,13 +664,13 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
>>           __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:%d, sspp:%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, __entry->sspp,
>>             __entry->multirect_idx, __entry->multirect_mode,
>>             __entry->pixel_format, __entry->modifier)
>>   );

-- 
With best wishes
Dmitry


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

end of thread, other threads:[~2023-03-03 12:18 UTC | newest]

Thread overview: 176+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-03 18:21 [PATCH v3 00/27] drm/msm/dpu: wide planes support Dmitry Baryshkov
2023-02-03 18:21 ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 01/27] drm/msm/dpu: rename struct dpu_hw_pipe(_cfg) to dpu_hw_sspp(_cfg) Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 19:31   ` Abhinav Kumar
2023-02-03 19:31     ` Abhinav Kumar
2023-02-03 18:21 ` [PATCH v3 02/27] drm/msm/dpu: move SSPP allocation to the RM Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 03/27] drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 04/27] drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 05/27] drm/msm/dpu: move pipe_hw to dpu_plane_state Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 19:34   ` Abhinav Kumar
2023-02-03 19:34     ` Abhinav Kumar
2023-02-03 18:21 ` [PATCH v3 06/27] drm/msm/dpu: drop dpu_plane_pipe function Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 07/27] drm/msm/dpu: introduce struct dpu_sw_pipe Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 08/27] drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 09/27] drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3() Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 19:36   ` Abhinav Kumar
2023-02-03 19:36     ` Abhinav Kumar
2023-02-03 18:21 ` [PATCH v3 10/27] drm/msm/dpu: clean up SRC addresses when setting up SSPP for solid fill Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 20:36   ` Abhinav Kumar
2023-02-03 20:36     ` Abhinav Kumar
2023-02-03 18:21 ` [PATCH v3 11/27] drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 20:37   ` Abhinav Kumar
2023-02-03 20:37     ` Abhinav Kumar
2023-02-03 18:21 ` [PATCH v3 12/27] drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_sspp_cfg Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 13/27] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 14/27] drm/msm/dpu: don't use unsupported blend stages Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 20:42   ` Abhinav Kumar
2023-02-03 20:42     ` Abhinav Kumar
2023-02-03 18:21 ` [PATCH v3 15/27] drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check() Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 22:44   ` Abhinav Kumar
2023-02-03 22:44     ` Abhinav Kumar
2023-02-03 22:55     ` Dmitry Baryshkov
2023-02-03 22:55       ` Dmitry Baryshkov
2023-02-14 23:25       ` Abhinav Kumar
2023-02-14 23:25         ` Abhinav Kumar
2023-02-15  0:08         ` Dmitry Baryshkov
2023-02-15  0:08           ` Dmitry Baryshkov
2023-03-03 11:43           ` Dmitry Baryshkov
2023-03-03 11:43             ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 16/27] drm/msm/dpu: drop redundant plane dst check from dpu_crtc_atomic_check() Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 22:57   ` Abhinav Kumar
2023-02-03 22:57     ` Abhinav Kumar
2023-02-03 18:21 ` [PATCH v3 17/27] drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 23:07   ` Abhinav Kumar
2023-02-03 23:07     ` Abhinav Kumar
2023-02-03 23:20     ` Dmitry Baryshkov
2023-02-03 23:20       ` Dmitry Baryshkov
2023-02-08 23:09       ` Abhinav Kumar
2023-02-08 23:09         ` Abhinav Kumar
2023-02-03 18:21 ` [PATCH v3 18/27] drm/msm/dpu: populate SmartDMA features in hw catalog Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-03 23:35   ` Abhinav Kumar
2023-02-03 23:35     ` Abhinav Kumar
2023-02-04  2:29     ` Dmitry Baryshkov
2023-02-04  2:29       ` Dmitry Baryshkov
2023-02-04  2:43       ` Abhinav Kumar
2023-02-04  2:43         ` Abhinav Kumar
2023-02-04  4:10         ` Dmitry Baryshkov
2023-02-04  4:10           ` Dmitry Baryshkov
2023-02-04  5:10           ` Abhinav Kumar
2023-02-04  5:10             ` Abhinav Kumar
2023-02-04 10:43             ` Dmitry Baryshkov
2023-02-04 10:43               ` Dmitry Baryshkov
2023-02-04 18:35               ` Abhinav Kumar
2023-02-04 18:35                 ` Abhinav Kumar
2023-02-04 21:08                 ` Dmitry Baryshkov
2023-02-04 21:08                   ` Dmitry Baryshkov
2023-02-04 23:20                   ` Abhinav Kumar
2023-02-04 23:20                     ` Abhinav Kumar
2023-02-05  0:29                     ` Dmitry Baryshkov
2023-02-05  0:29                       ` Dmitry Baryshkov
2023-02-05  0:36                       ` Abhinav Kumar
2023-02-05  0:36                         ` Abhinav Kumar
2023-02-08 23:53                         ` Dmitry Baryshkov
2023-02-08 23:53                           ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 19/27] drm/msm/dpu: make _dpu_plane_calc_clk accept mode directly Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-06 18:48   ` Abhinav Kumar
2023-02-06 18:48     ` Abhinav Kumar
2023-02-03 18:21 ` [PATCH v3 20/27] drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-06 19:07   ` Abhinav Kumar
2023-02-06 19:07     ` Abhinav Kumar
2023-02-16 16:49     ` Dmitry Baryshkov
2023-02-16 16:49       ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 21/27] drm/msm/dpu: simplify dpu_plane_validate_src() Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-06 22:40   ` Abhinav Kumar
2023-02-06 22:40     ` Abhinav Kumar
2023-02-07  0:27     ` Dmitry Baryshkov
2023-02-07  0:27       ` Dmitry Baryshkov
2023-02-07  0:42       ` Abhinav Kumar
2023-02-07  0:42         ` Abhinav Kumar
2023-02-03 18:21 ` [PATCH v3 22/27] drm/msm/dpu: rework dpu_plane_sspp_atomic_update() Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-07  0:22   ` Abhinav Kumar
2023-02-07  0:22     ` Abhinav Kumar
2023-02-09  0:49     ` Dmitry Baryshkov
2023-02-09  0:49       ` Dmitry Baryshkov
2023-02-09  0:51     ` Dmitry Baryshkov
2023-02-09  0:51       ` Dmitry Baryshkov
2023-02-09 11:46     ` Dmitry Baryshkov
2023-02-09 11:46       ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 23/27] drm/msm/dpu: rework dpu_plane_atomic_check() Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-07 17:49   ` Abhinav Kumar
2023-02-07 17:49     ` Abhinav Kumar
2023-02-07 17:51     ` Dmitry Baryshkov
2023-02-07 17:51       ` Dmitry Baryshkov
2023-02-07 17:57       ` Abhinav Kumar
2023-02-07 17:57         ` Abhinav Kumar
2023-02-07 17:59         ` Dmitry Baryshkov
2023-02-07 17:59           ` Dmitry Baryshkov
2023-02-07 18:08           ` Abhinav Kumar
2023-02-07 18:08             ` Abhinav Kumar
2023-02-07 19:51             ` Dmitry Baryshkov
2023-02-07 19:51               ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 24/27] drm/msm/dpu: rework plane CSC setting Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-07 20:05   ` Abhinav Kumar
2023-02-07 20:05     ` Abhinav Kumar
2023-02-07 20:44     ` Dmitry Baryshkov
2023-02-07 20:44       ` Dmitry Baryshkov
2023-02-07 20:57       ` Abhinav Kumar
2023-02-07 20:57         ` Abhinav Kumar
2023-02-03 18:21 ` [PATCH v3 25/27] drm/msm/dpu: rework static color fill code Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-08 22:34   ` Abhinav Kumar
2023-02-08 22:34     ` Abhinav Kumar
2023-02-09  0:53     ` Dmitry Baryshkov
2023-02-09  0:53       ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 26/27] drm/msm/dpu: split pipe handling from _dpu_crtc_blend_setup_mixer Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-08 23:44   ` Abhinav Kumar
2023-02-08 23:44     ` Abhinav Kumar
2023-02-08 23:47     ` Dmitry Baryshkov
2023-02-08 23:47       ` Dmitry Baryshkov
2023-03-03 12:18     ` Dmitry Baryshkov
2023-03-03 12:18       ` Dmitry Baryshkov
2023-02-03 18:21 ` [PATCH v3 27/27] drm/msm/dpu: add support for wide planes Dmitry Baryshkov
2023-02-03 18:21   ` Dmitry Baryshkov
2023-02-09  2:19   ` Abhinav Kumar
2023-02-09  2:19     ` Abhinav Kumar
2023-02-09 11:45     ` Dmitry Baryshkov
2023-02-09 11:45       ` Dmitry Baryshkov
2023-02-09 19:25       ` Abhinav Kumar
2023-02-09 19:25         ` Abhinav Kumar
2023-02-09 21:23         ` Dmitry Baryshkov
2023-02-09 21:23           ` Dmitry Baryshkov
2023-02-09 22:12           ` [Freedreno] " Abhinav Kumar
2023-02-09 22:12             ` Abhinav Kumar
2023-02-10  0:09             ` Dmitry Baryshkov
2023-02-10  0:09               ` Dmitry Baryshkov
2023-02-10  1:12               ` Abhinav Kumar
2023-02-10  1:12                 ` Abhinav Kumar
2023-02-10  2:46                 ` Dmitry Baryshkov
2023-02-10  2:46                   ` Dmitry Baryshkov
2023-02-03 18:24 ` [PATCH v3 00/27] drm/msm/dpu: wide planes support Dmitry Baryshkov
2023-02-03 18:24   ` Dmitry Baryshkov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.