All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/22] drm/msm/dpu: switch dpu_plane to be virtual
@ 2021-07-05  1:20 ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

As discussed on IRC, change dpu_plane implementation to be virtual:
register unified planes and select backing SSPP block at runtime.

Use msm.dpu_use_virtual_planes=1 to enable usage of virtual planes
rather than statically allocated SSPPs at the plane registration.

Patches 1-9 move state variables from struct dpu_plane onto the stack
allocation. State should not be a part of struct dpu_plane anyway.

Patches 10-18 make additional changes to plane code, reworking check,
debugfs, dropping old multirec support, which results in patch 19 adding
support for virtual planes per se.

Patches 20-22 demonstrate my main goal behind reworking dpu_plane
support. They change dpu_plane to automatically use one of SSPP block
features - multirec, an ability to display two unscaled RGB rectangles
using single SSPP block. This allows us to double the amount of created
planes. If the user tries to enable more planes than actually supported
by the underlying SSPP blocks, atomic_check code would return an error.

As you can see, this patchset is not atomic, so different patches can go
separately.

Changes since v1:
 - Add multirec implementation
 - Added msm.dpu_use_virtual_planes kernel parameter instead of using
   compile time switch
 - Changed code to always reallocate SSPPs in the CRTC atomic check to
   let the kernel pick up the best multirec config. This can be
   optimized later.
 - Rework RM SSPP API to always receive plane id
 - Removed scaler_cfg, pixel_ext and cdp_cfg from struct dpu_plane_state
 - Made _dpu_scaler_setup() call sspp's setup_scaler and setup_pe
 - Removed dpu_csc_cfg from dpu_plane

The following changes since commit e88bbc91849b2bf57683119c339e52916d34433f:

  Revert "drm/msm/mdp5: provide dynamic bandwidth management" (2021-06-23 14:06:20 -0700)

are available in the Git repository at:

  https://git.linaro.org/people/dmitry.baryshkov/kernel.git dpu-multirec-2

for you to fetch changes up to 19f6afd40097d4c826e56b8f4a8cbd807f7b61f6:

  drm/msm/dpu: add multirect support (2021-07-05 04:04:50 +0300)

----------------------------------------------------------------
Dmitry Baryshkov (22):
      drm/msm/dpu: move LUT levels out of QOS config
      drm/msm/dpu: remove pipe_qos_cfg from struct dpu_plane
      drm/msm/dpu: drop pipe_name from struct dpu_plane
      drm/msm/dpu: remove stage_cfg from struct dpu_crtc
      drm/msm/dpu: rip out master planes support
      drm/msm/dpu: move dpu_hw_pipe_cfg out of struct dpu_plane
      drm/msm/dpu: drop scaler config from plane state
      drm/msm/dpu: drop dpu_csc_cfg from dpu_plane
      drm/msm/dpu: remove dpu_hw_pipe_cdp_cfg from dpu_plane
      drm/msm/dpu: don't cache pipe->cap->features in dpu_plane
      drm/msm/dpu: don't cache pipe->cap->sblk in dpu_plane
      drm/msm/dpu: rip out debugfs support from dpu_plane
      drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check
      drm/msm/dpu: add list of supported formats to the DPU caps
      drm/msm/dpu: simplify DPU_SSPP features checks
      drm/msm/dpu: do not limit the zpos property
      drm/msm/dpu: add support for SSPP allocation to RM
      drm/msm/dpu: move pipe_hw to dpu_plane_state
      drm/msm/dpu: add support for virtualized planes
      drm/msm/dpu: fix smart dma support
      drm/msm/dpu: fix CDP setup to account for multirect index
      drm/msm/dpu: add multirect support

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c       | 261 +++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h       |   2 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  20 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  20 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c    |  41 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h    |  52 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c    |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h    |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c        | 234 ++++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h        |  70 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c      | 851 +++++++++++--------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h      |  75 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c         |  81 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h         |   6 +
 14 files changed, 793 insertions(+), 924 deletions(-)


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

* [PATCH v2 00/22] drm/msm/dpu: switch dpu_plane to be virtual
@ 2021-07-05  1:20 ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

As discussed on IRC, change dpu_plane implementation to be virtual:
register unified planes and select backing SSPP block at runtime.

Use msm.dpu_use_virtual_planes=1 to enable usage of virtual planes
rather than statically allocated SSPPs at the plane registration.

Patches 1-9 move state variables from struct dpu_plane onto the stack
allocation. State should not be a part of struct dpu_plane anyway.

Patches 10-18 make additional changes to plane code, reworking check,
debugfs, dropping old multirec support, which results in patch 19 adding
support for virtual planes per se.

Patches 20-22 demonstrate my main goal behind reworking dpu_plane
support. They change dpu_plane to automatically use one of SSPP block
features - multirec, an ability to display two unscaled RGB rectangles
using single SSPP block. This allows us to double the amount of created
planes. If the user tries to enable more planes than actually supported
by the underlying SSPP blocks, atomic_check code would return an error.

As you can see, this patchset is not atomic, so different patches can go
separately.

Changes since v1:
 - Add multirec implementation
 - Added msm.dpu_use_virtual_planes kernel parameter instead of using
   compile time switch
 - Changed code to always reallocate SSPPs in the CRTC atomic check to
   let the kernel pick up the best multirec config. This can be
   optimized later.
 - Rework RM SSPP API to always receive plane id
 - Removed scaler_cfg, pixel_ext and cdp_cfg from struct dpu_plane_state
 - Made _dpu_scaler_setup() call sspp's setup_scaler and setup_pe
 - Removed dpu_csc_cfg from dpu_plane

The following changes since commit e88bbc91849b2bf57683119c339e52916d34433f:

  Revert "drm/msm/mdp5: provide dynamic bandwidth management" (2021-06-23 14:06:20 -0700)

are available in the Git repository at:

  https://git.linaro.org/people/dmitry.baryshkov/kernel.git dpu-multirec-2

for you to fetch changes up to 19f6afd40097d4c826e56b8f4a8cbd807f7b61f6:

  drm/msm/dpu: add multirect support (2021-07-05 04:04:50 +0300)

----------------------------------------------------------------
Dmitry Baryshkov (22):
      drm/msm/dpu: move LUT levels out of QOS config
      drm/msm/dpu: remove pipe_qos_cfg from struct dpu_plane
      drm/msm/dpu: drop pipe_name from struct dpu_plane
      drm/msm/dpu: remove stage_cfg from struct dpu_crtc
      drm/msm/dpu: rip out master planes support
      drm/msm/dpu: move dpu_hw_pipe_cfg out of struct dpu_plane
      drm/msm/dpu: drop scaler config from plane state
      drm/msm/dpu: drop dpu_csc_cfg from dpu_plane
      drm/msm/dpu: remove dpu_hw_pipe_cdp_cfg from dpu_plane
      drm/msm/dpu: don't cache pipe->cap->features in dpu_plane
      drm/msm/dpu: don't cache pipe->cap->sblk in dpu_plane
      drm/msm/dpu: rip out debugfs support from dpu_plane
      drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check
      drm/msm/dpu: add list of supported formats to the DPU caps
      drm/msm/dpu: simplify DPU_SSPP features checks
      drm/msm/dpu: do not limit the zpos property
      drm/msm/dpu: add support for SSPP allocation to RM
      drm/msm/dpu: move pipe_hw to dpu_plane_state
      drm/msm/dpu: add support for virtualized planes
      drm/msm/dpu: fix smart dma support
      drm/msm/dpu: fix CDP setup to account for multirect index
      drm/msm/dpu: add multirect support

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c       | 261 +++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h       |   2 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  20 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  20 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c    |  41 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h    |  52 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c    |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h    |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c        | 234 ++++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h        |  70 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c      | 851 +++++++++++--------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h      |  75 +--
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c         |  81 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h         |   6 +
 14 files changed, 793 insertions(+), 924 deletions(-)


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

* [PATCH v2 01/22] drm/msm/dpu: move LUT levels out of QOS config
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:20   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

LUT levels are setup outside of setup_qos_ctrl, so remove them from the
struct dpu_hw_pipe_qos_cfg.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 15 ++++++++-------
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 ++++++----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 17 ++++++-----------
 3 files changed, 20 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 69eed7932486..cbafb61404d0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -569,19 +569,20 @@ static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, enum
 }
 
 static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_qos_cfg *cfg)
+			u32 danger_lut,
+			u32 safe_lut)
 {
 	u32 idx;
 
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
 		return;
 
-	DPU_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, cfg->danger_lut);
-	DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, cfg->safe_lut);
+	DPU_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, danger_lut);
+	DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, safe_lut);
 }
 
 static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_qos_cfg *cfg)
+			u64 creq_lut)
 {
 	u32 idx;
 
@@ -589,11 +590,11 @@ static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
 		return;
 
 	if (ctx->cap && test_bit(DPU_SSPP_QOS_8LVL, &ctx->cap->features)) {
-		DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_0 + idx, cfg->creq_lut);
+		DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_0 + idx, creq_lut);
 		DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_1 + idx,
-				cfg->creq_lut >> 32);
+				creq_lut >> 32);
 	} else {
-		DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, cfg->creq_lut);
+		DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, creq_lut);
 	}
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index fdfd4b46e2c6..27263bc1a1ef 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -166,18 +166,12 @@ struct dpu_hw_pipe_cfg {
 
 /**
  * struct dpu_hw_pipe_qos_cfg : Source pipe QoS configuration
- * @danger_lut: LUT for generate danger level based on fill level
- * @safe_lut: LUT for generate safe level based on fill level
- * @creq_lut: LUT for generate creq level based on fill level
  * @creq_vblank: creq value generated to vbif during vertical blanking
  * @danger_vblank: danger value generated during vertical blanking
  * @vblank_en: enable creq_vblank and danger_vblank during vblank
  * @danger_safe_en: enable danger safe generation
  */
 struct dpu_hw_pipe_qos_cfg {
-	u32 danger_lut;
-	u32 safe_lut;
-	u64 creq_lut;
 	u32 creq_vblank;
 	u32 danger_vblank;
 	bool vblank_en;
@@ -302,20 +296,22 @@ struct dpu_hw_sspp_ops {
 	/**
 	 * setup_danger_safe_lut - setup danger safe LUTs
 	 * @ctx: Pointer to pipe context
-	 * @cfg: Pointer to pipe QoS configuration
+	 * @danger_lut: LUT for generate danger level based on fill level
+	 * @safe_lut: LUT for generate safe level based on fill level
 	 *
 	 */
 	void (*setup_danger_safe_lut)(struct dpu_hw_pipe *ctx,
-			struct dpu_hw_pipe_qos_cfg *cfg);
+			u32 danger_lut,
+			u32 safe_lut);
 
 	/**
 	 * setup_creq_lut - setup CREQ LUT
 	 * @ctx: Pointer to pipe context
-	 * @cfg: Pointer to pipe QoS configuration
+	 * @creq_lut: LUT for generate creq level based on fill level
 	 *
 	 */
 	void (*setup_creq_lut)(struct dpu_hw_pipe *ctx,
-			struct dpu_hw_pipe_qos_cfg *cfg);
+			u64 creq_lut);
 
 	/**
 	 * setup_qos_ctrl - setup QoS control
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ec4a6f04394a..1e2c53a3f47b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -348,8 +348,6 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 	qos_lut = _dpu_plane_get_qos_lut(
 			&pdpu->catalog->perf.qos_lut_tbl[lut_usage], total_fl);
 
-	pdpu->pipe_qos_cfg.creq_lut = qos_lut;
-
 	trace_dpu_perf_set_qos_luts(pdpu->pipe - SSPP_VIG0,
 			(fmt) ? fmt->base.pixel_format : 0,
 			pdpu->is_rt_pipe, total_fl, qos_lut, lut_usage);
@@ -359,7 +357,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, &pdpu->pipe_qos_cfg);
+	pdpu->pipe_hw->ops.setup_creq_lut(pdpu->pipe_hw, qos_lut);
 }
 
 /**
@@ -397,24 +395,21 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
 		}
 	}
 
-	pdpu->pipe_qos_cfg.danger_lut = danger_lut;
-	pdpu->pipe_qos_cfg.safe_lut = safe_lut;
-
 	trace_dpu_perf_set_danger_luts(pdpu->pipe - SSPP_VIG0,
 			(fmt) ? fmt->base.pixel_format : 0,
 			(fmt) ? fmt->fetch_mode : 0,
-			pdpu->pipe_qos_cfg.danger_lut,
-			pdpu->pipe_qos_cfg.safe_lut);
+			danger_lut,
+			safe_lut);
 
 	DPU_DEBUG_PLANE(pdpu, "pnum:%d fmt: %4.4s mode:%d luts[0x%x, 0x%x]\n",
 		pdpu->pipe - SSPP_VIG0,
 		fmt ? (char *)&fmt->base.pixel_format : NULL,
 		fmt ? fmt->fetch_mode : -1,
-		pdpu->pipe_qos_cfg.danger_lut,
-		pdpu->pipe_qos_cfg.safe_lut);
+		danger_lut,
+		safe_lut);
 
 	pdpu->pipe_hw->ops.setup_danger_safe_lut(pdpu->pipe_hw,
-			&pdpu->pipe_qos_cfg);
+			danger_lut, safe_lut);
 }
 
 /**
-- 
2.30.2


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

* [PATCH v2 01/22] drm/msm/dpu: move LUT levels out of QOS config
@ 2021-07-05  1:20   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

LUT levels are setup outside of setup_qos_ctrl, so remove them from the
struct dpu_hw_pipe_qos_cfg.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 15 ++++++++-------
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 ++++++----------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 17 ++++++-----------
 3 files changed, 20 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 69eed7932486..cbafb61404d0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -569,19 +569,20 @@ static void dpu_hw_sspp_setup_solidfill(struct dpu_hw_pipe *ctx, u32 color, enum
 }
 
 static void dpu_hw_sspp_setup_danger_safe_lut(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_qos_cfg *cfg)
+			u32 danger_lut,
+			u32 safe_lut)
 {
 	u32 idx;
 
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
 		return;
 
-	DPU_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, cfg->danger_lut);
-	DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, cfg->safe_lut);
+	DPU_REG_WRITE(&ctx->hw, SSPP_DANGER_LUT + idx, danger_lut);
+	DPU_REG_WRITE(&ctx->hw, SSPP_SAFE_LUT + idx, safe_lut);
 }
 
 static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_qos_cfg *cfg)
+			u64 creq_lut)
 {
 	u32 idx;
 
@@ -589,11 +590,11 @@ static void dpu_hw_sspp_setup_creq_lut(struct dpu_hw_pipe *ctx,
 		return;
 
 	if (ctx->cap && test_bit(DPU_SSPP_QOS_8LVL, &ctx->cap->features)) {
-		DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_0 + idx, cfg->creq_lut);
+		DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_0 + idx, creq_lut);
 		DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_1 + idx,
-				cfg->creq_lut >> 32);
+				creq_lut >> 32);
 	} else {
-		DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, cfg->creq_lut);
+		DPU_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, creq_lut);
 	}
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index fdfd4b46e2c6..27263bc1a1ef 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -166,18 +166,12 @@ struct dpu_hw_pipe_cfg {
 
 /**
  * struct dpu_hw_pipe_qos_cfg : Source pipe QoS configuration
- * @danger_lut: LUT for generate danger level based on fill level
- * @safe_lut: LUT for generate safe level based on fill level
- * @creq_lut: LUT for generate creq level based on fill level
  * @creq_vblank: creq value generated to vbif during vertical blanking
  * @danger_vblank: danger value generated during vertical blanking
  * @vblank_en: enable creq_vblank and danger_vblank during vblank
  * @danger_safe_en: enable danger safe generation
  */
 struct dpu_hw_pipe_qos_cfg {
-	u32 danger_lut;
-	u32 safe_lut;
-	u64 creq_lut;
 	u32 creq_vblank;
 	u32 danger_vblank;
 	bool vblank_en;
@@ -302,20 +296,22 @@ struct dpu_hw_sspp_ops {
 	/**
 	 * setup_danger_safe_lut - setup danger safe LUTs
 	 * @ctx: Pointer to pipe context
-	 * @cfg: Pointer to pipe QoS configuration
+	 * @danger_lut: LUT for generate danger level based on fill level
+	 * @safe_lut: LUT for generate safe level based on fill level
 	 *
 	 */
 	void (*setup_danger_safe_lut)(struct dpu_hw_pipe *ctx,
-			struct dpu_hw_pipe_qos_cfg *cfg);
+			u32 danger_lut,
+			u32 safe_lut);
 
 	/**
 	 * setup_creq_lut - setup CREQ LUT
 	 * @ctx: Pointer to pipe context
-	 * @cfg: Pointer to pipe QoS configuration
+	 * @creq_lut: LUT for generate creq level based on fill level
 	 *
 	 */
 	void (*setup_creq_lut)(struct dpu_hw_pipe *ctx,
-			struct dpu_hw_pipe_qos_cfg *cfg);
+			u64 creq_lut);
 
 	/**
 	 * setup_qos_ctrl - setup QoS control
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index ec4a6f04394a..1e2c53a3f47b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -348,8 +348,6 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 	qos_lut = _dpu_plane_get_qos_lut(
 			&pdpu->catalog->perf.qos_lut_tbl[lut_usage], total_fl);
 
-	pdpu->pipe_qos_cfg.creq_lut = qos_lut;
-
 	trace_dpu_perf_set_qos_luts(pdpu->pipe - SSPP_VIG0,
 			(fmt) ? fmt->base.pixel_format : 0,
 			pdpu->is_rt_pipe, total_fl, qos_lut, lut_usage);
@@ -359,7 +357,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, &pdpu->pipe_qos_cfg);
+	pdpu->pipe_hw->ops.setup_creq_lut(pdpu->pipe_hw, qos_lut);
 }
 
 /**
@@ -397,24 +395,21 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
 		}
 	}
 
-	pdpu->pipe_qos_cfg.danger_lut = danger_lut;
-	pdpu->pipe_qos_cfg.safe_lut = safe_lut;
-
 	trace_dpu_perf_set_danger_luts(pdpu->pipe - SSPP_VIG0,
 			(fmt) ? fmt->base.pixel_format : 0,
 			(fmt) ? fmt->fetch_mode : 0,
-			pdpu->pipe_qos_cfg.danger_lut,
-			pdpu->pipe_qos_cfg.safe_lut);
+			danger_lut,
+			safe_lut);
 
 	DPU_DEBUG_PLANE(pdpu, "pnum:%d fmt: %4.4s mode:%d luts[0x%x, 0x%x]\n",
 		pdpu->pipe - SSPP_VIG0,
 		fmt ? (char *)&fmt->base.pixel_format : NULL,
 		fmt ? fmt->fetch_mode : -1,
-		pdpu->pipe_qos_cfg.danger_lut,
-		pdpu->pipe_qos_cfg.safe_lut);
+		danger_lut,
+		safe_lut);
 
 	pdpu->pipe_hw->ops.setup_danger_safe_lut(pdpu->pipe_hw,
-			&pdpu->pipe_qos_cfg);
+			danger_lut, safe_lut);
 }
 
 /**
-- 
2.30.2


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

* [PATCH v2 02/22] drm/msm/dpu: remove pipe_qos_cfg from struct dpu_plane
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:20   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

The pipe_qos_cfg is used only in _dpu_plane_set_qos_ctrl(), so remove it
from the dpu_plane struct and allocate it on stack when necessary.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 1e2c53a3f47b..20ff1832c958 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -105,7 +105,6 @@ struct dpu_plane {
 
 	struct dpu_hw_pipe *pipe_hw;
 	struct dpu_hw_pipe_cfg pipe_cfg;
-	struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
@@ -422,38 +421,41 @@ 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_hw_pipe_qos_cfg pipe_qos_cfg;
+
+	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
 	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
-		pdpu->pipe_qos_cfg.creq_vblank = pdpu->pipe_sblk->creq_vblank;
-		pdpu->pipe_qos_cfg.danger_vblank =
+		pipe_qos_cfg.creq_vblank = pdpu->pipe_sblk->creq_vblank;
+		pipe_qos_cfg.danger_vblank =
 				pdpu->pipe_sblk->danger_vblank;
-		pdpu->pipe_qos_cfg.vblank_en = enable;
+		pipe_qos_cfg.vblank_en = enable;
 	}
 
 	if (flags & DPU_PLANE_QOS_VBLANK_AMORTIZE) {
 		/* this feature overrules previous VBLANK_CTRL */
-		pdpu->pipe_qos_cfg.vblank_en = false;
-		pdpu->pipe_qos_cfg.creq_vblank = 0; /* clear vblank bits */
+		pipe_qos_cfg.vblank_en = false;
+		pipe_qos_cfg.creq_vblank = 0; /* clear vblank bits */
 	}
 
 	if (flags & DPU_PLANE_QOS_PANIC_CTRL)
-		pdpu->pipe_qos_cfg.danger_safe_en = enable;
+		pipe_qos_cfg.danger_safe_en = enable;
 
 	if (!pdpu->is_rt_pipe) {
-		pdpu->pipe_qos_cfg.vblank_en = false;
-		pdpu->pipe_qos_cfg.danger_safe_en = false;
+		pipe_qos_cfg.vblank_en = false;
+		pipe_qos_cfg.danger_safe_en = false;
 	}
 
 	DPU_DEBUG_PLANE(pdpu, "pnum:%d ds:%d vb:%d pri[0x%x, 0x%x] is_rt:%d\n",
 		pdpu->pipe - SSPP_VIG0,
-		pdpu->pipe_qos_cfg.danger_safe_en,
-		pdpu->pipe_qos_cfg.vblank_en,
-		pdpu->pipe_qos_cfg.creq_vblank,
-		pdpu->pipe_qos_cfg.danger_vblank,
+		pipe_qos_cfg.danger_safe_en,
+		pipe_qos_cfg.vblank_en,
+		pipe_qos_cfg.creq_vblank,
+		pipe_qos_cfg.danger_vblank,
 		pdpu->is_rt_pipe);
 
 	pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,
-			&pdpu->pipe_qos_cfg);
+			&pipe_qos_cfg);
 }
 
 /**
-- 
2.30.2


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

* [PATCH v2 02/22] drm/msm/dpu: remove pipe_qos_cfg from struct dpu_plane
@ 2021-07-05  1:20   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

The pipe_qos_cfg is used only in _dpu_plane_set_qos_ctrl(), so remove it
from the dpu_plane struct and allocate it on stack when necessary.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 1e2c53a3f47b..20ff1832c958 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -105,7 +105,6 @@ struct dpu_plane {
 
 	struct dpu_hw_pipe *pipe_hw;
 	struct dpu_hw_pipe_cfg pipe_cfg;
-	struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
@@ -422,38 +421,41 @@ 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_hw_pipe_qos_cfg pipe_qos_cfg;
+
+	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
 	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
-		pdpu->pipe_qos_cfg.creq_vblank = pdpu->pipe_sblk->creq_vblank;
-		pdpu->pipe_qos_cfg.danger_vblank =
+		pipe_qos_cfg.creq_vblank = pdpu->pipe_sblk->creq_vblank;
+		pipe_qos_cfg.danger_vblank =
 				pdpu->pipe_sblk->danger_vblank;
-		pdpu->pipe_qos_cfg.vblank_en = enable;
+		pipe_qos_cfg.vblank_en = enable;
 	}
 
 	if (flags & DPU_PLANE_QOS_VBLANK_AMORTIZE) {
 		/* this feature overrules previous VBLANK_CTRL */
-		pdpu->pipe_qos_cfg.vblank_en = false;
-		pdpu->pipe_qos_cfg.creq_vblank = 0; /* clear vblank bits */
+		pipe_qos_cfg.vblank_en = false;
+		pipe_qos_cfg.creq_vblank = 0; /* clear vblank bits */
 	}
 
 	if (flags & DPU_PLANE_QOS_PANIC_CTRL)
-		pdpu->pipe_qos_cfg.danger_safe_en = enable;
+		pipe_qos_cfg.danger_safe_en = enable;
 
 	if (!pdpu->is_rt_pipe) {
-		pdpu->pipe_qos_cfg.vblank_en = false;
-		pdpu->pipe_qos_cfg.danger_safe_en = false;
+		pipe_qos_cfg.vblank_en = false;
+		pipe_qos_cfg.danger_safe_en = false;
 	}
 
 	DPU_DEBUG_PLANE(pdpu, "pnum:%d ds:%d vb:%d pri[0x%x, 0x%x] is_rt:%d\n",
 		pdpu->pipe - SSPP_VIG0,
-		pdpu->pipe_qos_cfg.danger_safe_en,
-		pdpu->pipe_qos_cfg.vblank_en,
-		pdpu->pipe_qos_cfg.creq_vblank,
-		pdpu->pipe_qos_cfg.danger_vblank,
+		pipe_qos_cfg.danger_safe_en,
+		pipe_qos_cfg.vblank_en,
+		pipe_qos_cfg.creq_vblank,
+		pipe_qos_cfg.danger_vblank,
 		pdpu->is_rt_pipe);
 
 	pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,
-			&pdpu->pipe_qos_cfg);
+			&pipe_qos_cfg);
 }
 
 /**
-- 
2.30.2


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

* [PATCH v2 03/22] drm/msm/dpu: drop pipe_name from struct dpu_plane
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:20   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Use plane->name instead of artificial pipe_name.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 20ff1832c958..97507e25f4f3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -115,7 +115,6 @@ struct dpu_plane {
 	struct dpu_csc_cfg *csc_ptr;
 
 	const struct dpu_sspp_sub_blks *pipe_sblk;
-	char pipe_name[DPU_NAME_SIZE];
 
 	/* debugfs related stuff */
 	struct dentry *debugfs_root;
@@ -1431,7 +1430,7 @@ static int _dpu_plane_init_debugfs(struct drm_plane *plane)
 
 	/* create overall sub-directory for the pipe */
 	pdpu->debugfs_root =
-		debugfs_create_dir(pdpu->pipe_name,
+		debugfs_create_dir(plane->name,
 				plane->dev->primary->debugfs_root);
 
 	/* don't error check these */
@@ -1656,12 +1655,9 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	/* success! finalize initialization */
 	drm_plane_helper_add(plane, &dpu_plane_helper_funcs);
 
-	/* save user friendly pipe name for later */
-	snprintf(pdpu->pipe_name, DPU_NAME_SIZE, "plane%u", plane->base.id);
-
 	mutex_init(&pdpu->lock);
 
-	DPU_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", pdpu->pipe_name,
+	DPU_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", plane->name,
 					pipe, plane->base.id, master_plane_id);
 	return plane;
 
-- 
2.30.2


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

* [PATCH v2 03/22] drm/msm/dpu: drop pipe_name from struct dpu_plane
@ 2021-07-05  1:20   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

Use plane->name instead of artificial pipe_name.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 20ff1832c958..97507e25f4f3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -115,7 +115,6 @@ struct dpu_plane {
 	struct dpu_csc_cfg *csc_ptr;
 
 	const struct dpu_sspp_sub_blks *pipe_sblk;
-	char pipe_name[DPU_NAME_SIZE];
 
 	/* debugfs related stuff */
 	struct dentry *debugfs_root;
@@ -1431,7 +1430,7 @@ static int _dpu_plane_init_debugfs(struct drm_plane *plane)
 
 	/* create overall sub-directory for the pipe */
 	pdpu->debugfs_root =
-		debugfs_create_dir(pdpu->pipe_name,
+		debugfs_create_dir(plane->name,
 				plane->dev->primary->debugfs_root);
 
 	/* don't error check these */
@@ -1656,12 +1655,9 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	/* success! finalize initialization */
 	drm_plane_helper_add(plane, &dpu_plane_helper_funcs);
 
-	/* save user friendly pipe name for later */
-	snprintf(pdpu->pipe_name, DPU_NAME_SIZE, "plane%u", plane->base.id);
-
 	mutex_init(&pdpu->lock);
 
-	DPU_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", pdpu->pipe_name,
+	DPU_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", plane->name,
 					pipe, plane->base.id, master_plane_id);
 	return plane;
 
-- 
2.30.2


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

* [PATCH v2 04/22] drm/msm/dpu: remove stage_cfg from struct dpu_crtc
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:20   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

The stage_cfg is not used outside of _dpu_crtc_blend_setup(), so remove
the temporary config from global struct.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 9a5c70c87cc8..ea678ddd4589 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -190,7 +190,8 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
 }
 
 static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
-	struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer)
+	struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer,
+	struct dpu_hw_stage_cfg *stage_cfg)
 {
 	struct drm_plane *plane;
 	struct drm_framebuffer *fb;
@@ -199,7 +200,6 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	struct dpu_plane_state *pstate = NULL;
 	struct dpu_format *format;
 	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
-	struct dpu_hw_stage_cfg *stage_cfg = &dpu_crtc->stage_cfg;
 
 	u32 flush_mask;
 	uint32_t stage_idx, lm_idx;
@@ -275,6 +275,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
 	struct dpu_crtc_mixer *mixer = cstate->mixers;
 	struct dpu_hw_ctl *ctl;
 	struct dpu_hw_mixer *lm;
+	struct dpu_hw_stage_cfg stage_cfg;
 	int i;
 
 	DRM_DEBUG_ATOMIC("%s\n", dpu_crtc->name);
@@ -288,9 +289,9 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
 	}
 
 	/* initialize stage cfg */
-	memset(&dpu_crtc->stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg));
+	memset(&stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg));
 
-	_dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer);
+	_dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer, &stage_cfg);
 
 	for (i = 0; i < cstate->num_mixers; i++) {
 		ctl = mixer[i].lm_ctl;
@@ -311,7 +312,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
 			mixer[i].flush_mask);
 
 		ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
-			&dpu_crtc->stage_cfg);
+			&stage_cfg);
 	}
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index cec3474340e8..30535acec670 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -116,7 +116,6 @@ struct dpu_crtc_frame_event {
  * @drm_requested_vblank : Whether vblanks have been enabled in the encoder
  * @property_info : Opaque structure for generic property support
  * @property_defaults : Array of default values for generic property support
- * @stage_cfg     : H/w mixer stage configuration
  * @debugfs_root  : Parent of debugfs node
  * @vblank_cb_count : count of vblank callback since last reset
  * @play_count    : frame count between crtc enable and disable
@@ -147,7 +146,6 @@ struct dpu_crtc {
 	struct drm_pending_vblank_event *event;
 	u32 vsync_count;
 
-	struct dpu_hw_stage_cfg stage_cfg;
 	struct dentry *debugfs_root;
 
 	u32 vblank_cb_count;
-- 
2.30.2


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

* [PATCH v2 04/22] drm/msm/dpu: remove stage_cfg from struct dpu_crtc
@ 2021-07-05  1:20   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

The stage_cfg is not used outside of _dpu_crtc_blend_setup(), so remove
the temporary config from global struct.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 9a5c70c87cc8..ea678ddd4589 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -190,7 +190,8 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
 }
 
 static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
-	struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer)
+	struct dpu_crtc *dpu_crtc, struct dpu_crtc_mixer *mixer,
+	struct dpu_hw_stage_cfg *stage_cfg)
 {
 	struct drm_plane *plane;
 	struct drm_framebuffer *fb;
@@ -199,7 +200,6 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	struct dpu_plane_state *pstate = NULL;
 	struct dpu_format *format;
 	struct dpu_hw_ctl *ctl = mixer->lm_ctl;
-	struct dpu_hw_stage_cfg *stage_cfg = &dpu_crtc->stage_cfg;
 
 	u32 flush_mask;
 	uint32_t stage_idx, lm_idx;
@@ -275,6 +275,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
 	struct dpu_crtc_mixer *mixer = cstate->mixers;
 	struct dpu_hw_ctl *ctl;
 	struct dpu_hw_mixer *lm;
+	struct dpu_hw_stage_cfg stage_cfg;
 	int i;
 
 	DRM_DEBUG_ATOMIC("%s\n", dpu_crtc->name);
@@ -288,9 +289,9 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
 	}
 
 	/* initialize stage cfg */
-	memset(&dpu_crtc->stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg));
+	memset(&stage_cfg, 0, sizeof(struct dpu_hw_stage_cfg));
 
-	_dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer);
+	_dpu_crtc_blend_setup_mixer(crtc, dpu_crtc, mixer, &stage_cfg);
 
 	for (i = 0; i < cstate->num_mixers; i++) {
 		ctl = mixer[i].lm_ctl;
@@ -311,7 +312,7 @@ static void _dpu_crtc_blend_setup(struct drm_crtc *crtc)
 			mixer[i].flush_mask);
 
 		ctl->ops.setup_blendstage(ctl, mixer[i].hw_lm->idx,
-			&dpu_crtc->stage_cfg);
+			&stage_cfg);
 	}
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index cec3474340e8..30535acec670 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -116,7 +116,6 @@ struct dpu_crtc_frame_event {
  * @drm_requested_vblank : Whether vblanks have been enabled in the encoder
  * @property_info : Opaque structure for generic property support
  * @property_defaults : Array of default values for generic property support
- * @stage_cfg     : H/w mixer stage configuration
  * @debugfs_root  : Parent of debugfs node
  * @vblank_cb_count : count of vblank callback since last reset
  * @play_count    : frame count between crtc enable and disable
@@ -147,7 +146,6 @@ struct dpu_crtc {
 	struct drm_pending_vblank_event *event;
 	u32 vsync_count;
 
-	struct dpu_hw_stage_cfg stage_cfg;
 	struct dentry *debugfs_root;
 
 	u32 vblank_cb_count;
-- 
2.30.2


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

* [PATCH v2 05/22] drm/msm/dpu: rip out master planes support
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:20   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

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

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c    | 11 +---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c |  3 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  4 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c     |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 67 ++++-----------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   | 13 +---
 6 files changed, 17 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 ea678ddd4589..6fe0af9ffc23 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -974,17 +974,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	}
 
 	for (i = 1; i < SSPP_MAX; i++) {
-		if (pipe_staged[i]) {
+		if (pipe_staged[i])
 			dpu_plane_clear_multirect(pipe_staged[i]);
-
-			if (is_dpu_plane_virtual(pipe_staged[i]->plane)) {
-				DPU_ERROR(
-					"r1 only virt plane:%d not supported\n",
-					pipe_staged[i]->plane->base.id);
-				rc  = -EINVAL;
-				goto end;
-			}
-		}
 	}
 
 	z_pos = -1;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index cbafb61404d0..c16832898c51 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -708,8 +708,7 @@ static const struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp,
 }
 
 struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
-		void __iomem *addr, struct dpu_mdss_cfg *catalog,
-		bool is_virtual_pipe)
+		void __iomem *addr, struct dpu_mdss_cfg *catalog)
 {
 	struct dpu_hw_pipe *hw_pipe;
 	const struct dpu_sspp_cfg *cfg;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 27263bc1a1ef..35a848b1fcf8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -387,11 +387,9 @@ struct dpu_hw_pipe {
  * @idx:  Pipe index for which driver object is required
  * @addr: Mapped register io address of MDP
  * @catalog : Pointer to mdss catalog data
- * @is_virtual_pipe: is this pipe virtual pipe
  */
 struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
-		void __iomem *addr, struct dpu_mdss_cfg *catalog,
-		bool is_virtual_pipe);
+		void __iomem *addr, struct dpu_mdss_cfg *catalog);
 
 /**
  * dpu_hw_sspp_destroy(): Destroys SSPP driver context
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 1d3a4f395e74..b7b73d0de6f8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -623,7 +623,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
 			  catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR));
 
 		plane = dpu_plane_init(dev, catalog->sspp[i].id, type,
-				       (1UL << max_crtc_count) - 1, 0);
+				       (1UL << max_crtc_count) - 1);
 		if (IS_ERR(plane)) {
 			DPU_ERROR("dpu_plane_init failed\n");
 			ret = PTR_ERR(plane);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 97507e25f4f3..8095afdb4385 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -91,7 +91,6 @@ enum dpu_plane_qos {
  * struct dpu_plane - local dpu plane structure
  * @aspace: address space pointer
  * @csc_ptr: Points to dpu_csc_cfg structure to use for current
- * @mplane_list: List of multirect planes of the same pipe
  * @catalog: Points to dpu catalog structure
  * @revalidate: force revalidation of all the plane properties
  */
@@ -108,8 +107,6 @@ struct dpu_plane {
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
-	bool is_virtual;
-	struct list_head mplane_list;
 	struct dpu_mdss_cfg *catalog;
 
 	struct dpu_csc_cfg *csc_ptr;
@@ -237,7 +234,7 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane)
 static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
 		const struct dpu_format *fmt, u32 src_width)
 {
-	struct dpu_plane *pdpu, *tmp;
+	struct dpu_plane *pdpu;
 	struct dpu_plane_state *pstate;
 	u32 fixed_buff_size;
 	u32 total_fl;
@@ -251,16 +248,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
 	pstate = to_dpu_plane_state(plane->state);
 	fixed_buff_size = pdpu->catalog->caps->pixel_ram_size;
 
-	list_for_each_entry(tmp, &pdpu->mplane_list, mplane_list) {
-		if (!tmp->base.state->visible)
-			continue;
-		DPU_DEBUG("plane%d/%d src_width:%d/%d\n",
-				pdpu->base.base.id, tmp->base.base.id,
-				src_width,
-				drm_rect_width(&tmp->pipe_cfg.src_rect));
-		src_width = max_t(u32, src_width,
-				  drm_rect_width(&tmp->pipe_cfg.src_rect));
-	}
+	/* FIXME: in multirect case account for the src_width of all the planes */
 
 	if (fmt->fetch_planes == DPU_PLANE_PSEUDO_PLANAR) {
 		if (fmt->chroma_sample == DPU_CHROMA_420) {
@@ -836,13 +824,8 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 	}
 
 done:
-	if (dpu_plane[R0]->is_virtual) {
-		pstate[R0]->multirect_index = DPU_SSPP_RECT_1;
-		pstate[R1]->multirect_index = DPU_SSPP_RECT_0;
-	} else {
-		pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
-		pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
-	}
+	pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
+	pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
 
 	DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
 		pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
@@ -1218,19 +1201,13 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
 {
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct drm_plane_state *state = plane->state;
 	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
 
-	trace_dpu_plane_disable(DRMID(plane), is_dpu_plane_virtual(plane),
+	trace_dpu_plane_disable(DRMID(plane), false,
 				pstate->multirect_mode);
 
 	pstate->pending = true;
-
-	if (is_dpu_plane_virtual(plane) &&
-			pdpu->pipe_hw && pdpu->pipe_hw->ops.setup_multirect)
-		pdpu->pipe_hw->ops.setup_multirect(pdpu->pipe_hw,
-				DPU_SSPP_RECT_SOLO, DPU_SSPP_MULTIRECT_NONE);
 }
 
 static void dpu_plane_atomic_update(struct drm_plane *plane,
@@ -1556,17 +1533,12 @@ enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane)
 	return plane ? to_dpu_plane(plane)->pipe : SSPP_NONE;
 }
 
-bool is_dpu_plane_virtual(struct drm_plane *plane)
-{
-	return plane ? to_dpu_plane(plane)->is_virtual : false;
-}
-
 /* initialize plane */
 struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		uint32_t pipe, enum drm_plane_type type,
-		unsigned long possible_crtcs, u32 master_plane_id)
+		unsigned long possible_crtcs)
 {
-	struct drm_plane *plane = NULL, *master_plane = NULL;
+	struct drm_plane *plane = NULL;
 	const uint32_t *format_list;
 	struct dpu_plane *pdpu;
 	struct msm_drm_private *priv = dev->dev_private;
@@ -1586,18 +1558,9 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	/* cache local stuff for later */
 	plane = &pdpu->base;
 	pdpu->pipe = pipe;
-	pdpu->is_virtual = (master_plane_id != 0);
-	INIT_LIST_HEAD(&pdpu->mplane_list);
-	master_plane = drm_plane_find(dev, NULL, master_plane_id);
-	if (master_plane) {
-		struct dpu_plane *mpdpu = to_dpu_plane(master_plane);
-
-		list_add_tail(&pdpu->mplane_list, &mpdpu->mplane_list);
-	}
 
 	/* initialize underlying h/w driver */
-	pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog,
-							master_plane_id != 0);
+	pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog);
 	if (IS_ERR(pdpu->pipe_hw)) {
 		DPU_ERROR("[%u]SSPP init failed\n", pipe);
 		ret = PTR_ERR(pdpu->pipe_hw);
@@ -1615,14 +1578,8 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		goto clean_sspp;
 	}
 
-	if (pdpu->is_virtual) {
-		format_list = pdpu->pipe_sblk->virt_format_list;
-		num_formats = pdpu->pipe_sblk->virt_num_formats;
-	}
-	else {
-		format_list = pdpu->pipe_sblk->format_list;
-		num_formats = pdpu->pipe_sblk->num_formats;
-	}
+	format_list = pdpu->pipe_sblk->format_list;
+	num_formats = pdpu->pipe_sblk->num_formats;
 
 	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
 				format_list, num_formats,
@@ -1657,8 +1614,8 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 
 	mutex_init(&pdpu->lock);
 
-	DPU_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", plane->name,
-					pipe, plane->base.id, master_plane_id);
+	DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name,
+					pipe, plane->base.id);
 	return plane;
 
 clean_sspp:
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 34e03ac05f4a..d5b7f5876e64 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -67,14 +67,6 @@ struct dpu_multirect_plane_states {
  */
 enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
 
-/**
- * is_dpu_plane_virtual - check for virtual plane
- * @plane: Pointer to DRM plane object
- * returns: true - if the plane is virtual
- *          false - if the plane is primary
- */
-bool is_dpu_plane_virtual(struct drm_plane *plane);
-
 /**
  * dpu_plane_get_ctl_flush - get control flush mask
  * @plane:   Pointer to DRM plane object
@@ -102,14 +94,11 @@ void dpu_plane_set_error(struct drm_plane *plane, bool error);
  * @pipe:  dpu hardware pipe identifier
  * @type:  Plane type - PRIMARY/OVERLAY/CURSOR
  * @possible_crtcs: bitmask of crtc that can be attached to the given pipe
- * @master_plane_id: primary plane id of a multirect pipe. 0 value passed for
- *                   a regular plane initialization. A non-zero primary plane
- *                   id will be passed for a virtual pipe initialization.
  *
  */
 struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		uint32_t pipe, enum drm_plane_type type,
-		unsigned long possible_crtcs, u32 master_plane_id);
+		unsigned long possible_crtcs);
 
 /**
  * dpu_plane_validate_multirecti_v2 - validate the multirect planes
-- 
2.30.2


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

* [PATCH v2 05/22] drm/msm/dpu: rip out master planes support
@ 2021-07-05  1:20   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

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

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c    | 11 +---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c |  3 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  4 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c     |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 67 ++++-----------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h   | 13 +---
 6 files changed, 17 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 ea678ddd4589..6fe0af9ffc23 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -974,17 +974,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	}
 
 	for (i = 1; i < SSPP_MAX; i++) {
-		if (pipe_staged[i]) {
+		if (pipe_staged[i])
 			dpu_plane_clear_multirect(pipe_staged[i]);
-
-			if (is_dpu_plane_virtual(pipe_staged[i]->plane)) {
-				DPU_ERROR(
-					"r1 only virt plane:%d not supported\n",
-					pipe_staged[i]->plane->base.id);
-				rc  = -EINVAL;
-				goto end;
-			}
-		}
 	}
 
 	z_pos = -1;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index cbafb61404d0..c16832898c51 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -708,8 +708,7 @@ static const struct dpu_sspp_cfg *_sspp_offset(enum dpu_sspp sspp,
 }
 
 struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
-		void __iomem *addr, struct dpu_mdss_cfg *catalog,
-		bool is_virtual_pipe)
+		void __iomem *addr, struct dpu_mdss_cfg *catalog)
 {
 	struct dpu_hw_pipe *hw_pipe;
 	const struct dpu_sspp_cfg *cfg;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 27263bc1a1ef..35a848b1fcf8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -387,11 +387,9 @@ struct dpu_hw_pipe {
  * @idx:  Pipe index for which driver object is required
  * @addr: Mapped register io address of MDP
  * @catalog : Pointer to mdss catalog data
- * @is_virtual_pipe: is this pipe virtual pipe
  */
 struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
-		void __iomem *addr, struct dpu_mdss_cfg *catalog,
-		bool is_virtual_pipe);
+		void __iomem *addr, struct dpu_mdss_cfg *catalog);
 
 /**
  * dpu_hw_sspp_destroy(): Destroys SSPP driver context
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 1d3a4f395e74..b7b73d0de6f8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -623,7 +623,7 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
 			  catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR));
 
 		plane = dpu_plane_init(dev, catalog->sspp[i].id, type,
-				       (1UL << max_crtc_count) - 1, 0);
+				       (1UL << max_crtc_count) - 1);
 		if (IS_ERR(plane)) {
 			DPU_ERROR("dpu_plane_init failed\n");
 			ret = PTR_ERR(plane);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 97507e25f4f3..8095afdb4385 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -91,7 +91,6 @@ enum dpu_plane_qos {
  * struct dpu_plane - local dpu plane structure
  * @aspace: address space pointer
  * @csc_ptr: Points to dpu_csc_cfg structure to use for current
- * @mplane_list: List of multirect planes of the same pipe
  * @catalog: Points to dpu catalog structure
  * @revalidate: force revalidation of all the plane properties
  */
@@ -108,8 +107,6 @@ struct dpu_plane {
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
-	bool is_virtual;
-	struct list_head mplane_list;
 	struct dpu_mdss_cfg *catalog;
 
 	struct dpu_csc_cfg *csc_ptr;
@@ -237,7 +234,7 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane)
 static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
 		const struct dpu_format *fmt, u32 src_width)
 {
-	struct dpu_plane *pdpu, *tmp;
+	struct dpu_plane *pdpu;
 	struct dpu_plane_state *pstate;
 	u32 fixed_buff_size;
 	u32 total_fl;
@@ -251,16 +248,7 @@ static int _dpu_plane_calc_fill_level(struct drm_plane *plane,
 	pstate = to_dpu_plane_state(plane->state);
 	fixed_buff_size = pdpu->catalog->caps->pixel_ram_size;
 
-	list_for_each_entry(tmp, &pdpu->mplane_list, mplane_list) {
-		if (!tmp->base.state->visible)
-			continue;
-		DPU_DEBUG("plane%d/%d src_width:%d/%d\n",
-				pdpu->base.base.id, tmp->base.base.id,
-				src_width,
-				drm_rect_width(&tmp->pipe_cfg.src_rect));
-		src_width = max_t(u32, src_width,
-				  drm_rect_width(&tmp->pipe_cfg.src_rect));
-	}
+	/* FIXME: in multirect case account for the src_width of all the planes */
 
 	if (fmt->fetch_planes == DPU_PLANE_PSEUDO_PLANAR) {
 		if (fmt->chroma_sample == DPU_CHROMA_420) {
@@ -836,13 +824,8 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 	}
 
 done:
-	if (dpu_plane[R0]->is_virtual) {
-		pstate[R0]->multirect_index = DPU_SSPP_RECT_1;
-		pstate[R1]->multirect_index = DPU_SSPP_RECT_0;
-	} else {
-		pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
-		pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
-	}
+	pstate[R0]->multirect_index = DPU_SSPP_RECT_0;
+	pstate[R1]->multirect_index = DPU_SSPP_RECT_1;
 
 	DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
 		pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
@@ -1218,19 +1201,13 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
 {
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct drm_plane_state *state = plane->state;
 	struct dpu_plane_state *pstate = to_dpu_plane_state(state);
 
-	trace_dpu_plane_disable(DRMID(plane), is_dpu_plane_virtual(plane),
+	trace_dpu_plane_disable(DRMID(plane), false,
 				pstate->multirect_mode);
 
 	pstate->pending = true;
-
-	if (is_dpu_plane_virtual(plane) &&
-			pdpu->pipe_hw && pdpu->pipe_hw->ops.setup_multirect)
-		pdpu->pipe_hw->ops.setup_multirect(pdpu->pipe_hw,
-				DPU_SSPP_RECT_SOLO, DPU_SSPP_MULTIRECT_NONE);
 }
 
 static void dpu_plane_atomic_update(struct drm_plane *plane,
@@ -1556,17 +1533,12 @@ enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane)
 	return plane ? to_dpu_plane(plane)->pipe : SSPP_NONE;
 }
 
-bool is_dpu_plane_virtual(struct drm_plane *plane)
-{
-	return plane ? to_dpu_plane(plane)->is_virtual : false;
-}
-
 /* initialize plane */
 struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		uint32_t pipe, enum drm_plane_type type,
-		unsigned long possible_crtcs, u32 master_plane_id)
+		unsigned long possible_crtcs)
 {
-	struct drm_plane *plane = NULL, *master_plane = NULL;
+	struct drm_plane *plane = NULL;
 	const uint32_t *format_list;
 	struct dpu_plane *pdpu;
 	struct msm_drm_private *priv = dev->dev_private;
@@ -1586,18 +1558,9 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	/* cache local stuff for later */
 	plane = &pdpu->base;
 	pdpu->pipe = pipe;
-	pdpu->is_virtual = (master_plane_id != 0);
-	INIT_LIST_HEAD(&pdpu->mplane_list);
-	master_plane = drm_plane_find(dev, NULL, master_plane_id);
-	if (master_plane) {
-		struct dpu_plane *mpdpu = to_dpu_plane(master_plane);
-
-		list_add_tail(&pdpu->mplane_list, &mpdpu->mplane_list);
-	}
 
 	/* initialize underlying h/w driver */
-	pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog,
-							master_plane_id != 0);
+	pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog);
 	if (IS_ERR(pdpu->pipe_hw)) {
 		DPU_ERROR("[%u]SSPP init failed\n", pipe);
 		ret = PTR_ERR(pdpu->pipe_hw);
@@ -1615,14 +1578,8 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		goto clean_sspp;
 	}
 
-	if (pdpu->is_virtual) {
-		format_list = pdpu->pipe_sblk->virt_format_list;
-		num_formats = pdpu->pipe_sblk->virt_num_formats;
-	}
-	else {
-		format_list = pdpu->pipe_sblk->format_list;
-		num_formats = pdpu->pipe_sblk->num_formats;
-	}
+	format_list = pdpu->pipe_sblk->format_list;
+	num_formats = pdpu->pipe_sblk->num_formats;
 
 	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
 				format_list, num_formats,
@@ -1657,8 +1614,8 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 
 	mutex_init(&pdpu->lock);
 
-	DPU_DEBUG("%s created for pipe:%u id:%u virtual:%u\n", plane->name,
-					pipe, plane->base.id, master_plane_id);
+	DPU_DEBUG("%s created for pipe:%u id:%u\n", plane->name,
+					pipe, plane->base.id);
 	return plane;
 
 clean_sspp:
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 34e03ac05f4a..d5b7f5876e64 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -67,14 +67,6 @@ struct dpu_multirect_plane_states {
  */
 enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
 
-/**
- * is_dpu_plane_virtual - check for virtual plane
- * @plane: Pointer to DRM plane object
- * returns: true - if the plane is virtual
- *          false - if the plane is primary
- */
-bool is_dpu_plane_virtual(struct drm_plane *plane);
-
 /**
  * dpu_plane_get_ctl_flush - get control flush mask
  * @plane:   Pointer to DRM plane object
@@ -102,14 +94,11 @@ void dpu_plane_set_error(struct drm_plane *plane, bool error);
  * @pipe:  dpu hardware pipe identifier
  * @type:  Plane type - PRIMARY/OVERLAY/CURSOR
  * @possible_crtcs: bitmask of crtc that can be attached to the given pipe
- * @master_plane_id: primary plane id of a multirect pipe. 0 value passed for
- *                   a regular plane initialization. A non-zero primary plane
- *                   id will be passed for a virtual pipe initialization.
  *
  */
 struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		uint32_t pipe, enum drm_plane_type type,
-		unsigned long possible_crtcs, u32 master_plane_id);
+		unsigned long possible_crtcs);
 
 /**
  * dpu_plane_validate_multirecti_v2 - validate the multirect planes
-- 
2.30.2


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

* [PATCH v2 06/22] drm/msm/dpu: move dpu_hw_pipe_cfg out of struct dpu_plane
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:20   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

struct dpu_hw_pipe_cfg represents an interim state during atomic
update/color fill, so move it out of struct dpu_plane.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 8095afdb4385..cd1a1e333f7c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -103,7 +103,6 @@ struct dpu_plane {
 	uint32_t features;      /* capabilities from catalog */
 
 	struct dpu_hw_pipe *pipe_hw;
-	struct dpu_hw_pipe_cfg pipe_cfg;
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
@@ -140,14 +139,15 @@ 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
+ * @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)
+	struct drm_framebuffer *fb,
+	struct dpu_hw_pipe_cfg *pipe_cfg)
 {
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_plane_state *pstate;
 	struct drm_display_mode *mode;
 	const struct dpu_format *fmt = NULL;
@@ -164,9 +164,9 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
 
 	fmt = dpu_get_dpu_format_ext(fb->format->format, fb->modifier);
 
-	src_width = drm_rect_width(&pdpu->pipe_cfg.src_rect);
-	src_height = drm_rect_height(&pdpu->pipe_cfg.src_rect);
-	dst_height = drm_rect_height(&pdpu->pipe_cfg.dst_rect);
+	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);
 	fps = drm_mode_vrefresh(mode);
 	vbp = mode->vtotal - mode->vsync_end;
 	vpw = mode->vsync_end - mode->vsync_start;
@@ -197,12 +197,12 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
 /**
  * _dpu_plane_calc_clk - calculate clock required for a plane
  * @plane: Pointer to drm plane.
+ * @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)
+static void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_plane_state *pstate;
 	struct drm_display_mode *mode;
 	int dst_width, src_height, dst_height, fps;
@@ -210,9 +210,9 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane)
 	pstate = to_dpu_plane_state(plane->state);
 	mode = &plane->state->crtc->mode;
 
-	src_height = drm_rect_height(&pdpu->pipe_cfg.src_rect);
-	dst_width = drm_rect_width(&pdpu->pipe_cfg.dst_rect);
-	dst_height = drm_rect_height(&pdpu->pipe_cfg.dst_rect);
+	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 =
@@ -307,9 +307,10 @@ static u64 _dpu_plane_get_qos_lut(const struct dpu_qos_lut_tbl *tbl,
  * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
  * @plane:		Pointer to drm plane
  * @fb:			Pointer to framebuffer associated with the given plane
+ * @pipe_cfg:		Pointer to pipe configuration
  */
 static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
-		struct drm_framebuffer *fb)
+		struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	const struct dpu_format *fmt = NULL;
@@ -323,7 +324,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 				fb->format->format,
 				fb->modifier);
 		total_fl = _dpu_plane_calc_fill_level(plane, fmt,
-				drm_rect_width(&pdpu->pipe_cfg.src_rect));
+				drm_rect_width(&pipe_cfg->src_rect));
 
 		if (fmt && DPU_FORMAT_IS_LINEAR(fmt))
 			lut_usage = DPU_QOS_LUT_USAGE_LINEAR;
@@ -449,9 +450,10 @@ 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
  * @crtc:		Pointer to drm crtc
+ * @pipe_cfg:		Pointer to pipe configuration
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
-		struct drm_crtc *crtc)
+		struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_vbif_set_ot_params ot_params;
@@ -460,8 +462,8 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *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.width = drm_rect_width(&pdpu->pipe_cfg.src_rect);
-	ot_params.height = drm_rect_height(&pdpu->pipe_cfg.src_rect);
+	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;
@@ -639,17 +641,18 @@ static void _dpu_plane_setup_csc(struct dpu_plane *pdpu)
 
 static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 		struct dpu_plane_state *pstate,
-		const struct dpu_format *fmt, bool color_fill)
+		const struct dpu_format *fmt, bool color_fill,
+		struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
 
 	/* don't chroma subsample if decimating */
 	/* update scaler. calculate default config for QSEED3 */
 	_dpu_plane_setup_scaler3(pdpu, pstate,
-			drm_rect_width(&pdpu->pipe_cfg.src_rect),
-			drm_rect_height(&pdpu->pipe_cfg.src_rect),
-			drm_rect_width(&pdpu->pipe_cfg.dst_rect),
-			drm_rect_height(&pdpu->pipe_cfg.dst_rect),
+			drm_rect_width(&pipe_cfg->src_rect),
+			drm_rect_height(&pipe_cfg->src_rect),
+			drm_rect_width(&pipe_cfg->dst_rect),
+			drm_rect_height(&pipe_cfg->dst_rect),
 			&pstate->scaler3_cfg, fmt,
 			info->hsub, info->vsub);
 }
@@ -667,6 +670,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;
 
 	DPU_DEBUG_PLANE(pdpu, "\n");
 
@@ -683,13 +687,15 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 				pstate->multirect_index);
 
 		/* override scaler/decimation if solid fill */
-		pdpu->pipe_cfg.src_rect.x1 = 0;
-		pdpu->pipe_cfg.src_rect.y1 = 0;
-		pdpu->pipe_cfg.src_rect.x2 =
-			drm_rect_width(&pdpu->pipe_cfg.dst_rect);
-		pdpu->pipe_cfg.src_rect.y2 =
-			drm_rect_height(&pdpu->pipe_cfg.dst_rect);
-		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true);
+		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);
+		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
 
 		if (pdpu->pipe_hw->ops.setup_format)
 			pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw,
@@ -698,7 +704,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 
 		if (pdpu->pipe_hw->ops.setup_rects)
 			pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
-					&pdpu->pipe_cfg,
+					&pipe_cfg,
 					pstate->multirect_index);
 
 		if (pdpu->pipe_hw->ops.setup_pe)
@@ -708,7 +714,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 		if (pdpu->pipe_hw->ops.setup_scaler &&
 				pstate->multirect_index != DPU_SSPP_RECT_1)
 			pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
-					&pdpu->pipe_cfg, &pstate->pixel_ext,
+					&pipe_cfg, &pstate->pixel_ext,
 					&pstate->scaler3_cfg);
 	}
 
@@ -1070,10 +1076,11 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	bool is_rt_pipe, update_qos_remap;
 	const struct dpu_format *fmt =
 		to_dpu_format(msm_framebuffer_format(fb));
+	struct dpu_hw_pipe_cfg pipe_cfg;
 
-	memset(&(pdpu->pipe_cfg), 0, sizeof(struct dpu_hw_pipe_cfg));
+	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
 
-	_dpu_plane_set_scanout(plane, pstate, &pdpu->pipe_cfg, fb);
+	_dpu_plane_set_scanout(plane, pstate, &pipe_cfg, fb);
 
 	pstate->pending = true;
 
@@ -1085,17 +1092,17 @@ 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));
 
-	pdpu->pipe_cfg.src_rect = state->src;
+	pipe_cfg.src_rect = state->src;
 
 	/* state->src is 16.16, src_rect is not */
-	pdpu->pipe_cfg.src_rect.x1 >>= 16;
-	pdpu->pipe_cfg.src_rect.x2 >>= 16;
-	pdpu->pipe_cfg.src_rect.y1 >>= 16;
-	pdpu->pipe_cfg.src_rect.y2 >>= 16;
+	pipe_cfg.src_rect.x1 >>= 16;
+	pipe_cfg.src_rect.x2 >>= 16;
+	pipe_cfg.src_rect.y1 >>= 16;
+	pipe_cfg.src_rect.y2 >>= 16;
 
-	pdpu->pipe_cfg.dst_rect = state->dst;
+	pipe_cfg.dst_rect = state->dst;
 
-	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false);
+	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
 
 	/* override for color fill */
 	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
@@ -1105,7 +1112,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 	if (pdpu->pipe_hw->ops.setup_rects) {
 		pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
-				&pdpu->pipe_cfg,
+				&pipe_cfg,
 				pstate->multirect_index);
 	}
 
@@ -1122,7 +1129,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	if (pdpu->pipe_hw->ops.setup_scaler &&
 			pstate->multirect_index != DPU_SSPP_RECT_1)
 		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
-				&pdpu->pipe_cfg, &pstate->pixel_ext,
+				&pipe_cfg, &pstate->pixel_ext,
 				&pstate->scaler3_cfg);
 
 	if (pdpu->pipe_hw->ops.setup_multirect)
@@ -1175,12 +1182,12 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			pdpu->csc_ptr = 0;
 	}
 
-	_dpu_plane_set_qos_lut(plane, fb);
+	_dpu_plane_set_qos_lut(plane, fb, &pipe_cfg);
 	_dpu_plane_set_danger_lut(plane, fb);
 
 	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
 		_dpu_plane_set_qos_ctrl(plane, true, DPU_PLANE_QOS_PANIC_CTRL);
-		_dpu_plane_set_ot_limit(plane, crtc);
+		_dpu_plane_set_ot_limit(plane, crtc, &pipe_cfg);
 	}
 
 	update_qos_remap = (is_rt_pipe != pdpu->is_rt_pipe) ||
@@ -1194,9 +1201,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		_dpu_plane_set_qos_remap(plane);
 	}
 
-	_dpu_plane_calc_bw(plane, fb);
+	_dpu_plane_calc_bw(plane, fb, &pipe_cfg);
 
-	_dpu_plane_calc_clk(plane);
+	_dpu_plane_calc_clk(plane, &pipe_cfg);
 }
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
-- 
2.30.2


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

* [PATCH v2 06/22] drm/msm/dpu: move dpu_hw_pipe_cfg out of struct dpu_plane
@ 2021-07-05  1:20   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:20 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

struct dpu_hw_pipe_cfg represents an interim state during atomic
update/color fill, so move it out of struct dpu_plane.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 8095afdb4385..cd1a1e333f7c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -103,7 +103,6 @@ struct dpu_plane {
 	uint32_t features;      /* capabilities from catalog */
 
 	struct dpu_hw_pipe *pipe_hw;
-	struct dpu_hw_pipe_cfg pipe_cfg;
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
@@ -140,14 +139,15 @@ 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
+ * @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)
+	struct drm_framebuffer *fb,
+	struct dpu_hw_pipe_cfg *pipe_cfg)
 {
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_plane_state *pstate;
 	struct drm_display_mode *mode;
 	const struct dpu_format *fmt = NULL;
@@ -164,9 +164,9 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
 
 	fmt = dpu_get_dpu_format_ext(fb->format->format, fb->modifier);
 
-	src_width = drm_rect_width(&pdpu->pipe_cfg.src_rect);
-	src_height = drm_rect_height(&pdpu->pipe_cfg.src_rect);
-	dst_height = drm_rect_height(&pdpu->pipe_cfg.dst_rect);
+	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);
 	fps = drm_mode_vrefresh(mode);
 	vbp = mode->vtotal - mode->vsync_end;
 	vpw = mode->vsync_end - mode->vsync_start;
@@ -197,12 +197,12 @@ static void _dpu_plane_calc_bw(struct drm_plane *plane,
 /**
  * _dpu_plane_calc_clk - calculate clock required for a plane
  * @plane: Pointer to drm plane.
+ * @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)
+static void _dpu_plane_calc_clk(struct drm_plane *plane, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_plane_state *pstate;
 	struct drm_display_mode *mode;
 	int dst_width, src_height, dst_height, fps;
@@ -210,9 +210,9 @@ static void _dpu_plane_calc_clk(struct drm_plane *plane)
 	pstate = to_dpu_plane_state(plane->state);
 	mode = &plane->state->crtc->mode;
 
-	src_height = drm_rect_height(&pdpu->pipe_cfg.src_rect);
-	dst_width = drm_rect_width(&pdpu->pipe_cfg.dst_rect);
-	dst_height = drm_rect_height(&pdpu->pipe_cfg.dst_rect);
+	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 =
@@ -307,9 +307,10 @@ static u64 _dpu_plane_get_qos_lut(const struct dpu_qos_lut_tbl *tbl,
  * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
  * @plane:		Pointer to drm plane
  * @fb:			Pointer to framebuffer associated with the given plane
+ * @pipe_cfg:		Pointer to pipe configuration
  */
 static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
-		struct drm_framebuffer *fb)
+		struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	const struct dpu_format *fmt = NULL;
@@ -323,7 +324,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 				fb->format->format,
 				fb->modifier);
 		total_fl = _dpu_plane_calc_fill_level(plane, fmt,
-				drm_rect_width(&pdpu->pipe_cfg.src_rect));
+				drm_rect_width(&pipe_cfg->src_rect));
 
 		if (fmt && DPU_FORMAT_IS_LINEAR(fmt))
 			lut_usage = DPU_QOS_LUT_USAGE_LINEAR;
@@ -449,9 +450,10 @@ 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
  * @crtc:		Pointer to drm crtc
+ * @pipe_cfg:		Pointer to pipe configuration
  */
 static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
-		struct drm_crtc *crtc)
+		struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_vbif_set_ot_params ot_params;
@@ -460,8 +462,8 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *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.width = drm_rect_width(&pdpu->pipe_cfg.src_rect);
-	ot_params.height = drm_rect_height(&pdpu->pipe_cfg.src_rect);
+	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;
@@ -639,17 +641,18 @@ static void _dpu_plane_setup_csc(struct dpu_plane *pdpu)
 
 static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 		struct dpu_plane_state *pstate,
-		const struct dpu_format *fmt, bool color_fill)
+		const struct dpu_format *fmt, bool color_fill,
+		struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
 
 	/* don't chroma subsample if decimating */
 	/* update scaler. calculate default config for QSEED3 */
 	_dpu_plane_setup_scaler3(pdpu, pstate,
-			drm_rect_width(&pdpu->pipe_cfg.src_rect),
-			drm_rect_height(&pdpu->pipe_cfg.src_rect),
-			drm_rect_width(&pdpu->pipe_cfg.dst_rect),
-			drm_rect_height(&pdpu->pipe_cfg.dst_rect),
+			drm_rect_width(&pipe_cfg->src_rect),
+			drm_rect_height(&pipe_cfg->src_rect),
+			drm_rect_width(&pipe_cfg->dst_rect),
+			drm_rect_height(&pipe_cfg->dst_rect),
 			&pstate->scaler3_cfg, fmt,
 			info->hsub, info->vsub);
 }
@@ -667,6 +670,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;
 
 	DPU_DEBUG_PLANE(pdpu, "\n");
 
@@ -683,13 +687,15 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 				pstate->multirect_index);
 
 		/* override scaler/decimation if solid fill */
-		pdpu->pipe_cfg.src_rect.x1 = 0;
-		pdpu->pipe_cfg.src_rect.y1 = 0;
-		pdpu->pipe_cfg.src_rect.x2 =
-			drm_rect_width(&pdpu->pipe_cfg.dst_rect);
-		pdpu->pipe_cfg.src_rect.y2 =
-			drm_rect_height(&pdpu->pipe_cfg.dst_rect);
-		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true);
+		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);
+		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
 
 		if (pdpu->pipe_hw->ops.setup_format)
 			pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw,
@@ -698,7 +704,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 
 		if (pdpu->pipe_hw->ops.setup_rects)
 			pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
-					&pdpu->pipe_cfg,
+					&pipe_cfg,
 					pstate->multirect_index);
 
 		if (pdpu->pipe_hw->ops.setup_pe)
@@ -708,7 +714,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 		if (pdpu->pipe_hw->ops.setup_scaler &&
 				pstate->multirect_index != DPU_SSPP_RECT_1)
 			pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
-					&pdpu->pipe_cfg, &pstate->pixel_ext,
+					&pipe_cfg, &pstate->pixel_ext,
 					&pstate->scaler3_cfg);
 	}
 
@@ -1070,10 +1076,11 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	bool is_rt_pipe, update_qos_remap;
 	const struct dpu_format *fmt =
 		to_dpu_format(msm_framebuffer_format(fb));
+	struct dpu_hw_pipe_cfg pipe_cfg;
 
-	memset(&(pdpu->pipe_cfg), 0, sizeof(struct dpu_hw_pipe_cfg));
+	memset(&pipe_cfg, 0, sizeof(struct dpu_hw_pipe_cfg));
 
-	_dpu_plane_set_scanout(plane, pstate, &pdpu->pipe_cfg, fb);
+	_dpu_plane_set_scanout(plane, pstate, &pipe_cfg, fb);
 
 	pstate->pending = true;
 
@@ -1085,17 +1092,17 @@ 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));
 
-	pdpu->pipe_cfg.src_rect = state->src;
+	pipe_cfg.src_rect = state->src;
 
 	/* state->src is 16.16, src_rect is not */
-	pdpu->pipe_cfg.src_rect.x1 >>= 16;
-	pdpu->pipe_cfg.src_rect.x2 >>= 16;
-	pdpu->pipe_cfg.src_rect.y1 >>= 16;
-	pdpu->pipe_cfg.src_rect.y2 >>= 16;
+	pipe_cfg.src_rect.x1 >>= 16;
+	pipe_cfg.src_rect.x2 >>= 16;
+	pipe_cfg.src_rect.y1 >>= 16;
+	pipe_cfg.src_rect.y2 >>= 16;
 
-	pdpu->pipe_cfg.dst_rect = state->dst;
+	pipe_cfg.dst_rect = state->dst;
 
-	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false);
+	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
 
 	/* override for color fill */
 	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
@@ -1105,7 +1112,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 	if (pdpu->pipe_hw->ops.setup_rects) {
 		pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
-				&pdpu->pipe_cfg,
+				&pipe_cfg,
 				pstate->multirect_index);
 	}
 
@@ -1122,7 +1129,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 	if (pdpu->pipe_hw->ops.setup_scaler &&
 			pstate->multirect_index != DPU_SSPP_RECT_1)
 		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
-				&pdpu->pipe_cfg, &pstate->pixel_ext,
+				&pipe_cfg, &pstate->pixel_ext,
 				&pstate->scaler3_cfg);
 
 	if (pdpu->pipe_hw->ops.setup_multirect)
@@ -1175,12 +1182,12 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			pdpu->csc_ptr = 0;
 	}
 
-	_dpu_plane_set_qos_lut(plane, fb);
+	_dpu_plane_set_qos_lut(plane, fb, &pipe_cfg);
 	_dpu_plane_set_danger_lut(plane, fb);
 
 	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
 		_dpu_plane_set_qos_ctrl(plane, true, DPU_PLANE_QOS_PANIC_CTRL);
-		_dpu_plane_set_ot_limit(plane, crtc);
+		_dpu_plane_set_ot_limit(plane, crtc, &pipe_cfg);
 	}
 
 	update_qos_remap = (is_rt_pipe != pdpu->is_rt_pipe) ||
@@ -1194,9 +1201,9 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		_dpu_plane_set_qos_remap(plane);
 	}
 
-	_dpu_plane_calc_bw(plane, fb);
+	_dpu_plane_calc_bw(plane, fb, &pipe_cfg);
 
-	_dpu_plane_calc_clk(plane);
+	_dpu_plane_calc_clk(plane, &pipe_cfg);
 }
 
 static void _dpu_plane_atomic_disable(struct drm_plane *plane)
-- 
2.30.2


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

* [PATCH v2 07/22] drm/msm/dpu: drop scaler config from plane state
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Scaler and pixel_ext configuration does not contain a long living state,
it is used only during plane update, so remove these two fiels from
dpu_plane_state and allocate them on stack.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index cd1a1e333f7c..46446610e07e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -527,14 +527,12 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 		struct dpu_plane_state *pstate,
 		uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h,
 		struct dpu_hw_scaler3_cfg *scale_cfg,
+		struct dpu_hw_pixel_ext *pixel_ext,
 		const struct dpu_format *fmt,
 		uint32_t chroma_subsmpl_h, uint32_t chroma_subsmpl_v)
 {
 	uint32_t i;
 
-	memset(scale_cfg, 0, sizeof(*scale_cfg));
-	memset(&pstate->pixel_ext, 0, sizeof(struct dpu_hw_pixel_ext));
-
 	scale_cfg->phase_step_x[DPU_SSPP_COMP_0] =
 		mult_frac((1 << PHASE_STEP_SHIFT), src_w, dst_w);
 	scale_cfg->phase_step_y[DPU_SSPP_COMP_0] =
@@ -573,9 +571,9 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 			scale_cfg->preload_y[i] = DPU_QSEED3_DEFAULT_PRELOAD_V;
 		}
 
-		pstate->pixel_ext.num_ext_pxls_top[i] =
+		pixel_ext->num_ext_pxls_top[i] =
 			scale_cfg->src_height[i];
-		pstate->pixel_ext.num_ext_pxls_left[i] =
+		pixel_ext->num_ext_pxls_left[i] =
 			scale_cfg->src_width[i];
 	}
 	if (!(DPU_FORMAT_IS_YUV(fmt)) && (src_h == dst_h)
@@ -645,6 +643,11 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 		struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	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;
+
+	memset(&scaler3_cfg, 0, sizeof(scaler3_cfg));
+	memset(&pixel_ext, 0, sizeof(pixel_ext));
 
 	/* don't chroma subsample if decimating */
 	/* update scaler. calculate default config for QSEED3 */
@@ -653,8 +656,23 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 			drm_rect_height(&pipe_cfg->src_rect),
 			drm_rect_width(&pipe_cfg->dst_rect),
 			drm_rect_height(&pipe_cfg->dst_rect),
-			&pstate->scaler3_cfg, fmt,
+			&scaler3_cfg, &pixel_ext, fmt,
 			info->hsub, info->vsub);
+
+	if (pdpu->pipe_hw->ops.setup_pe)
+		pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
+				&pixel_ext);
+
+	/**
+	 * when programmed in multirect mode, scalar block will be
+	 * bypassed. Still we need to update alpha and bitwidth
+	 * ONLY for RECT0
+	 */
+	if (pdpu->pipe_hw->ops.setup_scaler &&
+			pstate->multirect_index != DPU_SSPP_RECT_1)
+		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
+				pipe_cfg, &pixel_ext,
+				&scaler3_cfg);
 }
 
 /**
@@ -695,7 +713,6 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 			drm_rect_width(&pipe_cfg.dst_rect);
 		pipe_cfg.src_rect.y2 =
 			drm_rect_height(&pipe_cfg.dst_rect);
-		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
 
 		if (pdpu->pipe_hw->ops.setup_format)
 			pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw,
@@ -707,15 +724,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 					&pipe_cfg,
 					pstate->multirect_index);
 
-		if (pdpu->pipe_hw->ops.setup_pe)
-			pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
-					&pstate->pixel_ext);
-
-		if (pdpu->pipe_hw->ops.setup_scaler &&
-				pstate->multirect_index != DPU_SSPP_RECT_1)
-			pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
-					&pipe_cfg, &pstate->pixel_ext,
-					&pstate->scaler3_cfg);
+		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
 	}
 
 	return 0;
@@ -1102,8 +1111,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 	pipe_cfg.dst_rect = state->dst;
 
-	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
-
 	/* override for color fill */
 	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
 		/* skip remaining processing on color fill */
@@ -1116,21 +1123,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 				pstate->multirect_index);
 	}
 
-	if (pdpu->pipe_hw->ops.setup_pe &&
-			(pstate->multirect_index != DPU_SSPP_RECT_1))
-		pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
-				&pstate->pixel_ext);
-
-	/**
-	 * when programmed in multirect mode, scalar block will be
-	 * bypassed. Still we need to update alpha and bitwidth
-	 * ONLY for RECT0
-	 */
-	if (pdpu->pipe_hw->ops.setup_scaler &&
-			pstate->multirect_index != DPU_SSPP_RECT_1)
-		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
-				&pipe_cfg, &pstate->pixel_ext,
-				&pstate->scaler3_cfg);
+	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
 
 	if (pdpu->pipe_hw->ops.setup_multirect)
 		pdpu->pipe_hw->ops.setup_multirect(
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index d5b7f5876e64..3e4ed8a33a3e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -23,8 +23,6 @@
  * @multirect_index: index of the rectangle of SSPP
  * @multirect_mode: parallel or time multiplex multirect mode
  * @pending:	whether the current update is still pending
- * @scaler3_cfg: configuration data for scaler3
- * @pixel_ext: configuration data for pixel extensions
  * @cdp_cfg:	CDP configuration
  * @plane_fetch_bw: calculated BW per plane
  * @plane_clk: calculated clk per plane
@@ -38,10 +36,6 @@ struct dpu_plane_state {
 	uint32_t multirect_mode;
 	bool pending;
 
-	/* scaler configuration */
-	struct dpu_hw_scaler3_cfg scaler3_cfg;
-	struct dpu_hw_pixel_ext pixel_ext;
-
 	struct dpu_hw_pipe_cdp_cfg cdp_cfg;
 	u64 plane_fetch_bw;
 	u64 plane_clk;
-- 
2.30.2


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

* [PATCH v2 07/22] drm/msm/dpu: drop scaler config from plane state
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

Scaler and pixel_ext configuration does not contain a long living state,
it is used only during plane update, so remove these two fiels from
dpu_plane_state and allocate them on stack.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index cd1a1e333f7c..46446610e07e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -527,14 +527,12 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 		struct dpu_plane_state *pstate,
 		uint32_t src_w, uint32_t src_h, uint32_t dst_w, uint32_t dst_h,
 		struct dpu_hw_scaler3_cfg *scale_cfg,
+		struct dpu_hw_pixel_ext *pixel_ext,
 		const struct dpu_format *fmt,
 		uint32_t chroma_subsmpl_h, uint32_t chroma_subsmpl_v)
 {
 	uint32_t i;
 
-	memset(scale_cfg, 0, sizeof(*scale_cfg));
-	memset(&pstate->pixel_ext, 0, sizeof(struct dpu_hw_pixel_ext));
-
 	scale_cfg->phase_step_x[DPU_SSPP_COMP_0] =
 		mult_frac((1 << PHASE_STEP_SHIFT), src_w, dst_w);
 	scale_cfg->phase_step_y[DPU_SSPP_COMP_0] =
@@ -573,9 +571,9 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 			scale_cfg->preload_y[i] = DPU_QSEED3_DEFAULT_PRELOAD_V;
 		}
 
-		pstate->pixel_ext.num_ext_pxls_top[i] =
+		pixel_ext->num_ext_pxls_top[i] =
 			scale_cfg->src_height[i];
-		pstate->pixel_ext.num_ext_pxls_left[i] =
+		pixel_ext->num_ext_pxls_left[i] =
 			scale_cfg->src_width[i];
 	}
 	if (!(DPU_FORMAT_IS_YUV(fmt)) && (src_h == dst_h)
@@ -645,6 +643,11 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 		struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	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;
+
+	memset(&scaler3_cfg, 0, sizeof(scaler3_cfg));
+	memset(&pixel_ext, 0, sizeof(pixel_ext));
 
 	/* don't chroma subsample if decimating */
 	/* update scaler. calculate default config for QSEED3 */
@@ -653,8 +656,23 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 			drm_rect_height(&pipe_cfg->src_rect),
 			drm_rect_width(&pipe_cfg->dst_rect),
 			drm_rect_height(&pipe_cfg->dst_rect),
-			&pstate->scaler3_cfg, fmt,
+			&scaler3_cfg, &pixel_ext, fmt,
 			info->hsub, info->vsub);
+
+	if (pdpu->pipe_hw->ops.setup_pe)
+		pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
+				&pixel_ext);
+
+	/**
+	 * when programmed in multirect mode, scalar block will be
+	 * bypassed. Still we need to update alpha and bitwidth
+	 * ONLY for RECT0
+	 */
+	if (pdpu->pipe_hw->ops.setup_scaler &&
+			pstate->multirect_index != DPU_SSPP_RECT_1)
+		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
+				pipe_cfg, &pixel_ext,
+				&scaler3_cfg);
 }
 
 /**
@@ -695,7 +713,6 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 			drm_rect_width(&pipe_cfg.dst_rect);
 		pipe_cfg.src_rect.y2 =
 			drm_rect_height(&pipe_cfg.dst_rect);
-		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
 
 		if (pdpu->pipe_hw->ops.setup_format)
 			pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw,
@@ -707,15 +724,7 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 					&pipe_cfg,
 					pstate->multirect_index);
 
-		if (pdpu->pipe_hw->ops.setup_pe)
-			pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
-					&pstate->pixel_ext);
-
-		if (pdpu->pipe_hw->ops.setup_scaler &&
-				pstate->multirect_index != DPU_SSPP_RECT_1)
-			pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
-					&pipe_cfg, &pstate->pixel_ext,
-					&pstate->scaler3_cfg);
+		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
 	}
 
 	return 0;
@@ -1102,8 +1111,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 	pipe_cfg.dst_rect = state->dst;
 
-	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
-
 	/* override for color fill */
 	if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG) {
 		/* skip remaining processing on color fill */
@@ -1116,21 +1123,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 				pstate->multirect_index);
 	}
 
-	if (pdpu->pipe_hw->ops.setup_pe &&
-			(pstate->multirect_index != DPU_SSPP_RECT_1))
-		pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
-				&pstate->pixel_ext);
-
-	/**
-	 * when programmed in multirect mode, scalar block will be
-	 * bypassed. Still we need to update alpha and bitwidth
-	 * ONLY for RECT0
-	 */
-	if (pdpu->pipe_hw->ops.setup_scaler &&
-			pstate->multirect_index != DPU_SSPP_RECT_1)
-		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
-				&pipe_cfg, &pstate->pixel_ext,
-				&pstate->scaler3_cfg);
+	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
 
 	if (pdpu->pipe_hw->ops.setup_multirect)
 		pdpu->pipe_hw->ops.setup_multirect(
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index d5b7f5876e64..3e4ed8a33a3e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -23,8 +23,6 @@
  * @multirect_index: index of the rectangle of SSPP
  * @multirect_mode: parallel or time multiplex multirect mode
  * @pending:	whether the current update is still pending
- * @scaler3_cfg: configuration data for scaler3
- * @pixel_ext: configuration data for pixel extensions
  * @cdp_cfg:	CDP configuration
  * @plane_fetch_bw: calculated BW per plane
  * @plane_clk: calculated clk per plane
@@ -38,10 +36,6 @@ struct dpu_plane_state {
 	uint32_t multirect_mode;
 	bool pending;
 
-	/* scaler configuration */
-	struct dpu_hw_scaler3_cfg scaler3_cfg;
-	struct dpu_hw_pixel_ext pixel_ext;
-
 	struct dpu_hw_pipe_cdp_cfg cdp_cfg;
 	u64 plane_fetch_bw;
 	u64 plane_clk;
-- 
2.30.2


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

* [PATCH v2 08/22] drm/msm/dpu: drop dpu_csc_cfg from dpu_plane
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Simplify code surrounding CSC table setup by removing struct dpu_csc_cfg
pointer from dpu_plane and getting it directly at the CSC setup time.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 96 +++++++++++----------
 5 files changed, 54 insertions(+), 50 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 c16832898c51..2be43d5a235a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -537,7 +537,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,
-		struct dpu_csc_cfg *data)
+		const struct dpu_csc_cfg *data)
 {
 	u32 idx;
 	bool csc10 = false;
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 35a848b1fcf8..264a9d0d5fca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -262,7 +262,7 @@ struct dpu_hw_sspp_ops {
 	 * @ctx: Pointer to pipe context
 	 * @data: Pointer to config structure
 	 */
-	void (*setup_csc)(struct dpu_hw_pipe *ctx, struct dpu_csc_cfg *data);
+	void (*setup_csc)(struct dpu_hw_pipe *ctx, const struct dpu_csc_cfg *data);
 
 	/**
 	 * setup_solidfill - enable/disable colorfill
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
index f94584c982cd..aad85116b0a0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
@@ -374,7 +374,7 @@ u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c,
 
 void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c,
 		u32 csc_reg_off,
-		struct dpu_csc_cfg *data, bool csc10)
+		const struct dpu_csc_cfg *data, bool csc10)
 {
 	static const u32 matrix_shift = 7;
 	u32 clamp_shift = csc10 ? 16 : 8;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
index ff3cffde84cd..bc2fdb2b8f5f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
@@ -321,6 +321,6 @@ u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c,
 
 void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map  *c,
 		u32 csc_reg_off,
-		struct dpu_csc_cfg *data, bool csc10);
+		const struct dpu_csc_cfg *data, bool csc10);
 
 #endif /* _DPU_HW_UTIL_H */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 46446610e07e..6f856aeaf6bc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -90,7 +90,6 @@ enum dpu_plane_qos {
 /*
  * struct dpu_plane - local dpu plane structure
  * @aspace: address space pointer
- * @csc_ptr: Points to dpu_csc_cfg structure to use for current
  * @catalog: Points to dpu catalog structure
  * @revalidate: force revalidation of all the plane properties
  */
@@ -108,8 +107,6 @@ struct dpu_plane {
 	bool is_rt_pipe;
 	struct dpu_mdss_cfg *catalog;
 
-	struct dpu_csc_cfg *csc_ptr;
-
 	const struct dpu_sspp_sub_blks *pipe_sblk;
 
 	/* debugfs related stuff */
@@ -590,51 +587,59 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 	scale_cfg->enable = 1;
 }
 
-static void _dpu_plane_setup_csc(struct dpu_plane *pdpu)
-{
-	static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = {
-		{
-			/* S15.16 format */
-			0x00012A00, 0x00000000, 0x00019880,
-			0x00012A00, 0xFFFF9B80, 0xFFFF3000,
-			0x00012A00, 0x00020480, 0x00000000,
+static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = {
+	{
+		/* S15.16 format */
+		0x00012A00, 0x00000000, 0x00019880,
+		0x00012A00, 0xFFFF9B80, 0xFFFF3000,
+		0x00012A00, 0x00020480, 0x00000000,
+	},
+	/* signed bias */
+	{ 0xfff0, 0xff80, 0xff80,},
+	{ 0x0, 0x0, 0x0,},
+	/* unsigned clamp */
+	{ 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0,},
+	{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,},
+};
+
+static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
+	{
+		/* S15.16 format */
+		0x00012A00, 0x00000000, 0x00019880,
+		0x00012A00, 0xFFFF9B80, 0xFFFF3000,
+		0x00012A00, 0x00020480, 0x00000000,
 		},
-		/* signed bias */
-		{ 0xfff0, 0xff80, 0xff80,},
-		{ 0x0, 0x0, 0x0,},
-		/* unsigned clamp */
-		{ 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0,},
-		{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,},
-	};
-	static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
-		{
-			/* S15.16 format */
-			0x00012A00, 0x00000000, 0x00019880,
-			0x00012A00, 0xFFFF9B80, 0xFFFF3000,
-			0x00012A00, 0x00020480, 0x00000000,
-			},
-		/* signed bias */
-		{ 0xffc0, 0xfe00, 0xfe00,},
-		{ 0x0, 0x0, 0x0,},
-		/* unsigned clamp */
-		{ 0x40, 0x3ac, 0x40, 0x3c0, 0x40, 0x3c0,},
-		{ 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,},
-	};
+	/* signed bias */
+	{ 0xffc0, 0xfe00, 0xfe00,},
+	{ 0x0, 0x0, 0x0,},
+	/* unsigned clamp */
+	{ 0x40, 0x3ac, 0x40, 0x3c0, 0x40, 0x3c0,},
+	{ 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)
+{
+	const struct dpu_csc_cfg *csc_ptr;
 
 	if (!pdpu) {
 		DPU_ERROR("invalid plane\n");
-		return;
+		return NULL;
 	}
 
+	if (!DPU_FORMAT_IS_YUV(fmt))
+		return NULL;
+
 	if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->features)
-		pdpu->csc_ptr = (struct dpu_csc_cfg *)&dpu_csc10_YUV2RGB_601L;
+		csc_ptr = &dpu_csc10_YUV2RGB_601L;
 	else
-		pdpu->csc_ptr = (struct dpu_csc_cfg *)&dpu_csc_YUV2RGB_601L;
+		csc_ptr = &dpu_csc_YUV2RGB_601L;
 
 	DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
-			pdpu->csc_ptr->csc_mv[0],
-			pdpu->csc_ptr->csc_mv[1],
-			pdpu->csc_ptr->csc_mv[2]);
+			csc_ptr->csc_mv[0],
+			csc_ptr->csc_mv[1],
+			csc_ptr->csc_mv[2]);
+
+	return csc_ptr;
 }
 
 static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
@@ -1050,8 +1055,13 @@ 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->csc_ptr && pdpu->pipe_hw->ops.setup_csc)
-		pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, pdpu->csc_ptr);
+	else if (pdpu->pipe_hw && pdpu->pipe_hw->ops.setup_csc) {
+		const struct dpu_format *fmt = to_dpu_format(msm_framebuffer_format(plane->state->fb));
+		const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, fmt);
+
+		if (csc_ptr)
+			pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, csc_ptr);
+	}
 
 	/* flag h/w flush complete */
 	if (plane->state)
@@ -1167,12 +1177,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 			pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, cdp_cfg);
 		}
-
-		/* update csc */
-		if (DPU_FORMAT_IS_YUV(fmt))
-			_dpu_plane_setup_csc(pdpu);
-		else
-			pdpu->csc_ptr = 0;
 	}
 
 	_dpu_plane_set_qos_lut(plane, fb, &pipe_cfg);
-- 
2.30.2


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

* [PATCH v2 08/22] drm/msm/dpu: drop dpu_csc_cfg from dpu_plane
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

Simplify code surrounding CSC table setup by removing struct dpu_csc_cfg
pointer from dpu_plane and getting it directly at the CSC setup time.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h |  2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   | 96 +++++++++++----------
 5 files changed, 54 insertions(+), 50 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 c16832898c51..2be43d5a235a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -537,7 +537,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,
-		struct dpu_csc_cfg *data)
+		const struct dpu_csc_cfg *data)
 {
 	u32 idx;
 	bool csc10 = false;
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 35a848b1fcf8..264a9d0d5fca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -262,7 +262,7 @@ struct dpu_hw_sspp_ops {
 	 * @ctx: Pointer to pipe context
 	 * @data: Pointer to config structure
 	 */
-	void (*setup_csc)(struct dpu_hw_pipe *ctx, struct dpu_csc_cfg *data);
+	void (*setup_csc)(struct dpu_hw_pipe *ctx, const struct dpu_csc_cfg *data);
 
 	/**
 	 * setup_solidfill - enable/disable colorfill
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
index f94584c982cd..aad85116b0a0 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c
@@ -374,7 +374,7 @@ u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c,
 
 void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map *c,
 		u32 csc_reg_off,
-		struct dpu_csc_cfg *data, bool csc10)
+		const struct dpu_csc_cfg *data, bool csc10)
 {
 	static const u32 matrix_shift = 7;
 	u32 clamp_shift = csc10 ? 16 : 8;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
index ff3cffde84cd..bc2fdb2b8f5f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h
@@ -321,6 +321,6 @@ u32 dpu_hw_get_scaler3_ver(struct dpu_hw_blk_reg_map *c,
 
 void dpu_hw_csc_setup(struct dpu_hw_blk_reg_map  *c,
 		u32 csc_reg_off,
-		struct dpu_csc_cfg *data, bool csc10);
+		const struct dpu_csc_cfg *data, bool csc10);
 
 #endif /* _DPU_HW_UTIL_H */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 46446610e07e..6f856aeaf6bc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -90,7 +90,6 @@ enum dpu_plane_qos {
 /*
  * struct dpu_plane - local dpu plane structure
  * @aspace: address space pointer
- * @csc_ptr: Points to dpu_csc_cfg structure to use for current
  * @catalog: Points to dpu catalog structure
  * @revalidate: force revalidation of all the plane properties
  */
@@ -108,8 +107,6 @@ struct dpu_plane {
 	bool is_rt_pipe;
 	struct dpu_mdss_cfg *catalog;
 
-	struct dpu_csc_cfg *csc_ptr;
-
 	const struct dpu_sspp_sub_blks *pipe_sblk;
 
 	/* debugfs related stuff */
@@ -590,51 +587,59 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 	scale_cfg->enable = 1;
 }
 
-static void _dpu_plane_setup_csc(struct dpu_plane *pdpu)
-{
-	static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = {
-		{
-			/* S15.16 format */
-			0x00012A00, 0x00000000, 0x00019880,
-			0x00012A00, 0xFFFF9B80, 0xFFFF3000,
-			0x00012A00, 0x00020480, 0x00000000,
+static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = {
+	{
+		/* S15.16 format */
+		0x00012A00, 0x00000000, 0x00019880,
+		0x00012A00, 0xFFFF9B80, 0xFFFF3000,
+		0x00012A00, 0x00020480, 0x00000000,
+	},
+	/* signed bias */
+	{ 0xfff0, 0xff80, 0xff80,},
+	{ 0x0, 0x0, 0x0,},
+	/* unsigned clamp */
+	{ 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0,},
+	{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,},
+};
+
+static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
+	{
+		/* S15.16 format */
+		0x00012A00, 0x00000000, 0x00019880,
+		0x00012A00, 0xFFFF9B80, 0xFFFF3000,
+		0x00012A00, 0x00020480, 0x00000000,
 		},
-		/* signed bias */
-		{ 0xfff0, 0xff80, 0xff80,},
-		{ 0x0, 0x0, 0x0,},
-		/* unsigned clamp */
-		{ 0x10, 0xeb, 0x10, 0xf0, 0x10, 0xf0,},
-		{ 0x00, 0xff, 0x00, 0xff, 0x00, 0xff,},
-	};
-	static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
-		{
-			/* S15.16 format */
-			0x00012A00, 0x00000000, 0x00019880,
-			0x00012A00, 0xFFFF9B80, 0xFFFF3000,
-			0x00012A00, 0x00020480, 0x00000000,
-			},
-		/* signed bias */
-		{ 0xffc0, 0xfe00, 0xfe00,},
-		{ 0x0, 0x0, 0x0,},
-		/* unsigned clamp */
-		{ 0x40, 0x3ac, 0x40, 0x3c0, 0x40, 0x3c0,},
-		{ 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,},
-	};
+	/* signed bias */
+	{ 0xffc0, 0xfe00, 0xfe00,},
+	{ 0x0, 0x0, 0x0,},
+	/* unsigned clamp */
+	{ 0x40, 0x3ac, 0x40, 0x3c0, 0x40, 0x3c0,},
+	{ 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)
+{
+	const struct dpu_csc_cfg *csc_ptr;
 
 	if (!pdpu) {
 		DPU_ERROR("invalid plane\n");
-		return;
+		return NULL;
 	}
 
+	if (!DPU_FORMAT_IS_YUV(fmt))
+		return NULL;
+
 	if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->features)
-		pdpu->csc_ptr = (struct dpu_csc_cfg *)&dpu_csc10_YUV2RGB_601L;
+		csc_ptr = &dpu_csc10_YUV2RGB_601L;
 	else
-		pdpu->csc_ptr = (struct dpu_csc_cfg *)&dpu_csc_YUV2RGB_601L;
+		csc_ptr = &dpu_csc_YUV2RGB_601L;
 
 	DPU_DEBUG_PLANE(pdpu, "using 0x%X 0x%X 0x%X...\n",
-			pdpu->csc_ptr->csc_mv[0],
-			pdpu->csc_ptr->csc_mv[1],
-			pdpu->csc_ptr->csc_mv[2]);
+			csc_ptr->csc_mv[0],
+			csc_ptr->csc_mv[1],
+			csc_ptr->csc_mv[2]);
+
+	return csc_ptr;
 }
 
 static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
@@ -1050,8 +1055,13 @@ 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->csc_ptr && pdpu->pipe_hw->ops.setup_csc)
-		pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, pdpu->csc_ptr);
+	else if (pdpu->pipe_hw && pdpu->pipe_hw->ops.setup_csc) {
+		const struct dpu_format *fmt = to_dpu_format(msm_framebuffer_format(plane->state->fb));
+		const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, fmt);
+
+		if (csc_ptr)
+			pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, csc_ptr);
+	}
 
 	/* flag h/w flush complete */
 	if (plane->state)
@@ -1167,12 +1177,6 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 
 			pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, cdp_cfg);
 		}
-
-		/* update csc */
-		if (DPU_FORMAT_IS_YUV(fmt))
-			_dpu_plane_setup_csc(pdpu);
-		else
-			pdpu->csc_ptr = 0;
 	}
 
 	_dpu_plane_set_qos_lut(plane, fb, &pipe_cfg);
-- 
2.30.2


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

* [PATCH v2 09/22] drm/msm/dpu: remove dpu_hw_pipe_cdp_cfg from dpu_plane
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Remove struct dpu_hw_pipe_cdp_cfg instance from dpu_plane, it is an
interim configuration structure. Allocate it on stack instead.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 6f856aeaf6bc..fdae6520c2bb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1162,20 +1162,20 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 				pstate->multirect_index);
 
 		if (pdpu->pipe_hw->ops.setup_cdp) {
-			struct dpu_hw_pipe_cdp_cfg *cdp_cfg = &pstate->cdp_cfg;
+			struct dpu_hw_pipe_cdp_cfg cdp_cfg;
 
-			memset(cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
+			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
 
-			cdp_cfg->enable = pdpu->catalog->perf.cdp_cfg
+			cdp_cfg.enable = pdpu->catalog->perf.cdp_cfg
 					[DPU_PERF_CDP_USAGE_RT].rd_enable;
-			cdp_cfg->ubwc_meta_enable =
+			cdp_cfg.ubwc_meta_enable =
 					DPU_FORMAT_IS_UBWC(fmt);
-			cdp_cfg->tile_amortize_enable =
+			cdp_cfg.tile_amortize_enable =
 					DPU_FORMAT_IS_UBWC(fmt) ||
 					DPU_FORMAT_IS_TILE(fmt);
-			cdp_cfg->preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
+			cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
 
-			pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, cdp_cfg);
+			pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, &cdp_cfg);
 		}
 	}
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 3e4ed8a33a3e..48366da5e86e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -23,7 +23,6 @@
  * @multirect_index: index of the rectangle of SSPP
  * @multirect_mode: parallel or time multiplex multirect mode
  * @pending:	whether the current update is still pending
- * @cdp_cfg:	CDP configuration
  * @plane_fetch_bw: calculated BW per plane
  * @plane_clk: calculated clk per plane
  */
@@ -36,7 +35,6 @@ struct dpu_plane_state {
 	uint32_t multirect_mode;
 	bool pending;
 
-	struct dpu_hw_pipe_cdp_cfg cdp_cfg;
 	u64 plane_fetch_bw;
 	u64 plane_clk;
 };
-- 
2.30.2


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

* [PATCH v2 09/22] drm/msm/dpu: remove dpu_hw_pipe_cdp_cfg from dpu_plane
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

Remove struct dpu_hw_pipe_cdp_cfg instance from dpu_plane, it is an
interim configuration structure. Allocate it on stack instead.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 6f856aeaf6bc..fdae6520c2bb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1162,20 +1162,20 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 				pstate->multirect_index);
 
 		if (pdpu->pipe_hw->ops.setup_cdp) {
-			struct dpu_hw_pipe_cdp_cfg *cdp_cfg = &pstate->cdp_cfg;
+			struct dpu_hw_pipe_cdp_cfg cdp_cfg;
 
-			memset(cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
+			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
 
-			cdp_cfg->enable = pdpu->catalog->perf.cdp_cfg
+			cdp_cfg.enable = pdpu->catalog->perf.cdp_cfg
 					[DPU_PERF_CDP_USAGE_RT].rd_enable;
-			cdp_cfg->ubwc_meta_enable =
+			cdp_cfg.ubwc_meta_enable =
 					DPU_FORMAT_IS_UBWC(fmt);
-			cdp_cfg->tile_amortize_enable =
+			cdp_cfg.tile_amortize_enable =
 					DPU_FORMAT_IS_UBWC(fmt) ||
 					DPU_FORMAT_IS_TILE(fmt);
-			cdp_cfg->preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
+			cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
 
-			pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, cdp_cfg);
+			pdpu->pipe_hw->ops.setup_cdp(pdpu->pipe_hw, &cdp_cfg);
 		}
 	}
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 3e4ed8a33a3e..48366da5e86e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -23,7 +23,6 @@
  * @multirect_index: index of the rectangle of SSPP
  * @multirect_mode: parallel or time multiplex multirect mode
  * @pending:	whether the current update is still pending
- * @cdp_cfg:	CDP configuration
  * @plane_fetch_bw: calculated BW per plane
  * @plane_clk: calculated clk per plane
  */
@@ -36,7 +35,6 @@ struct dpu_plane_state {
 	uint32_t multirect_mode;
 	bool pending;
 
-	struct dpu_hw_pipe_cdp_cfg cdp_cfg;
 	u64 plane_fetch_bw;
 	u64 plane_clk;
 };
-- 
2.30.2


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

* [PATCH v2 10/22] drm/msm/dpu: don't cache pipe->cap->features in dpu_plane
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Do not cache hw_pipe's features in dpu_plane. Use
pdpu->pipe_hw->cap->features directly.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index fdae6520c2bb..65446e8f5718 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -99,7 +99,6 @@ struct dpu_plane {
 	struct mutex lock;
 
 	enum dpu_sspp pipe;
-	uint32_t features;      /* capabilities from catalog */
 
 	struct dpu_hw_pipe *pipe_hw;
 	uint32_t color_fill;
@@ -629,7 +628,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->features)
+	if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->pipe_hw->cap->features)
 		csc_ptr = &dpu_csc10_YUV2RGB_601L;
 	else
 		csc_ptr = &dpu_csc_YUV2RGB_601L;
@@ -992,8 +991,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
 
 	if (DPU_FORMAT_IS_YUV(fmt) &&
-		(!(pdpu->features & DPU_SSPP_SCALER) ||
-		 !(pdpu->features & (BIT(DPU_SSPP_CSC)
+		(!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
+		 !(pdpu->pipe_hw->cap->features & (BIT(DPU_SSPP_CSC)
 		 | BIT(DPU_SSPP_CSC_10BIT))))) {
 		DPU_DEBUG_PLANE(pdpu,
 				"plane doesn't have scaler/csc for yuv\n");
@@ -1415,8 +1414,8 @@ static int _dpu_plane_init_debugfs(struct drm_plane *plane)
 				plane->dev->primary->debugfs_root);
 
 	/* don't error check these */
-	debugfs_create_x32("features", 0600,
-			pdpu->debugfs_root, &pdpu->features);
+	debugfs_create_xul("features", 0600,
+			pdpu->debugfs_root, (unsigned long *)&pdpu->pipe_hw->cap->features);
 
 	/* add register dump support */
 	dpu_debugfs_setup_regset32(&pdpu->debugfs_src,
@@ -1575,7 +1574,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	}
 
 	/* cache features mask for later */
-	pdpu->features = pdpu->pipe_hw->cap->features;
 	pdpu->pipe_sblk = pdpu->pipe_hw->cap->sblk;
 	if (!pdpu->pipe_sblk) {
 		DPU_ERROR("[%u]invalid sblk\n", pipe);
-- 
2.30.2


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

* [PATCH v2 10/22] drm/msm/dpu: don't cache pipe->cap->features in dpu_plane
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

Do not cache hw_pipe's features in dpu_plane. Use
pdpu->pipe_hw->cap->features directly.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index fdae6520c2bb..65446e8f5718 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -99,7 +99,6 @@ struct dpu_plane {
 	struct mutex lock;
 
 	enum dpu_sspp pipe;
-	uint32_t features;      /* capabilities from catalog */
 
 	struct dpu_hw_pipe *pipe_hw;
 	uint32_t color_fill;
@@ -629,7 +628,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->features)
+	if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->pipe_hw->cap->features)
 		csc_ptr = &dpu_csc10_YUV2RGB_601L;
 	else
 		csc_ptr = &dpu_csc_YUV2RGB_601L;
@@ -992,8 +991,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
 
 	if (DPU_FORMAT_IS_YUV(fmt) &&
-		(!(pdpu->features & DPU_SSPP_SCALER) ||
-		 !(pdpu->features & (BIT(DPU_SSPP_CSC)
+		(!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
+		 !(pdpu->pipe_hw->cap->features & (BIT(DPU_SSPP_CSC)
 		 | BIT(DPU_SSPP_CSC_10BIT))))) {
 		DPU_DEBUG_PLANE(pdpu,
 				"plane doesn't have scaler/csc for yuv\n");
@@ -1415,8 +1414,8 @@ static int _dpu_plane_init_debugfs(struct drm_plane *plane)
 				plane->dev->primary->debugfs_root);
 
 	/* don't error check these */
-	debugfs_create_x32("features", 0600,
-			pdpu->debugfs_root, &pdpu->features);
+	debugfs_create_xul("features", 0600,
+			pdpu->debugfs_root, (unsigned long *)&pdpu->pipe_hw->cap->features);
 
 	/* add register dump support */
 	dpu_debugfs_setup_regset32(&pdpu->debugfs_src,
@@ -1575,7 +1574,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	}
 
 	/* cache features mask for later */
-	pdpu->features = pdpu->pipe_hw->cap->features;
 	pdpu->pipe_sblk = pdpu->pipe_hw->cap->sblk;
 	if (!pdpu->pipe_sblk) {
 		DPU_ERROR("[%u]invalid sblk\n", pipe);
-- 
2.30.2


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

* [PATCH v2 11/22] drm/msm/dpu: don't cache pipe->cap->sblk in dpu_plane
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Do not cache hw_pipe's sblk in dpu_plane. Use
pdpu->pipe_hw->cap->sblk directly.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 65446e8f5718..8f1fef2367cd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -106,8 +106,6 @@ struct dpu_plane {
 	bool is_rt_pipe;
 	struct dpu_mdss_cfg *catalog;
 
-	const struct dpu_sspp_sub_blks *pipe_sblk;
-
 	/* debugfs related stuff */
 	struct dentry *debugfs_root;
 	struct dpu_debugfs_regset32 debugfs_src;
@@ -410,9 +408,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 = pdpu->pipe_sblk->creq_vblank;
+		pipe_qos_cfg.creq_vblank = pdpu->pipe_hw->cap->sblk->creq_vblank;
 		pipe_qos_cfg.danger_vblank =
-				pdpu->pipe_sblk->danger_vblank;
+				pdpu->pipe_hw->cap->sblk->danger_vblank;
 		pipe_qos_cfg.vblank_en = enable;
 	}
 
@@ -962,10 +960,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 		crtc_state = drm_atomic_get_new_crtc_state(state,
 							   new_plane_state->crtc);
 
-	min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxupscale);
+	min_scale = FRAC_16_16(1, pdpu->pipe_hw->cap->sblk->maxupscale);
 	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
 						  min_scale,
-						  pdpu->pipe_sblk->maxdwnscale << 16,
+						  pdpu->pipe_hw->cap->sblk->maxdwnscale << 16,
 						  true, true);
 	if (ret) {
 		DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
@@ -1573,15 +1571,8 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		goto clean_sspp;
 	}
 
-	/* cache features mask for later */
-	pdpu->pipe_sblk = pdpu->pipe_hw->cap->sblk;
-	if (!pdpu->pipe_sblk) {
-		DPU_ERROR("[%u]invalid sblk\n", pipe);
-		goto clean_sspp;
-	}
-
-	format_list = pdpu->pipe_sblk->format_list;
-	num_formats = pdpu->pipe_sblk->num_formats;
+	format_list = pdpu->pipe_hw->cap->sblk->format_list;
+	num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
 
 	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
 				format_list, num_formats,
-- 
2.30.2


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

* [PATCH v2 11/22] drm/msm/dpu: don't cache pipe->cap->sblk in dpu_plane
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

Do not cache hw_pipe's sblk in dpu_plane. Use
pdpu->pipe_hw->cap->sblk directly.

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 65446e8f5718..8f1fef2367cd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -106,8 +106,6 @@ struct dpu_plane {
 	bool is_rt_pipe;
 	struct dpu_mdss_cfg *catalog;
 
-	const struct dpu_sspp_sub_blks *pipe_sblk;
-
 	/* debugfs related stuff */
 	struct dentry *debugfs_root;
 	struct dpu_debugfs_regset32 debugfs_src;
@@ -410,9 +408,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 = pdpu->pipe_sblk->creq_vblank;
+		pipe_qos_cfg.creq_vblank = pdpu->pipe_hw->cap->sblk->creq_vblank;
 		pipe_qos_cfg.danger_vblank =
-				pdpu->pipe_sblk->danger_vblank;
+				pdpu->pipe_hw->cap->sblk->danger_vblank;
 		pipe_qos_cfg.vblank_en = enable;
 	}
 
@@ -962,10 +960,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 		crtc_state = drm_atomic_get_new_crtc_state(state,
 							   new_plane_state->crtc);
 
-	min_scale = FRAC_16_16(1, pdpu->pipe_sblk->maxupscale);
+	min_scale = FRAC_16_16(1, pdpu->pipe_hw->cap->sblk->maxupscale);
 	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
 						  min_scale,
-						  pdpu->pipe_sblk->maxdwnscale << 16,
+						  pdpu->pipe_hw->cap->sblk->maxdwnscale << 16,
 						  true, true);
 	if (ret) {
 		DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
@@ -1573,15 +1571,8 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		goto clean_sspp;
 	}
 
-	/* cache features mask for later */
-	pdpu->pipe_sblk = pdpu->pipe_hw->cap->sblk;
-	if (!pdpu->pipe_sblk) {
-		DPU_ERROR("[%u]invalid sblk\n", pipe);
-		goto clean_sspp;
-	}
-
-	format_list = pdpu->pipe_sblk->format_list;
-	num_formats = pdpu->pipe_sblk->num_formats;
+	format_list = pdpu->pipe_hw->cap->sblk->format_list;
+	num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
 
 	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
 				format_list, num_formats,
-- 
2.30.2


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

* [PATCH v2 12/22] drm/msm/dpu: rip out debugfs support from dpu_plane
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

In preparations of virtualizing the dpu_plane rip out debugfs support
from dpu_plane (as it is mostly used to expose plane's pipe registers).
Also move disable_danger file to danger/ debugfs subdir where it belongs.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 123 ++++++++--------
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |  69 ---------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 171 +---------------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   6 +
 4 files changed, 69 insertions(+), 300 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index b7b73d0de6f8..66a1c8889cf3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -101,84 +101,85 @@ static int dpu_debugfs_safe_stats_show(struct seq_file *s, void *v)
 }
 DEFINE_SHOW_ATTRIBUTE(dpu_debugfs_safe_stats);
 
-static void dpu_debugfs_danger_init(struct dpu_kms *dpu_kms,
-		struct dentry *parent)
+static ssize_t _dpu_plane_danger_read(struct file *file,
+			char __user *buff, size_t count, loff_t *ppos)
 {
-	struct dentry *entry = debugfs_create_dir("danger", parent);
+	struct dpu_kms *kms = file->private_data;
+	int len;
+	char buf[40];
 
-	debugfs_create_file("danger_status", 0600, entry,
-			dpu_kms, &dpu_debugfs_danger_stats_fops);
-	debugfs_create_file("safe_status", 0600, entry,
-			dpu_kms, &dpu_debugfs_safe_stats_fops);
+	len = scnprintf(buf, sizeof(buf), "%d\n", !kms->has_danger_ctrl);
+
+	return simple_read_from_buffer(buff, count, ppos, buf, len);
 }
 
-static int _dpu_debugfs_show_regset32(struct seq_file *s, void *data)
+static void _dpu_plane_set_danger_state(struct dpu_kms *kms, bool enable)
 {
-	struct dpu_debugfs_regset32 *regset = s->private;
-	struct dpu_kms *dpu_kms = regset->dpu_kms;
-	void __iomem *base;
-	uint32_t i, addr;
-
-	if (!dpu_kms->mmio)
-		return 0;
-
-	base = dpu_kms->mmio + regset->offset;
-
-	/* insert padding spaces, if needed */
-	if (regset->offset & 0xF) {
-		seq_printf(s, "[%x]", regset->offset & ~0xF);
-		for (i = 0; i < (regset->offset & 0xF); i += 4)
-			seq_puts(s, "         ");
-	}
-
-	pm_runtime_get_sync(&dpu_kms->pdev->dev);
-
-	/* main register output */
-	for (i = 0; i < regset->blk_len; i += 4) {
-		addr = regset->offset + i;
-		if ((addr & 0xF) == 0x0)
-			seq_printf(s, i ? "\n[%x]" : "[%x]", addr);
-		seq_printf(s, " %08x", readl_relaxed(base + i));
+	struct drm_plane *plane;
+
+	drm_for_each_plane(plane, kms->dev) {
+		if (plane->fb && plane->state) {
+			dpu_plane_danger_signal_ctrl(plane, enable);
+			DPU_DEBUG("plane:%d img:%dx%d ",
+				plane->base.id, plane->fb->width,
+				plane->fb->height);
+			DPU_DEBUG("src[%d,%d,%d,%d] dst[%d,%d,%d,%d]\n",
+				plane->state->src_x >> 16,
+				plane->state->src_y >> 16,
+				plane->state->src_w >> 16,
+				plane->state->src_h >> 16,
+				plane->state->crtc_x, plane->state->crtc_y,
+				plane->state->crtc_w, plane->state->crtc_h);
+		} else {
+			DPU_DEBUG("Inactive plane:%d\n", plane->base.id);
+		}
 	}
-	seq_puts(s, "\n");
-	pm_runtime_put_sync(&dpu_kms->pdev->dev);
-
-	return 0;
 }
 
-static int dpu_debugfs_open_regset32(struct inode *inode,
-		struct file *file)
+static ssize_t _dpu_plane_danger_write(struct file *file,
+		    const char __user *user_buf, size_t count, loff_t *ppos)
 {
-	return single_open(file, _dpu_debugfs_show_regset32, inode->i_private);
-}
+	struct dpu_kms *kms = file->private_data;
+	int disable_panic;
+	int ret;
 
-static const struct file_operations dpu_fops_regset32 = {
-	.open =		dpu_debugfs_open_regset32,
-	.read =		seq_read,
-	.llseek =	seq_lseek,
-	.release =	single_release,
-};
+	ret = kstrtouint_from_user(user_buf, count, 0, &disable_panic);
+	if (ret)
+		return ret;
 
-void dpu_debugfs_setup_regset32(struct dpu_debugfs_regset32 *regset,
-		uint32_t offset, uint32_t length, struct dpu_kms *dpu_kms)
-{
-	if (regset) {
-		regset->offset = offset;
-		regset->blk_len = length;
-		regset->dpu_kms = dpu_kms;
+	if (disable_panic) {
+		/* Disable panic signal for all active pipes */
+		DPU_DEBUG("Disabling danger:\n");
+		_dpu_plane_set_danger_state(kms, false);
+		kms->has_danger_ctrl = false;
+	} else {
+		/* Enable panic signal for all active pipes */
+		DPU_DEBUG("Enabling danger:\n");
+		kms->has_danger_ctrl = true;
+		_dpu_plane_set_danger_state(kms, true);
 	}
+
+	return count;
 }
 
-void dpu_debugfs_create_regset32(const char *name, umode_t mode,
-		void *parent, struct dpu_debugfs_regset32 *regset)
+static const struct file_operations dpu_plane_danger_enable = {
+	.open = simple_open,
+	.read = _dpu_plane_danger_read,
+	.write = _dpu_plane_danger_write,
+};
+
+static void dpu_debugfs_danger_init(struct dpu_kms *dpu_kms,
+		struct dentry *parent)
 {
-	if (!name || !regset || !regset->dpu_kms || !regset->blk_len)
-		return;
+	struct dentry *entry = debugfs_create_dir("danger", parent);
 
-	/* make sure offset is a multiple of 4 */
-	regset->offset = round_down(regset->offset, 4);
+	debugfs_create_file("danger_status", 0600, entry,
+			dpu_kms, &dpu_debugfs_danger_stats_fops);
+	debugfs_create_file("safe_status", 0600, entry,
+			dpu_kms, &dpu_debugfs_safe_stats_fops);
+	debugfs_create_file("disable_danger", 0600, entry,
+			dpu_kms, &dpu_plane_danger_enable);
 
-	debugfs_create_file(name, mode, parent, regset, &dpu_fops_regset32);
 }
 
 static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 323a6bce9e64..ab65c817eb42 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -166,75 +166,6 @@ struct dpu_global_state
 struct dpu_global_state
 	*__must_check dpu_kms_get_global_state(struct drm_atomic_state *s);
 
-/**
- * Debugfs functions - extra helper functions for debugfs support
- *
- * Main debugfs documentation is located at,
- *
- * Documentation/filesystems/debugfs.rst
- *
- * @dpu_debugfs_setup_regset32: Initialize data for dpu_debugfs_create_regset32
- * @dpu_debugfs_create_regset32: Create 32-bit register dump file
- * @dpu_debugfs_get_root: Get root dentry for DPU_KMS's debugfs node
- */
-
-/**
- * Companion structure for dpu_debugfs_create_regset32. Do not initialize the
- * members of this structure explicitly; use dpu_debugfs_setup_regset32 instead.
- */
-struct dpu_debugfs_regset32 {
-	uint32_t offset;
-	uint32_t blk_len;
-	struct dpu_kms *dpu_kms;
-};
-
-/**
- * dpu_debugfs_setup_regset32 - Initialize register block definition for debugfs
- * This function is meant to initialize dpu_debugfs_regset32 structures for use
- * with dpu_debugfs_create_regset32.
- * @regset: opaque register definition structure
- * @offset: sub-block offset
- * @length: sub-block length, in bytes
- * @dpu_kms: pointer to dpu kms structure
- */
-void dpu_debugfs_setup_regset32(struct dpu_debugfs_regset32 *regset,
-		uint32_t offset, uint32_t length, struct dpu_kms *dpu_kms);
-
-/**
- * dpu_debugfs_create_regset32 - Create register read back file for debugfs
- *
- * This function is almost identical to the standard debugfs_create_regset32()
- * function, with the main difference being that a list of register
- * names/offsets do not need to be provided. The 'read' function simply outputs
- * sequential register values over a specified range.
- *
- * Similar to the related debugfs_create_regset32 API, the structure pointed to
- * by regset needs to persist for the lifetime of the created file. The calling
- * code is responsible for initialization/management of this structure.
- *
- * The structure pointed to by regset is meant to be opaque. Please use
- * dpu_debugfs_setup_regset32 to initialize it.
- *
- * @name:   File name within debugfs
- * @mode:   File mode within debugfs
- * @parent: Parent directory entry within debugfs, can be NULL
- * @regset: Pointer to persistent register block definition
- */
-void dpu_debugfs_create_regset32(const char *name, umode_t mode,
-		void *parent, struct dpu_debugfs_regset32 *regset);
-
-/**
- * dpu_debugfs_get_root - Return root directory entry for KMS's debugfs
- *
- * The return value should be passed as the 'parent' argument to subsequent
- * debugfs create calls.
- *
- * @dpu_kms: Pointer to DPU's KMS structure
- *
- * Return: dentry pointer for DPU's debugfs location
- */
-void *dpu_debugfs_get_root(struct dpu_kms *dpu_kms);
-
 /**
  * DPU info management functions
  * These functions/definitions allow for building up a 'dpu_info' structure
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 8f1fef2367cd..34ecd971cbbb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -105,13 +105,6 @@ struct dpu_plane {
 	bool is_error;
 	bool is_rt_pipe;
 	struct dpu_mdss_cfg *catalog;
-
-	/* debugfs related stuff */
-	struct dentry *debugfs_root;
-	struct dpu_debugfs_regset32 debugfs_src;
-	struct dpu_debugfs_regset32 debugfs_scaler;
-	struct dpu_debugfs_regset32 debugfs_csc;
-	bool debugfs_default_scale;
 };
 
 static const uint64_t supported_format_modifiers[] = {
@@ -1319,7 +1312,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
 }
 
 #ifdef CONFIG_DEBUG_FS
-static void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
+void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
@@ -1331,168 +1324,8 @@ static 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);
 }
-
-static ssize_t _dpu_plane_danger_read(struct file *file,
-			char __user *buff, size_t count, loff_t *ppos)
-{
-	struct dpu_kms *kms = file->private_data;
-	int len;
-	char buf[40];
-
-	len = scnprintf(buf, sizeof(buf), "%d\n", !kms->has_danger_ctrl);
-
-	return simple_read_from_buffer(buff, count, ppos, buf, len);
-}
-
-static void _dpu_plane_set_danger_state(struct dpu_kms *kms, bool enable)
-{
-	struct drm_plane *plane;
-
-	drm_for_each_plane(plane, kms->dev) {
-		if (plane->fb && plane->state) {
-			dpu_plane_danger_signal_ctrl(plane, enable);
-			DPU_DEBUG("plane:%d img:%dx%d ",
-				plane->base.id, plane->fb->width,
-				plane->fb->height);
-			DPU_DEBUG("src[%d,%d,%d,%d] dst[%d,%d,%d,%d]\n",
-				plane->state->src_x >> 16,
-				plane->state->src_y >> 16,
-				plane->state->src_w >> 16,
-				plane->state->src_h >> 16,
-				plane->state->crtc_x, plane->state->crtc_y,
-				plane->state->crtc_w, plane->state->crtc_h);
-		} else {
-			DPU_DEBUG("Inactive plane:%d\n", plane->base.id);
-		}
-	}
-}
-
-static ssize_t _dpu_plane_danger_write(struct file *file,
-		    const char __user *user_buf, size_t count, loff_t *ppos)
-{
-	struct dpu_kms *kms = file->private_data;
-	int disable_panic;
-	int ret;
-
-	ret = kstrtouint_from_user(user_buf, count, 0, &disable_panic);
-	if (ret)
-		return ret;
-
-	if (disable_panic) {
-		/* Disable panic signal for all active pipes */
-		DPU_DEBUG("Disabling danger:\n");
-		_dpu_plane_set_danger_state(kms, false);
-		kms->has_danger_ctrl = false;
-	} else {
-		/* Enable panic signal for all active pipes */
-		DPU_DEBUG("Enabling danger:\n");
-		kms->has_danger_ctrl = true;
-		_dpu_plane_set_danger_state(kms, true);
-	}
-
-	return count;
-}
-
-static const struct file_operations dpu_plane_danger_enable = {
-	.open = simple_open,
-	.read = _dpu_plane_danger_read,
-	.write = _dpu_plane_danger_write,
-};
-
-static int _dpu_plane_init_debugfs(struct drm_plane *plane)
-{
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
-	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
-	const struct dpu_sspp_cfg *cfg = pdpu->pipe_hw->cap;
-	const struct dpu_sspp_sub_blks *sblk = cfg->sblk;
-
-	/* create overall sub-directory for the pipe */
-	pdpu->debugfs_root =
-		debugfs_create_dir(plane->name,
-				plane->dev->primary->debugfs_root);
-
-	/* don't error check these */
-	debugfs_create_xul("features", 0600,
-			pdpu->debugfs_root, (unsigned long *)&pdpu->pipe_hw->cap->features);
-
-	/* add register dump support */
-	dpu_debugfs_setup_regset32(&pdpu->debugfs_src,
-			sblk->src_blk.base + cfg->base,
-			sblk->src_blk.len,
-			kms);
-	dpu_debugfs_create_regset32("src_blk", 0400,
-			pdpu->debugfs_root, &pdpu->debugfs_src);
-
-	if (cfg->features & BIT(DPU_SSPP_SCALER_QSEED3) ||
-			cfg->features & BIT(DPU_SSPP_SCALER_QSEED3LITE) ||
-			cfg->features & BIT(DPU_SSPP_SCALER_QSEED2) ||
-			cfg->features & BIT(DPU_SSPP_SCALER_QSEED4)) {
-		dpu_debugfs_setup_regset32(&pdpu->debugfs_scaler,
-				sblk->scaler_blk.base + cfg->base,
-				sblk->scaler_blk.len,
-				kms);
-		dpu_debugfs_create_regset32("scaler_blk", 0400,
-				pdpu->debugfs_root,
-				&pdpu->debugfs_scaler);
-		debugfs_create_bool("default_scaling",
-				0600,
-				pdpu->debugfs_root,
-				&pdpu->debugfs_default_scale);
-	}
-
-	if (cfg->features & BIT(DPU_SSPP_CSC) ||
-			cfg->features & BIT(DPU_SSPP_CSC_10BIT)) {
-		dpu_debugfs_setup_regset32(&pdpu->debugfs_csc,
-				sblk->csc_blk.base + cfg->base,
-				sblk->csc_blk.len,
-				kms);
-		dpu_debugfs_create_regset32("csc_blk", 0400,
-				pdpu->debugfs_root, &pdpu->debugfs_csc);
-	}
-
-	debugfs_create_u32("xin_id",
-			0400,
-			pdpu->debugfs_root,
-			(u32 *) &cfg->xin_id);
-	debugfs_create_u32("clk_ctrl",
-			0400,
-			pdpu->debugfs_root,
-			(u32 *) &cfg->clk_ctrl);
-	debugfs_create_x32("creq_vblank",
-			0600,
-			pdpu->debugfs_root,
-			(u32 *) &sblk->creq_vblank);
-	debugfs_create_x32("danger_vblank",
-			0600,
-			pdpu->debugfs_root,
-			(u32 *) &sblk->danger_vblank);
-
-	debugfs_create_file("disable_danger",
-			0600,
-			pdpu->debugfs_root,
-			kms, &dpu_plane_danger_enable);
-
-	return 0;
-}
-#else
-static int _dpu_plane_init_debugfs(struct drm_plane *plane)
-{
-	return 0;
-}
 #endif
 
-static int dpu_plane_late_register(struct drm_plane *plane)
-{
-	return _dpu_plane_init_debugfs(plane);
-}
-
-static void dpu_plane_early_unregister(struct drm_plane *plane)
-{
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
-
-	debugfs_remove_recursive(pdpu->debugfs_root);
-}
-
 static bool dpu_plane_format_mod_supported(struct drm_plane *plane,
 		uint32_t format, uint64_t modifier)
 {
@@ -1517,8 +1350,6 @@ static const struct drm_plane_funcs dpu_plane_funcs = {
 		.reset = dpu_plane_reset,
 		.atomic_duplicate_state = dpu_plane_duplicate_state,
 		.atomic_destroy_state = dpu_plane_destroy_state,
-		.late_register = dpu_plane_late_register,
-		.early_unregister = dpu_plane_early_unregister,
 		.format_mod_supported = dpu_plane_format_mod_supported,
 };
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 48366da5e86e..d2f60810434e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -115,4 +115,10 @@ void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state);
 int dpu_plane_color_fill(struct drm_plane *plane,
 		uint32_t color, uint32_t alpha);
 
+#ifdef CONFIG_DEBUG_FS
+void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable);
+#else
+static inline void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) {}
+#endif
+
 #endif /* _DPU_PLANE_H_ */
-- 
2.30.2


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

* [PATCH v2 12/22] drm/msm/dpu: rip out debugfs support from dpu_plane
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

In preparations of virtualizing the dpu_plane rip out debugfs support
from dpu_plane (as it is mostly used to expose plane's pipe registers).
Also move disable_danger file to danger/ debugfs subdir where it belongs.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 123 ++++++++--------
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h   |  69 ---------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 171 +---------------------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |   6 +
 4 files changed, 69 insertions(+), 300 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index b7b73d0de6f8..66a1c8889cf3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -101,84 +101,85 @@ static int dpu_debugfs_safe_stats_show(struct seq_file *s, void *v)
 }
 DEFINE_SHOW_ATTRIBUTE(dpu_debugfs_safe_stats);
 
-static void dpu_debugfs_danger_init(struct dpu_kms *dpu_kms,
-		struct dentry *parent)
+static ssize_t _dpu_plane_danger_read(struct file *file,
+			char __user *buff, size_t count, loff_t *ppos)
 {
-	struct dentry *entry = debugfs_create_dir("danger", parent);
+	struct dpu_kms *kms = file->private_data;
+	int len;
+	char buf[40];
 
-	debugfs_create_file("danger_status", 0600, entry,
-			dpu_kms, &dpu_debugfs_danger_stats_fops);
-	debugfs_create_file("safe_status", 0600, entry,
-			dpu_kms, &dpu_debugfs_safe_stats_fops);
+	len = scnprintf(buf, sizeof(buf), "%d\n", !kms->has_danger_ctrl);
+
+	return simple_read_from_buffer(buff, count, ppos, buf, len);
 }
 
-static int _dpu_debugfs_show_regset32(struct seq_file *s, void *data)
+static void _dpu_plane_set_danger_state(struct dpu_kms *kms, bool enable)
 {
-	struct dpu_debugfs_regset32 *regset = s->private;
-	struct dpu_kms *dpu_kms = regset->dpu_kms;
-	void __iomem *base;
-	uint32_t i, addr;
-
-	if (!dpu_kms->mmio)
-		return 0;
-
-	base = dpu_kms->mmio + regset->offset;
-
-	/* insert padding spaces, if needed */
-	if (regset->offset & 0xF) {
-		seq_printf(s, "[%x]", regset->offset & ~0xF);
-		for (i = 0; i < (regset->offset & 0xF); i += 4)
-			seq_puts(s, "         ");
-	}
-
-	pm_runtime_get_sync(&dpu_kms->pdev->dev);
-
-	/* main register output */
-	for (i = 0; i < regset->blk_len; i += 4) {
-		addr = regset->offset + i;
-		if ((addr & 0xF) == 0x0)
-			seq_printf(s, i ? "\n[%x]" : "[%x]", addr);
-		seq_printf(s, " %08x", readl_relaxed(base + i));
+	struct drm_plane *plane;
+
+	drm_for_each_plane(plane, kms->dev) {
+		if (plane->fb && plane->state) {
+			dpu_plane_danger_signal_ctrl(plane, enable);
+			DPU_DEBUG("plane:%d img:%dx%d ",
+				plane->base.id, plane->fb->width,
+				plane->fb->height);
+			DPU_DEBUG("src[%d,%d,%d,%d] dst[%d,%d,%d,%d]\n",
+				plane->state->src_x >> 16,
+				plane->state->src_y >> 16,
+				plane->state->src_w >> 16,
+				plane->state->src_h >> 16,
+				plane->state->crtc_x, plane->state->crtc_y,
+				plane->state->crtc_w, plane->state->crtc_h);
+		} else {
+			DPU_DEBUG("Inactive plane:%d\n", plane->base.id);
+		}
 	}
-	seq_puts(s, "\n");
-	pm_runtime_put_sync(&dpu_kms->pdev->dev);
-
-	return 0;
 }
 
-static int dpu_debugfs_open_regset32(struct inode *inode,
-		struct file *file)
+static ssize_t _dpu_plane_danger_write(struct file *file,
+		    const char __user *user_buf, size_t count, loff_t *ppos)
 {
-	return single_open(file, _dpu_debugfs_show_regset32, inode->i_private);
-}
+	struct dpu_kms *kms = file->private_data;
+	int disable_panic;
+	int ret;
 
-static const struct file_operations dpu_fops_regset32 = {
-	.open =		dpu_debugfs_open_regset32,
-	.read =		seq_read,
-	.llseek =	seq_lseek,
-	.release =	single_release,
-};
+	ret = kstrtouint_from_user(user_buf, count, 0, &disable_panic);
+	if (ret)
+		return ret;
 
-void dpu_debugfs_setup_regset32(struct dpu_debugfs_regset32 *regset,
-		uint32_t offset, uint32_t length, struct dpu_kms *dpu_kms)
-{
-	if (regset) {
-		regset->offset = offset;
-		regset->blk_len = length;
-		regset->dpu_kms = dpu_kms;
+	if (disable_panic) {
+		/* Disable panic signal for all active pipes */
+		DPU_DEBUG("Disabling danger:\n");
+		_dpu_plane_set_danger_state(kms, false);
+		kms->has_danger_ctrl = false;
+	} else {
+		/* Enable panic signal for all active pipes */
+		DPU_DEBUG("Enabling danger:\n");
+		kms->has_danger_ctrl = true;
+		_dpu_plane_set_danger_state(kms, true);
 	}
+
+	return count;
 }
 
-void dpu_debugfs_create_regset32(const char *name, umode_t mode,
-		void *parent, struct dpu_debugfs_regset32 *regset)
+static const struct file_operations dpu_plane_danger_enable = {
+	.open = simple_open,
+	.read = _dpu_plane_danger_read,
+	.write = _dpu_plane_danger_write,
+};
+
+static void dpu_debugfs_danger_init(struct dpu_kms *dpu_kms,
+		struct dentry *parent)
 {
-	if (!name || !regset || !regset->dpu_kms || !regset->blk_len)
-		return;
+	struct dentry *entry = debugfs_create_dir("danger", parent);
 
-	/* make sure offset is a multiple of 4 */
-	regset->offset = round_down(regset->offset, 4);
+	debugfs_create_file("danger_status", 0600, entry,
+			dpu_kms, &dpu_debugfs_danger_stats_fops);
+	debugfs_create_file("safe_status", 0600, entry,
+			dpu_kms, &dpu_debugfs_safe_stats_fops);
+	debugfs_create_file("disable_danger", 0600, entry,
+			dpu_kms, &dpu_plane_danger_enable);
 
-	debugfs_create_file(name, mode, parent, regset, &dpu_fops_regset32);
 }
 
 static int dpu_kms_debugfs_init(struct msm_kms *kms, struct drm_minor *minor)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 323a6bce9e64..ab65c817eb42 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -166,75 +166,6 @@ struct dpu_global_state
 struct dpu_global_state
 	*__must_check dpu_kms_get_global_state(struct drm_atomic_state *s);
 
-/**
- * Debugfs functions - extra helper functions for debugfs support
- *
- * Main debugfs documentation is located at,
- *
- * Documentation/filesystems/debugfs.rst
- *
- * @dpu_debugfs_setup_regset32: Initialize data for dpu_debugfs_create_regset32
- * @dpu_debugfs_create_regset32: Create 32-bit register dump file
- * @dpu_debugfs_get_root: Get root dentry for DPU_KMS's debugfs node
- */
-
-/**
- * Companion structure for dpu_debugfs_create_regset32. Do not initialize the
- * members of this structure explicitly; use dpu_debugfs_setup_regset32 instead.
- */
-struct dpu_debugfs_regset32 {
-	uint32_t offset;
-	uint32_t blk_len;
-	struct dpu_kms *dpu_kms;
-};
-
-/**
- * dpu_debugfs_setup_regset32 - Initialize register block definition for debugfs
- * This function is meant to initialize dpu_debugfs_regset32 structures for use
- * with dpu_debugfs_create_regset32.
- * @regset: opaque register definition structure
- * @offset: sub-block offset
- * @length: sub-block length, in bytes
- * @dpu_kms: pointer to dpu kms structure
- */
-void dpu_debugfs_setup_regset32(struct dpu_debugfs_regset32 *regset,
-		uint32_t offset, uint32_t length, struct dpu_kms *dpu_kms);
-
-/**
- * dpu_debugfs_create_regset32 - Create register read back file for debugfs
- *
- * This function is almost identical to the standard debugfs_create_regset32()
- * function, with the main difference being that a list of register
- * names/offsets do not need to be provided. The 'read' function simply outputs
- * sequential register values over a specified range.
- *
- * Similar to the related debugfs_create_regset32 API, the structure pointed to
- * by regset needs to persist for the lifetime of the created file. The calling
- * code is responsible for initialization/management of this structure.
- *
- * The structure pointed to by regset is meant to be opaque. Please use
- * dpu_debugfs_setup_regset32 to initialize it.
- *
- * @name:   File name within debugfs
- * @mode:   File mode within debugfs
- * @parent: Parent directory entry within debugfs, can be NULL
- * @regset: Pointer to persistent register block definition
- */
-void dpu_debugfs_create_regset32(const char *name, umode_t mode,
-		void *parent, struct dpu_debugfs_regset32 *regset);
-
-/**
- * dpu_debugfs_get_root - Return root directory entry for KMS's debugfs
- *
- * The return value should be passed as the 'parent' argument to subsequent
- * debugfs create calls.
- *
- * @dpu_kms: Pointer to DPU's KMS structure
- *
- * Return: dentry pointer for DPU's debugfs location
- */
-void *dpu_debugfs_get_root(struct dpu_kms *dpu_kms);
-
 /**
  * DPU info management functions
  * These functions/definitions allow for building up a 'dpu_info' structure
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 8f1fef2367cd..34ecd971cbbb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -105,13 +105,6 @@ struct dpu_plane {
 	bool is_error;
 	bool is_rt_pipe;
 	struct dpu_mdss_cfg *catalog;
-
-	/* debugfs related stuff */
-	struct dentry *debugfs_root;
-	struct dpu_debugfs_regset32 debugfs_src;
-	struct dpu_debugfs_regset32 debugfs_scaler;
-	struct dpu_debugfs_regset32 debugfs_csc;
-	bool debugfs_default_scale;
 };
 
 static const uint64_t supported_format_modifiers[] = {
@@ -1319,7 +1312,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
 }
 
 #ifdef CONFIG_DEBUG_FS
-static void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
+void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
@@ -1331,168 +1324,8 @@ static 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);
 }
-
-static ssize_t _dpu_plane_danger_read(struct file *file,
-			char __user *buff, size_t count, loff_t *ppos)
-{
-	struct dpu_kms *kms = file->private_data;
-	int len;
-	char buf[40];
-
-	len = scnprintf(buf, sizeof(buf), "%d\n", !kms->has_danger_ctrl);
-
-	return simple_read_from_buffer(buff, count, ppos, buf, len);
-}
-
-static void _dpu_plane_set_danger_state(struct dpu_kms *kms, bool enable)
-{
-	struct drm_plane *plane;
-
-	drm_for_each_plane(plane, kms->dev) {
-		if (plane->fb && plane->state) {
-			dpu_plane_danger_signal_ctrl(plane, enable);
-			DPU_DEBUG("plane:%d img:%dx%d ",
-				plane->base.id, plane->fb->width,
-				plane->fb->height);
-			DPU_DEBUG("src[%d,%d,%d,%d] dst[%d,%d,%d,%d]\n",
-				plane->state->src_x >> 16,
-				plane->state->src_y >> 16,
-				plane->state->src_w >> 16,
-				plane->state->src_h >> 16,
-				plane->state->crtc_x, plane->state->crtc_y,
-				plane->state->crtc_w, plane->state->crtc_h);
-		} else {
-			DPU_DEBUG("Inactive plane:%d\n", plane->base.id);
-		}
-	}
-}
-
-static ssize_t _dpu_plane_danger_write(struct file *file,
-		    const char __user *user_buf, size_t count, loff_t *ppos)
-{
-	struct dpu_kms *kms = file->private_data;
-	int disable_panic;
-	int ret;
-
-	ret = kstrtouint_from_user(user_buf, count, 0, &disable_panic);
-	if (ret)
-		return ret;
-
-	if (disable_panic) {
-		/* Disable panic signal for all active pipes */
-		DPU_DEBUG("Disabling danger:\n");
-		_dpu_plane_set_danger_state(kms, false);
-		kms->has_danger_ctrl = false;
-	} else {
-		/* Enable panic signal for all active pipes */
-		DPU_DEBUG("Enabling danger:\n");
-		kms->has_danger_ctrl = true;
-		_dpu_plane_set_danger_state(kms, true);
-	}
-
-	return count;
-}
-
-static const struct file_operations dpu_plane_danger_enable = {
-	.open = simple_open,
-	.read = _dpu_plane_danger_read,
-	.write = _dpu_plane_danger_write,
-};
-
-static int _dpu_plane_init_debugfs(struct drm_plane *plane)
-{
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
-	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
-	const struct dpu_sspp_cfg *cfg = pdpu->pipe_hw->cap;
-	const struct dpu_sspp_sub_blks *sblk = cfg->sblk;
-
-	/* create overall sub-directory for the pipe */
-	pdpu->debugfs_root =
-		debugfs_create_dir(plane->name,
-				plane->dev->primary->debugfs_root);
-
-	/* don't error check these */
-	debugfs_create_xul("features", 0600,
-			pdpu->debugfs_root, (unsigned long *)&pdpu->pipe_hw->cap->features);
-
-	/* add register dump support */
-	dpu_debugfs_setup_regset32(&pdpu->debugfs_src,
-			sblk->src_blk.base + cfg->base,
-			sblk->src_blk.len,
-			kms);
-	dpu_debugfs_create_regset32("src_blk", 0400,
-			pdpu->debugfs_root, &pdpu->debugfs_src);
-
-	if (cfg->features & BIT(DPU_SSPP_SCALER_QSEED3) ||
-			cfg->features & BIT(DPU_SSPP_SCALER_QSEED3LITE) ||
-			cfg->features & BIT(DPU_SSPP_SCALER_QSEED2) ||
-			cfg->features & BIT(DPU_SSPP_SCALER_QSEED4)) {
-		dpu_debugfs_setup_regset32(&pdpu->debugfs_scaler,
-				sblk->scaler_blk.base + cfg->base,
-				sblk->scaler_blk.len,
-				kms);
-		dpu_debugfs_create_regset32("scaler_blk", 0400,
-				pdpu->debugfs_root,
-				&pdpu->debugfs_scaler);
-		debugfs_create_bool("default_scaling",
-				0600,
-				pdpu->debugfs_root,
-				&pdpu->debugfs_default_scale);
-	}
-
-	if (cfg->features & BIT(DPU_SSPP_CSC) ||
-			cfg->features & BIT(DPU_SSPP_CSC_10BIT)) {
-		dpu_debugfs_setup_regset32(&pdpu->debugfs_csc,
-				sblk->csc_blk.base + cfg->base,
-				sblk->csc_blk.len,
-				kms);
-		dpu_debugfs_create_regset32("csc_blk", 0400,
-				pdpu->debugfs_root, &pdpu->debugfs_csc);
-	}
-
-	debugfs_create_u32("xin_id",
-			0400,
-			pdpu->debugfs_root,
-			(u32 *) &cfg->xin_id);
-	debugfs_create_u32("clk_ctrl",
-			0400,
-			pdpu->debugfs_root,
-			(u32 *) &cfg->clk_ctrl);
-	debugfs_create_x32("creq_vblank",
-			0600,
-			pdpu->debugfs_root,
-			(u32 *) &sblk->creq_vblank);
-	debugfs_create_x32("danger_vblank",
-			0600,
-			pdpu->debugfs_root,
-			(u32 *) &sblk->danger_vblank);
-
-	debugfs_create_file("disable_danger",
-			0600,
-			pdpu->debugfs_root,
-			kms, &dpu_plane_danger_enable);
-
-	return 0;
-}
-#else
-static int _dpu_plane_init_debugfs(struct drm_plane *plane)
-{
-	return 0;
-}
 #endif
 
-static int dpu_plane_late_register(struct drm_plane *plane)
-{
-	return _dpu_plane_init_debugfs(plane);
-}
-
-static void dpu_plane_early_unregister(struct drm_plane *plane)
-{
-	struct dpu_plane *pdpu = to_dpu_plane(plane);
-
-	debugfs_remove_recursive(pdpu->debugfs_root);
-}
-
 static bool dpu_plane_format_mod_supported(struct drm_plane *plane,
 		uint32_t format, uint64_t modifier)
 {
@@ -1517,8 +1350,6 @@ static const struct drm_plane_funcs dpu_plane_funcs = {
 		.reset = dpu_plane_reset,
 		.atomic_duplicate_state = dpu_plane_duplicate_state,
 		.atomic_destroy_state = dpu_plane_destroy_state,
-		.late_register = dpu_plane_late_register,
-		.early_unregister = dpu_plane_early_unregister,
 		.format_mod_supported = dpu_plane_format_mod_supported,
 };
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 48366da5e86e..d2f60810434e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -115,4 +115,10 @@ void dpu_plane_clear_multirect(const struct drm_plane_state *drm_state);
 int dpu_plane_color_fill(struct drm_plane *plane,
 		uint32_t color, uint32_t alpha);
 
+#ifdef CONFIG_DEBUG_FS
+void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable);
+#else
+static inline void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) {}
+#endif
+
 #endif /* _DPU_PLANE_H_ */
-- 
2.30.2


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

* [PATCH v2 13/22] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

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

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 6fe0af9ffc23..f311cdbfe7d2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -895,12 +895,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	struct drm_plane *plane;
 	struct drm_display_mode *mode;
 
-	int cnt = 0, rc = 0, mixer_width = 0, i, z_pos;
+	int cnt = 0, rc = 0, i;
 
-	struct dpu_multirect_plane_states multirect_plane[DPU_STAGE_MAX * 2];
-	int multirect_count = 0;
-	const struct drm_plane_state *pipe_staged[SSPP_MAX];
-	int left_zpos_cnt = 0, right_zpos_cnt = 0;
 	struct drm_rect crtc_rect = { 0 };
 
 	pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
@@ -920,13 +916,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;
@@ -947,18 +938,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
 		pstates[cnt].drm_pstate = pstate;
 		pstates[cnt].stage = pstate->normalized_zpos;
-		pstates[cnt].pipe_id = dpu_plane_pipe(plane);
 
-		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;
-		}
+		dpu_plane_clear_multirect(pstate);
 
 		cnt++;
 
@@ -973,19 +954,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		}
 	}
 
-	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;
-		}
+		int z_pos = pstates[i].stage;
 
 		/* verify z_pos setting before using it */
 		if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
@@ -993,40 +963,12 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 					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++;
 		}
 
 		pstates[i].dpu_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);
 
 	rc = dpu_core_perf_crtc_check(crtc, crtc_state);
@@ -1036,68 +978,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		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;
-		}
-	}
-
 end:
 	kfree(pstates);
 	return rc;
-- 
2.30.2


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

* [PATCH v2 13/22] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

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

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 6fe0af9ffc23..f311cdbfe7d2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -895,12 +895,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	struct drm_plane *plane;
 	struct drm_display_mode *mode;
 
-	int cnt = 0, rc = 0, mixer_width = 0, i, z_pos;
+	int cnt = 0, rc = 0, i;
 
-	struct dpu_multirect_plane_states multirect_plane[DPU_STAGE_MAX * 2];
-	int multirect_count = 0;
-	const struct drm_plane_state *pipe_staged[SSPP_MAX];
-	int left_zpos_cnt = 0, right_zpos_cnt = 0;
 	struct drm_rect crtc_rect = { 0 };
 
 	pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
@@ -920,13 +916,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;
@@ -947,18 +938,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
 		pstates[cnt].drm_pstate = pstate;
 		pstates[cnt].stage = pstate->normalized_zpos;
-		pstates[cnt].pipe_id = dpu_plane_pipe(plane);
 
-		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;
-		}
+		dpu_plane_clear_multirect(pstate);
 
 		cnt++;
 
@@ -973,19 +954,8 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		}
 	}
 
-	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;
-		}
+		int z_pos = pstates[i].stage;
 
 		/* verify z_pos setting before using it */
 		if (z_pos >= DPU_STAGE_MAX - DPU_STAGE_0) {
@@ -993,40 +963,12 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 					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++;
 		}
 
 		pstates[i].dpu_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);
 
 	rc = dpu_core_perf_crtc_check(crtc, crtc_state);
@@ -1036,68 +978,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		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;
-		}
-	}
-
 end:
 	kfree(pstates);
 	return rc;
-- 
2.30.2


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

* [PATCH v2 14/22] drm/msm/dpu: add list of supported formats to the DPU caps
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

As we are going to add virtual planes, add the list of supported formats
to the hw catalog entry. It will be used to setup universal planes, with
later selecting a pipe depending on whether the YUV format is used for
the framebuffer.

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

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 d01c4c919504..b8e0fece1f0b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -195,6 +195,8 @@ static const struct dpu_caps sdm845_dpu_caps = {
 	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 	.max_hdeci_exp = MAX_HORZ_DECIMATION,
 	.max_vdeci_exp = MAX_VERT_DECIMATION,
+	.format_list = plane_formats_yuv,
+	.num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sc7180_dpu_caps = {
@@ -207,6 +209,8 @@ static const struct dpu_caps sc7180_dpu_caps = {
 	.has_idle_pc = true,
 	.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+	.format_list = plane_formats_yuv,
+	.num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sm8150_dpu_caps = {
@@ -223,6 +227,8 @@ static const struct dpu_caps sm8150_dpu_caps = {
 	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 	.max_hdeci_exp = MAX_HORZ_DECIMATION,
 	.max_vdeci_exp = MAX_VERT_DECIMATION,
+	.format_list = plane_formats_yuv,
+	.num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sm8250_dpu_caps = {
@@ -237,6 +243,8 @@ static const struct dpu_caps sm8250_dpu_caps = {
 	.has_3d_merge = true,
 	.max_linewidth = 4096,
 	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+	.format_list = plane_formats_yuv,
+	.num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sc7280_dpu_caps = {
@@ -249,6 +257,8 @@ static const struct dpu_caps sc7280_dpu_caps = {
 	.has_idle_pc = true,
 	.max_linewidth = 2400,
 	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+	.format_list = plane_formats_yuv,
+	.num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_mdp_cfg sdm845_mdp[] = {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index d2a945a27cfa..f3c5aa3f4b3f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -324,6 +324,8 @@ struct dpu_qos_lut_tbl {
  * @pixel_ram_size     size of latency hiding and de-tiling buffer in bytes
  * @max_hdeci_exp      max horizontal decimation supported (max is 2^value)
  * @max_vdeci_exp      max vertical decimation supported (max is 2^value)
+ * @format_list: Pointer to list of supported formats
+ * @num_formats: Number of supported formats
  */
 struct dpu_caps {
 	u32 max_mixer_width;
@@ -340,6 +342,8 @@ struct dpu_caps {
 	u32 pixel_ram_size;
 	u32 max_hdeci_exp;
 	u32 max_vdeci_exp;
+	const u32 *format_list;
+	u32 num_formats;
 };
 
 /**
-- 
2.30.2


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

* [PATCH v2 14/22] drm/msm/dpu: add list of supported formats to the DPU caps
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

As we are going to add virtual planes, add the list of supported formats
to the hw catalog entry. It will be used to setup universal planes, with
later selecting a pipe depending on whether the YUV format is used for
the framebuffer.

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

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 d01c4c919504..b8e0fece1f0b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -195,6 +195,8 @@ static const struct dpu_caps sdm845_dpu_caps = {
 	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 	.max_hdeci_exp = MAX_HORZ_DECIMATION,
 	.max_vdeci_exp = MAX_VERT_DECIMATION,
+	.format_list = plane_formats_yuv,
+	.num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sc7180_dpu_caps = {
@@ -207,6 +209,8 @@ static const struct dpu_caps sc7180_dpu_caps = {
 	.has_idle_pc = true,
 	.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+	.format_list = plane_formats_yuv,
+	.num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sm8150_dpu_caps = {
@@ -223,6 +227,8 @@ static const struct dpu_caps sm8150_dpu_caps = {
 	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
 	.max_hdeci_exp = MAX_HORZ_DECIMATION,
 	.max_vdeci_exp = MAX_VERT_DECIMATION,
+	.format_list = plane_formats_yuv,
+	.num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sm8250_dpu_caps = {
@@ -237,6 +243,8 @@ static const struct dpu_caps sm8250_dpu_caps = {
 	.has_3d_merge = true,
 	.max_linewidth = 4096,
 	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+	.format_list = plane_formats_yuv,
+	.num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_caps sc7280_dpu_caps = {
@@ -249,6 +257,8 @@ static const struct dpu_caps sc7280_dpu_caps = {
 	.has_idle_pc = true,
 	.max_linewidth = 2400,
 	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
+	.format_list = plane_formats_yuv,
+	.num_formats = ARRAY_SIZE(plane_formats_yuv),
 };
 
 static const struct dpu_mdp_cfg sdm845_mdp[] = {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index d2a945a27cfa..f3c5aa3f4b3f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -324,6 +324,8 @@ struct dpu_qos_lut_tbl {
  * @pixel_ram_size     size of latency hiding and de-tiling buffer in bytes
  * @max_hdeci_exp      max horizontal decimation supported (max is 2^value)
  * @max_vdeci_exp      max vertical decimation supported (max is 2^value)
+ * @format_list: Pointer to list of supported formats
+ * @num_formats: Number of supported formats
  */
 struct dpu_caps {
 	u32 max_mixer_width;
@@ -340,6 +342,8 @@ struct dpu_caps {
 	u32 pixel_ram_size;
 	u32 max_hdeci_exp;
 	u32 max_vdeci_exp;
+	const u32 *format_list;
+	u32 num_formats;
 };
 
 /**
-- 
2.30.2


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

* [PATCH v2 15/22] drm/msm/dpu: simplify DPU_SSPP features checks
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Add DPU_SSPP_CSC_ANY denoting any CSC block. As we are at it, rewrite
DPU_SSPP_SCALER (any scaler) to use BIT(x) instead of hand-coded
bitshifts.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 +++++++++++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  3 +--
 2 files changed, 12 insertions(+), 7 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 264a9d0d5fca..00098e33391e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -25,11 +25,17 @@ struct dpu_hw_pipe;
 /**
  * Define all scaler feature bits in catalog
  */
-#define DPU_SSPP_SCALER ((1UL << DPU_SSPP_SCALER_RGB) | \
-	(1UL << DPU_SSPP_SCALER_QSEED2) | \
-	 (1UL << DPU_SSPP_SCALER_QSEED3) | \
-	 (1UL << DPU_SSPP_SCALER_QSEED3LITE) | \
-	  (1UL << DPU_SSPP_SCALER_QSEED4))
+#define DPU_SSPP_SCALER (BIT(DPU_SSPP_SCALER_RGB) | \
+			 BIT(DPU_SSPP_SCALER_QSEED2) | \
+			 BIT(DPU_SSPP_SCALER_QSEED3) | \
+			 BIT(DPU_SSPP_SCALER_QSEED3LITE) | \
+			 BIT(DPU_SSPP_SCALER_QSEED4))
+
+/*
+ * Define all CSC feature bits in catalog
+ */
+#define DPU_SSPP_CSC_ANY (BIT(DPU_SSPP_CSC) | \
+			  BIT(DPU_SSPP_CSC_10BIT))
 
 /**
  * Component indices
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 34ecd971cbbb..8ed7b8f0db69 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -983,8 +983,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	if (DPU_FORMAT_IS_YUV(fmt) &&
 		(!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
-		 !(pdpu->pipe_hw->cap->features & (BIT(DPU_SSPP_CSC)
-		 | BIT(DPU_SSPP_CSC_10BIT))))) {
+		 !(pdpu->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
 		DPU_DEBUG_PLANE(pdpu,
 				"plane doesn't have scaler/csc for yuv\n");
 		return -EINVAL;
-- 
2.30.2


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

* [PATCH v2 15/22] drm/msm/dpu: simplify DPU_SSPP features checks
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

Add DPU_SSPP_CSC_ANY denoting any CSC block. As we are at it, rewrite
DPU_SSPP_SCALER (any scaler) to use BIT(x) instead of hand-coded
bitshifts.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 +++++++++++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  3 +--
 2 files changed, 12 insertions(+), 7 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 264a9d0d5fca..00098e33391e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -25,11 +25,17 @@ struct dpu_hw_pipe;
 /**
  * Define all scaler feature bits in catalog
  */
-#define DPU_SSPP_SCALER ((1UL << DPU_SSPP_SCALER_RGB) | \
-	(1UL << DPU_SSPP_SCALER_QSEED2) | \
-	 (1UL << DPU_SSPP_SCALER_QSEED3) | \
-	 (1UL << DPU_SSPP_SCALER_QSEED3LITE) | \
-	  (1UL << DPU_SSPP_SCALER_QSEED4))
+#define DPU_SSPP_SCALER (BIT(DPU_SSPP_SCALER_RGB) | \
+			 BIT(DPU_SSPP_SCALER_QSEED2) | \
+			 BIT(DPU_SSPP_SCALER_QSEED3) | \
+			 BIT(DPU_SSPP_SCALER_QSEED3LITE) | \
+			 BIT(DPU_SSPP_SCALER_QSEED4))
+
+/*
+ * Define all CSC feature bits in catalog
+ */
+#define DPU_SSPP_CSC_ANY (BIT(DPU_SSPP_CSC) | \
+			  BIT(DPU_SSPP_CSC_10BIT))
 
 /**
  * Component indices
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 34ecd971cbbb..8ed7b8f0db69 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -983,8 +983,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 	if (DPU_FORMAT_IS_YUV(fmt) &&
 		(!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
-		 !(pdpu->pipe_hw->cap->features & (BIT(DPU_SSPP_CSC)
-		 | BIT(DPU_SSPP_CSC_10BIT))))) {
+		 !(pdpu->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
 		DPU_DEBUG_PLANE(pdpu,
 				"plane doesn't have scaler/csc for yuv\n");
 		return -EINVAL;
-- 
2.30.2


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

* [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

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

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 8ed7b8f0db69..3850f2714bf3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -44,7 +44,6 @@
 #define DPU_NAME_SIZE  12
 
 #define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
-#define DPU_ZPOS_MAX 255
 
 /* multirect rect index */
 enum {
@@ -1374,7 +1373,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	struct dpu_plane *pdpu;
 	struct msm_drm_private *priv = dev->dev_private;
 	struct dpu_kms *kms = to_dpu_kms(priv->kms);
-	int zpos_max = DPU_ZPOS_MAX;
 	uint32_t num_formats;
 	int ret = -EINVAL;
 
@@ -1412,14 +1410,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 
 	pdpu->catalog = kms->catalog;
 
-	if (kms->catalog->mixer_count &&
-		kms->catalog->mixer[0].sblk->maxblendstages) {
-		zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
-		if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
-			zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
-	}
-
-	ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
+	ret = drm_plane_create_zpos_property(plane, 0, 0, 255);
 	if (ret)
 		DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
 
-- 
2.30.2


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

* [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

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

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 8ed7b8f0db69..3850f2714bf3 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -44,7 +44,6 @@
 #define DPU_NAME_SIZE  12
 
 #define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
-#define DPU_ZPOS_MAX 255
 
 /* multirect rect index */
 enum {
@@ -1374,7 +1373,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	struct dpu_plane *pdpu;
 	struct msm_drm_private *priv = dev->dev_private;
 	struct dpu_kms *kms = to_dpu_kms(priv->kms);
-	int zpos_max = DPU_ZPOS_MAX;
 	uint32_t num_formats;
 	int ret = -EINVAL;
 
@@ -1412,14 +1410,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 
 	pdpu->catalog = kms->catalog;
 
-	if (kms->catalog->mixer_count &&
-		kms->catalog->mixer[0].sblk->maxblendstages) {
-		zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
-		if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
-			zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
-	}
-
-	ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
+	ret = drm_plane_create_zpos_property(plane, 0, 0, 255);
 	if (ret)
 		DPU_ERROR("failed to install zpos property, rc = %d\n", ret);
 
-- 
2.30.2


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

* [PATCH v2 17/22] drm/msm/dpu: add support for SSPP allocation to RM
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

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

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

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


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

* [PATCH v2 17/22] drm/msm/dpu: add support for SSPP allocation to RM
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

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

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

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


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

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

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

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 61008e8afb0a..a6de7f3ae2d8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -99,7 +99,6 @@ struct dpu_plane {
 
 	enum dpu_sspp pipe;
 
-	struct dpu_hw_pipe *pipe_hw;
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
@@ -299,6 +298,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 		struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	const struct dpu_format *fmt = NULL;
 	u64 qos_lut;
 	u32 total_fl = 0, lut_usage;
@@ -330,7 +330,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 			fmt ? (char *)&fmt->base.pixel_format : NULL,
 			pdpu->is_rt_pipe, total_fl, qos_lut);
 
-	pdpu->pipe_hw->ops.setup_creq_lut(pdpu->pipe_hw, qos_lut);
+	pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
 }
 
 /**
@@ -342,6 +342,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;
 
@@ -381,7 +382,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
 		danger_lut,
 		safe_lut);
 
-	pdpu->pipe_hw->ops.setup_danger_safe_lut(pdpu->pipe_hw,
+	pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
 			danger_lut, safe_lut);
 }
 
@@ -395,14 +396,15 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 	bool enable, u32 flags)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
 
 	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
 	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
-		pipe_qos_cfg.creq_vblank = pdpu->pipe_hw->cap->sblk->creq_vblank;
+		pipe_qos_cfg.creq_vblank = pstate->pipe_hw->cap->sblk->creq_vblank;
 		pipe_qos_cfg.danger_vblank =
-				pdpu->pipe_hw->cap->sblk->danger_vblank;
+				pstate->pipe_hw->cap->sblk->danger_vblank;
 		pipe_qos_cfg.vblank_en = enable;
 	}
 
@@ -428,7 +430,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 		pipe_qos_cfg.danger_vblank,
 		pdpu->is_rt_pipe);
 
-	pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,
+	pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
 			&pipe_qos_cfg);
 }
 
@@ -442,18 +444,19 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 		struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_vbif_set_ot_params ot_params;
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
 	memset(&ot_params, 0, sizeof(ot_params));
-	ot_params.xin_id = pdpu->pipe_hw->cap->xin_id;
-	ot_params.num = pdpu->pipe_hw->idx - SSPP_NONE;
+	ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
+	ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
 	ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
 	ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
 	ot_params.is_wfd = !pdpu->is_rt_pipe;
 	ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
 	ot_params.vbif_idx = VBIF_RT;
-	ot_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
+	ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
 	ot_params.rd = true;
 
 	dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
@@ -466,14 +469,15 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_vbif_set_qos_params qos_params;
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
 	memset(&qos_params, 0, sizeof(qos_params));
 	qos_params.vbif_idx = VBIF_RT;
-	qos_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
-	qos_params.xin_id = pdpu->pipe_hw->cap->xin_id;
-	qos_params.num = pdpu->pipe_hw->idx - SSPP_VIG0;
+	qos_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
+	qos_params.xin_id = pstate->pipe_hw->cap->xin_id;
+	qos_params.num = pstate->pipe_hw->idx - SSPP_VIG0;
 	qos_params.is_rt = pdpu->is_rt_pipe;
 
 	DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, clk_ctrl:%d\n",
@@ -500,11 +504,11 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
 	else if (ret)
 		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-	else if (pdpu->pipe_hw->ops.setup_sourceaddress) {
-		trace_dpu_plane_set_scanout(pdpu->pipe_hw->idx,
+	else if (pstate->pipe_hw->ops.setup_sourceaddress) {
+		trace_dpu_plane_set_scanout(pstate->pipe_hw->idx,
 					    &pipe_cfg->layout,
 					    pstate->multirect_index);
-		pdpu->pipe_hw->ops.setup_sourceaddress(pdpu->pipe_hw, pipe_cfg,
+		pstate->pipe_hw->ops.setup_sourceaddress(pstate->pipe_hw, pipe_cfg,
 						pstate->multirect_index);
 	}
 }
@@ -548,7 +552,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 			scale_cfg->src_height[i] /= chroma_subsmpl_v;
 		}
 
-		if (pdpu->pipe_hw->cap->features &
+		if (pstate->pipe_hw->cap->features &
 			BIT(DPU_SSPP_SCALER_QSEED4)) {
 			scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
 			scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
@@ -608,6 +612,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) {
@@ -618,7 +623,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
 	if (!DPU_FORMAT_IS_YUV(fmt))
 		return NULL;
 
-	if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->pipe_hw->cap->features)
+	if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe_hw->cap->features)
 		csc_ptr = &dpu_csc10_YUV2RGB_601L;
 	else
 		csc_ptr = &dpu_csc_YUV2RGB_601L;
@@ -653,8 +658,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 			&scaler3_cfg, &pixel_ext, fmt,
 			info->hsub, info->vsub);
 
-	if (pdpu->pipe_hw->ops.setup_pe)
-		pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
+	if (pstate->pipe_hw->ops.setup_pe)
+		pstate->pipe_hw->ops.setup_pe(pstate->pipe_hw,
 				&pixel_ext);
 
 	/**
@@ -662,9 +667,9 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 	 * bypassed. Still we need to update alpha and bitwidth
 	 * ONLY for RECT0
 	 */
-	if (pdpu->pipe_hw->ops.setup_scaler &&
+	if (pstate->pipe_hw->ops.setup_scaler &&
 			pstate->multirect_index != DPU_SSPP_RECT_1)
-		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
+		pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
 				pipe_cfg, &pixel_ext,
 				&scaler3_cfg);
 }
@@ -693,8 +698,8 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
 
 	/* update sspp */
-	if (fmt && pdpu->pipe_hw->ops.setup_solidfill) {
-		pdpu->pipe_hw->ops.setup_solidfill(pdpu->pipe_hw,
+	if (fmt && pstate->pipe_hw->ops.setup_solidfill) {
+		pstate->pipe_hw->ops.setup_solidfill(pstate->pipe_hw,
 				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
 				pstate->multirect_index);
 
@@ -708,13 +713,13 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 		pipe_cfg.src_rect.y2 =
 			drm_rect_height(&pipe_cfg.dst_rect);
 
-		if (pdpu->pipe_hw->ops.setup_format)
-			pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw,
+		if (pstate->pipe_hw->ops.setup_format)
+			pstate->pipe_hw->ops.setup_format(pstate->pipe_hw,
 					fmt, DPU_SSPP_SOLID_FILL,
 					pstate->multirect_index);
 
-		if (pdpu->pipe_hw->ops.setup_rects)
-			pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
+		if (pstate->pipe_hw->ops.setup_rects)
+			pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
 					&pipe_cfg,
 					pstate->multirect_index);
 
@@ -952,10 +957,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 		crtc_state = drm_atomic_get_new_crtc_state(state,
 							   new_plane_state->crtc);
 
-	min_scale = FRAC_16_16(1, pdpu->pipe_hw->cap->sblk->maxupscale);
+	min_scale = FRAC_16_16(1, pstate->pipe_hw->cap->sblk->maxupscale);
 	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
 						  min_scale,
-						  pdpu->pipe_hw->cap->sblk->maxdwnscale << 16,
+						  pstate->pipe_hw->cap->sblk->maxdwnscale << 16,
 						  true, true);
 	if (ret) {
 		DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
@@ -981,8 +986,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
 
 	if (DPU_FORMAT_IS_YUV(fmt) &&
-		(!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
-		 !(pdpu->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
+		(!(pstate->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
+		 !(pstate->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
 		DPU_DEBUG_PLANE(pdpu,
 				"plane doesn't have scaler/csc for yuv\n");
 		return -EINVAL;
@@ -1043,12 +1048,12 @@ void dpu_plane_flush(struct drm_plane *plane)
 	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
 		/* force 100% alpha */
 		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
-	else if (pdpu->pipe_hw && pdpu->pipe_hw->ops.setup_csc) {
+	else if (pstate->pipe_hw && pstate->pipe_hw->ops.setup_csc) {
 		const struct dpu_format *fmt = to_dpu_format(msm_framebuffer_format(plane->state->fb));
 		const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, fmt);
 
 		if (csc_ptr)
-			pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, csc_ptr);
+			pstate->pipe_hw->ops.setup_csc(pstate->pipe_hw, csc_ptr);
 	}
 
 	/* flag h/w flush complete */
@@ -1115,21 +1120,21 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		return;
 	}
 
-	if (pdpu->pipe_hw->ops.setup_rects) {
-		pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
+	if (pstate->pipe_hw->ops.setup_rects) {
+		pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
 				&pipe_cfg,
 				pstate->multirect_index);
 	}
 
 	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
 
-	if (pdpu->pipe_hw->ops.setup_multirect)
-		pdpu->pipe_hw->ops.setup_multirect(
-				pdpu->pipe_hw,
+	if (pstate->pipe_hw->ops.setup_multirect)
+		pstate->pipe_hw->ops.setup_multirect(
+				pstate->pipe_hw,
 				pstate->multirect_index,
 				pstate->multirect_mode);
 
-	if (pdpu->pipe_hw->ops.setup_format) {
+	if (pstate->pipe_hw->ops.setup_format) {
 		unsigned int rotation;
 
 		src_flags = 0x0;
@@ -1146,10 +1151,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			src_flags |= DPU_SSPP_FLIP_UD;
 
 		/* update format */
-		pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw, fmt, src_flags,
+		pstate->pipe_hw->ops.setup_format(pstate->pipe_hw, fmt, src_flags,
 				pstate->multirect_index);
 
-		if (pdpu->pipe_hw->ops.setup_cdp) {
+		if (pstate->pipe_hw->ops.setup_cdp) {
 			struct dpu_hw_pipe_cdp_cfg cdp_cfg;
 
 			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
@@ -1163,7 +1168,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->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg);
 		}
 	}
 
@@ -1281,6 +1286,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu;
 	struct dpu_plane_state *pstate;
+	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
 
 	if (!plane) {
 		DPU_ERROR("invalid plane\n");
@@ -1302,6 +1308,8 @@ static void dpu_plane_reset(struct drm_plane *plane)
 		return;
 	}
 
+	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
+
 	pstate->base.plane = plane;
 
 	plane->state = &pstate->base;
@@ -1371,6 +1379,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	struct dpu_plane *pdpu;
 	struct msm_drm_private *priv = dev->dev_private;
 	struct dpu_kms *kms = to_dpu_kms(priv->kms);
+	struct dpu_hw_pipe *pipe_hw;
 	uint32_t num_formats;
 	int ret = -EINVAL;
 
@@ -1389,15 +1398,15 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	/* initialize underlying h/w driver */
 	if (!kms->rm.sspp_blks[pipe - SSPP_NONE])
 		goto clean_plane;
-	pdpu->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
+	pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
 
-	if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
+	if (!pipe_hw->cap || !pipe_hw->cap->sblk) {
 		DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
 		goto clean_plane;
 	}
 
-	format_list = pdpu->pipe_hw->cap->sblk->format_list;
-	num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
+	format_list = pipe_hw->cap->sblk->format_list;
+	num_formats = pipe_hw->cap->sblk->num_formats;
 
 	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
 				format_list, num_formats,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index d2f60810434e..42b88b6bc9c2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -35,6 +35,8 @@ struct dpu_plane_state {
 	uint32_t multirect_mode;
 	bool pending;
 
+	struct dpu_hw_pipe *pipe_hw;
+
 	u64 plane_fetch_bw;
 	u64 plane_clk;
 };
-- 
2.30.2


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

* [PATCH v2 18/22] drm/msm/dpu: move pipe_hw to dpu_plane_state
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

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

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

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 61008e8afb0a..a6de7f3ae2d8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -99,7 +99,6 @@ struct dpu_plane {
 
 	enum dpu_sspp pipe;
 
-	struct dpu_hw_pipe *pipe_hw;
 	uint32_t color_fill;
 	bool is_error;
 	bool is_rt_pipe;
@@ -299,6 +298,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 		struct drm_framebuffer *fb, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	const struct dpu_format *fmt = NULL;
 	u64 qos_lut;
 	u32 total_fl = 0, lut_usage;
@@ -330,7 +330,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 			fmt ? (char *)&fmt->base.pixel_format : NULL,
 			pdpu->is_rt_pipe, total_fl, qos_lut);
 
-	pdpu->pipe_hw->ops.setup_creq_lut(pdpu->pipe_hw, qos_lut);
+	pstate->pipe_hw->ops.setup_creq_lut(pstate->pipe_hw, qos_lut);
 }
 
 /**
@@ -342,6 +342,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;
 
@@ -381,7 +382,7 @@ static void _dpu_plane_set_danger_lut(struct drm_plane *plane,
 		danger_lut,
 		safe_lut);
 
-	pdpu->pipe_hw->ops.setup_danger_safe_lut(pdpu->pipe_hw,
+	pstate->pipe_hw->ops.setup_danger_safe_lut(pstate->pipe_hw,
 			danger_lut, safe_lut);
 }
 
@@ -395,14 +396,15 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 	bool enable, u32 flags)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_hw_pipe_qos_cfg pipe_qos_cfg;
 
 	memset(&pipe_qos_cfg, 0, sizeof(pipe_qos_cfg));
 
 	if (flags & DPU_PLANE_QOS_VBLANK_CTRL) {
-		pipe_qos_cfg.creq_vblank = pdpu->pipe_hw->cap->sblk->creq_vblank;
+		pipe_qos_cfg.creq_vblank = pstate->pipe_hw->cap->sblk->creq_vblank;
 		pipe_qos_cfg.danger_vblank =
-				pdpu->pipe_hw->cap->sblk->danger_vblank;
+				pstate->pipe_hw->cap->sblk->danger_vblank;
 		pipe_qos_cfg.vblank_en = enable;
 	}
 
@@ -428,7 +430,7 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane,
 		pipe_qos_cfg.danger_vblank,
 		pdpu->is_rt_pipe);
 
-	pdpu->pipe_hw->ops.setup_qos_ctrl(pdpu->pipe_hw,
+	pstate->pipe_hw->ops.setup_qos_ctrl(pstate->pipe_hw,
 			&pipe_qos_cfg);
 }
 
@@ -442,18 +444,19 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 		struct drm_crtc *crtc, struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_vbif_set_ot_params ot_params;
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
 	memset(&ot_params, 0, sizeof(ot_params));
-	ot_params.xin_id = pdpu->pipe_hw->cap->xin_id;
-	ot_params.num = pdpu->pipe_hw->idx - SSPP_NONE;
+	ot_params.xin_id = pstate->pipe_hw->cap->xin_id;
+	ot_params.num = pstate->pipe_hw->idx - SSPP_NONE;
 	ot_params.width = drm_rect_width(&pipe_cfg->src_rect);
 	ot_params.height = drm_rect_height(&pipe_cfg->src_rect);
 	ot_params.is_wfd = !pdpu->is_rt_pipe;
 	ot_params.frame_rate = drm_mode_vrefresh(&crtc->mode);
 	ot_params.vbif_idx = VBIF_RT;
-	ot_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
+	ot_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
 	ot_params.rd = true;
 
 	dpu_vbif_set_ot_limit(dpu_kms, &ot_params);
@@ -466,14 +469,15 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 static void _dpu_plane_set_qos_remap(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
 	struct dpu_vbif_set_qos_params qos_params;
 	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
 
 	memset(&qos_params, 0, sizeof(qos_params));
 	qos_params.vbif_idx = VBIF_RT;
-	qos_params.clk_ctrl = pdpu->pipe_hw->cap->clk_ctrl;
-	qos_params.xin_id = pdpu->pipe_hw->cap->xin_id;
-	qos_params.num = pdpu->pipe_hw->idx - SSPP_VIG0;
+	qos_params.clk_ctrl = pstate->pipe_hw->cap->clk_ctrl;
+	qos_params.xin_id = pstate->pipe_hw->cap->xin_id;
+	qos_params.num = pstate->pipe_hw->idx - SSPP_VIG0;
 	qos_params.is_rt = pdpu->is_rt_pipe;
 
 	DPU_DEBUG_PLANE(pdpu, "pipe:%d vbif:%d xin:%d rt:%d, clk_ctrl:%d\n",
@@ -500,11 +504,11 @@ static void _dpu_plane_set_scanout(struct drm_plane *plane,
 		DPU_DEBUG_PLANE(pdpu, "not updating same src addrs\n");
 	else if (ret)
 		DPU_ERROR_PLANE(pdpu, "failed to get format layout, %d\n", ret);
-	else if (pdpu->pipe_hw->ops.setup_sourceaddress) {
-		trace_dpu_plane_set_scanout(pdpu->pipe_hw->idx,
+	else if (pstate->pipe_hw->ops.setup_sourceaddress) {
+		trace_dpu_plane_set_scanout(pstate->pipe_hw->idx,
 					    &pipe_cfg->layout,
 					    pstate->multirect_index);
-		pdpu->pipe_hw->ops.setup_sourceaddress(pdpu->pipe_hw, pipe_cfg,
+		pstate->pipe_hw->ops.setup_sourceaddress(pstate->pipe_hw, pipe_cfg,
 						pstate->multirect_index);
 	}
 }
@@ -548,7 +552,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 			scale_cfg->src_height[i] /= chroma_subsmpl_v;
 		}
 
-		if (pdpu->pipe_hw->cap->features &
+		if (pstate->pipe_hw->cap->features &
 			BIT(DPU_SSPP_SCALER_QSEED4)) {
 			scale_cfg->preload_x[i] = DPU_QSEED4_DEFAULT_PRELOAD_H;
 			scale_cfg->preload_y[i] = DPU_QSEED4_DEFAULT_PRELOAD_V;
@@ -608,6 +612,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) {
@@ -618,7 +623,7 @@ static const struct dpu_csc_cfg *_dpu_plane_get_csc(struct dpu_plane *pdpu, cons
 	if (!DPU_FORMAT_IS_YUV(fmt))
 		return NULL;
 
-	if (BIT(DPU_SSPP_CSC_10BIT) & pdpu->pipe_hw->cap->features)
+	if (BIT(DPU_SSPP_CSC_10BIT) & pstate->pipe_hw->cap->features)
 		csc_ptr = &dpu_csc10_YUV2RGB_601L;
 	else
 		csc_ptr = &dpu_csc_YUV2RGB_601L;
@@ -653,8 +658,8 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 			&scaler3_cfg, &pixel_ext, fmt,
 			info->hsub, info->vsub);
 
-	if (pdpu->pipe_hw->ops.setup_pe)
-		pdpu->pipe_hw->ops.setup_pe(pdpu->pipe_hw,
+	if (pstate->pipe_hw->ops.setup_pe)
+		pstate->pipe_hw->ops.setup_pe(pstate->pipe_hw,
 				&pixel_ext);
 
 	/**
@@ -662,9 +667,9 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 	 * bypassed. Still we need to update alpha and bitwidth
 	 * ONLY for RECT0
 	 */
-	if (pdpu->pipe_hw->ops.setup_scaler &&
+	if (pstate->pipe_hw->ops.setup_scaler &&
 			pstate->multirect_index != DPU_SSPP_RECT_1)
-		pdpu->pipe_hw->ops.setup_scaler(pdpu->pipe_hw,
+		pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
 				pipe_cfg, &pixel_ext,
 				&scaler3_cfg);
 }
@@ -693,8 +698,8 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 	fmt = dpu_get_dpu_format(DRM_FORMAT_ABGR8888);
 
 	/* update sspp */
-	if (fmt && pdpu->pipe_hw->ops.setup_solidfill) {
-		pdpu->pipe_hw->ops.setup_solidfill(pdpu->pipe_hw,
+	if (fmt && pstate->pipe_hw->ops.setup_solidfill) {
+		pstate->pipe_hw->ops.setup_solidfill(pstate->pipe_hw,
 				(color & 0xFFFFFF) | ((alpha & 0xFF) << 24),
 				pstate->multirect_index);
 
@@ -708,13 +713,13 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 		pipe_cfg.src_rect.y2 =
 			drm_rect_height(&pipe_cfg.dst_rect);
 
-		if (pdpu->pipe_hw->ops.setup_format)
-			pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw,
+		if (pstate->pipe_hw->ops.setup_format)
+			pstate->pipe_hw->ops.setup_format(pstate->pipe_hw,
 					fmt, DPU_SSPP_SOLID_FILL,
 					pstate->multirect_index);
 
-		if (pdpu->pipe_hw->ops.setup_rects)
-			pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
+		if (pstate->pipe_hw->ops.setup_rects)
+			pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
 					&pipe_cfg,
 					pstate->multirect_index);
 
@@ -952,10 +957,10 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 		crtc_state = drm_atomic_get_new_crtc_state(state,
 							   new_plane_state->crtc);
 
-	min_scale = FRAC_16_16(1, pdpu->pipe_hw->cap->sblk->maxupscale);
+	min_scale = FRAC_16_16(1, pstate->pipe_hw->cap->sblk->maxupscale);
 	ret = drm_atomic_helper_check_plane_state(new_plane_state, crtc_state,
 						  min_scale,
-						  pdpu->pipe_hw->cap->sblk->maxdwnscale << 16,
+						  pstate->pipe_hw->cap->sblk->maxdwnscale << 16,
 						  true, true);
 	if (ret) {
 		DPU_DEBUG_PLANE(pdpu, "Check plane state failed (%d)\n", ret);
@@ -981,8 +986,8 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
 
 	if (DPU_FORMAT_IS_YUV(fmt) &&
-		(!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
-		 !(pdpu->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
+		(!(pstate->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
+		 !(pstate->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
 		DPU_DEBUG_PLANE(pdpu,
 				"plane doesn't have scaler/csc for yuv\n");
 		return -EINVAL;
@@ -1043,12 +1048,12 @@ void dpu_plane_flush(struct drm_plane *plane)
 	else if (pdpu->color_fill & DPU_PLANE_COLOR_FILL_FLAG)
 		/* force 100% alpha */
 		_dpu_plane_color_fill(pdpu, pdpu->color_fill, 0xFF);
-	else if (pdpu->pipe_hw && pdpu->pipe_hw->ops.setup_csc) {
+	else if (pstate->pipe_hw && pstate->pipe_hw->ops.setup_csc) {
 		const struct dpu_format *fmt = to_dpu_format(msm_framebuffer_format(plane->state->fb));
 		const struct dpu_csc_cfg *csc_ptr = _dpu_plane_get_csc(pdpu, fmt);
 
 		if (csc_ptr)
-			pdpu->pipe_hw->ops.setup_csc(pdpu->pipe_hw, csc_ptr);
+			pstate->pipe_hw->ops.setup_csc(pstate->pipe_hw, csc_ptr);
 	}
 
 	/* flag h/w flush complete */
@@ -1115,21 +1120,21 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 		return;
 	}
 
-	if (pdpu->pipe_hw->ops.setup_rects) {
-		pdpu->pipe_hw->ops.setup_rects(pdpu->pipe_hw,
+	if (pstate->pipe_hw->ops.setup_rects) {
+		pstate->pipe_hw->ops.setup_rects(pstate->pipe_hw,
 				&pipe_cfg,
 				pstate->multirect_index);
 	}
 
 	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
 
-	if (pdpu->pipe_hw->ops.setup_multirect)
-		pdpu->pipe_hw->ops.setup_multirect(
-				pdpu->pipe_hw,
+	if (pstate->pipe_hw->ops.setup_multirect)
+		pstate->pipe_hw->ops.setup_multirect(
+				pstate->pipe_hw,
 				pstate->multirect_index,
 				pstate->multirect_mode);
 
-	if (pdpu->pipe_hw->ops.setup_format) {
+	if (pstate->pipe_hw->ops.setup_format) {
 		unsigned int rotation;
 
 		src_flags = 0x0;
@@ -1146,10 +1151,10 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 			src_flags |= DPU_SSPP_FLIP_UD;
 
 		/* update format */
-		pdpu->pipe_hw->ops.setup_format(pdpu->pipe_hw, fmt, src_flags,
+		pstate->pipe_hw->ops.setup_format(pstate->pipe_hw, fmt, src_flags,
 				pstate->multirect_index);
 
-		if (pdpu->pipe_hw->ops.setup_cdp) {
+		if (pstate->pipe_hw->ops.setup_cdp) {
 			struct dpu_hw_pipe_cdp_cfg cdp_cfg;
 
 			memset(&cdp_cfg, 0, sizeof(struct dpu_hw_pipe_cdp_cfg));
@@ -1163,7 +1168,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->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg);
 		}
 	}
 
@@ -1281,6 +1286,7 @@ static void dpu_plane_reset(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu;
 	struct dpu_plane_state *pstate;
+	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
 
 	if (!plane) {
 		DPU_ERROR("invalid plane\n");
@@ -1302,6 +1308,8 @@ static void dpu_plane_reset(struct drm_plane *plane)
 		return;
 	}
 
+	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
+
 	pstate->base.plane = plane;
 
 	plane->state = &pstate->base;
@@ -1371,6 +1379,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	struct dpu_plane *pdpu;
 	struct msm_drm_private *priv = dev->dev_private;
 	struct dpu_kms *kms = to_dpu_kms(priv->kms);
+	struct dpu_hw_pipe *pipe_hw;
 	uint32_t num_formats;
 	int ret = -EINVAL;
 
@@ -1389,15 +1398,15 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	/* initialize underlying h/w driver */
 	if (!kms->rm.sspp_blks[pipe - SSPP_NONE])
 		goto clean_plane;
-	pdpu->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
+	pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
 
-	if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
+	if (!pipe_hw->cap || !pipe_hw->cap->sblk) {
 		DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
 		goto clean_plane;
 	}
 
-	format_list = pdpu->pipe_hw->cap->sblk->format_list;
-	num_formats = pdpu->pipe_hw->cap->sblk->num_formats;
+	format_list = pipe_hw->cap->sblk->format_list;
+	num_formats = pipe_hw->cap->sblk->num_formats;
 
 	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
 				format_list, num_formats,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index d2f60810434e..42b88b6bc9c2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -35,6 +35,8 @@ struct dpu_plane_state {
 	uint32_t multirect_mode;
 	bool pending;
 
+	struct dpu_hw_pipe *pipe_hw;
+
 	u64 plane_fetch_bw;
 	u64 plane_clk;
 };
-- 
2.30.2


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

* [PATCH v2 19/22] drm/msm/dpu: add support for virtualized planes
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Add support for registering unified (virtualized) planes, allowing SSPP
block to be allocated at runtime, during atomic_check. This allows
userspace app to use any plane without caring if it supports scaler or
YUV formats. All planes are marked as supporting all formats and scaler
options. The kernel space will select the appropriate SSPP pipe or
return an error if we run out of resources.

Virtual planes are disabled by default, use msm.dpu_use_virtual_planes=1
kernel parameter to enable them.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 115 ++++++++++++-------
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 109 ++++++++++++++----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 133 ++++++++++++++++------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  21 +---
 4 files changed, 272 insertions(+), 106 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index f311cdbfe7d2..49bdd5953b9f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -206,6 +206,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
 	bool bg_alpha_enable = false;
 	DECLARE_BITMAP(fetch_active, SSPP_MAX);
+	enum dpu_sspp pipe;
 
 	memset(fetch_active, 0, sizeof(fetch_active));
 	drm_atomic_crtc_for_each_plane(plane, crtc) {
@@ -216,14 +217,19 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		pstate = to_dpu_plane_state(state);
 		fb = state->fb;
 
-		dpu_plane_get_ctl_flush(plane, ctl, &flush_mask);
-		set_bit(dpu_plane_pipe(plane), fetch_active);
+		if (WARN_ON(!pstate->pipe_hw))
+			continue;
+
+		pipe = pstate->pipe_hw->idx;
+
+		flush_mask = ctl->ops.get_bitmask_sspp(ctl, pipe);
+		set_bit(pipe, fetch_active);
 
 		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
 				crtc->base.id,
 				pstate->stage,
 				plane->base.id,
-				dpu_plane_pipe(plane) - SSPP_VIG0,
+				pipe - SSPP_VIG0,
 				state->fb ? state->fb->base.id : -1);
 
 		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
@@ -233,13 +239,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 
 		stage_idx = zpos_cnt[pstate->stage]++;
 		stage_cfg->stage[pstate->stage][stage_idx] =
-					dpu_plane_pipe(plane);
+					pipe;
 		stage_cfg->multirect_index[pstate->stage][stage_idx] =
 					pstate->multirect_index;
 
 		trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
 					   state, pstate, stage_idx,
-					   dpu_plane_pipe(plane) - SSPP_VIG0,
+					   pipe - SSPP_VIG0,
 					   format->base.pixel_format,
 					   fb ? fb->modifier : 0);
 
@@ -875,13 +881,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
 	drm_crtc_vblank_on(crtc);
 }
 
-struct plane_state {
-	struct dpu_plane_state *dpu_pstate;
-	const struct drm_plane_state *drm_pstate;
-	int stage;
-	u32 pipe_id;
-};
-
 static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		struct drm_atomic_state *state)
 {
@@ -889,17 +888,25 @@ 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;
+	struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
+	struct dpu_global_state *global_state = dpu_kms_get_global_state(state);
+
+	struct dpu_plane_state **pstates;
+	struct dpu_plane_state *pstate;
 
-	const struct drm_plane_state *pstate;
+	struct drm_plane_state *plane_state;
 	struct drm_plane *plane;
 	struct drm_display_mode *mode;
 
-	int cnt = 0, rc = 0, i;
+	int rc = 0, i;
+	unsigned int num_planes, max_zpos = 0;
 
+	struct drm_rect dst;
 	struct drm_rect crtc_rect = { 0 };
+	int stage;
 
-	pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
+	num_planes = DPU_STAGE_MAX * 4;
+	pstates = kcalloc(num_planes, sizeof(*pstates), GFP_KERNEL);
 
 	if (!crtc_state->enable || !crtc_state->active) {
 		DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n",
@@ -923,28 +930,57 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	crtc_rect.y2 = mode->vdisplay;
 
 	 /* get plane state for all drm planes associated with crtc state */
-	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
-		struct drm_rect dst, clip = crtc_rect;
-
-		if (IS_ERR_OR_NULL(pstate)) {
-			rc = PTR_ERR(pstate);
+	drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
+		plane_state = drm_atomic_get_plane_state(state, plane);
+		if (IS_ERR(plane_state)) {
+			rc = PTR_ERR(plane_state);
 			DPU_ERROR("%s: failed to get plane%d state, %d\n",
 					dpu_crtc->name, plane->base.id, rc);
 			goto end;
 		}
-		if (cnt >= DPU_STAGE_MAX * 4)
+
+		if (plane_state->normalized_zpos >= num_planes) {
+			DPU_ERROR("%s: normalized zpos is too big for plane %d: %d\n",
+					dpu_crtc->name, plane->base.id, plane_state->normalized_zpos);
+			rc = -EINVAL;
+			goto end;
+		}
+
+		pstate = to_dpu_plane_state(plane_state);
+		pstates[plane_state->normalized_zpos] = pstate;
+		max_zpos = max(max_zpos, plane_state->normalized_zpos);
+
+		/* Here we are going to release SSPP blocks and acquire them later in dpu_plane_set_pipe.
+		 *
+		 * TODO: optimize to that we do not reacquire SSPPs if none of
+		 * the plane modes/formats/etc were changed, no planes added or removed.
+		 */
+		if (pstate->pipe_hw) {
+			dpu_rm_release_sspp(&dpu_kms->rm, global_state, plane->base.id);
+			pstate->pipe_hw = NULL;
+		}
+	}
+
+	stage = DPU_STAGE_0;
+	for (i = 0; i <= max_zpos; i++) {
+		pstate = pstates[i];
+		if (!pstate)
 			continue;
 
-		pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
-		pstates[cnt].drm_pstate = pstate;
-		pstates[cnt].stage = pstate->normalized_zpos;
+		/* verify stage setting before using it */
+		if (stage >= DPU_STAGE_MAX) {
+			DPU_ERROR("> %d plane stages assigned\n",
+					DPU_STAGE_MAX - DPU_STAGE_0);
+			rc = -EINVAL;
+			goto end;
+		}
 
-		dpu_plane_clear_multirect(pstate);
+		plane_state = &pstate->base;
 
-		cnt++;
+		dpu_plane_clear_multirect(plane_state);
 
-		dst = drm_plane_state_dest(pstate);
-		if (!drm_rect_intersect(&clip, &dst)) {
+		dst = drm_plane_state_dest(plane_state);
+		if (!drm_rect_intersect(&dst, &crtc_rect)) {
 			DPU_ERROR("invalid vertical/horizontal destination\n");
 			DPU_ERROR("display: " DRM_RECT_FMT " plane: "
 				  DRM_RECT_FMT "\n", DRM_RECT_ARG(&crtc_rect),
@@ -952,21 +988,22 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 			rc = -E2BIG;
 			goto end;
 		}
-	}
 
-	for (i = 0; i < cnt; i++) {
-		int z_pos = pstates[i].stage;
+		plane = pstate->base.plane;
+		rc = dpu_plane_set_pipe(plane, pstate);
+		if (rc) {
+			DPU_ERROR("%s: error setting pipe for %s\n", dpu_crtc->name, plane->name);
+			goto end;
+		}
 
-		/* 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;
+		rc = dpu_plane_real_atomic_check(plane, state);
+		if (rc) {
+			DPU_ERROR("%s: error checking pipe for %s\n", dpu_crtc->name, plane->name);
 			goto end;
 		}
 
-		pstates[i].dpu_pstate->stage = z_pos + DPU_STAGE_0;
-		DRM_DEBUG_ATOMIC("%s: zpos %d\n", dpu_crtc->name, z_pos);
+		pstates[i]->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_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 66a1c8889cf3..08a7e56cc98f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -47,6 +47,9 @@
 
 #define MIN_IB_BW	400000000ULL /* Min ib vote 400MB */
 
+static bool dpu_use_virtual_planes = false;
+module_param(dpu_use_virtual_planes, bool, 0);
+
 static int dpu_kms_hw_init(struct msm_kms *kms);
 static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms);
 
@@ -581,32 +584,20 @@ static void _dpu_kms_drm_obj_destroy(struct dpu_kms *dpu_kms)
 	priv->num_encoders = 0;
 }
 
-static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
+static int _dpu_kms_create_planes(struct dpu_kms *dpu_kms, int max_crtc_count, struct drm_plane **primary_planes, struct drm_plane **cursor_planes)
 {
 	struct drm_device *dev;
-	struct drm_plane *primary_planes[MAX_PLANES], *plane;
-	struct drm_plane *cursor_planes[MAX_PLANES] = { NULL };
-	struct drm_crtc *crtc;
+	struct drm_plane *plane;
 
 	struct msm_drm_private *priv;
 	struct dpu_mdss_cfg *catalog;
 
-	int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret;
-	int max_crtc_count;
+	int primary_planes_idx = 0, cursor_planes_idx = 0, i;
+
 	dev = dpu_kms->dev;
 	priv = dev->dev_private;
 	catalog = dpu_kms->catalog;
 
-	/*
-	 * Create encoder and query display drivers to create
-	 * bridges and connectors
-	 */
-	ret = _dpu_kms_setup_displays(dev, priv, dpu_kms);
-	if (ret)
-		goto fail;
-
-	max_crtc_count = min(catalog->mixer_count, priv->num_encoders);
-
 	/* Create the planes, keeping track of one primary/cursor per crtc */
 	for (i = 0; i < catalog->sspp_count; i++) {
 		enum drm_plane_type type;
@@ -627,8 +618,51 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
 				       (1UL << max_crtc_count) - 1);
 		if (IS_ERR(plane)) {
 			DPU_ERROR("dpu_plane_init failed\n");
-			ret = PTR_ERR(plane);
-			goto fail;
+			return PTR_ERR(plane);
+		}
+		priv->planes[priv->num_planes++] = plane;
+
+		if (type == DRM_PLANE_TYPE_CURSOR)
+			cursor_planes[cursor_planes_idx++] = plane;
+		else if (type == DRM_PLANE_TYPE_PRIMARY)
+			primary_planes[primary_planes_idx++] = plane;
+	}
+
+	return 0;
+}
+
+static int _dpu_kms_create_planes_virtual(struct dpu_kms *dpu_kms, int max_crtc_count, struct drm_plane **primary_planes, struct drm_plane **cursor_planes)
+{
+	struct drm_device *dev;
+	struct drm_plane *plane;
+
+	struct msm_drm_private *priv;
+	struct dpu_mdss_cfg *catalog;
+
+	int primary_planes_idx = 0, cursor_planes_idx = 0, i;
+
+	dev = dpu_kms->dev;
+	priv = dev->dev_private;
+	catalog = dpu_kms->catalog;
+
+	/* Create the planes, keeping track of one primary/cursor per crtc */
+	for (i = 0; i < catalog->sspp_count; i++) {
+		enum drm_plane_type type;
+
+		if (primary_planes_idx < max_crtc_count)
+			type = DRM_PLANE_TYPE_PRIMARY;
+		else if (cursor_planes_idx < max_crtc_count)
+			type = DRM_PLANE_TYPE_CURSOR;
+		else
+			type = DRM_PLANE_TYPE_OVERLAY;
+
+		DPU_DEBUG("Create virtual plane type %d \n", type);
+
+		plane = dpu_plane_init(dev, SSPP_NONE, type,
+				       (1UL << max_crtc_count) - 1);
+		if (IS_ERR(plane)) {
+			DPU_ERROR("dpu_plane_init failed\n");
+			return PTR_ERR(plane);
 		}
 		priv->planes[priv->num_planes++] = plane;
 
@@ -638,10 +672,47 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
 			primary_planes[primary_planes_idx++] = plane;
 	}
 
-	max_crtc_count = min(max_crtc_count, primary_planes_idx);
+	return 0;
+}
+
+static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
+{
+	struct drm_device *dev;
+	struct drm_plane *primary_planes[MAX_PLANES] = { NULL };
+	struct drm_plane *cursor_planes[MAX_PLANES] = { NULL };
+	struct drm_crtc *crtc;
+
+	struct msm_drm_private *priv;
+	struct dpu_mdss_cfg *catalog;
+
+	int i, ret;
+	int max_crtc_count;
+	dev = dpu_kms->dev;
+	priv = dev->dev_private;
+	catalog = dpu_kms->catalog;
+
+	/*
+	 * Create encoder and query display drivers to create
+	 * bridges and connectors
+	 */
+	ret = _dpu_kms_setup_displays(dev, priv, dpu_kms);
+	if (ret)
+		goto fail;
+
+	max_crtc_count = min(catalog->mixer_count, priv->num_encoders);
+
+	if (dpu_use_virtual_planes)
+		ret = _dpu_kms_create_planes_virtual(dpu_kms, max_crtc_count, primary_planes, cursor_planes);
+	else
+		ret = _dpu_kms_create_planes(dpu_kms, max_crtc_count, primary_planes, cursor_planes);
+	if (ret)
+		goto fail;
 
 	/* Create one CRTC per encoder */
 	for (i = 0; i < max_crtc_count; i++) {
+		if (!primary_planes[i])
+			break;
+
 		crtc = dpu_crtc_init(dev, primary_planes[i], cursor_planes[i]);
 		if (IS_ERR(crtc)) {
 			ret = PTR_ERR(crtc);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index a6de7f3ae2d8..d692136884ad 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -848,18 +848,6 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 	return 0;
 }
 
-/**
- * dpu_plane_get_ctl_flush - get control flush for the given plane
- * @plane: Pointer to drm plane structure
- * @ctl: Pointer to hardware control driver
- * @flush_sspp: Pointer to sspp flush control word
- */
-void dpu_plane_get_ctl_flush(struct drm_plane *plane, struct dpu_hw_ctl *ctl,
-		u32 *flush_sspp)
-{
-	*flush_sspp = ctl->ops.get_bitmask_sspp(ctl, dpu_plane_pipe(plane));
-}
-
 static int dpu_plane_prepare_fb(struct drm_plane *plane,
 		struct drm_plane_state *new_state)
 {
@@ -940,8 +928,86 @@ static bool dpu_plane_validate_src(struct drm_rect *src,
 		drm_rect_equals(fb_rect, src);
 }
 
+int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate)
+{
+	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_global_state *global_state = dpu_kms_get_global_state(pstate->base.state);
+	enum dpu_sspp pipe;
+	bool yuv, scale;
+
+	if (pdpu->pipe != SSPP_NONE) {
+		pipe = pdpu->pipe;
+		goto out;
+	}
+
+	yuv = pstate->base.fb ? DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(pstate->base.fb))) : false;
+	scale = (pstate->base.src_w >> 16 != pstate->base.crtc_w) ||
+		(pstate->base.src_h >> 16 != pstate->base.crtc_h);
+
+	pipe = dpu_rm_get_sspp(&kms->rm, global_state, plane->base.id, yuv, scale);
+
+	DRM_DEBUG_ATOMIC("PLANE %d got SSPP %d\n", plane->base.id, pipe);
+
+out:
+	if (pipe == SSPP_NONE || pipe >= SSPP_MAX || !kms->rm.sspp_blks[pipe - SSPP_NONE])
+		return -EINVAL;
+
+	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
+
+	return 0;
+}
+
 static int dpu_plane_atomic_check(struct drm_plane *plane,
 				  struct drm_atomic_state *state)
+{
+	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
+										 plane);
+	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
+	struct dpu_global_state *global_state = dpu_kms_get_global_state(state);
+
+	if (!new_plane_state->fb)
+		new_plane_state->visible = false;
+
+	/*
+	 * Free unused pipes during atomic_check. They might be picked up
+	 * later, during pipes reallocation. The real checks will be executed
+	 * later, from dpu_plane_real_atomic_check() called from
+	 * dpu_crtc_atomic_check when the pipes are allocated.
+	 */
+	if (!new_plane_state->visible &&
+	    pstate->pipe_hw != NULL) {
+		/*
+		 * If the pipe was statically allocated during dpu_plane_init, do not
+		 * touch dpu_rm here.
+		 */
+		if (pdpu->pipe != SSPP_NONE)
+			return 0;
+
+		DRM_DEBUG_ATOMIC("PLANE %d released SSPP %d\n", plane->base.id, pstate->pipe_hw->idx);
+		dpu_rm_release_sspp(&dpu_kms->rm, global_state, plane->base.id);
+		pstate->pipe_hw = NULL;
+	}
+
+	return 0;
+}
+
+static bool dpu_plane_check_sspp_format(struct dpu_hw_pipe *pipe_hw, u32 format)
+{
+	int i;
+
+	for (i = 0; i < pipe_hw->cap->sblk->num_formats; i++) {
+		if (format == pipe_hw->cap->sblk->format_list[i])
+			return true;
+	}
+
+	return false;
+}
+
+int dpu_plane_real_atomic_check(struct drm_plane *plane,
+				struct drm_atomic_state *state)
 {
 	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
 										 plane);
@@ -969,6 +1035,13 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	if (!new_plane_state->visible)
 		return 0;
 
+	if (!dpu_plane_check_sspp_format(pstate->pipe_hw, new_plane_state->fb->format->format)) {
+		DPU_ERROR("Format %p4cc not supported by the selected SSPP %d\n",
+				&new_plane_state->fb->format->format, pstate->pipe_hw->idx);
+
+		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);
@@ -1205,6 +1278,8 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
 				pstate->multirect_mode);
 
 	pstate->pending = true;
+
+	pstate->pipe_hw = NULL;
 }
 
 static void dpu_plane_atomic_update(struct drm_plane *plane,
@@ -1286,7 +1361,6 @@ static void dpu_plane_reset(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu;
 	struct dpu_plane_state *pstate;
-	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
 
 	if (!plane) {
 		DPU_ERROR("invalid plane\n");
@@ -1308,8 +1382,6 @@ static void dpu_plane_reset(struct drm_plane *plane)
 		return;
 	}
 
-	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
-
 	pstate->base.plane = plane;
 
 	plane->state = &pstate->base;
@@ -1364,11 +1436,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,
@@ -1379,7 +1446,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	struct dpu_plane *pdpu;
 	struct msm_drm_private *priv = dev->dev_private;
 	struct dpu_kms *kms = to_dpu_kms(priv->kms);
-	struct dpu_hw_pipe *pipe_hw;
 	uint32_t num_formats;
 	int ret = -EINVAL;
 
@@ -1395,19 +1461,22 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	plane = &pdpu->base;
 	pdpu->pipe = pipe;
 
-	/* initialize underlying h/w driver */
-	if (!kms->rm.sspp_blks[pipe - SSPP_NONE])
-		goto clean_plane;
-	pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
-
-	if (!pipe_hw->cap || !pipe_hw->cap->sblk) {
-		DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
-		goto clean_plane;
+	if (pdpu->pipe == SSPP_NONE) {
+		format_list = kms->catalog->caps->format_list;
+		num_formats = kms->catalog->caps->num_formats;
+	} else if (pdpu->pipe < SSPP_MAX) {
+		struct dpu_hw_pipe *pipe_hw;
+
+		if (!kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE])
+			return ERR_PTR(-EINVAL);
+		pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
+		format_list = pipe_hw->cap->sblk->format_list;
+		num_formats = pipe_hw->cap->sblk->num_formats;
+	} else {
+		return ERR_PTR(-EINVAL);
 	}
 
-	format_list = pipe_hw->cap->sblk->format_list;
-	num_formats = pipe_hw->cap->sblk->num_formats;
-
+	/* initialize underlying h/w driver */
 	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
 				format_list, num_formats,
 				supported_format_modifiers, type, NULL);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 42b88b6bc9c2..0940ffbb8b28 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -54,22 +54,6 @@ struct dpu_multirect_plane_states {
 #define to_dpu_plane_state(x) \
 	container_of(x, struct dpu_plane_state, base)
 
-/**
- * dpu_plane_pipe - return sspp identifier for the given plane
- * @plane:   Pointer to DRM plane object
- * Returns: sspp identifier of the given plane
- */
-enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
-
-/**
- * dpu_plane_get_ctl_flush - get control flush mask
- * @plane:   Pointer to DRM plane object
- * @ctl: Pointer to control hardware
- * @flush_sspp: Pointer to sspp flush control word
- */
-void dpu_plane_get_ctl_flush(struct drm_plane *plane, struct dpu_hw_ctl *ctl,
-		u32 *flush_sspp);
-
 /**
  * dpu_plane_flush - final plane operations before commit flush
  * @plane: Pointer to drm plane structure
@@ -123,4 +107,9 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable);
 static inline void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) {}
 #endif
 
+int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate);
+
+int dpu_plane_real_atomic_check(struct drm_plane *plane,
+				struct drm_atomic_state *state);
+
 #endif /* _DPU_PLANE_H_ */
-- 
2.30.2


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

* [PATCH v2 19/22] drm/msm/dpu: add support for virtualized planes
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

Add support for registering unified (virtualized) planes, allowing SSPP
block to be allocated at runtime, during atomic_check. This allows
userspace app to use any plane without caring if it supports scaler or
YUV formats. All planes are marked as supporting all formats and scaler
options. The kernel space will select the appropriate SSPP pipe or
return an error if we run out of resources.

Virtual planes are disabled by default, use msm.dpu_use_virtual_planes=1
kernel parameter to enable them.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c  | 115 ++++++++++++-------
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c   | 109 ++++++++++++++----
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 133 ++++++++++++++++------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  21 +---
 4 files changed, 272 insertions(+), 106 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index f311cdbfe7d2..49bdd5953b9f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -206,6 +206,7 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	int zpos_cnt[DPU_STAGE_MAX + 1] = { 0 };
 	bool bg_alpha_enable = false;
 	DECLARE_BITMAP(fetch_active, SSPP_MAX);
+	enum dpu_sspp pipe;
 
 	memset(fetch_active, 0, sizeof(fetch_active));
 	drm_atomic_crtc_for_each_plane(plane, crtc) {
@@ -216,14 +217,19 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		pstate = to_dpu_plane_state(state);
 		fb = state->fb;
 
-		dpu_plane_get_ctl_flush(plane, ctl, &flush_mask);
-		set_bit(dpu_plane_pipe(plane), fetch_active);
+		if (WARN_ON(!pstate->pipe_hw))
+			continue;
+
+		pipe = pstate->pipe_hw->idx;
+
+		flush_mask = ctl->ops.get_bitmask_sspp(ctl, pipe);
+		set_bit(pipe, fetch_active);
 
 		DRM_DEBUG_ATOMIC("crtc %d stage:%d - plane %d sspp %d fb %d\n",
 				crtc->base.id,
 				pstate->stage,
 				plane->base.id,
-				dpu_plane_pipe(plane) - SSPP_VIG0,
+				pipe - SSPP_VIG0,
 				state->fb ? state->fb->base.id : -1);
 
 		format = to_dpu_format(msm_framebuffer_format(pstate->base.fb));
@@ -233,13 +239,13 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 
 		stage_idx = zpos_cnt[pstate->stage]++;
 		stage_cfg->stage[pstate->stage][stage_idx] =
-					dpu_plane_pipe(plane);
+					pipe;
 		stage_cfg->multirect_index[pstate->stage][stage_idx] =
 					pstate->multirect_index;
 
 		trace_dpu_crtc_setup_mixer(DRMID(crtc), DRMID(plane),
 					   state, pstate, stage_idx,
-					   dpu_plane_pipe(plane) - SSPP_VIG0,
+					   pipe - SSPP_VIG0,
 					   format->base.pixel_format,
 					   fb ? fb->modifier : 0);
 
@@ -875,13 +881,6 @@ static void dpu_crtc_enable(struct drm_crtc *crtc,
 	drm_crtc_vblank_on(crtc);
 }
 
-struct plane_state {
-	struct dpu_plane_state *dpu_pstate;
-	const struct drm_plane_state *drm_pstate;
-	int stage;
-	u32 pipe_id;
-};
-
 static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		struct drm_atomic_state *state)
 {
@@ -889,17 +888,25 @@ 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;
+	struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc);
+	struct dpu_global_state *global_state = dpu_kms_get_global_state(state);
+
+	struct dpu_plane_state **pstates;
+	struct dpu_plane_state *pstate;
 
-	const struct drm_plane_state *pstate;
+	struct drm_plane_state *plane_state;
 	struct drm_plane *plane;
 	struct drm_display_mode *mode;
 
-	int cnt = 0, rc = 0, i;
+	int rc = 0, i;
+	unsigned int num_planes, max_zpos = 0;
 
+	struct drm_rect dst;
 	struct drm_rect crtc_rect = { 0 };
+	int stage;
 
-	pstates = kzalloc(sizeof(*pstates) * DPU_STAGE_MAX * 4, GFP_KERNEL);
+	num_planes = DPU_STAGE_MAX * 4;
+	pstates = kcalloc(num_planes, sizeof(*pstates), GFP_KERNEL);
 
 	if (!crtc_state->enable || !crtc_state->active) {
 		DRM_DEBUG_ATOMIC("crtc%d -> enable %d, active %d, skip atomic_check\n",
@@ -923,28 +930,57 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	crtc_rect.y2 = mode->vdisplay;
 
 	 /* get plane state for all drm planes associated with crtc state */
-	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) {
-		struct drm_rect dst, clip = crtc_rect;
-
-		if (IS_ERR_OR_NULL(pstate)) {
-			rc = PTR_ERR(pstate);
+	drm_atomic_crtc_state_for_each_plane(plane, crtc_state) {
+		plane_state = drm_atomic_get_plane_state(state, plane);
+		if (IS_ERR(plane_state)) {
+			rc = PTR_ERR(plane_state);
 			DPU_ERROR("%s: failed to get plane%d state, %d\n",
 					dpu_crtc->name, plane->base.id, rc);
 			goto end;
 		}
-		if (cnt >= DPU_STAGE_MAX * 4)
+
+		if (plane_state->normalized_zpos >= num_planes) {
+			DPU_ERROR("%s: normalized zpos is too big for plane %d: %d\n",
+					dpu_crtc->name, plane->base.id, plane_state->normalized_zpos);
+			rc = -EINVAL;
+			goto end;
+		}
+
+		pstate = to_dpu_plane_state(plane_state);
+		pstates[plane_state->normalized_zpos] = pstate;
+		max_zpos = max(max_zpos, plane_state->normalized_zpos);
+
+		/* Here we are going to release SSPP blocks and acquire them later in dpu_plane_set_pipe.
+		 *
+		 * TODO: optimize to that we do not reacquire SSPPs if none of
+		 * the plane modes/formats/etc were changed, no planes added or removed.
+		 */
+		if (pstate->pipe_hw) {
+			dpu_rm_release_sspp(&dpu_kms->rm, global_state, plane->base.id);
+			pstate->pipe_hw = NULL;
+		}
+	}
+
+	stage = DPU_STAGE_0;
+	for (i = 0; i <= max_zpos; i++) {
+		pstate = pstates[i];
+		if (!pstate)
 			continue;
 
-		pstates[cnt].dpu_pstate = to_dpu_plane_state(pstate);
-		pstates[cnt].drm_pstate = pstate;
-		pstates[cnt].stage = pstate->normalized_zpos;
+		/* verify stage setting before using it */
+		if (stage >= DPU_STAGE_MAX) {
+			DPU_ERROR("> %d plane stages assigned\n",
+					DPU_STAGE_MAX - DPU_STAGE_0);
+			rc = -EINVAL;
+			goto end;
+		}
 
-		dpu_plane_clear_multirect(pstate);
+		plane_state = &pstate->base;
 
-		cnt++;
+		dpu_plane_clear_multirect(plane_state);
 
-		dst = drm_plane_state_dest(pstate);
-		if (!drm_rect_intersect(&clip, &dst)) {
+		dst = drm_plane_state_dest(plane_state);
+		if (!drm_rect_intersect(&dst, &crtc_rect)) {
 			DPU_ERROR("invalid vertical/horizontal destination\n");
 			DPU_ERROR("display: " DRM_RECT_FMT " plane: "
 				  DRM_RECT_FMT "\n", DRM_RECT_ARG(&crtc_rect),
@@ -952,21 +988,22 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 			rc = -E2BIG;
 			goto end;
 		}
-	}
 
-	for (i = 0; i < cnt; i++) {
-		int z_pos = pstates[i].stage;
+		plane = pstate->base.plane;
+		rc = dpu_plane_set_pipe(plane, pstate);
+		if (rc) {
+			DPU_ERROR("%s: error setting pipe for %s\n", dpu_crtc->name, plane->name);
+			goto end;
+		}
 
-		/* 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;
+		rc = dpu_plane_real_atomic_check(plane, state);
+		if (rc) {
+			DPU_ERROR("%s: error checking pipe for %s\n", dpu_crtc->name, plane->name);
 			goto end;
 		}
 
-		pstates[i].dpu_pstate->stage = z_pos + DPU_STAGE_0;
-		DRM_DEBUG_ATOMIC("%s: zpos %d\n", dpu_crtc->name, z_pos);
+		pstates[i]->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_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 66a1c8889cf3..08a7e56cc98f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -47,6 +47,9 @@
 
 #define MIN_IB_BW	400000000ULL /* Min ib vote 400MB */
 
+static bool dpu_use_virtual_planes = false;
+module_param(dpu_use_virtual_planes, bool, 0);
+
 static int dpu_kms_hw_init(struct msm_kms *kms);
 static void _dpu_kms_mmu_destroy(struct dpu_kms *dpu_kms);
 
@@ -581,32 +584,20 @@ static void _dpu_kms_drm_obj_destroy(struct dpu_kms *dpu_kms)
 	priv->num_encoders = 0;
 }
 
-static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
+static int _dpu_kms_create_planes(struct dpu_kms *dpu_kms, int max_crtc_count, struct drm_plane **primary_planes, struct drm_plane **cursor_planes)
 {
 	struct drm_device *dev;
-	struct drm_plane *primary_planes[MAX_PLANES], *plane;
-	struct drm_plane *cursor_planes[MAX_PLANES] = { NULL };
-	struct drm_crtc *crtc;
+	struct drm_plane *plane;
 
 	struct msm_drm_private *priv;
 	struct dpu_mdss_cfg *catalog;
 
-	int primary_planes_idx = 0, cursor_planes_idx = 0, i, ret;
-	int max_crtc_count;
+	int primary_planes_idx = 0, cursor_planes_idx = 0, i;
+
 	dev = dpu_kms->dev;
 	priv = dev->dev_private;
 	catalog = dpu_kms->catalog;
 
-	/*
-	 * Create encoder and query display drivers to create
-	 * bridges and connectors
-	 */
-	ret = _dpu_kms_setup_displays(dev, priv, dpu_kms);
-	if (ret)
-		goto fail;
-
-	max_crtc_count = min(catalog->mixer_count, priv->num_encoders);
-
 	/* Create the planes, keeping track of one primary/cursor per crtc */
 	for (i = 0; i < catalog->sspp_count; i++) {
 		enum drm_plane_type type;
@@ -627,8 +618,51 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
 				       (1UL << max_crtc_count) - 1);
 		if (IS_ERR(plane)) {
 			DPU_ERROR("dpu_plane_init failed\n");
-			ret = PTR_ERR(plane);
-			goto fail;
+			return PTR_ERR(plane);
+		}
+		priv->planes[priv->num_planes++] = plane;
+
+		if (type == DRM_PLANE_TYPE_CURSOR)
+			cursor_planes[cursor_planes_idx++] = plane;
+		else if (type == DRM_PLANE_TYPE_PRIMARY)
+			primary_planes[primary_planes_idx++] = plane;
+	}
+
+	return 0;
+}
+
+static int _dpu_kms_create_planes_virtual(struct dpu_kms *dpu_kms, int max_crtc_count, struct drm_plane **primary_planes, struct drm_plane **cursor_planes)
+{
+	struct drm_device *dev;
+	struct drm_plane *plane;
+
+	struct msm_drm_private *priv;
+	struct dpu_mdss_cfg *catalog;
+
+	int primary_planes_idx = 0, cursor_planes_idx = 0, i;
+
+	dev = dpu_kms->dev;
+	priv = dev->dev_private;
+	catalog = dpu_kms->catalog;
+
+	/* Create the planes, keeping track of one primary/cursor per crtc */
+	for (i = 0; i < catalog->sspp_count; i++) {
+		enum drm_plane_type type;
+
+		if (primary_planes_idx < max_crtc_count)
+			type = DRM_PLANE_TYPE_PRIMARY;
+		else if (cursor_planes_idx < max_crtc_count)
+			type = DRM_PLANE_TYPE_CURSOR;
+		else
+			type = DRM_PLANE_TYPE_OVERLAY;
+
+		DPU_DEBUG("Create virtual plane type %d \n", type);
+
+		plane = dpu_plane_init(dev, SSPP_NONE, type,
+				       (1UL << max_crtc_count) - 1);
+		if (IS_ERR(plane)) {
+			DPU_ERROR("dpu_plane_init failed\n");
+			return PTR_ERR(plane);
 		}
 		priv->planes[priv->num_planes++] = plane;
 
@@ -638,10 +672,47 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
 			primary_planes[primary_planes_idx++] = plane;
 	}
 
-	max_crtc_count = min(max_crtc_count, primary_planes_idx);
+	return 0;
+}
+
+static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
+{
+	struct drm_device *dev;
+	struct drm_plane *primary_planes[MAX_PLANES] = { NULL };
+	struct drm_plane *cursor_planes[MAX_PLANES] = { NULL };
+	struct drm_crtc *crtc;
+
+	struct msm_drm_private *priv;
+	struct dpu_mdss_cfg *catalog;
+
+	int i, ret;
+	int max_crtc_count;
+	dev = dpu_kms->dev;
+	priv = dev->dev_private;
+	catalog = dpu_kms->catalog;
+
+	/*
+	 * Create encoder and query display drivers to create
+	 * bridges and connectors
+	 */
+	ret = _dpu_kms_setup_displays(dev, priv, dpu_kms);
+	if (ret)
+		goto fail;
+
+	max_crtc_count = min(catalog->mixer_count, priv->num_encoders);
+
+	if (dpu_use_virtual_planes)
+		ret = _dpu_kms_create_planes_virtual(dpu_kms, max_crtc_count, primary_planes, cursor_planes);
+	else
+		ret = _dpu_kms_create_planes(dpu_kms, max_crtc_count, primary_planes, cursor_planes);
+	if (ret)
+		goto fail;
 
 	/* Create one CRTC per encoder */
 	for (i = 0; i < max_crtc_count; i++) {
+		if (!primary_planes[i])
+			break;
+
 		crtc = dpu_crtc_init(dev, primary_planes[i], cursor_planes[i]);
 		if (IS_ERR(crtc)) {
 			ret = PTR_ERR(crtc);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index a6de7f3ae2d8..d692136884ad 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -848,18 +848,6 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 	return 0;
 }
 
-/**
- * dpu_plane_get_ctl_flush - get control flush for the given plane
- * @plane: Pointer to drm plane structure
- * @ctl: Pointer to hardware control driver
- * @flush_sspp: Pointer to sspp flush control word
- */
-void dpu_plane_get_ctl_flush(struct drm_plane *plane, struct dpu_hw_ctl *ctl,
-		u32 *flush_sspp)
-{
-	*flush_sspp = ctl->ops.get_bitmask_sspp(ctl, dpu_plane_pipe(plane));
-}
-
 static int dpu_plane_prepare_fb(struct drm_plane *plane,
 		struct drm_plane_state *new_state)
 {
@@ -940,8 +928,86 @@ static bool dpu_plane_validate_src(struct drm_rect *src,
 		drm_rect_equals(fb_rect, src);
 }
 
+int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate)
+{
+	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_global_state *global_state = dpu_kms_get_global_state(pstate->base.state);
+	enum dpu_sspp pipe;
+	bool yuv, scale;
+
+	if (pdpu->pipe != SSPP_NONE) {
+		pipe = pdpu->pipe;
+		goto out;
+	}
+
+	yuv = pstate->base.fb ? DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(pstate->base.fb))) : false;
+	scale = (pstate->base.src_w >> 16 != pstate->base.crtc_w) ||
+		(pstate->base.src_h >> 16 != pstate->base.crtc_h);
+
+	pipe = dpu_rm_get_sspp(&kms->rm, global_state, plane->base.id, yuv, scale);
+
+	DRM_DEBUG_ATOMIC("PLANE %d got SSPP %d\n", plane->base.id, pipe);
+
+out:
+	if (pipe == SSPP_NONE || pipe >= SSPP_MAX || !kms->rm.sspp_blks[pipe - SSPP_NONE])
+		return -EINVAL;
+
+	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
+
+	return 0;
+}
+
 static int dpu_plane_atomic_check(struct drm_plane *plane,
 				  struct drm_atomic_state *state)
+{
+	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
+										 plane);
+	struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane);
+	struct dpu_plane *pdpu = to_dpu_plane(plane);
+	struct dpu_plane_state *pstate = to_dpu_plane_state(new_plane_state);
+	struct dpu_global_state *global_state = dpu_kms_get_global_state(state);
+
+	if (!new_plane_state->fb)
+		new_plane_state->visible = false;
+
+	/*
+	 * Free unused pipes during atomic_check. They might be picked up
+	 * later, during pipes reallocation. The real checks will be executed
+	 * later, from dpu_plane_real_atomic_check() called from
+	 * dpu_crtc_atomic_check when the pipes are allocated.
+	 */
+	if (!new_plane_state->visible &&
+	    pstate->pipe_hw != NULL) {
+		/*
+		 * If the pipe was statically allocated during dpu_plane_init, do not
+		 * touch dpu_rm here.
+		 */
+		if (pdpu->pipe != SSPP_NONE)
+			return 0;
+
+		DRM_DEBUG_ATOMIC("PLANE %d released SSPP %d\n", plane->base.id, pstate->pipe_hw->idx);
+		dpu_rm_release_sspp(&dpu_kms->rm, global_state, plane->base.id);
+		pstate->pipe_hw = NULL;
+	}
+
+	return 0;
+}
+
+static bool dpu_plane_check_sspp_format(struct dpu_hw_pipe *pipe_hw, u32 format)
+{
+	int i;
+
+	for (i = 0; i < pipe_hw->cap->sblk->num_formats; i++) {
+		if (format == pipe_hw->cap->sblk->format_list[i])
+			return true;
+	}
+
+	return false;
+}
+
+int dpu_plane_real_atomic_check(struct drm_plane *plane,
+				struct drm_atomic_state *state)
 {
 	struct drm_plane_state *new_plane_state = drm_atomic_get_new_plane_state(state,
 										 plane);
@@ -969,6 +1035,13 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 	if (!new_plane_state->visible)
 		return 0;
 
+	if (!dpu_plane_check_sspp_format(pstate->pipe_hw, new_plane_state->fb->format->format)) {
+		DPU_ERROR("Format %p4cc not supported by the selected SSPP %d\n",
+				&new_plane_state->fb->format->format, pstate->pipe_hw->idx);
+
+		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);
@@ -1205,6 +1278,8 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
 				pstate->multirect_mode);
 
 	pstate->pending = true;
+
+	pstate->pipe_hw = NULL;
 }
 
 static void dpu_plane_atomic_update(struct drm_plane *plane,
@@ -1286,7 +1361,6 @@ static void dpu_plane_reset(struct drm_plane *plane)
 {
 	struct dpu_plane *pdpu;
 	struct dpu_plane_state *pstate;
-	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
 
 	if (!plane) {
 		DPU_ERROR("invalid plane\n");
@@ -1308,8 +1382,6 @@ static void dpu_plane_reset(struct drm_plane *plane)
 		return;
 	}
 
-	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
-
 	pstate->base.plane = plane;
 
 	plane->state = &pstate->base;
@@ -1364,11 +1436,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,
@@ -1379,7 +1446,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	struct dpu_plane *pdpu;
 	struct msm_drm_private *priv = dev->dev_private;
 	struct dpu_kms *kms = to_dpu_kms(priv->kms);
-	struct dpu_hw_pipe *pipe_hw;
 	uint32_t num_formats;
 	int ret = -EINVAL;
 
@@ -1395,19 +1461,22 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 	plane = &pdpu->base;
 	pdpu->pipe = pipe;
 
-	/* initialize underlying h/w driver */
-	if (!kms->rm.sspp_blks[pipe - SSPP_NONE])
-		goto clean_plane;
-	pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
-
-	if (!pipe_hw->cap || !pipe_hw->cap->sblk) {
-		DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
-		goto clean_plane;
+	if (pdpu->pipe == SSPP_NONE) {
+		format_list = kms->catalog->caps->format_list;
+		num_formats = kms->catalog->caps->num_formats;
+	} else if (pdpu->pipe < SSPP_MAX) {
+		struct dpu_hw_pipe *pipe_hw;
+
+		if (!kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE])
+			return ERR_PTR(-EINVAL);
+		pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pdpu->pipe - SSPP_NONE]);
+		format_list = pipe_hw->cap->sblk->format_list;
+		num_formats = pipe_hw->cap->sblk->num_formats;
+	} else {
+		return ERR_PTR(-EINVAL);
 	}
 
-	format_list = pipe_hw->cap->sblk->format_list;
-	num_formats = pipe_hw->cap->sblk->num_formats;
-
+	/* initialize underlying h/w driver */
 	ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
 				format_list, num_formats,
 				supported_format_modifiers, type, NULL);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
index 42b88b6bc9c2..0940ffbb8b28 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -54,22 +54,6 @@ struct dpu_multirect_plane_states {
 #define to_dpu_plane_state(x) \
 	container_of(x, struct dpu_plane_state, base)
 
-/**
- * dpu_plane_pipe - return sspp identifier for the given plane
- * @plane:   Pointer to DRM plane object
- * Returns: sspp identifier of the given plane
- */
-enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane);
-
-/**
- * dpu_plane_get_ctl_flush - get control flush mask
- * @plane:   Pointer to DRM plane object
- * @ctl: Pointer to control hardware
- * @flush_sspp: Pointer to sspp flush control word
- */
-void dpu_plane_get_ctl_flush(struct drm_plane *plane, struct dpu_hw_ctl *ctl,
-		u32 *flush_sspp);
-
 /**
  * dpu_plane_flush - final plane operations before commit flush
  * @plane: Pointer to drm plane structure
@@ -123,4 +107,9 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable);
 static inline void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) {}
 #endif
 
+int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate);
+
+int dpu_plane_real_atomic_check(struct drm_plane *plane,
+				struct drm_atomic_state *state);
+
 #endif /* _DPU_PLANE_H_ */
-- 
2.30.2


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

* [PATCH v2 20/22] drm/msm/dpu: fix smart dma support
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Downstream driver uses dpu->caps->smart_dma_rev to update
sspp->cap->features with the bit corresponding to the supported SmartDMA
version. Upstream driver does not do this, resulting in SSPP subdriver
not enbaling setup_multirect callback. Make SSPP subdriver check global
smart_dma_rev to decide if setup_multirect should be enabled.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +++++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 16 ++++++++++++----
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c    |  9 +++++----
 3 files changed, 22 insertions(+), 13 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 b8e0fece1f0b..d2321648b8d2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -185,7 +185,7 @@ static const struct dpu_caps sdm845_dpu_caps = {
 	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 	.max_mixer_blendstages = 0xb,
 	.qseed_type = DPU_SSPP_SCALER_QSEED3,
-	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
+	.smart_dma_rev = DPU_SMART_DMA_V2,
 	.ubwc_version = DPU_HW_UBWC_VER_20,
 	.has_src_split = true,
 	.has_dim_layer = true,
@@ -203,7 +203,7 @@ static const struct dpu_caps sc7180_dpu_caps = {
 	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 	.max_mixer_blendstages = 0x9,
 	.qseed_type = DPU_SSPP_SCALER_QSEED4,
-	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
+	.smart_dma_rev = DPU_SMART_DMA_V2,
 	.ubwc_version = DPU_HW_UBWC_VER_20,
 	.has_dim_layer = true,
 	.has_idle_pc = true,
@@ -217,7 +217,7 @@ static const struct dpu_caps sm8150_dpu_caps = {
 	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 	.max_mixer_blendstages = 0xb,
 	.qseed_type = DPU_SSPP_SCALER_QSEED3,
-	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+	.smart_dma_rev = DPU_SMART_DMA_V2, /* TODO: v2.5 */
 	.ubwc_version = DPU_HW_UBWC_VER_30,
 	.has_src_split = true,
 	.has_dim_layer = true,
@@ -235,7 +235,7 @@ static const struct dpu_caps sm8250_dpu_caps = {
 	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 	.max_mixer_blendstages = 0xb,
 	.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
-	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+	.smart_dma_rev = DPU_SMART_DMA_V2, /* TODO: v2.5 */
 	.ubwc_version = DPU_HW_UBWC_VER_40,
 	.has_src_split = true,
 	.has_dim_layer = true,
@@ -251,7 +251,7 @@ 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,
+	.smart_dma_rev = DPU_SMART_DMA_V2,
 	.ubwc_version = DPU_HW_UBWC_VER_30,
 	.has_dim_layer = true,
 	.has_idle_pc = true,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index f3c5aa3f4b3f..66d7b43c0019 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -70,6 +70,18 @@ enum {
 	DPU_HW_UBWC_VER_40 = 0x400,
 };
 
+/**
+ * SmartDMA support
+ * @DPU_SMART_DMA_UNSUPPORTED,   SmartDMA not support
+ * @DPU_SMART_DMA_V1,   SmartDMA 1.0 support
+ * @DPU_SMART_DMA_V2,   SmartDMA 2.0 support
+ */
+enum {
+	DPU_SMART_DMA_UNSUPPORTED,
+	DPU_SMART_DMA_V1,
+	DPU_SMART_DMA_V2,
+};
+
 /**
  * MDP TOP BLOCK features
  * @DPU_MDP_PANIC_PER_PIPE Panic configuration needs to be be done per pipe
@@ -104,8 +116,6 @@ enum {
  * @DPU_SSPP_QOS,            SSPP support QoS control, danger/safe/creq
  * @DPU_SSPP_QOS_8LVL,       SSPP support 8-level QoS control
  * @DPU_SSPP_EXCL_RECT,      SSPP supports exclusion rect
- * @DPU_SSPP_SMART_DMA_V1,   SmartDMA 1.0 support
- * @DPU_SSPP_SMART_DMA_V2,   SmartDMA 2.0 support
  * @DPU_SSPP_TS_PREFILL      Supports prefill with traffic shaper
  * @DPU_SSPP_TS_PREFILL_REC1 Supports prefill with traffic shaper multirec
  * @DPU_SSPP_CDP             Supports client driven prefetch
@@ -124,8 +134,6 @@ enum {
 	DPU_SSPP_QOS,
 	DPU_SSPP_QOS_8LVL,
 	DPU_SSPP_EXCL_RECT,
-	DPU_SSPP_SMART_DMA_V1,
-	DPU_SSPP_SMART_DMA_V2,
 	DPU_SSPP_TS_PREFILL,
 	DPU_SSPP_TS_PREFILL_REC1,
 	DPU_SSPP_CDP,
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 2be43d5a235a..f93cdeb08ac7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -648,7 +648,8 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
 }
 
 static void _setup_layer_ops(struct dpu_hw_pipe *c,
-		unsigned long features)
+		unsigned long features,
+		int smart_dma_rev)
 {
 	if (test_bit(DPU_SSPP_SRC, &features)) {
 		c->ops.setup_format = dpu_hw_sspp_setup_format;
@@ -669,8 +670,8 @@ static void _setup_layer_ops(struct dpu_hw_pipe *c,
 		test_bit(DPU_SSPP_CSC_10BIT, &features))
 		c->ops.setup_csc = dpu_hw_sspp_setup_csc;
 
-	if (test_bit(DPU_SSPP_SMART_DMA_V1, &c->cap->features) ||
-		test_bit(DPU_SSPP_SMART_DMA_V2, &c->cap->features))
+	if (smart_dma_rev == DPU_SMART_DMA_V1 ||
+	    smart_dma_rev == DPU_SMART_DMA_V2)
 		c->ops.setup_multirect = dpu_hw_sspp_setup_multirect;
 
 	if (test_bit(DPU_SSPP_SCALER_QSEED3, &features) ||
@@ -731,7 +732,7 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
 	hw_pipe->mdp = &catalog->mdp[0];
 	hw_pipe->idx = idx;
 	hw_pipe->cap = cfg;
-	_setup_layer_ops(hw_pipe, hw_pipe->cap->features);
+	_setup_layer_ops(hw_pipe, hw_pipe->cap->features, catalog->caps->smart_dma_rev);
 
 	return hw_pipe;
 }
-- 
2.30.2


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

* [PATCH v2 20/22] drm/msm/dpu: fix smart dma support
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, 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. Make SSPP subdriver check global
smart_dma_rev to decide if setup_multirect should be enabled.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +++++-----
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 16 ++++++++++++----
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c    |  9 +++++----
 3 files changed, 22 insertions(+), 13 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 b8e0fece1f0b..d2321648b8d2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -185,7 +185,7 @@ static const struct dpu_caps sdm845_dpu_caps = {
 	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 	.max_mixer_blendstages = 0xb,
 	.qseed_type = DPU_SSPP_SCALER_QSEED3,
-	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
+	.smart_dma_rev = DPU_SMART_DMA_V2,
 	.ubwc_version = DPU_HW_UBWC_VER_20,
 	.has_src_split = true,
 	.has_dim_layer = true,
@@ -203,7 +203,7 @@ static const struct dpu_caps sc7180_dpu_caps = {
 	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 	.max_mixer_blendstages = 0x9,
 	.qseed_type = DPU_SSPP_SCALER_QSEED4,
-	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
+	.smart_dma_rev = DPU_SMART_DMA_V2,
 	.ubwc_version = DPU_HW_UBWC_VER_20,
 	.has_dim_layer = true,
 	.has_idle_pc = true,
@@ -217,7 +217,7 @@ static const struct dpu_caps sm8150_dpu_caps = {
 	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 	.max_mixer_blendstages = 0xb,
 	.qseed_type = DPU_SSPP_SCALER_QSEED3,
-	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+	.smart_dma_rev = DPU_SMART_DMA_V2, /* TODO: v2.5 */
 	.ubwc_version = DPU_HW_UBWC_VER_30,
 	.has_src_split = true,
 	.has_dim_layer = true,
@@ -235,7 +235,7 @@ static const struct dpu_caps sm8250_dpu_caps = {
 	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
 	.max_mixer_blendstages = 0xb,
 	.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
-	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
+	.smart_dma_rev = DPU_SMART_DMA_V2, /* TODO: v2.5 */
 	.ubwc_version = DPU_HW_UBWC_VER_40,
 	.has_src_split = true,
 	.has_dim_layer = true,
@@ -251,7 +251,7 @@ 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,
+	.smart_dma_rev = DPU_SMART_DMA_V2,
 	.ubwc_version = DPU_HW_UBWC_VER_30,
 	.has_dim_layer = true,
 	.has_idle_pc = true,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
index f3c5aa3f4b3f..66d7b43c0019 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -70,6 +70,18 @@ enum {
 	DPU_HW_UBWC_VER_40 = 0x400,
 };
 
+/**
+ * SmartDMA support
+ * @DPU_SMART_DMA_UNSUPPORTED,   SmartDMA not support
+ * @DPU_SMART_DMA_V1,   SmartDMA 1.0 support
+ * @DPU_SMART_DMA_V2,   SmartDMA 2.0 support
+ */
+enum {
+	DPU_SMART_DMA_UNSUPPORTED,
+	DPU_SMART_DMA_V1,
+	DPU_SMART_DMA_V2,
+};
+
 /**
  * MDP TOP BLOCK features
  * @DPU_MDP_PANIC_PER_PIPE Panic configuration needs to be be done per pipe
@@ -104,8 +116,6 @@ enum {
  * @DPU_SSPP_QOS,            SSPP support QoS control, danger/safe/creq
  * @DPU_SSPP_QOS_8LVL,       SSPP support 8-level QoS control
  * @DPU_SSPP_EXCL_RECT,      SSPP supports exclusion rect
- * @DPU_SSPP_SMART_DMA_V1,   SmartDMA 1.0 support
- * @DPU_SSPP_SMART_DMA_V2,   SmartDMA 2.0 support
  * @DPU_SSPP_TS_PREFILL      Supports prefill with traffic shaper
  * @DPU_SSPP_TS_PREFILL_REC1 Supports prefill with traffic shaper multirec
  * @DPU_SSPP_CDP             Supports client driven prefetch
@@ -124,8 +134,6 @@ enum {
 	DPU_SSPP_QOS,
 	DPU_SSPP_QOS_8LVL,
 	DPU_SSPP_EXCL_RECT,
-	DPU_SSPP_SMART_DMA_V1,
-	DPU_SSPP_SMART_DMA_V2,
 	DPU_SSPP_TS_PREFILL,
 	DPU_SSPP_TS_PREFILL_REC1,
 	DPU_SSPP_CDP,
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 2be43d5a235a..f93cdeb08ac7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -648,7 +648,8 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
 }
 
 static void _setup_layer_ops(struct dpu_hw_pipe *c,
-		unsigned long features)
+		unsigned long features,
+		int smart_dma_rev)
 {
 	if (test_bit(DPU_SSPP_SRC, &features)) {
 		c->ops.setup_format = dpu_hw_sspp_setup_format;
@@ -669,8 +670,8 @@ static void _setup_layer_ops(struct dpu_hw_pipe *c,
 		test_bit(DPU_SSPP_CSC_10BIT, &features))
 		c->ops.setup_csc = dpu_hw_sspp_setup_csc;
 
-	if (test_bit(DPU_SSPP_SMART_DMA_V1, &c->cap->features) ||
-		test_bit(DPU_SSPP_SMART_DMA_V2, &c->cap->features))
+	if (smart_dma_rev == DPU_SMART_DMA_V1 ||
+	    smart_dma_rev == DPU_SMART_DMA_V2)
 		c->ops.setup_multirect = dpu_hw_sspp_setup_multirect;
 
 	if (test_bit(DPU_SSPP_SCALER_QSEED3, &features) ||
@@ -731,7 +732,7 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp idx,
 	hw_pipe->mdp = &catalog->mdp[0];
 	hw_pipe->idx = idx;
 	hw_pipe->cap = cfg;
-	_setup_layer_ops(hw_pipe, hw_pipe->cap->features);
+	_setup_layer_ops(hw_pipe, hw_pipe->cap->features, catalog->caps->smart_dma_rev);
 
 	return hw_pipe;
 }
-- 
2.30.2


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

* [PATCH v2 21/22] drm/msm/dpu: fix CDP setup to account for multirect index
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

Client driven prefetch (CDP) is properly setup only for SSPP REC0
currently. Enable client driven prefetch also for SSPP REC1.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 12 ++++++++++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  4 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  2 +-
 3 files changed, 14 insertions(+), 4 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 f93cdeb08ac7..96f2f3f12f34 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -75,6 +75,7 @@
 #define SSPP_TRAFFIC_SHAPER                0x130
 #define SSPP_CDP_CNTL                      0x134
 #define SSPP_UBWC_ERROR_STATUS             0x138
+#define SSPP_CDP_CNTL_REC1                 0x13c
 #define SSPP_TRAFFIC_SHAPER_PREFILL        0x150
 #define SSPP_TRAFFIC_SHAPER_REC1_PREFILL   0x154
 #define SSPP_TRAFFIC_SHAPER_REC1           0x158
@@ -624,10 +625,12 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe *ctx,
 }
 
 static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_cdp_cfg *cfg)
+		struct dpu_hw_pipe_cdp_cfg *cfg,
+		enum dpu_sspp_multirect_index index)
 {
 	u32 idx;
 	u32 cdp_cntl = 0;
+	u32 cdp_cntl_offset = 0;
 
 	if (!ctx || !cfg)
 		return;
@@ -635,6 +638,11 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
 		return;
 
+	if (index == DPU_SSPP_RECT_SOLO || index == DPU_SSPP_RECT_0)
+		cdp_cntl_offset = SSPP_CDP_CNTL;
+	else
+		cdp_cntl_offset = SSPP_CDP_CNTL_REC1;
+
 	if (cfg->enable)
 		cdp_cntl |= BIT(0);
 	if (cfg->ubwc_meta_enable)
@@ -644,7 +652,7 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
 	if (cfg->preload_ahead == DPU_SSPP_CDP_PRELOAD_AHEAD_64)
 		cdp_cntl |= BIT(3);
 
-	DPU_REG_WRITE(&ctx->hw, SSPP_CDP_CNTL, cdp_cntl);
+	DPU_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl);
 }
 
 static void _setup_layer_ops(struct dpu_hw_pipe *c,
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 c5ac8defa073..19c5358b962c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -358,9 +358,11 @@ struct dpu_hw_sspp_ops {
 	 * setup_cdp - setup client driven prefetch
 	 * @ctx: Pointer to pipe context
 	 * @cfg: Pointer to cdp configuration
+	 * @index: rectangle index in multirect
 	 */
 	void (*setup_cdp)(struct dpu_hw_pipe *ctx,
-			struct dpu_hw_pipe_cdp_cfg *cfg);
+			struct dpu_hw_pipe_cdp_cfg *cfg,
+			enum dpu_sspp_multirect_index index);
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index d692136884ad..420cdd90e89b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1241,7 +1241,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 					DPU_FORMAT_IS_TILE(fmt);
 			cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
 
-			pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg);
+			pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg, pstate->multirect_index);
 		}
 	}
 
-- 
2.30.2


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

* [PATCH v2 21/22] drm/msm/dpu: fix CDP setup to account for multirect index
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

Client driven prefetch (CDP) is properly setup only for SSPP REC0
currently. Enable client driven prefetch also for SSPP REC1.

Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 12 ++++++++++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  4 +++-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  2 +-
 3 files changed, 14 insertions(+), 4 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 f93cdeb08ac7..96f2f3f12f34 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -75,6 +75,7 @@
 #define SSPP_TRAFFIC_SHAPER                0x130
 #define SSPP_CDP_CNTL                      0x134
 #define SSPP_UBWC_ERROR_STATUS             0x138
+#define SSPP_CDP_CNTL_REC1                 0x13c
 #define SSPP_TRAFFIC_SHAPER_PREFILL        0x150
 #define SSPP_TRAFFIC_SHAPER_REC1_PREFILL   0x154
 #define SSPP_TRAFFIC_SHAPER_REC1           0x158
@@ -624,10 +625,12 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct dpu_hw_pipe *ctx,
 }
 
 static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
-		struct dpu_hw_pipe_cdp_cfg *cfg)
+		struct dpu_hw_pipe_cdp_cfg *cfg,
+		enum dpu_sspp_multirect_index index)
 {
 	u32 idx;
 	u32 cdp_cntl = 0;
+	u32 cdp_cntl_offset = 0;
 
 	if (!ctx || !cfg)
 		return;
@@ -635,6 +638,11 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
 	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
 		return;
 
+	if (index == DPU_SSPP_RECT_SOLO || index == DPU_SSPP_RECT_0)
+		cdp_cntl_offset = SSPP_CDP_CNTL;
+	else
+		cdp_cntl_offset = SSPP_CDP_CNTL_REC1;
+
 	if (cfg->enable)
 		cdp_cntl |= BIT(0);
 	if (cfg->ubwc_meta_enable)
@@ -644,7 +652,7 @@ static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
 	if (cfg->preload_ahead == DPU_SSPP_CDP_PRELOAD_AHEAD_64)
 		cdp_cntl |= BIT(3);
 
-	DPU_REG_WRITE(&ctx->hw, SSPP_CDP_CNTL, cdp_cntl);
+	DPU_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl);
 }
 
 static void _setup_layer_ops(struct dpu_hw_pipe *c,
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 c5ac8defa073..19c5358b962c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -358,9 +358,11 @@ struct dpu_hw_sspp_ops {
 	 * setup_cdp - setup client driven prefetch
 	 * @ctx: Pointer to pipe context
 	 * @cfg: Pointer to cdp configuration
+	 * @index: rectangle index in multirect
 	 */
 	void (*setup_cdp)(struct dpu_hw_pipe *ctx,
-			struct dpu_hw_pipe_cdp_cfg *cfg);
+			struct dpu_hw_pipe_cdp_cfg *cfg,
+			enum dpu_sspp_multirect_index index);
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index d692136884ad..420cdd90e89b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -1241,7 +1241,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 					DPU_FORMAT_IS_TILE(fmt);
 			cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
 
-			pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg);
+			pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg, pstate->multirect_index);
 		}
 	}
 
-- 
2.30.2


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

* [PATCH v2 22/22] drm/msm/dpu: add multirect support
  2021-07-05  1:20 ` Dmitry Baryshkov
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, David Airlie, Daniel Vetter,
	linux-arm-msm, dri-devel, freedreno

If SmartDMA is supported by the hardware, SSPPs allow using two RGB
layers per the hardware pipe (with some additional restrictions, like no
support for scaling, etc). Register additional planes (two per the SSPP)
and check if we can use multirect during 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_kms.c   |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 109 +++++++++++++---------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  29 +-----
 4 files changed, 86 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 49bdd5953b9f..49bd9df387b8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -892,7 +892,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	struct dpu_global_state *global_state = dpu_kms_get_global_state(state);
 
 	struct dpu_plane_state **pstates;
-	struct dpu_plane_state *pstate;
+	struct dpu_plane_state *pstate, *prev_plane_state;
 
 	struct drm_plane_state *plane_state;
 	struct drm_plane *plane;
@@ -962,6 +962,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	}
 
 	stage = DPU_STAGE_0;
+	prev_plane_state = NULL;
 	for (i = 0; i <= max_zpos; i++) {
 		pstate = pstates[i];
 		if (!pstate)
@@ -977,8 +978,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
 		plane_state = &pstate->base;
 
-		dpu_plane_clear_multirect(plane_state);
-
 		dst = drm_plane_state_dest(plane_state);
 		if (!drm_rect_intersect(&dst, &crtc_rect)) {
 			DPU_ERROR("invalid vertical/horizontal destination\n");
@@ -990,7 +989,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		}
 
 		plane = pstate->base.plane;
-		rc = dpu_plane_set_pipe(plane, pstate);
+		rc = dpu_plane_set_pipe(plane, pstate, prev_plane_state);
 		if (rc) {
 			DPU_ERROR("%s: error setting pipe for %s\n", dpu_crtc->name, plane->name);
 			goto end;
@@ -1002,6 +1001,17 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 			goto end;
 		}
 
+		/*
+		 * If this plane was not selected for multirect, so we can try
+		 * using it together with the next pipe.  If it selected for
+		 * the REC1, next pipe will have to start from REC_SOLO (and
+		 * maybe be promoted to REC0 later.
+		 */
+		if (pstate->multirect_index == DPU_SSPP_RECT_SOLO)
+			prev_plane_state = pstate;
+		else
+			prev_plane_state = NULL;
+
 		pstates[i]->stage = stage++;
 		DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 08a7e56cc98f..c3c3972627ca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -646,7 +646,7 @@ static int _dpu_kms_create_planes_virtual(struct dpu_kms *dpu_kms, int max_crtc_
 	catalog = dpu_kms->catalog;
 
 	/* Create the planes, keeping track of one primary/cursor per crtc */
-	for (i = 0; i < catalog->sspp_count; i++) {
+	for (i = 0; i < 2 * catalog->sspp_count; i++) {
 		enum drm_plane_type type;
 
 		if (primary_planes_idx < max_crtc_count)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 420cdd90e89b..77cb4f172379 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -292,10 +292,10 @@ static u64 _dpu_plane_get_qos_lut(const struct dpu_qos_lut_tbl *tbl,
  * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
  * @plane:		Pointer to drm plane
  * @fb:			Pointer to framebuffer associated with the given plane
- * @pipe_cfg:		Pointer to pipe configuration
+ * @src_width:		Plane source width (max for both multirect planes).
  */
 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, u32 src_width)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
@@ -309,8 +309,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 		fmt = dpu_get_dpu_format_ext(
 				fb->format->format,
 				fb->modifier);
-		total_fl = _dpu_plane_calc_fill_level(plane, fmt,
-				drm_rect_width(&pipe_cfg->src_rect));
+		total_fl = _dpu_plane_calc_fill_level(plane, fmt, src_width);
 
 		if (fmt && DPU_FORMAT_IS_LINEAR(fmt))
 			lut_usage = DPU_QOS_LUT_USAGE_LINEAR;
@@ -570,6 +569,9 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 		&& (src_w == dst_w))
 		return;
 
+	if (pstate->multirect_index != DPU_SSPP_RECT_SOLO)
+		return;
+
 	scale_cfg->dst_width = dst_w;
 	scale_cfg->dst_height = dst_h;
 	scale_cfg->y_rgb_filter_cfg = DPU_SCALE_BIL;
@@ -638,13 +640,16 @@ 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,
+		const struct dpu_format *fmt,
 		struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	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;
 
+	if (pstate->multirect_index == DPU_SSPP_RECT_1)
+		return;
+
 	memset(&scaler3_cfg, 0, sizeof(scaler3_cfg));
 	memset(&pixel_ext, 0, sizeof(pixel_ext));
 
@@ -667,8 +672,7 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 	 * bypassed. Still we need to update alpha and bitwidth
 	 * ONLY for RECT0
 	 */
-	if (pstate->pipe_hw->ops.setup_scaler &&
-			pstate->multirect_index != DPU_SSPP_RECT_1)
+	if (pstate->pipe_hw->ops.setup_scaler)
 		pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
 				pipe_cfg, &pixel_ext,
 				&scaler3_cfg);
@@ -723,23 +727,15 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 					&pipe_cfg,
 					pstate->multirect_index);
 
-		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
+		_dpu_plane_setup_scaler(pdpu, pstate, fmt, &pipe_cfg);
 	}
 
 	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->multirect_index = DPU_SSPP_RECT_SOLO;
-	pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
-}
-
-int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
+static int dpu_plane_validate_multirect_v2(struct dpu_plane_state *pstate0,
+					   struct dpu_plane_state *pstate1)
 {
-	struct dpu_plane_state *pstate[R_MAX];
 	const struct drm_plane_state *drm_state[R_MAX];
 	struct drm_rect src[R_MAX], dst[R_MAX];
 	struct dpu_plane *dpu_plane[R_MAX];
@@ -750,9 +746,17 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 	bool has_tiled_rect = false;
 
 	for (i = 0; i < R_MAX; i++) {
+		struct dpu_plane_state *pstate;
 		const struct msm_format *msm_fmt;
 
-		drm_state[i] = i ? plane->r1 : plane->r0;
+		pstate = i ? pstate1 : pstate0;
+		if (pstate == NULL) {
+			DPU_DEBUG("DPU plane state of plane id %d is NULL\n",
+				drm_state[i]->plane->base.id);
+			return -EINVAL;
+		}
+
+		drm_state[i] = &pstate->base;
 		msm_fmt = msm_framebuffer_format(drm_state[i]->fb);
 		fmt[i] = to_dpu_format(msm_fmt);
 
@@ -766,15 +770,8 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 	for (i = 0; i < R_MAX; i++) {
 		int width_threshold;
 
-		pstate[i] = to_dpu_plane_state(drm_state[i]);
 		dpu_plane[i] = to_dpu_plane(drm_state[i]->plane);
 
-		if (pstate[i] == NULL) {
-			DPU_ERROR("DPU plane state of plane id %d is NULL\n",
-				drm_state[i]->plane->base.id);
-			return -EINVAL;
-		}
-
 		src[i].x1 = drm_state[i]->src_x >> 16;
 		src[i].y1 = drm_state[i]->src_y >> 16;
 		src[i].x2 = src[i].x1 + (drm_state[i]->src_w >> 16);
@@ -784,13 +781,13 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 
 		if (drm_rect_calc_hscale(&src[i], &dst[i], 1, 1) != 1 ||
 		    drm_rect_calc_vscale(&src[i], &dst[i], 1, 1) != 1) {
-			DPU_ERROR_PLANE(dpu_plane[i],
+			DPU_DEBUG_PLANE(dpu_plane[i],
 				"scaling is not supported in multirect mode\n");
 			return -EINVAL;
 		}
 
 		if (DPU_FORMAT_IS_YUV(fmt[i])) {
-			DPU_ERROR_PLANE(dpu_plane[i],
+			DPU_DEBUG_PLANE(dpu_plane[i],
 				"Unsupported format for multirect mode\n");
 			return -EINVAL;
 		}
@@ -816,8 +813,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;
+		pstate0->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+		pstate1->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
 
 		goto done;
 	}
@@ -827,10 +824,10 @@ 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;
+		pstate0->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
+		pstate1->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
 	} else {
-		DPU_ERROR(
+		DPU_DEBUG(
 			"No multirect mode possible for the planes (%d - %d)\n",
 			drm_state[R0]->plane->base.id,
 			drm_state[R1]->plane->base.id);
@@ -838,13 +835,15 @@ 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;
+	pstate0->multirect_index = DPU_SSPP_RECT_0;
+	pstate1->multirect_index = DPU_SSPP_RECT_1;
+
+	pstate0->qos_src_w = max(pstate0->qos_src_w, pstate1->base.src_w >> 16);
 
 	DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
-		pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
+		pstate0->multirect_mode, pstate0->multirect_index);
 	DPU_DEBUG_PLANE(dpu_plane[R1], "R1: %d - %d\n",
-		pstate[R1]->multirect_mode, pstate[R1]->multirect_index);
+		pstate1->multirect_mode, pstate1->multirect_index);
 	return 0;
 }
 
@@ -928,7 +927,8 @@ static bool dpu_plane_validate_src(struct drm_rect *src,
 		drm_rect_equals(fb_rect, src);
 }
 
-int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate)
+int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate,
+		struct dpu_plane_state *prev_plane_state)
 {
 	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
@@ -936,11 +936,24 @@ int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate)
 	enum dpu_sspp pipe;
 	bool yuv, scale;
 
+	pstate->multirect_index = DPU_SSPP_RECT_SOLO;
+	pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
 	if (pdpu->pipe != SSPP_NONE) {
 		pipe = pdpu->pipe;
 		goto out;
 	}
 
+	if (prev_plane_state &&
+	    kms->catalog->caps->smart_dma_rev != DPU_SMART_DMA_UNSUPPORTED &&
+	    !dpu_plane_validate_multirect_v2(prev_plane_state, pstate)) {
+		/* multirect capable, use the same pipe */
+		DPU_DEBUG_PLANE(pdpu, "multirect, SSPP %d\n", prev_plane_state->pipe_hw->idx);
+		pstate->pipe_hw = prev_plane_state->pipe_hw;
+
+		return 0;
+	}
+
 	yuv = pstate->base.fb ? DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(pstate->base.fb))) : false;
 	scale = (pstate->base.src_w >> 16 != pstate->base.crtc_w) ||
 		(pstate->base.src_h >> 16 != pstate->base.crtc_h);
@@ -953,6 +966,8 @@ int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate)
 	if (pipe == SSPP_NONE || pipe >= SSPP_MAX || !kms->rm.sspp_blks[pipe - SSPP_NONE])
 		return -EINVAL;
 
+	pstate->qos_src_w = pstate->base.src_w >> 16;
+
 	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
 
 	return 0;
@@ -988,7 +1003,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 		DRM_DEBUG_ATOMIC("PLANE %d released SSPP %d\n", plane->base.id, pstate->pipe_hw->idx);
 		dpu_rm_release_sspp(&dpu_kms->rm, global_state, plane->base.id);
-		pstate->pipe_hw = NULL;
+		/* do not clear pipe_hw here, use it in atomic_disable to cleanup mutlirect */
 	}
 
 	return 0;
@@ -1199,7 +1214,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 				pstate->multirect_index);
 	}
 
-	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
+	_dpu_plane_setup_scaler(pdpu, pstate, fmt, &pipe_cfg);
 
 	if (pstate->pipe_hw->ops.setup_multirect)
 		pstate->pipe_hw->ops.setup_multirect(
@@ -1245,8 +1260,10 @@ 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);
+	if (pstate->multirect_index != DPU_SSPP_RECT_1) {
+		_dpu_plane_set_qos_lut(plane, fb, pstate->qos_src_w);
+		_dpu_plane_set_danger_lut(plane, fb);
+	}
 
 	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
 		_dpu_plane_set_qos_ctrl(plane, true, DPU_PLANE_QOS_PANIC_CTRL);
@@ -1279,7 +1296,13 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
 
 	pstate->pending = true;
 
-	pstate->pipe_hw = NULL;
+	if (pstate->multirect_index != DPU_SSPP_RECT_SOLO &&
+	    pstate->pipe_hw &&
+	    pstate->pipe_hw->ops.setup_multirect)
+		pstate->pipe_hw->ops.setup_multirect(
+				pstate->pipe_hw,
+				DPU_SSPP_RECT_SOLO,
+				DPU_SSPP_MULTIRECT_NONE);
 }
 
 static void dpu_plane_atomic_update(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 0940ffbb8b28..6ec7f5edc06a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -23,6 +23,7 @@
  * @multirect_index: index of the rectangle of SSPP
  * @multirect_mode: parallel or time multiplex multirect mode
  * @pending:	whether the current update is still pending
+ * @qos_src_w: src_width used for qos_lut setup
  * @plane_fetch_bw: calculated BW per plane
  * @plane_clk: calculated clk per plane
  */
@@ -35,22 +36,14 @@ struct dpu_plane_state {
 	uint32_t multirect_mode;
 	bool pending;
 
+	uint32_t qos_src_w;
+
 	struct dpu_hw_pipe *pipe_hw;
 
 	u64 plane_fetch_bw;
 	u64 plane_clk;
 };
 
-/**
- * struct dpu_multirect_plane_states: Defines multirect pair of drm plane states
- * @r0: drm plane configured on rect 0
- * @r1: drm plane configured on rect 1
- */
-struct dpu_multirect_plane_states {
-	const struct drm_plane_state *r0;
-	const struct drm_plane_state *r1;
-};
-
 #define to_dpu_plane_state(x) \
 	container_of(x, struct dpu_plane_state, base)
 
@@ -78,19 +71,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		uint32_t pipe, enum drm_plane_type type,
 		unsigned long possible_crtcs);
 
-/**
- * dpu_plane_validate_multirecti_v2 - validate the multirect planes
- *				      against hw limitations
- * @plane: drm plate states of the multirect pair
- */
-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
@@ -107,7 +87,8 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable);
 static inline void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) {}
 #endif
 
-int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate);
+int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate,
+		struct dpu_plane_state *prev_plane_state);
 
 int dpu_plane_real_atomic_check(struct drm_plane *plane,
 				struct drm_atomic_state *state);
-- 
2.30.2


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

* [PATCH v2 22/22] drm/msm/dpu: add multirect support
@ 2021-07-05  1:21   ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-07-05  1:21 UTC (permalink / raw)
  To: Bjorn Andersson, Rob Clark, Sean Paul, Abhinav Kumar
  Cc: Jonathan Marek, Stephen Boyd, linux-arm-msm, dri-devel,
	David Airlie, freedreno

If SmartDMA is supported by the hardware, SSPPs allow using two RGB
layers per the hardware pipe (with some additional restrictions, like no
support for scaling, etc). Register additional planes (two per the SSPP)
and check if we can use multirect during 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_kms.c   |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 109 +++++++++++++---------
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  29 +-----
 4 files changed, 86 insertions(+), 72 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index 49bdd5953b9f..49bd9df387b8 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -892,7 +892,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	struct dpu_global_state *global_state = dpu_kms_get_global_state(state);
 
 	struct dpu_plane_state **pstates;
-	struct dpu_plane_state *pstate;
+	struct dpu_plane_state *pstate, *prev_plane_state;
 
 	struct drm_plane_state *plane_state;
 	struct drm_plane *plane;
@@ -962,6 +962,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	}
 
 	stage = DPU_STAGE_0;
+	prev_plane_state = NULL;
 	for (i = 0; i <= max_zpos; i++) {
 		pstate = pstates[i];
 		if (!pstate)
@@ -977,8 +978,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
 		plane_state = &pstate->base;
 
-		dpu_plane_clear_multirect(plane_state);
-
 		dst = drm_plane_state_dest(plane_state);
 		if (!drm_rect_intersect(&dst, &crtc_rect)) {
 			DPU_ERROR("invalid vertical/horizontal destination\n");
@@ -990,7 +989,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		}
 
 		plane = pstate->base.plane;
-		rc = dpu_plane_set_pipe(plane, pstate);
+		rc = dpu_plane_set_pipe(plane, pstate, prev_plane_state);
 		if (rc) {
 			DPU_ERROR("%s: error setting pipe for %s\n", dpu_crtc->name, plane->name);
 			goto end;
@@ -1002,6 +1001,17 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 			goto end;
 		}
 
+		/*
+		 * If this plane was not selected for multirect, so we can try
+		 * using it together with the next pipe.  If it selected for
+		 * the REC1, next pipe will have to start from REC_SOLO (and
+		 * maybe be promoted to REC0 later.
+		 */
+		if (pstate->multirect_index == DPU_SSPP_RECT_SOLO)
+			prev_plane_state = pstate;
+		else
+			prev_plane_state = NULL;
+
 		pstates[i]->stage = stage++;
 		DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
 	}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
index 08a7e56cc98f..c3c3972627ca 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
@@ -646,7 +646,7 @@ static int _dpu_kms_create_planes_virtual(struct dpu_kms *dpu_kms, int max_crtc_
 	catalog = dpu_kms->catalog;
 
 	/* Create the planes, keeping track of one primary/cursor per crtc */
-	for (i = 0; i < catalog->sspp_count; i++) {
+	for (i = 0; i < 2 * catalog->sspp_count; i++) {
 		enum drm_plane_type type;
 
 		if (primary_planes_idx < max_crtc_count)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 420cdd90e89b..77cb4f172379 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -292,10 +292,10 @@ static u64 _dpu_plane_get_qos_lut(const struct dpu_qos_lut_tbl *tbl,
  * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
  * @plane:		Pointer to drm plane
  * @fb:			Pointer to framebuffer associated with the given plane
- * @pipe_cfg:		Pointer to pipe configuration
+ * @src_width:		Plane source width (max for both multirect planes).
  */
 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, u32 src_width)
 {
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
 	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
@@ -309,8 +309,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 		fmt = dpu_get_dpu_format_ext(
 				fb->format->format,
 				fb->modifier);
-		total_fl = _dpu_plane_calc_fill_level(plane, fmt,
-				drm_rect_width(&pipe_cfg->src_rect));
+		total_fl = _dpu_plane_calc_fill_level(plane, fmt, src_width);
 
 		if (fmt && DPU_FORMAT_IS_LINEAR(fmt))
 			lut_usage = DPU_QOS_LUT_USAGE_LINEAR;
@@ -570,6 +569,9 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu,
 		&& (src_w == dst_w))
 		return;
 
+	if (pstate->multirect_index != DPU_SSPP_RECT_SOLO)
+		return;
+
 	scale_cfg->dst_width = dst_w;
 	scale_cfg->dst_height = dst_h;
 	scale_cfg->y_rgb_filter_cfg = DPU_SCALE_BIL;
@@ -638,13 +640,16 @@ 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,
+		const struct dpu_format *fmt,
 		struct dpu_hw_pipe_cfg *pipe_cfg)
 {
 	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;
 
+	if (pstate->multirect_index == DPU_SSPP_RECT_1)
+		return;
+
 	memset(&scaler3_cfg, 0, sizeof(scaler3_cfg));
 	memset(&pixel_ext, 0, sizeof(pixel_ext));
 
@@ -667,8 +672,7 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 	 * bypassed. Still we need to update alpha and bitwidth
 	 * ONLY for RECT0
 	 */
-	if (pstate->pipe_hw->ops.setup_scaler &&
-			pstate->multirect_index != DPU_SSPP_RECT_1)
+	if (pstate->pipe_hw->ops.setup_scaler)
 		pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
 				pipe_cfg, &pixel_ext,
 				&scaler3_cfg);
@@ -723,23 +727,15 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 					&pipe_cfg,
 					pstate->multirect_index);
 
-		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
+		_dpu_plane_setup_scaler(pdpu, pstate, fmt, &pipe_cfg);
 	}
 
 	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->multirect_index = DPU_SSPP_RECT_SOLO;
-	pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
-}
-
-int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
+static int dpu_plane_validate_multirect_v2(struct dpu_plane_state *pstate0,
+					   struct dpu_plane_state *pstate1)
 {
-	struct dpu_plane_state *pstate[R_MAX];
 	const struct drm_plane_state *drm_state[R_MAX];
 	struct drm_rect src[R_MAX], dst[R_MAX];
 	struct dpu_plane *dpu_plane[R_MAX];
@@ -750,9 +746,17 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 	bool has_tiled_rect = false;
 
 	for (i = 0; i < R_MAX; i++) {
+		struct dpu_plane_state *pstate;
 		const struct msm_format *msm_fmt;
 
-		drm_state[i] = i ? plane->r1 : plane->r0;
+		pstate = i ? pstate1 : pstate0;
+		if (pstate == NULL) {
+			DPU_DEBUG("DPU plane state of plane id %d is NULL\n",
+				drm_state[i]->plane->base.id);
+			return -EINVAL;
+		}
+
+		drm_state[i] = &pstate->base;
 		msm_fmt = msm_framebuffer_format(drm_state[i]->fb);
 		fmt[i] = to_dpu_format(msm_fmt);
 
@@ -766,15 +770,8 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 	for (i = 0; i < R_MAX; i++) {
 		int width_threshold;
 
-		pstate[i] = to_dpu_plane_state(drm_state[i]);
 		dpu_plane[i] = to_dpu_plane(drm_state[i]->plane);
 
-		if (pstate[i] == NULL) {
-			DPU_ERROR("DPU plane state of plane id %d is NULL\n",
-				drm_state[i]->plane->base.id);
-			return -EINVAL;
-		}
-
 		src[i].x1 = drm_state[i]->src_x >> 16;
 		src[i].y1 = drm_state[i]->src_y >> 16;
 		src[i].x2 = src[i].x1 + (drm_state[i]->src_w >> 16);
@@ -784,13 +781,13 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 
 		if (drm_rect_calc_hscale(&src[i], &dst[i], 1, 1) != 1 ||
 		    drm_rect_calc_vscale(&src[i], &dst[i], 1, 1) != 1) {
-			DPU_ERROR_PLANE(dpu_plane[i],
+			DPU_DEBUG_PLANE(dpu_plane[i],
 				"scaling is not supported in multirect mode\n");
 			return -EINVAL;
 		}
 
 		if (DPU_FORMAT_IS_YUV(fmt[i])) {
-			DPU_ERROR_PLANE(dpu_plane[i],
+			DPU_DEBUG_PLANE(dpu_plane[i],
 				"Unsupported format for multirect mode\n");
 			return -EINVAL;
 		}
@@ -816,8 +813,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;
+		pstate0->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
+		pstate1->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
 
 		goto done;
 	}
@@ -827,10 +824,10 @@ 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;
+		pstate0->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
+		pstate1->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
 	} else {
-		DPU_ERROR(
+		DPU_DEBUG(
 			"No multirect mode possible for the planes (%d - %d)\n",
 			drm_state[R0]->plane->base.id,
 			drm_state[R1]->plane->base.id);
@@ -838,13 +835,15 @@ 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;
+	pstate0->multirect_index = DPU_SSPP_RECT_0;
+	pstate1->multirect_index = DPU_SSPP_RECT_1;
+
+	pstate0->qos_src_w = max(pstate0->qos_src_w, pstate1->base.src_w >> 16);
 
 	DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
-		pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
+		pstate0->multirect_mode, pstate0->multirect_index);
 	DPU_DEBUG_PLANE(dpu_plane[R1], "R1: %d - %d\n",
-		pstate[R1]->multirect_mode, pstate[R1]->multirect_index);
+		pstate1->multirect_mode, pstate1->multirect_index);
 	return 0;
 }
 
@@ -928,7 +927,8 @@ static bool dpu_plane_validate_src(struct drm_rect *src,
 		drm_rect_equals(fb_rect, src);
 }
 
-int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate)
+int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate,
+		struct dpu_plane_state *prev_plane_state)
 {
 	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
 	struct dpu_plane *pdpu = to_dpu_plane(plane);
@@ -936,11 +936,24 @@ int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate)
 	enum dpu_sspp pipe;
 	bool yuv, scale;
 
+	pstate->multirect_index = DPU_SSPP_RECT_SOLO;
+	pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
+
 	if (pdpu->pipe != SSPP_NONE) {
 		pipe = pdpu->pipe;
 		goto out;
 	}
 
+	if (prev_plane_state &&
+	    kms->catalog->caps->smart_dma_rev != DPU_SMART_DMA_UNSUPPORTED &&
+	    !dpu_plane_validate_multirect_v2(prev_plane_state, pstate)) {
+		/* multirect capable, use the same pipe */
+		DPU_DEBUG_PLANE(pdpu, "multirect, SSPP %d\n", prev_plane_state->pipe_hw->idx);
+		pstate->pipe_hw = prev_plane_state->pipe_hw;
+
+		return 0;
+	}
+
 	yuv = pstate->base.fb ? DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(pstate->base.fb))) : false;
 	scale = (pstate->base.src_w >> 16 != pstate->base.crtc_w) ||
 		(pstate->base.src_h >> 16 != pstate->base.crtc_h);
@@ -953,6 +966,8 @@ int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate)
 	if (pipe == SSPP_NONE || pipe >= SSPP_MAX || !kms->rm.sspp_blks[pipe - SSPP_NONE])
 		return -EINVAL;
 
+	pstate->qos_src_w = pstate->base.src_w >> 16;
+
 	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - SSPP_NONE]);
 
 	return 0;
@@ -988,7 +1003,7 @@ static int dpu_plane_atomic_check(struct drm_plane *plane,
 
 		DRM_DEBUG_ATOMIC("PLANE %d released SSPP %d\n", plane->base.id, pstate->pipe_hw->idx);
 		dpu_rm_release_sspp(&dpu_kms->rm, global_state, plane->base.id);
-		pstate->pipe_hw = NULL;
+		/* do not clear pipe_hw here, use it in atomic_disable to cleanup mutlirect */
 	}
 
 	return 0;
@@ -1199,7 +1214,7 @@ static void dpu_plane_sspp_atomic_update(struct drm_plane *plane)
 				pstate->multirect_index);
 	}
 
-	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
+	_dpu_plane_setup_scaler(pdpu, pstate, fmt, &pipe_cfg);
 
 	if (pstate->pipe_hw->ops.setup_multirect)
 		pstate->pipe_hw->ops.setup_multirect(
@@ -1245,8 +1260,10 @@ 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);
+	if (pstate->multirect_index != DPU_SSPP_RECT_1) {
+		_dpu_plane_set_qos_lut(plane, fb, pstate->qos_src_w);
+		_dpu_plane_set_danger_lut(plane, fb);
+	}
 
 	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
 		_dpu_plane_set_qos_ctrl(plane, true, DPU_PLANE_QOS_PANIC_CTRL);
@@ -1279,7 +1296,13 @@ static void _dpu_plane_atomic_disable(struct drm_plane *plane)
 
 	pstate->pending = true;
 
-	pstate->pipe_hw = NULL;
+	if (pstate->multirect_index != DPU_SSPP_RECT_SOLO &&
+	    pstate->pipe_hw &&
+	    pstate->pipe_hw->ops.setup_multirect)
+		pstate->pipe_hw->ops.setup_multirect(
+				pstate->pipe_hw,
+				DPU_SSPP_RECT_SOLO,
+				DPU_SSPP_MULTIRECT_NONE);
 }
 
 static void dpu_plane_atomic_update(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 0940ffbb8b28..6ec7f5edc06a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
@@ -23,6 +23,7 @@
  * @multirect_index: index of the rectangle of SSPP
  * @multirect_mode: parallel or time multiplex multirect mode
  * @pending:	whether the current update is still pending
+ * @qos_src_w: src_width used for qos_lut setup
  * @plane_fetch_bw: calculated BW per plane
  * @plane_clk: calculated clk per plane
  */
@@ -35,22 +36,14 @@ struct dpu_plane_state {
 	uint32_t multirect_mode;
 	bool pending;
 
+	uint32_t qos_src_w;
+
 	struct dpu_hw_pipe *pipe_hw;
 
 	u64 plane_fetch_bw;
 	u64 plane_clk;
 };
 
-/**
- * struct dpu_multirect_plane_states: Defines multirect pair of drm plane states
- * @r0: drm plane configured on rect 0
- * @r1: drm plane configured on rect 1
- */
-struct dpu_multirect_plane_states {
-	const struct drm_plane_state *r0;
-	const struct drm_plane_state *r1;
-};
-
 #define to_dpu_plane_state(x) \
 	container_of(x, struct dpu_plane_state, base)
 
@@ -78,19 +71,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
 		uint32_t pipe, enum drm_plane_type type,
 		unsigned long possible_crtcs);
 
-/**
- * dpu_plane_validate_multirecti_v2 - validate the multirect planes
- *				      against hw limitations
- * @plane: drm plate states of the multirect pair
- */
-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
@@ -107,7 +87,8 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable);
 static inline void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) {}
 #endif
 
-int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate);
+int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state *pstate,
+		struct dpu_plane_state *prev_plane_state);
 
 int dpu_plane_real_atomic_check(struct drm_plane *plane,
 				struct drm_atomic_state *state);
-- 
2.30.2


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

* Re: [Freedreno] [PATCH v2 00/22] drm/msm/dpu: switch dpu_plane to be virtual
  2021-07-05  1:20 ` Dmitry Baryshkov
                   ` (22 preceding siblings ...)
  (?)
@ 2021-09-30  2:19 ` abhinavk
  2021-09-30 10:56     ` Dmitry Baryshkov
  -1 siblings, 1 reply; 69+ messages in thread
From: abhinavk @ 2021-09-30  2:19 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Rob Clark, Sean Paul, Jonathan Marek,
	Stephen Boyd, linux-arm-msm, dri-devel, David Airlie,
	Daniel Vetter, freedreno

Hi Dmitry

On 2021-07-04 18:20, Dmitry Baryshkov wrote:
> As discussed on IRC, change dpu_plane implementation to be virtual:
> register unified planes and select backing SSPP block at runtime.
> 
> Use msm.dpu_use_virtual_planes=1 to enable usage of virtual planes
> rather than statically allocated SSPPs at the plane registration.
> 
> Patches 1-9 move state variables from struct dpu_plane onto the stack
> allocation. State should not be a part of struct dpu_plane anyway.
> 
> Patches 10-18 make additional changes to plane code, reworking check,
> debugfs, dropping old multirec support, which results in patch 19 
> adding
> support for virtual planes per se.
> 
> Patches 20-22 demonstrate my main goal behind reworking dpu_plane
> support. They change dpu_plane to automatically use one of SSPP block
> features - multirec, an ability to display two unscaled RGB rectangles
> using single SSPP block. This allows us to double the amount of created
> planes. If the user tries to enable more planes than actually supported
> by the underlying SSPP blocks, atomic_check code would return an error.
> 
> As you can see, this patchset is not atomic, so different patches can 
> go
> separately.

I am half way through this series and have finished checking patches 
1-12
I am okay with patches 1-4, 6-12. Its a reasonable cleanup to make the 
dpu_plane struct lighter.
I need a little more time with the rest as I am comparing the downstream 
solution against yours.

As you mentioned, this patchset is not atomic, hence can you break it up 
like
-> cleanup of dpu_plane struct in one series
-> removal of current multirect and current src split which will include 
patch 5 as well

So that the first series can go through and it gives us a little more 
time to check the second
series.

Thanks

Abhinav

> 
> Changes since v1:
>  - Add multirec implementation
>  - Added msm.dpu_use_virtual_planes kernel parameter instead of using
>    compile time switch
>  - Changed code to always reallocate SSPPs in the CRTC atomic check to
>    let the kernel pick up the best multirec config. This can be
>    optimized later.
>  - Rework RM SSPP API to always receive plane id
>  - Removed scaler_cfg, pixel_ext and cdp_cfg from struct 
> dpu_plane_state
>  - Made _dpu_scaler_setup() call sspp's setup_scaler and setup_pe
>  - Removed dpu_csc_cfg from dpu_plane
> 
> The following changes since commit 
> e88bbc91849b2bf57683119c339e52916d34433f:
> 
>   Revert "drm/msm/mdp5: provide dynamic bandwidth management"
> (2021-06-23 14:06:20 -0700)
> 
> are available in the Git repository at:
> 
>   https://git.linaro.org/people/dmitry.baryshkov/kernel.git 
> dpu-multirec-2
> 
> for you to fetch changes up to 
> 19f6afd40097d4c826e56b8f4a8cbd807f7b61f6:
> 
>   drm/msm/dpu: add multirect support (2021-07-05 04:04:50 +0300)
> 
> ----------------------------------------------------------------
> Dmitry Baryshkov (22):
>       drm/msm/dpu: move LUT levels out of QOS config
>       drm/msm/dpu: remove pipe_qos_cfg from struct dpu_plane
>       drm/msm/dpu: drop pipe_name from struct dpu_plane
>       drm/msm/dpu: remove stage_cfg from struct dpu_crtc
>       drm/msm/dpu: rip out master planes support
>       drm/msm/dpu: move dpu_hw_pipe_cfg out of struct dpu_plane
>       drm/msm/dpu: drop scaler config from plane state
>       drm/msm/dpu: drop dpu_csc_cfg from dpu_plane
>       drm/msm/dpu: remove dpu_hw_pipe_cdp_cfg from dpu_plane
>       drm/msm/dpu: don't cache pipe->cap->features in dpu_plane
>       drm/msm/dpu: don't cache pipe->cap->sblk in dpu_plane
>       drm/msm/dpu: rip out debugfs support from dpu_plane
>       drm/msm/dpu: drop src_split and multirect check from 
> dpu_crtc_atomic_check
>       drm/msm/dpu: add list of supported formats to the DPU caps
>       drm/msm/dpu: simplify DPU_SSPP features checks
>       drm/msm/dpu: do not limit the zpos property
>       drm/msm/dpu: add support for SSPP allocation to RM
>       drm/msm/dpu: move pipe_hw to dpu_plane_state
>       drm/msm/dpu: add support for virtualized planes
>       drm/msm/dpu: fix smart dma support
>       drm/msm/dpu: fix CDP setup to account for multirect index
>       drm/msm/dpu: add multirect support
> 
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c       | 261 +++-----
>  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h       |   2 -
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  20 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  20 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c    |  41 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h    |  52 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c    |   2 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h    |   2 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c        | 234 ++++---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h        |  70 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c      | 851 
> +++++++++++--------------
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h      |  75 +--
>  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c         |  81 +++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h         |   6 +
>  14 files changed, 793 insertions(+), 924 deletions(-)
> 
> _______________________________________________
> Freedreno mailing list
> Freedreno@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/freedreno

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

* Re: [Freedreno] [PATCH v2 00/22] drm/msm/dpu: switch dpu_plane to be virtual
  2021-09-30  2:19 ` [Freedreno] [PATCH v2 00/22] drm/msm/dpu: switch dpu_plane to be virtual abhinavk
@ 2021-09-30 10:56     ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-09-30 10:56 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Bjorn Andersson, Rob Clark, Sean Paul, Jonathan Marek,
	Stephen Boyd, open list:DRM DRIVER FOR MSM ADRENO GPU,
	open list:DRM DRIVER FOR MSM ADRENO GPU, David Airlie,
	Daniel Vetter, freedreno

Hi,

On Thu, 30 Sept 2021 at 05:19, <abhinavk@codeaurora.org> wrote:
>
> Hi Dmitry
>
> On 2021-07-04 18:20, Dmitry Baryshkov wrote:
> > As discussed on IRC, change dpu_plane implementation to be virtual:
> > register unified planes and select backing SSPP block at runtime.
> >
> > Use msm.dpu_use_virtual_planes=1 to enable usage of virtual planes
> > rather than statically allocated SSPPs at the plane registration.
> >
> > Patches 1-9 move state variables from struct dpu_plane onto the stack
> > allocation. State should not be a part of struct dpu_plane anyway.
> >
> > Patches 10-18 make additional changes to plane code, reworking check,
> > debugfs, dropping old multirec support, which results in patch 19
> > adding
> > support for virtual planes per se.
> >
> > Patches 20-22 demonstrate my main goal behind reworking dpu_plane
> > support. They change dpu_plane to automatically use one of SSPP block
> > features - multirec, an ability to display two unscaled RGB rectangles
> > using single SSPP block. This allows us to double the amount of created
> > planes. If the user tries to enable more planes than actually supported
> > by the underlying SSPP blocks, atomic_check code would return an error.
> >
> > As you can see, this patchset is not atomic, so different patches can
> > go
> > separately.
>
> I am half way through this series and have finished checking patches
> 1-12
> I am okay with patches 1-4, 6-12. Its a reasonable cleanup to make the
> dpu_plane struct lighter.
> I need a little more time with the rest as I am comparing the downstream
> solution against yours.
>
> As you mentioned, this patchset is not atomic, hence can you break it up
> like
> -> cleanup of dpu_plane struct in one series
> -> removal of current multirect and current src split which will include
> patch 5 as well
>
> So that the first series can go through and it gives us a little more
> time to check the second
> series.

Ok, I'll split the series according to your review.

>
> Thanks
>
> Abhinav
>
> >
> > Changes since v1:
> >  - Add multirec implementation
> >  - Added msm.dpu_use_virtual_planes kernel parameter instead of using
> >    compile time switch
> >  - Changed code to always reallocate SSPPs in the CRTC atomic check to
> >    let the kernel pick up the best multirec config. This can be
> >    optimized later.
> >  - Rework RM SSPP API to always receive plane id
> >  - Removed scaler_cfg, pixel_ext and cdp_cfg from struct
> > dpu_plane_state
> >  - Made _dpu_scaler_setup() call sspp's setup_scaler and setup_pe
> >  - Removed dpu_csc_cfg from dpu_plane
> >
> > The following changes since commit
> > e88bbc91849b2bf57683119c339e52916d34433f:
> >
> >   Revert "drm/msm/mdp5: provide dynamic bandwidth management"
> > (2021-06-23 14:06:20 -0700)
> >
> > are available in the Git repository at:
> >
> >   https://git.linaro.org/people/dmitry.baryshkov/kernel.git
> > dpu-multirec-2
> >
> > for you to fetch changes up to
> > 19f6afd40097d4c826e56b8f4a8cbd807f7b61f6:
> >
> >   drm/msm/dpu: add multirect support (2021-07-05 04:04:50 +0300)
> >
> > ----------------------------------------------------------------
> > Dmitry Baryshkov (22):
> >       drm/msm/dpu: move LUT levels out of QOS config
> >       drm/msm/dpu: remove pipe_qos_cfg from struct dpu_plane
> >       drm/msm/dpu: drop pipe_name from struct dpu_plane
> >       drm/msm/dpu: remove stage_cfg from struct dpu_crtc
> >       drm/msm/dpu: rip out master planes support
> >       drm/msm/dpu: move dpu_hw_pipe_cfg out of struct dpu_plane
> >       drm/msm/dpu: drop scaler config from plane state
> >       drm/msm/dpu: drop dpu_csc_cfg from dpu_plane
> >       drm/msm/dpu: remove dpu_hw_pipe_cdp_cfg from dpu_plane
> >       drm/msm/dpu: don't cache pipe->cap->features in dpu_plane
> >       drm/msm/dpu: don't cache pipe->cap->sblk in dpu_plane
> >       drm/msm/dpu: rip out debugfs support from dpu_plane
> >       drm/msm/dpu: drop src_split and multirect check from
> > dpu_crtc_atomic_check
> >       drm/msm/dpu: add list of supported formats to the DPU caps
> >       drm/msm/dpu: simplify DPU_SSPP features checks
> >       drm/msm/dpu: do not limit the zpos property
> >       drm/msm/dpu: add support for SSPP allocation to RM
> >       drm/msm/dpu: move pipe_hw to dpu_plane_state
> >       drm/msm/dpu: add support for virtualized planes
> >       drm/msm/dpu: fix smart dma support
> >       drm/msm/dpu: fix CDP setup to account for multirect index
> >       drm/msm/dpu: add multirect support
> >
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c       | 261 +++-----
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h       |   2 -
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  20 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  20 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c    |  41 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h    |  52 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c    |   2 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h    |   2 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c        | 234 ++++---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h        |  70 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c      | 851
> > +++++++++++--------------
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h      |  75 +--
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c         |  81 +++
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h         |   6 +
> >  14 files changed, 793 insertions(+), 924 deletions(-)
> >
> > _______________________________________________
> > Freedreno mailing list
> > Freedreno@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/freedreno



-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [PATCH v2 00/22] drm/msm/dpu: switch dpu_plane to be virtual
@ 2021-09-30 10:56     ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-09-30 10:56 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Bjorn Andersson, Rob Clark, Sean Paul, Jonathan Marek,
	Stephen Boyd, open list:DRM DRIVER FOR MSM ADRENO GPU,
	open list:DRM DRIVER FOR MSM ADRENO GPU, David Airlie,
	Daniel Vetter, freedreno

Hi,

On Thu, 30 Sept 2021 at 05:19, <abhinavk@codeaurora.org> wrote:
>
> Hi Dmitry
>
> On 2021-07-04 18:20, Dmitry Baryshkov wrote:
> > As discussed on IRC, change dpu_plane implementation to be virtual:
> > register unified planes and select backing SSPP block at runtime.
> >
> > Use msm.dpu_use_virtual_planes=1 to enable usage of virtual planes
> > rather than statically allocated SSPPs at the plane registration.
> >
> > Patches 1-9 move state variables from struct dpu_plane onto the stack
> > allocation. State should not be a part of struct dpu_plane anyway.
> >
> > Patches 10-18 make additional changes to plane code, reworking check,
> > debugfs, dropping old multirec support, which results in patch 19
> > adding
> > support for virtual planes per se.
> >
> > Patches 20-22 demonstrate my main goal behind reworking dpu_plane
> > support. They change dpu_plane to automatically use one of SSPP block
> > features - multirec, an ability to display two unscaled RGB rectangles
> > using single SSPP block. This allows us to double the amount of created
> > planes. If the user tries to enable more planes than actually supported
> > by the underlying SSPP blocks, atomic_check code would return an error.
> >
> > As you can see, this patchset is not atomic, so different patches can
> > go
> > separately.
>
> I am half way through this series and have finished checking patches
> 1-12
> I am okay with patches 1-4, 6-12. Its a reasonable cleanup to make the
> dpu_plane struct lighter.
> I need a little more time with the rest as I am comparing the downstream
> solution against yours.
>
> As you mentioned, this patchset is not atomic, hence can you break it up
> like
> -> cleanup of dpu_plane struct in one series
> -> removal of current multirect and current src split which will include
> patch 5 as well
>
> So that the first series can go through and it gives us a little more
> time to check the second
> series.

Ok, I'll split the series according to your review.

>
> Thanks
>
> Abhinav
>
> >
> > Changes since v1:
> >  - Add multirec implementation
> >  - Added msm.dpu_use_virtual_planes kernel parameter instead of using
> >    compile time switch
> >  - Changed code to always reallocate SSPPs in the CRTC atomic check to
> >    let the kernel pick up the best multirec config. This can be
> >    optimized later.
> >  - Rework RM SSPP API to always receive plane id
> >  - Removed scaler_cfg, pixel_ext and cdp_cfg from struct
> > dpu_plane_state
> >  - Made _dpu_scaler_setup() call sspp's setup_scaler and setup_pe
> >  - Removed dpu_csc_cfg from dpu_plane
> >
> > The following changes since commit
> > e88bbc91849b2bf57683119c339e52916d34433f:
> >
> >   Revert "drm/msm/mdp5: provide dynamic bandwidth management"
> > (2021-06-23 14:06:20 -0700)
> >
> > are available in the Git repository at:
> >
> >   https://git.linaro.org/people/dmitry.baryshkov/kernel.git
> > dpu-multirec-2
> >
> > for you to fetch changes up to
> > 19f6afd40097d4c826e56b8f4a8cbd807f7b61f6:
> >
> >   drm/msm/dpu: add multirect support (2021-07-05 04:04:50 +0300)
> >
> > ----------------------------------------------------------------
> > Dmitry Baryshkov (22):
> >       drm/msm/dpu: move LUT levels out of QOS config
> >       drm/msm/dpu: remove pipe_qos_cfg from struct dpu_plane
> >       drm/msm/dpu: drop pipe_name from struct dpu_plane
> >       drm/msm/dpu: remove stage_cfg from struct dpu_crtc
> >       drm/msm/dpu: rip out master planes support
> >       drm/msm/dpu: move dpu_hw_pipe_cfg out of struct dpu_plane
> >       drm/msm/dpu: drop scaler config from plane state
> >       drm/msm/dpu: drop dpu_csc_cfg from dpu_plane
> >       drm/msm/dpu: remove dpu_hw_pipe_cdp_cfg from dpu_plane
> >       drm/msm/dpu: don't cache pipe->cap->features in dpu_plane
> >       drm/msm/dpu: don't cache pipe->cap->sblk in dpu_plane
> >       drm/msm/dpu: rip out debugfs support from dpu_plane
> >       drm/msm/dpu: drop src_split and multirect check from
> > dpu_crtc_atomic_check
> >       drm/msm/dpu: add list of supported formats to the DPU caps
> >       drm/msm/dpu: simplify DPU_SSPP features checks
> >       drm/msm/dpu: do not limit the zpos property
> >       drm/msm/dpu: add support for SSPP allocation to RM
> >       drm/msm/dpu: move pipe_hw to dpu_plane_state
> >       drm/msm/dpu: add support for virtualized planes
> >       drm/msm/dpu: fix smart dma support
> >       drm/msm/dpu: fix CDP setup to account for multirect index
> >       drm/msm/dpu: add multirect support
> >
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c       | 261 +++-----
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h       |   2 -
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c |  20 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  20 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c    |  41 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h    |  52 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.c    |   2 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h    |   2 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c        | 234 ++++---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h        |  70 +-
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c      | 851
> > +++++++++++--------------
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h      |  75 +--
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c         |  81 +++
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h         |   6 +
> >  14 files changed, 793 insertions(+), 924 deletions(-)
> >
> > _______________________________________________
> > Freedreno mailing list
> > Freedreno@lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/freedreno



-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [PATCH v2 14/22] drm/msm/dpu: add list of supported formats to the DPU caps
  2021-07-05  1:21   ` Dmitry Baryshkov
@ 2021-11-09 20:05     ` abhinavk
  -1 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-09 20:05 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Rob Clark, Sean Paul, Jonathan Marek,
	Stephen Boyd, linux-arm-msm, dri-devel, David Airlie,
	Daniel Vetter, freedreno

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> As we are going to add virtual planes, add the list of supported 
> formats
> to the hw catalog entry. It will be used to setup universal planes, 
> with
> later selecting a pipe depending on whether the YUV format is used for
> the framebuffer.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

I dont see an issue with exposing the format_list in the catalog, hence
Reviewed-by: Abhinav Kumar <abhinavk@codeaurora.org>

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 ++++++++++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  4 ++++
>  2 files changed, 14 insertions(+)
> 
> 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 d01c4c919504..b8e0fece1f0b 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -195,6 +195,8 @@ static const struct dpu_caps sdm845_dpu_caps = {
>  	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
>  	.max_hdeci_exp = MAX_HORZ_DECIMATION,
>  	.max_vdeci_exp = MAX_VERT_DECIMATION,
> +	.format_list = plane_formats_yuv,
> +	.num_formats = ARRAY_SIZE(plane_formats_yuv),
>  };
> 
>  static const struct dpu_caps sc7180_dpu_caps = {
> @@ -207,6 +209,8 @@ static const struct dpu_caps sc7180_dpu_caps = {
>  	.has_idle_pc = true,
>  	.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>  	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
> +	.format_list = plane_formats_yuv,
> +	.num_formats = ARRAY_SIZE(plane_formats_yuv),
>  };
> 
>  static const struct dpu_caps sm8150_dpu_caps = {
> @@ -223,6 +227,8 @@ static const struct dpu_caps sm8150_dpu_caps = {
>  	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
>  	.max_hdeci_exp = MAX_HORZ_DECIMATION,
>  	.max_vdeci_exp = MAX_VERT_DECIMATION,
> +	.format_list = plane_formats_yuv,
> +	.num_formats = ARRAY_SIZE(plane_formats_yuv),
>  };
> 
>  static const struct dpu_caps sm8250_dpu_caps = {
> @@ -237,6 +243,8 @@ static const struct dpu_caps sm8250_dpu_caps = {
>  	.has_3d_merge = true,
>  	.max_linewidth = 4096,
>  	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
> +	.format_list = plane_formats_yuv,
> +	.num_formats = ARRAY_SIZE(plane_formats_yuv),
>  };
> 
>  static const struct dpu_caps sc7280_dpu_caps = {
> @@ -249,6 +257,8 @@ static const struct dpu_caps sc7280_dpu_caps = {
>  	.has_idle_pc = true,
>  	.max_linewidth = 2400,
>  	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
> +	.format_list = plane_formats_yuv,
> +	.num_formats = ARRAY_SIZE(plane_formats_yuv),
>  };
> 
>  static const struct dpu_mdp_cfg sdm845_mdp[] = {
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> index d2a945a27cfa..f3c5aa3f4b3f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -324,6 +324,8 @@ struct dpu_qos_lut_tbl {
>   * @pixel_ram_size     size of latency hiding and de-tiling buffer in 
> bytes
>   * @max_hdeci_exp      max horizontal decimation supported (max is 
> 2^value)
>   * @max_vdeci_exp      max vertical decimation supported (max is 
> 2^value)
> + * @format_list: Pointer to list of supported formats
> + * @num_formats: Number of supported formats
>   */
>  struct dpu_caps {
>  	u32 max_mixer_width;
> @@ -340,6 +342,8 @@ struct dpu_caps {
>  	u32 pixel_ram_size;
>  	u32 max_hdeci_exp;
>  	u32 max_vdeci_exp;
> +	const u32 *format_list;
> +	u32 num_formats;
>  };
> 
>  /**

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

* Re: [Freedreno] [PATCH v2 14/22] drm/msm/dpu: add list of supported formats to the DPU caps
@ 2021-11-09 20:05     ` abhinavk
  0 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-09 20:05 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, Bjorn Andersson, David Airlie, Sean Paul

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> As we are going to add virtual planes, add the list of supported 
> formats
> to the hw catalog entry. It will be used to setup universal planes, 
> with
> later selecting a pipe depending on whether the YUV format is used for
> the framebuffer.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

I dont see an issue with exposing the format_list in the catalog, hence
Reviewed-by: Abhinav Kumar <abhinavk@codeaurora.org>

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 ++++++++++
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  4 ++++
>  2 files changed, 14 insertions(+)
> 
> 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 d01c4c919504..b8e0fece1f0b 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -195,6 +195,8 @@ static const struct dpu_caps sdm845_dpu_caps = {
>  	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
>  	.max_hdeci_exp = MAX_HORZ_DECIMATION,
>  	.max_vdeci_exp = MAX_VERT_DECIMATION,
> +	.format_list = plane_formats_yuv,
> +	.num_formats = ARRAY_SIZE(plane_formats_yuv),
>  };
> 
>  static const struct dpu_caps sc7180_dpu_caps = {
> @@ -207,6 +209,8 @@ static const struct dpu_caps sc7180_dpu_caps = {
>  	.has_idle_pc = true,
>  	.max_linewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>  	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
> +	.format_list = plane_formats_yuv,
> +	.num_formats = ARRAY_SIZE(plane_formats_yuv),
>  };
> 
>  static const struct dpu_caps sm8150_dpu_caps = {
> @@ -223,6 +227,8 @@ static const struct dpu_caps sm8150_dpu_caps = {
>  	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
>  	.max_hdeci_exp = MAX_HORZ_DECIMATION,
>  	.max_vdeci_exp = MAX_VERT_DECIMATION,
> +	.format_list = plane_formats_yuv,
> +	.num_formats = ARRAY_SIZE(plane_formats_yuv),
>  };
> 
>  static const struct dpu_caps sm8250_dpu_caps = {
> @@ -237,6 +243,8 @@ static const struct dpu_caps sm8250_dpu_caps = {
>  	.has_3d_merge = true,
>  	.max_linewidth = 4096,
>  	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
> +	.format_list = plane_formats_yuv,
> +	.num_formats = ARRAY_SIZE(plane_formats_yuv),
>  };
> 
>  static const struct dpu_caps sc7280_dpu_caps = {
> @@ -249,6 +257,8 @@ static const struct dpu_caps sc7280_dpu_caps = {
>  	.has_idle_pc = true,
>  	.max_linewidth = 2400,
>  	.pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
> +	.format_list = plane_formats_yuv,
> +	.num_formats = ARRAY_SIZE(plane_formats_yuv),
>  };
> 
>  static const struct dpu_mdp_cfg sdm845_mdp[] = {
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> index d2a945a27cfa..f3c5aa3f4b3f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -324,6 +324,8 @@ struct dpu_qos_lut_tbl {
>   * @pixel_ram_size     size of latency hiding and de-tiling buffer in 
> bytes
>   * @max_hdeci_exp      max horizontal decimation supported (max is 
> 2^value)
>   * @max_vdeci_exp      max vertical decimation supported (max is 
> 2^value)
> + * @format_list: Pointer to list of supported formats
> + * @num_formats: Number of supported formats
>   */
>  struct dpu_caps {
>  	u32 max_mixer_width;
> @@ -340,6 +342,8 @@ struct dpu_caps {
>  	u32 pixel_ram_size;
>  	u32 max_hdeci_exp;
>  	u32 max_vdeci_exp;
> +	const u32 *format_list;
> +	u32 num_formats;
>  };
> 
>  /**

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

* Re: [Freedreno] [PATCH v2 15/22] drm/msm/dpu: simplify DPU_SSPP features checks
  2021-07-05  1:21   ` Dmitry Baryshkov
@ 2021-11-09 20:06     ` abhinavk
  -1 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-09 20:06 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Rob Clark, Sean Paul, Jonathan Marek,
	Stephen Boyd, linux-arm-msm, dri-devel, David Airlie,
	Daniel Vetter, freedreno

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> Add DPU_SSPP_CSC_ANY denoting any CSC block. As we are at it, rewrite
> DPU_SSPP_SCALER (any scaler) to use BIT(x) instead of hand-coded
> bitshifts.
> 
This can go independent of the multi-rect series, so can you please take 
this with the
first half of the series which was going to be taken separately?

With that,
Reviewed-by: Abhinav Kumar <abhinavk@codeaurora.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 +++++++++++-----
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  3 +--
>  2 files changed, 12 insertions(+), 7 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 264a9d0d5fca..00098e33391e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -25,11 +25,17 @@ struct dpu_hw_pipe;
>  /**
>   * Define all scaler feature bits in catalog
>   */
> -#define DPU_SSPP_SCALER ((1UL << DPU_SSPP_SCALER_RGB) | \
> -	(1UL << DPU_SSPP_SCALER_QSEED2) | \
> -	 (1UL << DPU_SSPP_SCALER_QSEED3) | \
> -	 (1UL << DPU_SSPP_SCALER_QSEED3LITE) | \
> -	  (1UL << DPU_SSPP_SCALER_QSEED4))
> +#define DPU_SSPP_SCALER (BIT(DPU_SSPP_SCALER_RGB) | \
> +			 BIT(DPU_SSPP_SCALER_QSEED2) | \
> +			 BIT(DPU_SSPP_SCALER_QSEED3) | \
> +			 BIT(DPU_SSPP_SCALER_QSEED3LITE) | \
> +			 BIT(DPU_SSPP_SCALER_QSEED4))
> +
> +/*
> + * Define all CSC feature bits in catalog
> + */
> +#define DPU_SSPP_CSC_ANY (BIT(DPU_SSPP_CSC) | \
> +			  BIT(DPU_SSPP_CSC_10BIT))
> 
>  /**
>   * Component indices
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 34ecd971cbbb..8ed7b8f0db69 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -983,8 +983,7 @@ static int dpu_plane_atomic_check(struct drm_plane 
> *plane,
> 
>  	if (DPU_FORMAT_IS_YUV(fmt) &&
>  		(!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
> -		 !(pdpu->pipe_hw->cap->features & (BIT(DPU_SSPP_CSC)
> -		 | BIT(DPU_SSPP_CSC_10BIT))))) {
> +		 !(pdpu->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
>  		DPU_DEBUG_PLANE(pdpu,
>  				"plane doesn't have scaler/csc for yuv\n");
>  		return -EINVAL;

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

* Re: [Freedreno] [PATCH v2 15/22] drm/msm/dpu: simplify DPU_SSPP features checks
@ 2021-11-09 20:06     ` abhinavk
  0 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-09 20:06 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, Bjorn Andersson, David Airlie, Sean Paul

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> Add DPU_SSPP_CSC_ANY denoting any CSC block. As we are at it, rewrite
> DPU_SSPP_SCALER (any scaler) to use BIT(x) instead of hand-coded
> bitshifts.
> 
This can go independent of the multi-rect series, so can you please take 
this with the
first half of the series which was going to be taken separately?

With that,
Reviewed-by: Abhinav Kumar <abhinavk@codeaurora.org>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 16 +++++++++++-----
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  3 +--
>  2 files changed, 12 insertions(+), 7 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 264a9d0d5fca..00098e33391e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -25,11 +25,17 @@ struct dpu_hw_pipe;
>  /**
>   * Define all scaler feature bits in catalog
>   */
> -#define DPU_SSPP_SCALER ((1UL << DPU_SSPP_SCALER_RGB) | \
> -	(1UL << DPU_SSPP_SCALER_QSEED2) | \
> -	 (1UL << DPU_SSPP_SCALER_QSEED3) | \
> -	 (1UL << DPU_SSPP_SCALER_QSEED3LITE) | \
> -	  (1UL << DPU_SSPP_SCALER_QSEED4))
> +#define DPU_SSPP_SCALER (BIT(DPU_SSPP_SCALER_RGB) | \
> +			 BIT(DPU_SSPP_SCALER_QSEED2) | \
> +			 BIT(DPU_SSPP_SCALER_QSEED3) | \
> +			 BIT(DPU_SSPP_SCALER_QSEED3LITE) | \
> +			 BIT(DPU_SSPP_SCALER_QSEED4))
> +
> +/*
> + * Define all CSC feature bits in catalog
> + */
> +#define DPU_SSPP_CSC_ANY (BIT(DPU_SSPP_CSC) | \
> +			  BIT(DPU_SSPP_CSC_10BIT))
> 
>  /**
>   * Component indices
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 34ecd971cbbb..8ed7b8f0db69 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -983,8 +983,7 @@ static int dpu_plane_atomic_check(struct drm_plane 
> *plane,
> 
>  	if (DPU_FORMAT_IS_YUV(fmt) &&
>  		(!(pdpu->pipe_hw->cap->features & DPU_SSPP_SCALER) ||
> -		 !(pdpu->pipe_hw->cap->features & (BIT(DPU_SSPP_CSC)
> -		 | BIT(DPU_SSPP_CSC_10BIT))))) {
> +		 !(pdpu->pipe_hw->cap->features & DPU_SSPP_CSC_ANY))) {
>  		DPU_DEBUG_PLANE(pdpu,
>  				"plane doesn't have scaler/csc for yuv\n");
>  		return -EINVAL;

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

* Re: [Freedreno] [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property
  2021-07-05  1:21   ` Dmitry Baryshkov
@ 2021-11-09 20:15     ` abhinavk
  -1 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-09 20:15 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Rob Clark, Sean Paul, Jonathan Marek,
	Stephen Boyd, linux-arm-msm, dri-devel, David Airlie,
	Daniel Vetter, freedreno

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> Stop limiting zpos property values, we use normalized_zpos anyway. And
> nothing stops userspace from assigning several planes to a single zpos
> (it is a userspace bug, but the kernel is forgiving about it).

Userspace assigning several planes to a single zpos was intended to 
identify
cases where src split can be used. Downstream does not use normalized 
zpos,
hence it did not come across as a bug but mostly as a way to identify 
when
usermode needs src split to be enabled based on the composition 
strategy.

We can talk about that more in the rest of the patches of this series.

For this one, I only have a couple of questions:

1) Across different vendors, some have gone with limiting the zpos and 
some have gone with
the max, so is there an issue with sticking with the max_blend_stages 
limit?

2) If there is no hard reason to make this change, I think its better to 
keep it the way it is.

> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 11 +----------
>  1 file changed, 1 insertion(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 8ed7b8f0db69..3850f2714bf3 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -44,7 +44,6 @@
>  #define DPU_NAME_SIZE  12
> 
>  #define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
> -#define DPU_ZPOS_MAX 255
> 
>  /* multirect rect index */
>  enum {
> @@ -1374,7 +1373,6 @@ struct drm_plane *dpu_plane_init(struct 
> drm_device *dev,
>  	struct dpu_plane *pdpu;
>  	struct msm_drm_private *priv = dev->dev_private;
>  	struct dpu_kms *kms = to_dpu_kms(priv->kms);
> -	int zpos_max = DPU_ZPOS_MAX;
>  	uint32_t num_formats;
>  	int ret = -EINVAL;
> 
> @@ -1412,14 +1410,7 @@ struct drm_plane *dpu_plane_init(struct 
> drm_device *dev,
> 
>  	pdpu->catalog = kms->catalog;
> 
> -	if (kms->catalog->mixer_count &&
> -		kms->catalog->mixer[0].sblk->maxblendstages) {
> -		zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
> -		if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
> -			zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
> -	}
> -
> -	ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
> +	ret = drm_plane_create_zpos_property(plane, 0, 0, 255);
>  	if (ret)
>  		DPU_ERROR("failed to install zpos property, rc = %d\n", ret);

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

* Re: [Freedreno] [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property
@ 2021-11-09 20:15     ` abhinavk
  0 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-09 20:15 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, Bjorn Andersson, David Airlie, Sean Paul

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> Stop limiting zpos property values, we use normalized_zpos anyway. And
> nothing stops userspace from assigning several planes to a single zpos
> (it is a userspace bug, but the kernel is forgiving about it).

Userspace assigning several planes to a single zpos was intended to 
identify
cases where src split can be used. Downstream does not use normalized 
zpos,
hence it did not come across as a bug but mostly as a way to identify 
when
usermode needs src split to be enabled based on the composition 
strategy.

We can talk about that more in the rest of the patches of this series.

For this one, I only have a couple of questions:

1) Across different vendors, some have gone with limiting the zpos and 
some have gone with
the max, so is there an issue with sticking with the max_blend_stages 
limit?

2) If there is no hard reason to make this change, I think its better to 
keep it the way it is.

> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 11 +----------
>  1 file changed, 1 insertion(+), 10 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 8ed7b8f0db69..3850f2714bf3 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -44,7 +44,6 @@
>  #define DPU_NAME_SIZE  12
> 
>  #define DPU_PLANE_COLOR_FILL_FLAG	BIT(31)
> -#define DPU_ZPOS_MAX 255
> 
>  /* multirect rect index */
>  enum {
> @@ -1374,7 +1373,6 @@ struct drm_plane *dpu_plane_init(struct 
> drm_device *dev,
>  	struct dpu_plane *pdpu;
>  	struct msm_drm_private *priv = dev->dev_private;
>  	struct dpu_kms *kms = to_dpu_kms(priv->kms);
> -	int zpos_max = DPU_ZPOS_MAX;
>  	uint32_t num_formats;
>  	int ret = -EINVAL;
> 
> @@ -1412,14 +1410,7 @@ struct drm_plane *dpu_plane_init(struct 
> drm_device *dev,
> 
>  	pdpu->catalog = kms->catalog;
> 
> -	if (kms->catalog->mixer_count &&
> -		kms->catalog->mixer[0].sblk->maxblendstages) {
> -		zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
> -		if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
> -			zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
> -	}
> -
> -	ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
> +	ret = drm_plane_create_zpos_property(plane, 0, 0, 255);
>  	if (ret)
>  		DPU_ERROR("failed to install zpos property, rc = %d\n", ret);

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

* Re: [Freedreno] [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property
  2021-11-09 20:15     ` abhinavk
@ 2021-11-09 20:21       ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-11-09 20:21 UTC (permalink / raw)
  To: abhinavk
  Cc: Bjorn Andersson, Rob Clark, Sean Paul, Jonathan Marek,
	Stephen Boyd, linux-arm-msm, dri-devel, David Airlie,
	Daniel Vetter, freedreno

On Tue, 9 Nov 2021 at 23:15, <abhinavk@codeaurora.org> wrote:
>
> On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> > Stop limiting zpos property values, we use normalized_zpos anyway. And
> > nothing stops userspace from assigning several planes to a single zpos
> > (it is a userspace bug, but the kernel is forgiving about it).
>
> Userspace assigning several planes to a single zpos was intended to
> identify
> cases where src split can be used. Downstream does not use normalized
> zpos,
> hence it did not come across as a bug but mostly as a way to identify
> when
> usermode needs src split to be enabled based on the composition
> strategy.
>
> We can talk about that more in the rest of the patches of this series.
>
> For this one, I only have a couple of questions:
>
> 1) Across different vendors, some have gone with limiting the zpos and
> some have gone with
> the max, so is there an issue with sticking with the max_blend_stages
> limit?
>
> 2) If there is no hard reason to make this change, I think its better to
> keep it the way it is.

Short answer to both questions: we want to have more planes than the
max_blend_stages. So we should remove the limit.

Consider this to be a unification with MDP5, which uses 255 here.

>
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 11 +----------
> >  1 file changed, 1 insertion(+), 10 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > index 8ed7b8f0db69..3850f2714bf3 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -44,7 +44,6 @@
> >  #define DPU_NAME_SIZE  12
> >
> >  #define DPU_PLANE_COLOR_FILL_FLAG    BIT(31)
> > -#define DPU_ZPOS_MAX 255
> >
> >  /* multirect rect index */
> >  enum {
> > @@ -1374,7 +1373,6 @@ struct drm_plane *dpu_plane_init(struct
> > drm_device *dev,
> >       struct dpu_plane *pdpu;
> >       struct msm_drm_private *priv = dev->dev_private;
> >       struct dpu_kms *kms = to_dpu_kms(priv->kms);
> > -     int zpos_max = DPU_ZPOS_MAX;
> >       uint32_t num_formats;
> >       int ret = -EINVAL;
> >
> > @@ -1412,14 +1410,7 @@ struct drm_plane *dpu_plane_init(struct
> > drm_device *dev,
> >
> >       pdpu->catalog = kms->catalog;
> >
> > -     if (kms->catalog->mixer_count &&
> > -             kms->catalog->mixer[0].sblk->maxblendstages) {
> > -             zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
> > -             if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
> > -                     zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
> > -     }
> > -
> > -     ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
> > +     ret = drm_plane_create_zpos_property(plane, 0, 0, 255);
> >       if (ret)
> >               DPU_ERROR("failed to install zpos property, rc = %d\n", ret);



-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property
@ 2021-11-09 20:21       ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-11-09 20:21 UTC (permalink / raw)
  To: abhinavk
  Cc: freedreno, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, Bjorn Andersson, David Airlie, Sean Paul

On Tue, 9 Nov 2021 at 23:15, <abhinavk@codeaurora.org> wrote:
>
> On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> > Stop limiting zpos property values, we use normalized_zpos anyway. And
> > nothing stops userspace from assigning several planes to a single zpos
> > (it is a userspace bug, but the kernel is forgiving about it).
>
> Userspace assigning several planes to a single zpos was intended to
> identify
> cases where src split can be used. Downstream does not use normalized
> zpos,
> hence it did not come across as a bug but mostly as a way to identify
> when
> usermode needs src split to be enabled based on the composition
> strategy.
>
> We can talk about that more in the rest of the patches of this series.
>
> For this one, I only have a couple of questions:
>
> 1) Across different vendors, some have gone with limiting the zpos and
> some have gone with
> the max, so is there an issue with sticking with the max_blend_stages
> limit?
>
> 2) If there is no hard reason to make this change, I think its better to
> keep it the way it is.

Short answer to both questions: we want to have more planes than the
max_blend_stages. So we should remove the limit.

Consider this to be a unification with MDP5, which uses 255 here.

>
> >
> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> > ---
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 11 +----------
> >  1 file changed, 1 insertion(+), 10 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > index 8ed7b8f0db69..3850f2714bf3 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> > @@ -44,7 +44,6 @@
> >  #define DPU_NAME_SIZE  12
> >
> >  #define DPU_PLANE_COLOR_FILL_FLAG    BIT(31)
> > -#define DPU_ZPOS_MAX 255
> >
> >  /* multirect rect index */
> >  enum {
> > @@ -1374,7 +1373,6 @@ struct drm_plane *dpu_plane_init(struct
> > drm_device *dev,
> >       struct dpu_plane *pdpu;
> >       struct msm_drm_private *priv = dev->dev_private;
> >       struct dpu_kms *kms = to_dpu_kms(priv->kms);
> > -     int zpos_max = DPU_ZPOS_MAX;
> >       uint32_t num_formats;
> >       int ret = -EINVAL;
> >
> > @@ -1412,14 +1410,7 @@ struct drm_plane *dpu_plane_init(struct
> > drm_device *dev,
> >
> >       pdpu->catalog = kms->catalog;
> >
> > -     if (kms->catalog->mixer_count &&
> > -             kms->catalog->mixer[0].sblk->maxblendstages) {
> > -             zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
> > -             if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
> > -                     zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
> > -     }
> > -
> > -     ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
> > +     ret = drm_plane_create_zpos_property(plane, 0, 0, 255);
> >       if (ret)
> >               DPU_ERROR("failed to install zpos property, rc = %d\n", ret);



-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [PATCH v2 17/22] drm/msm/dpu: add support for SSPP allocation to RM
  2021-07-05  1:21   ` Dmitry Baryshkov
@ 2021-11-10  0:30     ` abhinavk
  -1 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-10  0:30 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Rob Clark, Sean Paul, Jonathan Marek,
	Stephen Boyd, linux-arm-msm, dri-devel, David Airlie,
	Daniel Vetter, freedreno

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> Add support for handling and allocting SSPP blocks through the resource
> manager. Handling code is not converted to use it though.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Conceptually this is identical to the previous attempt from QC on this:

https://patchwork.kernel.org/project/dri-devel/patch/1529499020-8499-5-git-send-email-skolluku@codeaurora.org/

So I wanted to get your comments on the foll questions:

1) Originally the idea was that to add 4K support to DPU, we will expand 
on top of your series.
 From our prior discussion on why the previous QC attempt was not taken 
over to add multirect support, the reason
was that it removed mutirect support which is was actually the end goal 
of this series. The end goal of the previous
attempt was to add 4K support hence looks like multirect was given lower 
priority and removed that time and not added
back.

But overall idea is the same which is to allocate hw sspps for drm 
planes to suit the requirement needed in the dpu_rm.

So to add 4K support on top of this series, we would just have to tweak 
dpu_rm_get_sspp to allocate 2x hw sspps right?


2) If the sspps are going to be iterated over a loop potentially every 
frame in the atomic check, wouldnt there be
a performance hit due to this?

> +retry_loop:
> +	for (i = 0; i < ARRAY_SIZE(rm->sspp_blks) && pipe == SSPP_NONE; i++) 
> {

This is where some help from usermode will help to optimize number of 
atomic_checks coming in.
If usermode tries atomic_checks too many times there can be potential 
glitches with this. Is that something
factored into this design?



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

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

* Re: [Freedreno] [PATCH v2 17/22] drm/msm/dpu: add support for SSPP allocation to RM
@ 2021-11-10  0:30     ` abhinavk
  0 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-10  0:30 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, Bjorn Andersson, David Airlie, Sean Paul

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> Add support for handling and allocting SSPP blocks through the resource
> manager. Handling code is not converted to use it though.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Conceptually this is identical to the previous attempt from QC on this:

https://patchwork.kernel.org/project/dri-devel/patch/1529499020-8499-5-git-send-email-skolluku@codeaurora.org/

So I wanted to get your comments on the foll questions:

1) Originally the idea was that to add 4K support to DPU, we will expand 
on top of your series.
 From our prior discussion on why the previous QC attempt was not taken 
over to add multirect support, the reason
was that it removed mutirect support which is was actually the end goal 
of this series. The end goal of the previous
attempt was to add 4K support hence looks like multirect was given lower 
priority and removed that time and not added
back.

But overall idea is the same which is to allocate hw sspps for drm 
planes to suit the requirement needed in the dpu_rm.

So to add 4K support on top of this series, we would just have to tweak 
dpu_rm_get_sspp to allocate 2x hw sspps right?


2) If the sspps are going to be iterated over a loop potentially every 
frame in the atomic check, wouldnt there be
a performance hit due to this?

> +retry_loop:
> +	for (i = 0; i < ARRAY_SIZE(rm->sspp_blks) && pipe == SSPP_NONE; i++) 
> {

This is where some help from usermode will help to optimize number of 
atomic_checks coming in.
If usermode tries atomic_checks too many times there can be potential 
glitches with this. Is that something
factored into this design?



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

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

* Re: [Freedreno] [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property
  2021-11-09 20:21       ` Dmitry Baryshkov
@ 2021-11-10  1:35         ` abhinavk
  -1 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-10  1:35 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, Bjorn Andersson, David Airlie, Sean Paul

On 2021-11-09 12:21, Dmitry Baryshkov wrote:
> On Tue, 9 Nov 2021 at 23:15, <abhinavk@codeaurora.org> wrote:
>> 
>> On 2021-07-04 18:21, Dmitry Baryshkov wrote:
>> > Stop limiting zpos property values, we use normalized_zpos anyway. And
>> > nothing stops userspace from assigning several planes to a single zpos
>> > (it is a userspace bug, but the kernel is forgiving about it).
>> 
>> Userspace assigning several planes to a single zpos was intended to
>> identify
>> cases where src split can be used. Downstream does not use normalized
>> zpos,
>> hence it did not come across as a bug but mostly as a way to identify
>> when
>> usermode needs src split to be enabled based on the composition
>> strategy.
>> 
>> We can talk about that more in the rest of the patches of this series.
>> 
>> For this one, I only have a couple of questions:
>> 
>> 1) Across different vendors, some have gone with limiting the zpos and
>> some have gone with
>> the max, so is there an issue with sticking with the max_blend_stages
>> limit?
>> 
>> 2) If there is no hard reason to make this change, I think its better 
>> to
>> keep it the way it is.
> 
> Short answer to both questions: we want to have more planes than the
> max_blend_stages. So we should remove the limit.
> 
> Consider this to be a unification with MDP5, which uses 255 here.

Alright, one minor comment below.

Also, what you have mentioned now "wanting to have more planes than 
blend stages"
should goto the commit text and the userspace bug part can be omitted as 
its technically
isnt a bug but just the way we intended it to be.


> 
>> 
>> >
>> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> > ---
>> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 11 +----------
>> >  1 file changed, 1 insertion(+), 10 deletions(-)
>> >
>> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> > index 8ed7b8f0db69..3850f2714bf3 100644
>> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> > @@ -44,7 +44,6 @@
>> >  #define DPU_NAME_SIZE  12
>> >
>> >  #define DPU_PLANE_COLOR_FILL_FLAG    BIT(31)
>> > -#define DPU_ZPOS_MAX 255
instead of getting rid of this, you can use this macro below where 255 
is hardcoded.
>> >
>> >  /* multirect rect index */
>> >  enum {
>> > @@ -1374,7 +1373,6 @@ struct drm_plane *dpu_plane_init(struct
>> > drm_device *dev,
>> >       struct dpu_plane *pdpu;
>> >       struct msm_drm_private *priv = dev->dev_private;
>> >       struct dpu_kms *kms = to_dpu_kms(priv->kms);
>> > -     int zpos_max = DPU_ZPOS_MAX;
>> >       uint32_t num_formats;
>> >       int ret = -EINVAL;
>> >
>> > @@ -1412,14 +1410,7 @@ struct drm_plane *dpu_plane_init(struct
>> > drm_device *dev,
>> >
>> >       pdpu->catalog = kms->catalog;
>> >
>> > -     if (kms->catalog->mixer_count &&
>> > -             kms->catalog->mixer[0].sblk->maxblendstages) {
>> > -             zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
>> > -             if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
>> > -                     zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
>> > -     }
>> > -
>> > -     ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
>> > +     ret = drm_plane_create_zpos_property(plane, 0, 0, 255);
>> >       if (ret)
>> >               DPU_ERROR("failed to install zpos property, rc = %d\n", ret);

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

* Re: [Freedreno] [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property
@ 2021-11-10  1:35         ` abhinavk
  0 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-10  1:35 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Sean Paul, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, Bjorn Andersson, David Airlie, freedreno

On 2021-11-09 12:21, Dmitry Baryshkov wrote:
> On Tue, 9 Nov 2021 at 23:15, <abhinavk@codeaurora.org> wrote:
>> 
>> On 2021-07-04 18:21, Dmitry Baryshkov wrote:
>> > Stop limiting zpos property values, we use normalized_zpos anyway. And
>> > nothing stops userspace from assigning several planes to a single zpos
>> > (it is a userspace bug, but the kernel is forgiving about it).
>> 
>> Userspace assigning several planes to a single zpos was intended to
>> identify
>> cases where src split can be used. Downstream does not use normalized
>> zpos,
>> hence it did not come across as a bug but mostly as a way to identify
>> when
>> usermode needs src split to be enabled based on the composition
>> strategy.
>> 
>> We can talk about that more in the rest of the patches of this series.
>> 
>> For this one, I only have a couple of questions:
>> 
>> 1) Across different vendors, some have gone with limiting the zpos and
>> some have gone with
>> the max, so is there an issue with sticking with the max_blend_stages
>> limit?
>> 
>> 2) If there is no hard reason to make this change, I think its better 
>> to
>> keep it the way it is.
> 
> Short answer to both questions: we want to have more planes than the
> max_blend_stages. So we should remove the limit.
> 
> Consider this to be a unification with MDP5, which uses 255 here.

Alright, one minor comment below.

Also, what you have mentioned now "wanting to have more planes than 
blend stages"
should goto the commit text and the userspace bug part can be omitted as 
its technically
isnt a bug but just the way we intended it to be.


> 
>> 
>> >
>> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
>> > ---
>> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 11 +----------
>> >  1 file changed, 1 insertion(+), 10 deletions(-)
>> >
>> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> > index 8ed7b8f0db69..3850f2714bf3 100644
>> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
>> > @@ -44,7 +44,6 @@
>> >  #define DPU_NAME_SIZE  12
>> >
>> >  #define DPU_PLANE_COLOR_FILL_FLAG    BIT(31)
>> > -#define DPU_ZPOS_MAX 255
instead of getting rid of this, you can use this macro below where 255 
is hardcoded.
>> >
>> >  /* multirect rect index */
>> >  enum {
>> > @@ -1374,7 +1373,6 @@ struct drm_plane *dpu_plane_init(struct
>> > drm_device *dev,
>> >       struct dpu_plane *pdpu;
>> >       struct msm_drm_private *priv = dev->dev_private;
>> >       struct dpu_kms *kms = to_dpu_kms(priv->kms);
>> > -     int zpos_max = DPU_ZPOS_MAX;
>> >       uint32_t num_formats;
>> >       int ret = -EINVAL;
>> >
>> > @@ -1412,14 +1410,7 @@ struct drm_plane *dpu_plane_init(struct
>> > drm_device *dev,
>> >
>> >       pdpu->catalog = kms->catalog;
>> >
>> > -     if (kms->catalog->mixer_count &&
>> > -             kms->catalog->mixer[0].sblk->maxblendstages) {
>> > -             zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
>> > -             if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
>> > -                     zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
>> > -     }
>> > -
>> > -     ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
>> > +     ret = drm_plane_create_zpos_property(plane, 0, 0, 255);
>> >       if (ret)
>> >               DPU_ERROR("failed to install zpos property, rc = %d\n", ret);

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

* Re: [Freedreno] [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property
  2021-11-10  1:35         ` abhinavk
@ 2021-11-10  1:58           ` Dmitry Baryshkov
  -1 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-11-10  1:58 UTC (permalink / raw)
  To: abhinavk
  Cc: freedreno, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, Bjorn Andersson, David Airlie, Sean Paul

On Wed, 10 Nov 2021 at 04:35, <abhinavk@codeaurora.org> wrote:
>
> On 2021-11-09 12:21, Dmitry Baryshkov wrote:
> > On Tue, 9 Nov 2021 at 23:15, <abhinavk@codeaurora.org> wrote:
> >>
> >> On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> >> > Stop limiting zpos property values, we use normalized_zpos anyway. And
> >> > nothing stops userspace from assigning several planes to a single zpos
> >> > (it is a userspace bug, but the kernel is forgiving about it).
> >>
> >> Userspace assigning several planes to a single zpos was intended to
> >> identify
> >> cases where src split can be used. Downstream does not use normalized
> >> zpos,
> >> hence it did not come across as a bug but mostly as a way to identify
> >> when
> >> usermode needs src split to be enabled based on the composition
> >> strategy.
> >>
> >> We can talk about that more in the rest of the patches of this series.
> >>
> >> For this one, I only have a couple of questions:
> >>
> >> 1) Across different vendors, some have gone with limiting the zpos and
> >> some have gone with
> >> the max, so is there an issue with sticking with the max_blend_stages
> >> limit?
> >>
> >> 2) If there is no hard reason to make this change, I think its better
> >> to
> >> keep it the way it is.
> >
> > Short answer to both questions: we want to have more planes than the
> > max_blend_stages. So we should remove the limit.
> >
> > Consider this to be a unification with MDP5, which uses 255 here.
>
> Alright, one minor comment below.
>
> Also, what you have mentioned now "wanting to have more planes than
> blend stages"
> should goto the commit text and the userspace bug part can be omitted as
> its technically
> isnt a bug but just the way we intended it to be.

It still is a bug. See
https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#plane-abstraction,
"zpos" description:
'User-space may set mutable zpos properties so that multiple active
planes on the same CRTC have identical zpos values. This is a
user-space bug...'

>
>
> >
> >>
> >> >
> >> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >> > ---
> >> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 11 +----------
> >> >  1 file changed, 1 insertion(+), 10 deletions(-)
> >> >
> >> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >> > index 8ed7b8f0db69..3850f2714bf3 100644
> >> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >> > @@ -44,7 +44,6 @@
> >> >  #define DPU_NAME_SIZE  12
> >> >
> >> >  #define DPU_PLANE_COLOR_FILL_FLAG    BIT(31)
> >> > -#define DPU_ZPOS_MAX 255
> instead of getting rid of this, you can use this macro below where 255
> is hardcoded.

Ack

> >> >
> >> >  /* multirect rect index */
> >> >  enum {
> >> > @@ -1374,7 +1373,6 @@ struct drm_plane *dpu_plane_init(struct
> >> > drm_device *dev,
> >> >       struct dpu_plane *pdpu;
> >> >       struct msm_drm_private *priv = dev->dev_private;
> >> >       struct dpu_kms *kms = to_dpu_kms(priv->kms);
> >> > -     int zpos_max = DPU_ZPOS_MAX;
> >> >       uint32_t num_formats;
> >> >       int ret = -EINVAL;
> >> >
> >> > @@ -1412,14 +1410,7 @@ struct drm_plane *dpu_plane_init(struct
> >> > drm_device *dev,
> >> >
> >> >       pdpu->catalog = kms->catalog;
> >> >
> >> > -     if (kms->catalog->mixer_count &&
> >> > -             kms->catalog->mixer[0].sblk->maxblendstages) {
> >> > -             zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
> >> > -             if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
> >> > -                     zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
> >> > -     }
> >> > -
> >> > -     ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
> >> > +     ret = drm_plane_create_zpos_property(plane, 0, 0, 255);
> >> >       if (ret)
> >> >               DPU_ERROR("failed to install zpos property, rc = %d\n", ret);



-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property
@ 2021-11-10  1:58           ` Dmitry Baryshkov
  0 siblings, 0 replies; 69+ messages in thread
From: Dmitry Baryshkov @ 2021-11-10  1:58 UTC (permalink / raw)
  To: abhinavk
  Cc: Sean Paul, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, Bjorn Andersson, David Airlie, freedreno

On Wed, 10 Nov 2021 at 04:35, <abhinavk@codeaurora.org> wrote:
>
> On 2021-11-09 12:21, Dmitry Baryshkov wrote:
> > On Tue, 9 Nov 2021 at 23:15, <abhinavk@codeaurora.org> wrote:
> >>
> >> On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> >> > Stop limiting zpos property values, we use normalized_zpos anyway. And
> >> > nothing stops userspace from assigning several planes to a single zpos
> >> > (it is a userspace bug, but the kernel is forgiving about it).
> >>
> >> Userspace assigning several planes to a single zpos was intended to
> >> identify
> >> cases where src split can be used. Downstream does not use normalized
> >> zpos,
> >> hence it did not come across as a bug but mostly as a way to identify
> >> when
> >> usermode needs src split to be enabled based on the composition
> >> strategy.
> >>
> >> We can talk about that more in the rest of the patches of this series.
> >>
> >> For this one, I only have a couple of questions:
> >>
> >> 1) Across different vendors, some have gone with limiting the zpos and
> >> some have gone with
> >> the max, so is there an issue with sticking with the max_blend_stages
> >> limit?
> >>
> >> 2) If there is no hard reason to make this change, I think its better
> >> to
> >> keep it the way it is.
> >
> > Short answer to both questions: we want to have more planes than the
> > max_blend_stages. So we should remove the limit.
> >
> > Consider this to be a unification with MDP5, which uses 255 here.
>
> Alright, one minor comment below.
>
> Also, what you have mentioned now "wanting to have more planes than
> blend stages"
> should goto the commit text and the userspace bug part can be omitted as
> its technically
> isnt a bug but just the way we intended it to be.

It still is a bug. See
https://www.kernel.org/doc/html/latest/gpu/drm-kms.html#plane-abstraction,
"zpos" description:
'User-space may set mutable zpos properties so that multiple active
planes on the same CRTC have identical zpos values. This is a
user-space bug...'

>
>
> >
> >>
> >> >
> >> > Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
> >> > ---
> >> >  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 11 +----------
> >> >  1 file changed, 1 insertion(+), 10 deletions(-)
> >> >
> >> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >> > b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >> > index 8ed7b8f0db69..3850f2714bf3 100644
> >> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> >> > @@ -44,7 +44,6 @@
> >> >  #define DPU_NAME_SIZE  12
> >> >
> >> >  #define DPU_PLANE_COLOR_FILL_FLAG    BIT(31)
> >> > -#define DPU_ZPOS_MAX 255
> instead of getting rid of this, you can use this macro below where 255
> is hardcoded.

Ack

> >> >
> >> >  /* multirect rect index */
> >> >  enum {
> >> > @@ -1374,7 +1373,6 @@ struct drm_plane *dpu_plane_init(struct
> >> > drm_device *dev,
> >> >       struct dpu_plane *pdpu;
> >> >       struct msm_drm_private *priv = dev->dev_private;
> >> >       struct dpu_kms *kms = to_dpu_kms(priv->kms);
> >> > -     int zpos_max = DPU_ZPOS_MAX;
> >> >       uint32_t num_formats;
> >> >       int ret = -EINVAL;
> >> >
> >> > @@ -1412,14 +1410,7 @@ struct drm_plane *dpu_plane_init(struct
> >> > drm_device *dev,
> >> >
> >> >       pdpu->catalog = kms->catalog;
> >> >
> >> > -     if (kms->catalog->mixer_count &&
> >> > -             kms->catalog->mixer[0].sblk->maxblendstages) {
> >> > -             zpos_max = kms->catalog->mixer[0].sblk->maxblendstages - 1;
> >> > -             if (zpos_max > DPU_STAGE_MAX - DPU_STAGE_0 - 1)
> >> > -                     zpos_max = DPU_STAGE_MAX - DPU_STAGE_0 - 1;
> >> > -     }
> >> > -
> >> > -     ret = drm_plane_create_zpos_property(plane, 0, 0, zpos_max);
> >> > +     ret = drm_plane_create_zpos_property(plane, 0, 0, 255);
> >> >       if (ret)
> >> >               DPU_ERROR("failed to install zpos property, rc = %d\n", ret);



-- 
With best wishes
Dmitry

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

* Re: [Freedreno] [PATCH v2 20/22] drm/msm/dpu: fix smart dma support
  2021-07-05  1:21   ` Dmitry Baryshkov
@ 2021-11-10  2:06     ` abhinavk
  -1 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-10  2:06 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Rob Clark, Sean Paul, Jonathan Marek,
	Stephen Boyd, linux-arm-msm, dri-devel, David Airlie,
	Daniel Vetter, freedreno

On 2021-07-04 18:21, 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. Make SSPP subdriver check global
> smart_dma_rev to decide if setup_multirect should be enabled.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Instead of this approach, we can OR the DPU_SSPP_SMART_DMA_* to the 
features list?

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +++++-----
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 16 ++++++++++++----
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c    |  9 +++++----
>  3 files changed, 22 insertions(+), 13 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 b8e0fece1f0b..d2321648b8d2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -185,7 +185,7 @@ static const struct dpu_caps sdm845_dpu_caps = {
>  	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>  	.max_mixer_blendstages = 0xb,
>  	.qseed_type = DPU_SSPP_SCALER_QSEED3,
> -	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
> +	.smart_dma_rev = DPU_SMART_DMA_V2,
>  	.ubwc_version = DPU_HW_UBWC_VER_20,
>  	.has_src_split = true,
>  	.has_dim_layer = true,
> @@ -203,7 +203,7 @@ static const struct dpu_caps sc7180_dpu_caps = {
>  	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>  	.max_mixer_blendstages = 0x9,
>  	.qseed_type = DPU_SSPP_SCALER_QSEED4,
> -	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
> +	.smart_dma_rev = DPU_SMART_DMA_V2,
>  	.ubwc_version = DPU_HW_UBWC_VER_20,
>  	.has_dim_layer = true,
>  	.has_idle_pc = true,
> @@ -217,7 +217,7 @@ static const struct dpu_caps sm8150_dpu_caps = {
>  	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>  	.max_mixer_blendstages = 0xb,
>  	.qseed_type = DPU_SSPP_SCALER_QSEED3,
> -	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
> +	.smart_dma_rev = DPU_SMART_DMA_V2, /* TODO: v2.5 */
>  	.ubwc_version = DPU_HW_UBWC_VER_30,
>  	.has_src_split = true,
>  	.has_dim_layer = true,
> @@ -235,7 +235,7 @@ static const struct dpu_caps sm8250_dpu_caps = {
>  	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>  	.max_mixer_blendstages = 0xb,
>  	.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
> -	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
> +	.smart_dma_rev = DPU_SMART_DMA_V2, /* TODO: v2.5 */
>  	.ubwc_version = DPU_HW_UBWC_VER_40,
>  	.has_src_split = true,
>  	.has_dim_layer = true,
> @@ -251,7 +251,7 @@ 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,
> +	.smart_dma_rev = DPU_SMART_DMA_V2,
>  	.ubwc_version = DPU_HW_UBWC_VER_30,
>  	.has_dim_layer = true,
>  	.has_idle_pc = true,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> index f3c5aa3f4b3f..66d7b43c0019 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -70,6 +70,18 @@ enum {
>  	DPU_HW_UBWC_VER_40 = 0x400,
>  };
> 
> +/**
> + * SmartDMA support
> + * @DPU_SMART_DMA_UNSUPPORTED,   SmartDMA not support
> + * @DPU_SMART_DMA_V1,   SmartDMA 1.0 support
> + * @DPU_SMART_DMA_V2,   SmartDMA 2.0 support
> + */
> +enum {
> +	DPU_SMART_DMA_UNSUPPORTED,
> +	DPU_SMART_DMA_V1,
> +	DPU_SMART_DMA_V2,
> +};
> +
>  /**
>   * MDP TOP BLOCK features
>   * @DPU_MDP_PANIC_PER_PIPE Panic configuration needs to be be done per 
> pipe
> @@ -104,8 +116,6 @@ enum {
>   * @DPU_SSPP_QOS,            SSPP support QoS control, 
> danger/safe/creq
>   * @DPU_SSPP_QOS_8LVL,       SSPP support 8-level QoS control
>   * @DPU_SSPP_EXCL_RECT,      SSPP supports exclusion rect
> - * @DPU_SSPP_SMART_DMA_V1,   SmartDMA 1.0 support
> - * @DPU_SSPP_SMART_DMA_V2,   SmartDMA 2.0 support
>   * @DPU_SSPP_TS_PREFILL      Supports prefill with traffic shaper
>   * @DPU_SSPP_TS_PREFILL_REC1 Supports prefill with traffic shaper 
> multirec
>   * @DPU_SSPP_CDP             Supports client driven prefetch
> @@ -124,8 +134,6 @@ enum {
>  	DPU_SSPP_QOS,
>  	DPU_SSPP_QOS_8LVL,
>  	DPU_SSPP_EXCL_RECT,
> -	DPU_SSPP_SMART_DMA_V1,
> -	DPU_SSPP_SMART_DMA_V2,
>  	DPU_SSPP_TS_PREFILL,
>  	DPU_SSPP_TS_PREFILL_REC1,
>  	DPU_SSPP_CDP,
> 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 2be43d5a235a..f93cdeb08ac7 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -648,7 +648,8 @@ static void dpu_hw_sspp_setup_cdp(struct 
> dpu_hw_pipe *ctx,
>  }
> 
>  static void _setup_layer_ops(struct dpu_hw_pipe *c,
> -		unsigned long features)
> +		unsigned long features,
> +		int smart_dma_rev)
>  {
>  	if (test_bit(DPU_SSPP_SRC, &features)) {
>  		c->ops.setup_format = dpu_hw_sspp_setup_format;
> @@ -669,8 +670,8 @@ static void _setup_layer_ops(struct dpu_hw_pipe *c,
>  		test_bit(DPU_SSPP_CSC_10BIT, &features))
>  		c->ops.setup_csc = dpu_hw_sspp_setup_csc;
> 
> -	if (test_bit(DPU_SSPP_SMART_DMA_V1, &c->cap->features) ||
> -		test_bit(DPU_SSPP_SMART_DMA_V2, &c->cap->features))
> +	if (smart_dma_rev == DPU_SMART_DMA_V1 ||
> +	    smart_dma_rev == DPU_SMART_DMA_V2)
>  		c->ops.setup_multirect = dpu_hw_sspp_setup_multirect;
> 
>  	if (test_bit(DPU_SSPP_SCALER_QSEED3, &features) ||
> @@ -731,7 +732,7 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp 
> idx,
>  	hw_pipe->mdp = &catalog->mdp[0];
>  	hw_pipe->idx = idx;
>  	hw_pipe->cap = cfg;
> -	_setup_layer_ops(hw_pipe, hw_pipe->cap->features);
> +	_setup_layer_ops(hw_pipe, hw_pipe->cap->features,
> catalog->caps->smart_dma_rev);
> 
>  	return hw_pipe;
>  }

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

* Re: [Freedreno] [PATCH v2 20/22] drm/msm/dpu: fix smart dma support
@ 2021-11-10  2:06     ` abhinavk
  0 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-10  2:06 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, Bjorn Andersson, David Airlie, Sean Paul

On 2021-07-04 18:21, 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. Make SSPP subdriver check global
> smart_dma_rev to decide if setup_multirect should be enabled.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

Instead of this approach, we can OR the DPU_SSPP_SMART_DMA_* to the 
features list?

> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +++++-----
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 16 ++++++++++++----
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c    |  9 +++++----
>  3 files changed, 22 insertions(+), 13 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 b8e0fece1f0b..d2321648b8d2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -185,7 +185,7 @@ static const struct dpu_caps sdm845_dpu_caps = {
>  	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>  	.max_mixer_blendstages = 0xb,
>  	.qseed_type = DPU_SSPP_SCALER_QSEED3,
> -	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
> +	.smart_dma_rev = DPU_SMART_DMA_V2,
>  	.ubwc_version = DPU_HW_UBWC_VER_20,
>  	.has_src_split = true,
>  	.has_dim_layer = true,
> @@ -203,7 +203,7 @@ static const struct dpu_caps sc7180_dpu_caps = {
>  	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>  	.max_mixer_blendstages = 0x9,
>  	.qseed_type = DPU_SSPP_SCALER_QSEED4,
> -	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2,
> +	.smart_dma_rev = DPU_SMART_DMA_V2,
>  	.ubwc_version = DPU_HW_UBWC_VER_20,
>  	.has_dim_layer = true,
>  	.has_idle_pc = true,
> @@ -217,7 +217,7 @@ static const struct dpu_caps sm8150_dpu_caps = {
>  	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>  	.max_mixer_blendstages = 0xb,
>  	.qseed_type = DPU_SSPP_SCALER_QSEED3,
> -	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
> +	.smart_dma_rev = DPU_SMART_DMA_V2, /* TODO: v2.5 */
>  	.ubwc_version = DPU_HW_UBWC_VER_30,
>  	.has_src_split = true,
>  	.has_dim_layer = true,
> @@ -235,7 +235,7 @@ static const struct dpu_caps sm8250_dpu_caps = {
>  	.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
>  	.max_mixer_blendstages = 0xb,
>  	.qseed_type = DPU_SSPP_SCALER_QSEED3LITE,
> -	.smart_dma_rev = DPU_SSPP_SMART_DMA_V2, /* TODO: v2.5 */
> +	.smart_dma_rev = DPU_SMART_DMA_V2, /* TODO: v2.5 */
>  	.ubwc_version = DPU_HW_UBWC_VER_40,
>  	.has_src_split = true,
>  	.has_dim_layer = true,
> @@ -251,7 +251,7 @@ 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,
> +	.smart_dma_rev = DPU_SMART_DMA_V2,
>  	.ubwc_version = DPU_HW_UBWC_VER_30,
>  	.has_dim_layer = true,
>  	.has_idle_pc = true,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> index f3c5aa3f4b3f..66d7b43c0019 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -70,6 +70,18 @@ enum {
>  	DPU_HW_UBWC_VER_40 = 0x400,
>  };
> 
> +/**
> + * SmartDMA support
> + * @DPU_SMART_DMA_UNSUPPORTED,   SmartDMA not support
> + * @DPU_SMART_DMA_V1,   SmartDMA 1.0 support
> + * @DPU_SMART_DMA_V2,   SmartDMA 2.0 support
> + */
> +enum {
> +	DPU_SMART_DMA_UNSUPPORTED,
> +	DPU_SMART_DMA_V1,
> +	DPU_SMART_DMA_V2,
> +};
> +
>  /**
>   * MDP TOP BLOCK features
>   * @DPU_MDP_PANIC_PER_PIPE Panic configuration needs to be be done per 
> pipe
> @@ -104,8 +116,6 @@ enum {
>   * @DPU_SSPP_QOS,            SSPP support QoS control, 
> danger/safe/creq
>   * @DPU_SSPP_QOS_8LVL,       SSPP support 8-level QoS control
>   * @DPU_SSPP_EXCL_RECT,      SSPP supports exclusion rect
> - * @DPU_SSPP_SMART_DMA_V1,   SmartDMA 1.0 support
> - * @DPU_SSPP_SMART_DMA_V2,   SmartDMA 2.0 support
>   * @DPU_SSPP_TS_PREFILL      Supports prefill with traffic shaper
>   * @DPU_SSPP_TS_PREFILL_REC1 Supports prefill with traffic shaper 
> multirec
>   * @DPU_SSPP_CDP             Supports client driven prefetch
> @@ -124,8 +134,6 @@ enum {
>  	DPU_SSPP_QOS,
>  	DPU_SSPP_QOS_8LVL,
>  	DPU_SSPP_EXCL_RECT,
> -	DPU_SSPP_SMART_DMA_V1,
> -	DPU_SSPP_SMART_DMA_V2,
>  	DPU_SSPP_TS_PREFILL,
>  	DPU_SSPP_TS_PREFILL_REC1,
>  	DPU_SSPP_CDP,
> 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 2be43d5a235a..f93cdeb08ac7 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -648,7 +648,8 @@ static void dpu_hw_sspp_setup_cdp(struct 
> dpu_hw_pipe *ctx,
>  }
> 
>  static void _setup_layer_ops(struct dpu_hw_pipe *c,
> -		unsigned long features)
> +		unsigned long features,
> +		int smart_dma_rev)
>  {
>  	if (test_bit(DPU_SSPP_SRC, &features)) {
>  		c->ops.setup_format = dpu_hw_sspp_setup_format;
> @@ -669,8 +670,8 @@ static void _setup_layer_ops(struct dpu_hw_pipe *c,
>  		test_bit(DPU_SSPP_CSC_10BIT, &features))
>  		c->ops.setup_csc = dpu_hw_sspp_setup_csc;
> 
> -	if (test_bit(DPU_SSPP_SMART_DMA_V1, &c->cap->features) ||
> -		test_bit(DPU_SSPP_SMART_DMA_V2, &c->cap->features))
> +	if (smart_dma_rev == DPU_SMART_DMA_V1 ||
> +	    smart_dma_rev == DPU_SMART_DMA_V2)
>  		c->ops.setup_multirect = dpu_hw_sspp_setup_multirect;
> 
>  	if (test_bit(DPU_SSPP_SCALER_QSEED3, &features) ||
> @@ -731,7 +732,7 @@ struct dpu_hw_pipe *dpu_hw_sspp_init(enum dpu_sspp 
> idx,
>  	hw_pipe->mdp = &catalog->mdp[0];
>  	hw_pipe->idx = idx;
>  	hw_pipe->cap = cfg;
> -	_setup_layer_ops(hw_pipe, hw_pipe->cap->features);
> +	_setup_layer_ops(hw_pipe, hw_pipe->cap->features,
> catalog->caps->smart_dma_rev);
> 
>  	return hw_pipe;
>  }

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

* Re: [Freedreno] [PATCH v2 21/22] drm/msm/dpu: fix CDP setup to account for multirect index
  2021-07-05  1:21   ` Dmitry Baryshkov
@ 2021-11-10  2:12     ` abhinavk
  -1 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-10  2:12 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Rob Clark, Sean Paul, Jonathan Marek,
	Stephen Boyd, linux-arm-msm, dri-devel, David Airlie,
	Daniel Vetter, freedreno

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> Client driven prefetch (CDP) is properly setup only for SSPP REC0
> currently. Enable client driven prefetch also for SSPP REC1.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Abhinav Kumar <abhinavk@codeaurora.org>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 12 ++++++++++--
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  4 +++-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  2 +-
>  3 files changed, 14 insertions(+), 4 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 f93cdeb08ac7..96f2f3f12f34 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -75,6 +75,7 @@
>  #define SSPP_TRAFFIC_SHAPER                0x130
>  #define SSPP_CDP_CNTL                      0x134
>  #define SSPP_UBWC_ERROR_STATUS             0x138
> +#define SSPP_CDP_CNTL_REC1                 0x13c
>  #define SSPP_TRAFFIC_SHAPER_PREFILL        0x150
>  #define SSPP_TRAFFIC_SHAPER_REC1_PREFILL   0x154
>  #define SSPP_TRAFFIC_SHAPER_REC1           0x158
> @@ -624,10 +625,12 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct
> dpu_hw_pipe *ctx,
>  }
> 
>  static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
> -		struct dpu_hw_pipe_cdp_cfg *cfg)
> +		struct dpu_hw_pipe_cdp_cfg *cfg,
> +		enum dpu_sspp_multirect_index index)
>  {
>  	u32 idx;
>  	u32 cdp_cntl = 0;
> +	u32 cdp_cntl_offset = 0;
> 
>  	if (!ctx || !cfg)
>  		return;
> @@ -635,6 +638,11 @@ static void dpu_hw_sspp_setup_cdp(struct 
> dpu_hw_pipe *ctx,
>  	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
>  		return;
> 
> +	if (index == DPU_SSPP_RECT_SOLO || index == DPU_SSPP_RECT_0)
> +		cdp_cntl_offset = SSPP_CDP_CNTL;
> +	else
> +		cdp_cntl_offset = SSPP_CDP_CNTL_REC1;
> +
>  	if (cfg->enable)
>  		cdp_cntl |= BIT(0);
>  	if (cfg->ubwc_meta_enable)
> @@ -644,7 +652,7 @@ static void dpu_hw_sspp_setup_cdp(struct 
> dpu_hw_pipe *ctx,
>  	if (cfg->preload_ahead == DPU_SSPP_CDP_PRELOAD_AHEAD_64)
>  		cdp_cntl |= BIT(3);
> 
> -	DPU_REG_WRITE(&ctx->hw, SSPP_CDP_CNTL, cdp_cntl);
> +	DPU_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl);
>  }
> 
>  static void _setup_layer_ops(struct dpu_hw_pipe *c,
> 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 c5ac8defa073..19c5358b962c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -358,9 +358,11 @@ struct dpu_hw_sspp_ops {
>  	 * setup_cdp - setup client driven prefetch
>  	 * @ctx: Pointer to pipe context
>  	 * @cfg: Pointer to cdp configuration
> +	 * @index: rectangle index in multirect
>  	 */
>  	void (*setup_cdp)(struct dpu_hw_pipe *ctx,
> -			struct dpu_hw_pipe_cdp_cfg *cfg);
> +			struct dpu_hw_pipe_cdp_cfg *cfg,
> +			enum dpu_sspp_multirect_index index);
>  };
> 
>  /**
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index d692136884ad..420cdd90e89b 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1241,7 +1241,7 @@ static void dpu_plane_sspp_atomic_update(struct
> drm_plane *plane)
>  					DPU_FORMAT_IS_TILE(fmt);
>  			cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
> 
> -			pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg);
> +			pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg,
> pstate->multirect_index);
>  		}
>  	}

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

* Re: [Freedreno] [PATCH v2 21/22] drm/msm/dpu: fix CDP setup to account for multirect index
@ 2021-11-10  2:12     ` abhinavk
  0 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-10  2:12 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, Bjorn Andersson, David Airlie, Sean Paul

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> Client driven prefetch (CDP) is properly setup only for SSPP REC0
> currently. Enable client driven prefetch also for SSPP REC1.
> 
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
Reviewed-by: Abhinav Kumar <abhinavk@codeaurora.org>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 12 ++++++++++--
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h |  4 +++-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c   |  2 +-
>  3 files changed, 14 insertions(+), 4 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 f93cdeb08ac7..96f2f3f12f34 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
> @@ -75,6 +75,7 @@
>  #define SSPP_TRAFFIC_SHAPER                0x130
>  #define SSPP_CDP_CNTL                      0x134
>  #define SSPP_UBWC_ERROR_STATUS             0x138
> +#define SSPP_CDP_CNTL_REC1                 0x13c
>  #define SSPP_TRAFFIC_SHAPER_PREFILL        0x150
>  #define SSPP_TRAFFIC_SHAPER_REC1_PREFILL   0x154
>  #define SSPP_TRAFFIC_SHAPER_REC1           0x158
> @@ -624,10 +625,12 @@ static void dpu_hw_sspp_setup_qos_ctrl(struct
> dpu_hw_pipe *ctx,
>  }
> 
>  static void dpu_hw_sspp_setup_cdp(struct dpu_hw_pipe *ctx,
> -		struct dpu_hw_pipe_cdp_cfg *cfg)
> +		struct dpu_hw_pipe_cdp_cfg *cfg,
> +		enum dpu_sspp_multirect_index index)
>  {
>  	u32 idx;
>  	u32 cdp_cntl = 0;
> +	u32 cdp_cntl_offset = 0;
> 
>  	if (!ctx || !cfg)
>  		return;
> @@ -635,6 +638,11 @@ static void dpu_hw_sspp_setup_cdp(struct 
> dpu_hw_pipe *ctx,
>  	if (_sspp_subblk_offset(ctx, DPU_SSPP_SRC, &idx))
>  		return;
> 
> +	if (index == DPU_SSPP_RECT_SOLO || index == DPU_SSPP_RECT_0)
> +		cdp_cntl_offset = SSPP_CDP_CNTL;
> +	else
> +		cdp_cntl_offset = SSPP_CDP_CNTL_REC1;
> +
>  	if (cfg->enable)
>  		cdp_cntl |= BIT(0);
>  	if (cfg->ubwc_meta_enable)
> @@ -644,7 +652,7 @@ static void dpu_hw_sspp_setup_cdp(struct 
> dpu_hw_pipe *ctx,
>  	if (cfg->preload_ahead == DPU_SSPP_CDP_PRELOAD_AHEAD_64)
>  		cdp_cntl |= BIT(3);
> 
> -	DPU_REG_WRITE(&ctx->hw, SSPP_CDP_CNTL, cdp_cntl);
> +	DPU_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl);
>  }
> 
>  static void _setup_layer_ops(struct dpu_hw_pipe *c,
> 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 c5ac8defa073..19c5358b962c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
> @@ -358,9 +358,11 @@ struct dpu_hw_sspp_ops {
>  	 * setup_cdp - setup client driven prefetch
>  	 * @ctx: Pointer to pipe context
>  	 * @cfg: Pointer to cdp configuration
> +	 * @index: rectangle index in multirect
>  	 */
>  	void (*setup_cdp)(struct dpu_hw_pipe *ctx,
> -			struct dpu_hw_pipe_cdp_cfg *cfg);
> +			struct dpu_hw_pipe_cdp_cfg *cfg,
> +			enum dpu_sspp_multirect_index index);
>  };
> 
>  /**
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index d692136884ad..420cdd90e89b 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -1241,7 +1241,7 @@ static void dpu_plane_sspp_atomic_update(struct
> drm_plane *plane)
>  					DPU_FORMAT_IS_TILE(fmt);
>  			cdp_cfg.preload_ahead = DPU_SSPP_CDP_PRELOAD_AHEAD_64;
> 
> -			pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg);
> +			pstate->pipe_hw->ops.setup_cdp(pstate->pipe_hw, &cdp_cfg,
> pstate->multirect_index);
>  		}
>  	}

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

* Re: [Freedreno] [PATCH v2 22/22] drm/msm/dpu: add multirect support
  2021-07-05  1:21   ` Dmitry Baryshkov
@ 2021-11-10  2:22     ` abhinavk
  -1 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-10  2:22 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: Bjorn Andersson, Rob Clark, Sean Paul, Jonathan Marek,
	Stephen Boyd, linux-arm-msm, dri-devel, David Airlie,
	Daniel Vetter, freedreno

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> If SmartDMA is supported by the hardware, SSPPs allow using two RGB
> layers per the hardware pipe (with some additional restrictions, like 
> no
> support for scaling, etc). Register additional planes (two per the 
> SSPP)
> and check if we can use multirect during atomic_check.
> 

I can see you are still making use of the dpu_rm_get_sspp() function to 
allocate SSPPs
for the drm planes even in the case of smart dma.

That function doesnt account for the foll considerations:

1) How does it guarantee plane priority while allocation? smart dma 
planes need to be allocated
in a priority order and that priority order decides which sspp does on 
the left rectangle and which one
on the right. I am not seeing how that is enforced in this 
implementation.

2) Another condition to be taken into account is that if one rectangle 
of one SSPP is utilized for one display,
the other rectangle of the SSPP cannot be used for another display. How 
is this guaranteed?
Does the RM global state account for this?

> 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_kms.c   |   2 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 109 +++++++++++++---------
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  29 +-----
>  4 files changed, 86 insertions(+), 72 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 49bdd5953b9f..49bd9df387b8 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -892,7 +892,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
> *crtc,
>  	struct dpu_global_state *global_state = 
> dpu_kms_get_global_state(state);
> 
>  	struct dpu_plane_state **pstates;
> -	struct dpu_plane_state *pstate;
> +	struct dpu_plane_state *pstate, *prev_plane_state;
> 
>  	struct drm_plane_state *plane_state;
>  	struct drm_plane *plane;
> @@ -962,6 +962,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
> *crtc,
>  	}
> 
>  	stage = DPU_STAGE_0;
> +	prev_plane_state = NULL;
>  	for (i = 0; i <= max_zpos; i++) {
>  		pstate = pstates[i];
>  		if (!pstate)
> @@ -977,8 +978,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
> *crtc,
> 
>  		plane_state = &pstate->base;
> 
> -		dpu_plane_clear_multirect(plane_state);
> -
>  		dst = drm_plane_state_dest(plane_state);
>  		if (!drm_rect_intersect(&dst, &crtc_rect)) {
>  			DPU_ERROR("invalid vertical/horizontal destination\n");
> @@ -990,7 +989,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
> *crtc,
>  		}
> 
>  		plane = pstate->base.plane;
> -		rc = dpu_plane_set_pipe(plane, pstate);
> +		rc = dpu_plane_set_pipe(plane, pstate, prev_plane_state);
>  		if (rc) {
>  			DPU_ERROR("%s: error setting pipe for %s\n", dpu_crtc->name, 
> plane->name);
>  			goto end;
> @@ -1002,6 +1001,17 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
> *crtc,
>  			goto end;
>  		}
> 
> +		/*
> +		 * If this plane was not selected for multirect, so we can try
> +		 * using it together with the next pipe.  If it selected for
> +		 * the REC1, next pipe will have to start from REC_SOLO (and
> +		 * maybe be promoted to REC0 later.
> +		 */
> +		if (pstate->multirect_index == DPU_SSPP_RECT_SOLO)
> +			prev_plane_state = pstate;
> +		else
> +			prev_plane_state = NULL;
> +
>  		pstates[i]->stage = stage++;
>  		DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
>  	}
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index 08a7e56cc98f..c3c3972627ca 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -646,7 +646,7 @@ static int _dpu_kms_create_planes_virtual(struct
> dpu_kms *dpu_kms, int max_crtc_
>  	catalog = dpu_kms->catalog;
> 
>  	/* Create the planes, keeping track of one primary/cursor per crtc */
> -	for (i = 0; i < catalog->sspp_count; i++) {
> +	for (i = 0; i < 2 * catalog->sspp_count; i++) {
>  		enum drm_plane_type type;
> 
>  		if (primary_planes_idx < max_crtc_count)
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 420cdd90e89b..77cb4f172379 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -292,10 +292,10 @@ static u64 _dpu_plane_get_qos_lut(const struct
> dpu_qos_lut_tbl *tbl,
>   * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
>   * @plane:		Pointer to drm plane
>   * @fb:			Pointer to framebuffer associated with the given plane
> - * @pipe_cfg:		Pointer to pipe configuration
> + * @src_width:		Plane source width (max for both multirect planes).
>   */
>  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, u32 src_width)
>  {
>  	struct dpu_plane *pdpu = to_dpu_plane(plane);
>  	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
> @@ -309,8 +309,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane 
> *plane,
>  		fmt = dpu_get_dpu_format_ext(
>  				fb->format->format,
>  				fb->modifier);
> -		total_fl = _dpu_plane_calc_fill_level(plane, fmt,
> -				drm_rect_width(&pipe_cfg->src_rect));
> +		total_fl = _dpu_plane_calc_fill_level(plane, fmt, src_width);
> 
>  		if (fmt && DPU_FORMAT_IS_LINEAR(fmt))
>  			lut_usage = DPU_QOS_LUT_USAGE_LINEAR;
> @@ -570,6 +569,9 @@ static void _dpu_plane_setup_scaler3(struct 
> dpu_plane *pdpu,
>  		&& (src_w == dst_w))
>  		return;
> 
> +	if (pstate->multirect_index != DPU_SSPP_RECT_SOLO)
> +		return;
> +
>  	scale_cfg->dst_width = dst_w;
>  	scale_cfg->dst_height = dst_h;
>  	scale_cfg->y_rgb_filter_cfg = DPU_SCALE_BIL;
> @@ -638,13 +640,16 @@ 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,
> +		const struct dpu_format *fmt,
>  		struct dpu_hw_pipe_cfg *pipe_cfg)
>  {
>  	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;
> 
> +	if (pstate->multirect_index == DPU_SSPP_RECT_1)
> +		return;
> +
>  	memset(&scaler3_cfg, 0, sizeof(scaler3_cfg));
>  	memset(&pixel_ext, 0, sizeof(pixel_ext));
> 
> @@ -667,8 +672,7 @@ static void _dpu_plane_setup_scaler(struct 
> dpu_plane *pdpu,
>  	 * bypassed. Still we need to update alpha and bitwidth
>  	 * ONLY for RECT0
>  	 */
> -	if (pstate->pipe_hw->ops.setup_scaler &&
> -			pstate->multirect_index != DPU_SSPP_RECT_1)
> +	if (pstate->pipe_hw->ops.setup_scaler)
>  		pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
>  				pipe_cfg, &pixel_ext,
>  				&scaler3_cfg);
> @@ -723,23 +727,15 @@ static int _dpu_plane_color_fill(struct dpu_plane 
> *pdpu,
>  					&pipe_cfg,
>  					pstate->multirect_index);
> 
> -		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
> +		_dpu_plane_setup_scaler(pdpu, pstate, fmt, &pipe_cfg);
>  	}
> 
>  	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->multirect_index = DPU_SSPP_RECT_SOLO;
> -	pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> -}
> -
> -int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states 
> *plane)
> +static int dpu_plane_validate_multirect_v2(struct dpu_plane_state 
> *pstate0,
> +					   struct dpu_plane_state *pstate1)
>  {
> -	struct dpu_plane_state *pstate[R_MAX];
>  	const struct drm_plane_state *drm_state[R_MAX];
>  	struct drm_rect src[R_MAX], dst[R_MAX];
>  	struct dpu_plane *dpu_plane[R_MAX];
> @@ -750,9 +746,17 @@ int dpu_plane_validate_multirect_v2(struct
> dpu_multirect_plane_states *plane)
>  	bool has_tiled_rect = false;
> 
>  	for (i = 0; i < R_MAX; i++) {
> +		struct dpu_plane_state *pstate;
>  		const struct msm_format *msm_fmt;
> 
> -		drm_state[i] = i ? plane->r1 : plane->r0;
> +		pstate = i ? pstate1 : pstate0;
> +		if (pstate == NULL) {
> +			DPU_DEBUG("DPU plane state of plane id %d is NULL\n",
> +				drm_state[i]->plane->base.id);
> +			return -EINVAL;
> +		}
> +
> +		drm_state[i] = &pstate->base;
>  		msm_fmt = msm_framebuffer_format(drm_state[i]->fb);
>  		fmt[i] = to_dpu_format(msm_fmt);
> 
> @@ -766,15 +770,8 @@ int dpu_plane_validate_multirect_v2(struct
> dpu_multirect_plane_states *plane)
>  	for (i = 0; i < R_MAX; i++) {
>  		int width_threshold;
> 
> -		pstate[i] = to_dpu_plane_state(drm_state[i]);
>  		dpu_plane[i] = to_dpu_plane(drm_state[i]->plane);
> 
> -		if (pstate[i] == NULL) {
> -			DPU_ERROR("DPU plane state of plane id %d is NULL\n",
> -				drm_state[i]->plane->base.id);
> -			return -EINVAL;
> -		}
> -
>  		src[i].x1 = drm_state[i]->src_x >> 16;
>  		src[i].y1 = drm_state[i]->src_y >> 16;
>  		src[i].x2 = src[i].x1 + (drm_state[i]->src_w >> 16);
> @@ -784,13 +781,13 @@ int dpu_plane_validate_multirect_v2(struct
> dpu_multirect_plane_states *plane)
> 
>  		if (drm_rect_calc_hscale(&src[i], &dst[i], 1, 1) != 1 ||
>  		    drm_rect_calc_vscale(&src[i], &dst[i], 1, 1) != 1) {
> -			DPU_ERROR_PLANE(dpu_plane[i],
> +			DPU_DEBUG_PLANE(dpu_plane[i],
>  				"scaling is not supported in multirect mode\n");
>  			return -EINVAL;
>  		}
> 
>  		if (DPU_FORMAT_IS_YUV(fmt[i])) {
> -			DPU_ERROR_PLANE(dpu_plane[i],
> +			DPU_DEBUG_PLANE(dpu_plane[i],
>  				"Unsupported format for multirect mode\n");
>  			return -EINVAL;
>  		}
> @@ -816,8 +813,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;
> +		pstate0->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
> +		pstate1->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
> 
>  		goto done;
>  	}
> @@ -827,10 +824,10 @@ 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;
> +		pstate0->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
> +		pstate1->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>  	} else {
> -		DPU_ERROR(
> +		DPU_DEBUG(
>  			"No multirect mode possible for the planes (%d - %d)\n",
>  			drm_state[R0]->plane->base.id,
>  			drm_state[R1]->plane->base.id);
> @@ -838,13 +835,15 @@ 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;
> +	pstate0->multirect_index = DPU_SSPP_RECT_0;
> +	pstate1->multirect_index = DPU_SSPP_RECT_1;
> +
> +	pstate0->qos_src_w = max(pstate0->qos_src_w, pstate1->base.src_w >> 
> 16);
> 
>  	DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
> -		pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
> +		pstate0->multirect_mode, pstate0->multirect_index);
>  	DPU_DEBUG_PLANE(dpu_plane[R1], "R1: %d - %d\n",
> -		pstate[R1]->multirect_mode, pstate[R1]->multirect_index);
> +		pstate1->multirect_mode, pstate1->multirect_index);
>  	return 0;
>  }
> 
> @@ -928,7 +927,8 @@ static bool dpu_plane_validate_src(struct drm_rect 
> *src,
>  		drm_rect_equals(fb_rect, src);
>  }
> 
> -int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state 
> *pstate)
> +int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state 
> *pstate,
> +		struct dpu_plane_state *prev_plane_state)
>  {
>  	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
>  	struct dpu_plane *pdpu = to_dpu_plane(plane);
> @@ -936,11 +936,24 @@ int dpu_plane_set_pipe(struct drm_plane *plane,
> struct dpu_plane_state *pstate)
>  	enum dpu_sspp pipe;
>  	bool yuv, scale;
> 
> +	pstate->multirect_index = DPU_SSPP_RECT_SOLO;
> +	pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> +
>  	if (pdpu->pipe != SSPP_NONE) {
>  		pipe = pdpu->pipe;
>  		goto out;
>  	}
> 
> +	if (prev_plane_state &&
> +	    kms->catalog->caps->smart_dma_rev != DPU_SMART_DMA_UNSUPPORTED &&
> +	    !dpu_plane_validate_multirect_v2(prev_plane_state, pstate)) {
> +		/* multirect capable, use the same pipe */
> +		DPU_DEBUG_PLANE(pdpu, "multirect, SSPP %d\n",
> prev_plane_state->pipe_hw->idx);
> +		pstate->pipe_hw = prev_plane_state->pipe_hw;
> +
> +		return 0;
> +	}
> +
>  	yuv = pstate->base.fb ?
> DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(pstate->base.fb)))
> : false;
>  	scale = (pstate->base.src_w >> 16 != pstate->base.crtc_w) ||
>  		(pstate->base.src_h >> 16 != pstate->base.crtc_h);
> @@ -953,6 +966,8 @@ int dpu_plane_set_pipe(struct drm_plane *plane,
> struct dpu_plane_state *pstate)
>  	if (pipe == SSPP_NONE || pipe >= SSPP_MAX || !kms->rm.sspp_blks[pipe
> - SSPP_NONE])
>  		return -EINVAL;
> 
> +	pstate->qos_src_w = pstate->base.src_w >> 16;
> +
>  	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - 
> SSPP_NONE]);
> 
>  	return 0;
> @@ -988,7 +1003,7 @@ static int dpu_plane_atomic_check(struct drm_plane 
> *plane,
> 
>  		DRM_DEBUG_ATOMIC("PLANE %d released SSPP %d\n", plane->base.id,
> pstate->pipe_hw->idx);
>  		dpu_rm_release_sspp(&dpu_kms->rm, global_state, plane->base.id);
> -		pstate->pipe_hw = NULL;
> +		/* do not clear pipe_hw here, use it in atomic_disable to cleanup
> mutlirect */
>  	}
> 
>  	return 0;
> @@ -1199,7 +1214,7 @@ static void dpu_plane_sspp_atomic_update(struct
> drm_plane *plane)
>  				pstate->multirect_index);
>  	}
> 
> -	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
> +	_dpu_plane_setup_scaler(pdpu, pstate, fmt, &pipe_cfg);
> 
>  	if (pstate->pipe_hw->ops.setup_multirect)
>  		pstate->pipe_hw->ops.setup_multirect(
> @@ -1245,8 +1260,10 @@ 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);
> +	if (pstate->multirect_index != DPU_SSPP_RECT_1) {
> +		_dpu_plane_set_qos_lut(plane, fb, pstate->qos_src_w);
> +		_dpu_plane_set_danger_lut(plane, fb);
> +	}
> 
>  	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
>  		_dpu_plane_set_qos_ctrl(plane, true, DPU_PLANE_QOS_PANIC_CTRL);
> @@ -1279,7 +1296,13 @@ static void _dpu_plane_atomic_disable(struct
> drm_plane *plane)
> 
>  	pstate->pending = true;
> 
> -	pstate->pipe_hw = NULL;
> +	if (pstate->multirect_index != DPU_SSPP_RECT_SOLO &&
> +	    pstate->pipe_hw &&
> +	    pstate->pipe_hw->ops.setup_multirect)
> +		pstate->pipe_hw->ops.setup_multirect(
> +				pstate->pipe_hw,
> +				DPU_SSPP_RECT_SOLO,
> +				DPU_SSPP_MULTIRECT_NONE);
>  }
> 
>  static void dpu_plane_atomic_update(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 0940ffbb8b28..6ec7f5edc06a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -23,6 +23,7 @@
>   * @multirect_index: index of the rectangle of SSPP
>   * @multirect_mode: parallel or time multiplex multirect mode
>   * @pending:	whether the current update is still pending
> + * @qos_src_w: src_width used for qos_lut setup
>   * @plane_fetch_bw: calculated BW per plane
>   * @plane_clk: calculated clk per plane
>   */
> @@ -35,22 +36,14 @@ struct dpu_plane_state {
>  	uint32_t multirect_mode;
>  	bool pending;
> 
> +	uint32_t qos_src_w;
> +
>  	struct dpu_hw_pipe *pipe_hw;
> 
>  	u64 plane_fetch_bw;
>  	u64 plane_clk;
>  };
> 
> -/**
> - * struct dpu_multirect_plane_states: Defines multirect pair of drm
> plane states
> - * @r0: drm plane configured on rect 0
> - * @r1: drm plane configured on rect 1
> - */
> -struct dpu_multirect_plane_states {
> -	const struct drm_plane_state *r0;
> -	const struct drm_plane_state *r1;
> -};
> -
>  #define to_dpu_plane_state(x) \
>  	container_of(x, struct dpu_plane_state, base)
> 
> @@ -78,19 +71,6 @@ struct drm_plane *dpu_plane_init(struct drm_device 
> *dev,
>  		uint32_t pipe, enum drm_plane_type type,
>  		unsigned long possible_crtcs);
> 
> -/**
> - * dpu_plane_validate_multirecti_v2 - validate the multirect planes
> - *				      against hw limitations
> - * @plane: drm plate states of the multirect pair
> - */
> -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
> @@ -107,7 +87,8 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane
> *plane, bool enable);
>  static inline void dpu_plane_danger_signal_ctrl(struct drm_plane
> *plane, bool enable) {}
>  #endif
> 
> -int dpu_plane_set_pipe(struct drm_plane *plane, struct
> dpu_plane_state *pstate);
> +int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state 
> *pstate,
> +		struct dpu_plane_state *prev_plane_state);
> 
>  int dpu_plane_real_atomic_check(struct drm_plane *plane,
>  				struct drm_atomic_state *state);

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

* Re: [Freedreno] [PATCH v2 22/22] drm/msm/dpu: add multirect support
@ 2021-11-10  2:22     ` abhinavk
  0 siblings, 0 replies; 69+ messages in thread
From: abhinavk @ 2021-11-10  2:22 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: freedreno, Jonathan Marek, Stephen Boyd, linux-arm-msm,
	dri-devel, Bjorn Andersson, David Airlie, Sean Paul

On 2021-07-04 18:21, Dmitry Baryshkov wrote:
> If SmartDMA is supported by the hardware, SSPPs allow using two RGB
> layers per the hardware pipe (with some additional restrictions, like 
> no
> support for scaling, etc). Register additional planes (two per the 
> SSPP)
> and check if we can use multirect during atomic_check.
> 

I can see you are still making use of the dpu_rm_get_sspp() function to 
allocate SSPPs
for the drm planes even in the case of smart dma.

That function doesnt account for the foll considerations:

1) How does it guarantee plane priority while allocation? smart dma 
planes need to be allocated
in a priority order and that priority order decides which sspp does on 
the left rectangle and which one
on the right. I am not seeing how that is enforced in this 
implementation.

2) Another condition to be taken into account is that if one rectangle 
of one SSPP is utilized for one display,
the other rectangle of the SSPP cannot be used for another display. How 
is this guaranteed?
Does the RM global state account for this?

> 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_kms.c   |   2 +-
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 109 +++++++++++++---------
>  drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h |  29 +-----
>  4 files changed, 86 insertions(+), 72 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> index 49bdd5953b9f..49bd9df387b8 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
> @@ -892,7 +892,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
> *crtc,
>  	struct dpu_global_state *global_state = 
> dpu_kms_get_global_state(state);
> 
>  	struct dpu_plane_state **pstates;
> -	struct dpu_plane_state *pstate;
> +	struct dpu_plane_state *pstate, *prev_plane_state;
> 
>  	struct drm_plane_state *plane_state;
>  	struct drm_plane *plane;
> @@ -962,6 +962,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
> *crtc,
>  	}
> 
>  	stage = DPU_STAGE_0;
> +	prev_plane_state = NULL;
>  	for (i = 0; i <= max_zpos; i++) {
>  		pstate = pstates[i];
>  		if (!pstate)
> @@ -977,8 +978,6 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
> *crtc,
> 
>  		plane_state = &pstate->base;
> 
> -		dpu_plane_clear_multirect(plane_state);
> -
>  		dst = drm_plane_state_dest(plane_state);
>  		if (!drm_rect_intersect(&dst, &crtc_rect)) {
>  			DPU_ERROR("invalid vertical/horizontal destination\n");
> @@ -990,7 +989,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
> *crtc,
>  		}
> 
>  		plane = pstate->base.plane;
> -		rc = dpu_plane_set_pipe(plane, pstate);
> +		rc = dpu_plane_set_pipe(plane, pstate, prev_plane_state);
>  		if (rc) {
>  			DPU_ERROR("%s: error setting pipe for %s\n", dpu_crtc->name, 
> plane->name);
>  			goto end;
> @@ -1002,6 +1001,17 @@ static int dpu_crtc_atomic_check(struct drm_crtc 
> *crtc,
>  			goto end;
>  		}
> 
> +		/*
> +		 * If this plane was not selected for multirect, so we can try
> +		 * using it together with the next pipe.  If it selected for
> +		 * the REC1, next pipe will have to start from REC_SOLO (and
> +		 * maybe be promoted to REC0 later.
> +		 */
> +		if (pstate->multirect_index == DPU_SSPP_RECT_SOLO)
> +			prev_plane_state = pstate;
> +		else
> +			prev_plane_state = NULL;
> +
>  		pstates[i]->stage = stage++;
>  		DRM_DEBUG_ATOMIC("%s: stage %d\n", dpu_crtc->name, stage);
>  	}
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> index 08a7e56cc98f..c3c3972627ca 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c
> @@ -646,7 +646,7 @@ static int _dpu_kms_create_planes_virtual(struct
> dpu_kms *dpu_kms, int max_crtc_
>  	catalog = dpu_kms->catalog;
> 
>  	/* Create the planes, keeping track of one primary/cursor per crtc */
> -	for (i = 0; i < catalog->sspp_count; i++) {
> +	for (i = 0; i < 2 * catalog->sspp_count; i++) {
>  		enum drm_plane_type type;
> 
>  		if (primary_planes_idx < max_crtc_count)
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> index 420cdd90e89b..77cb4f172379 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
> @@ -292,10 +292,10 @@ static u64 _dpu_plane_get_qos_lut(const struct
> dpu_qos_lut_tbl *tbl,
>   * _dpu_plane_set_qos_lut - set QoS LUT of the given plane
>   * @plane:		Pointer to drm plane
>   * @fb:			Pointer to framebuffer associated with the given plane
> - * @pipe_cfg:		Pointer to pipe configuration
> + * @src_width:		Plane source width (max for both multirect planes).
>   */
>  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, u32 src_width)
>  {
>  	struct dpu_plane *pdpu = to_dpu_plane(plane);
>  	struct dpu_plane_state *pstate = to_dpu_plane_state(plane->state);
> @@ -309,8 +309,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane 
> *plane,
>  		fmt = dpu_get_dpu_format_ext(
>  				fb->format->format,
>  				fb->modifier);
> -		total_fl = _dpu_plane_calc_fill_level(plane, fmt,
> -				drm_rect_width(&pipe_cfg->src_rect));
> +		total_fl = _dpu_plane_calc_fill_level(plane, fmt, src_width);
> 
>  		if (fmt && DPU_FORMAT_IS_LINEAR(fmt))
>  			lut_usage = DPU_QOS_LUT_USAGE_LINEAR;
> @@ -570,6 +569,9 @@ static void _dpu_plane_setup_scaler3(struct 
> dpu_plane *pdpu,
>  		&& (src_w == dst_w))
>  		return;
> 
> +	if (pstate->multirect_index != DPU_SSPP_RECT_SOLO)
> +		return;
> +
>  	scale_cfg->dst_width = dst_w;
>  	scale_cfg->dst_height = dst_h;
>  	scale_cfg->y_rgb_filter_cfg = DPU_SCALE_BIL;
> @@ -638,13 +640,16 @@ 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,
> +		const struct dpu_format *fmt,
>  		struct dpu_hw_pipe_cfg *pipe_cfg)
>  {
>  	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;
> 
> +	if (pstate->multirect_index == DPU_SSPP_RECT_1)
> +		return;
> +
>  	memset(&scaler3_cfg, 0, sizeof(scaler3_cfg));
>  	memset(&pixel_ext, 0, sizeof(pixel_ext));
> 
> @@ -667,8 +672,7 @@ static void _dpu_plane_setup_scaler(struct 
> dpu_plane *pdpu,
>  	 * bypassed. Still we need to update alpha and bitwidth
>  	 * ONLY for RECT0
>  	 */
> -	if (pstate->pipe_hw->ops.setup_scaler &&
> -			pstate->multirect_index != DPU_SSPP_RECT_1)
> +	if (pstate->pipe_hw->ops.setup_scaler)
>  		pstate->pipe_hw->ops.setup_scaler(pstate->pipe_hw,
>  				pipe_cfg, &pixel_ext,
>  				&scaler3_cfg);
> @@ -723,23 +727,15 @@ static int _dpu_plane_color_fill(struct dpu_plane 
> *pdpu,
>  					&pipe_cfg,
>  					pstate->multirect_index);
> 
> -		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true, &pipe_cfg);
> +		_dpu_plane_setup_scaler(pdpu, pstate, fmt, &pipe_cfg);
>  	}
> 
>  	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->multirect_index = DPU_SSPP_RECT_SOLO;
> -	pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> -}
> -
> -int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states 
> *plane)
> +static int dpu_plane_validate_multirect_v2(struct dpu_plane_state 
> *pstate0,
> +					   struct dpu_plane_state *pstate1)
>  {
> -	struct dpu_plane_state *pstate[R_MAX];
>  	const struct drm_plane_state *drm_state[R_MAX];
>  	struct drm_rect src[R_MAX], dst[R_MAX];
>  	struct dpu_plane *dpu_plane[R_MAX];
> @@ -750,9 +746,17 @@ int dpu_plane_validate_multirect_v2(struct
> dpu_multirect_plane_states *plane)
>  	bool has_tiled_rect = false;
> 
>  	for (i = 0; i < R_MAX; i++) {
> +		struct dpu_plane_state *pstate;
>  		const struct msm_format *msm_fmt;
> 
> -		drm_state[i] = i ? plane->r1 : plane->r0;
> +		pstate = i ? pstate1 : pstate0;
> +		if (pstate == NULL) {
> +			DPU_DEBUG("DPU plane state of plane id %d is NULL\n",
> +				drm_state[i]->plane->base.id);
> +			return -EINVAL;
> +		}
> +
> +		drm_state[i] = &pstate->base;
>  		msm_fmt = msm_framebuffer_format(drm_state[i]->fb);
>  		fmt[i] = to_dpu_format(msm_fmt);
> 
> @@ -766,15 +770,8 @@ int dpu_plane_validate_multirect_v2(struct
> dpu_multirect_plane_states *plane)
>  	for (i = 0; i < R_MAX; i++) {
>  		int width_threshold;
> 
> -		pstate[i] = to_dpu_plane_state(drm_state[i]);
>  		dpu_plane[i] = to_dpu_plane(drm_state[i]->plane);
> 
> -		if (pstate[i] == NULL) {
> -			DPU_ERROR("DPU plane state of plane id %d is NULL\n",
> -				drm_state[i]->plane->base.id);
> -			return -EINVAL;
> -		}
> -
>  		src[i].x1 = drm_state[i]->src_x >> 16;
>  		src[i].y1 = drm_state[i]->src_y >> 16;
>  		src[i].x2 = src[i].x1 + (drm_state[i]->src_w >> 16);
> @@ -784,13 +781,13 @@ int dpu_plane_validate_multirect_v2(struct
> dpu_multirect_plane_states *plane)
> 
>  		if (drm_rect_calc_hscale(&src[i], &dst[i], 1, 1) != 1 ||
>  		    drm_rect_calc_vscale(&src[i], &dst[i], 1, 1) != 1) {
> -			DPU_ERROR_PLANE(dpu_plane[i],
> +			DPU_DEBUG_PLANE(dpu_plane[i],
>  				"scaling is not supported in multirect mode\n");
>  			return -EINVAL;
>  		}
> 
>  		if (DPU_FORMAT_IS_YUV(fmt[i])) {
> -			DPU_ERROR_PLANE(dpu_plane[i],
> +			DPU_DEBUG_PLANE(dpu_plane[i],
>  				"Unsupported format for multirect mode\n");
>  			return -EINVAL;
>  		}
> @@ -816,8 +813,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;
> +		pstate0->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
> +		pstate1->multirect_mode = DPU_SSPP_MULTIRECT_PARALLEL;
> 
>  		goto done;
>  	}
> @@ -827,10 +824,10 @@ 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;
> +		pstate0->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
> +		pstate1->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
>  	} else {
> -		DPU_ERROR(
> +		DPU_DEBUG(
>  			"No multirect mode possible for the planes (%d - %d)\n",
>  			drm_state[R0]->plane->base.id,
>  			drm_state[R1]->plane->base.id);
> @@ -838,13 +835,15 @@ 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;
> +	pstate0->multirect_index = DPU_SSPP_RECT_0;
> +	pstate1->multirect_index = DPU_SSPP_RECT_1;
> +
> +	pstate0->qos_src_w = max(pstate0->qos_src_w, pstate1->base.src_w >> 
> 16);
> 
>  	DPU_DEBUG_PLANE(dpu_plane[R0], "R0: %d - %d\n",
> -		pstate[R0]->multirect_mode, pstate[R0]->multirect_index);
> +		pstate0->multirect_mode, pstate0->multirect_index);
>  	DPU_DEBUG_PLANE(dpu_plane[R1], "R1: %d - %d\n",
> -		pstate[R1]->multirect_mode, pstate[R1]->multirect_index);
> +		pstate1->multirect_mode, pstate1->multirect_index);
>  	return 0;
>  }
> 
> @@ -928,7 +927,8 @@ static bool dpu_plane_validate_src(struct drm_rect 
> *src,
>  		drm_rect_equals(fb_rect, src);
>  }
> 
> -int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state 
> *pstate)
> +int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state 
> *pstate,
> +		struct dpu_plane_state *prev_plane_state)
>  {
>  	struct dpu_kms *kms = _dpu_plane_get_kms(plane);
>  	struct dpu_plane *pdpu = to_dpu_plane(plane);
> @@ -936,11 +936,24 @@ int dpu_plane_set_pipe(struct drm_plane *plane,
> struct dpu_plane_state *pstate)
>  	enum dpu_sspp pipe;
>  	bool yuv, scale;
> 
> +	pstate->multirect_index = DPU_SSPP_RECT_SOLO;
> +	pstate->multirect_mode = DPU_SSPP_MULTIRECT_NONE;
> +
>  	if (pdpu->pipe != SSPP_NONE) {
>  		pipe = pdpu->pipe;
>  		goto out;
>  	}
> 
> +	if (prev_plane_state &&
> +	    kms->catalog->caps->smart_dma_rev != DPU_SMART_DMA_UNSUPPORTED &&
> +	    !dpu_plane_validate_multirect_v2(prev_plane_state, pstate)) {
> +		/* multirect capable, use the same pipe */
> +		DPU_DEBUG_PLANE(pdpu, "multirect, SSPP %d\n",
> prev_plane_state->pipe_hw->idx);
> +		pstate->pipe_hw = prev_plane_state->pipe_hw;
> +
> +		return 0;
> +	}
> +
>  	yuv = pstate->base.fb ?
> DPU_FORMAT_IS_YUV(to_dpu_format(msm_framebuffer_format(pstate->base.fb)))
> : false;
>  	scale = (pstate->base.src_w >> 16 != pstate->base.crtc_w) ||
>  		(pstate->base.src_h >> 16 != pstate->base.crtc_h);
> @@ -953,6 +966,8 @@ int dpu_plane_set_pipe(struct drm_plane *plane,
> struct dpu_plane_state *pstate)
>  	if (pipe == SSPP_NONE || pipe >= SSPP_MAX || !kms->rm.sspp_blks[pipe
> - SSPP_NONE])
>  		return -EINVAL;
> 
> +	pstate->qos_src_w = pstate->base.src_w >> 16;
> +
>  	pstate->pipe_hw = to_dpu_hw_pipe(kms->rm.sspp_blks[pipe - 
> SSPP_NONE]);
> 
>  	return 0;
> @@ -988,7 +1003,7 @@ static int dpu_plane_atomic_check(struct drm_plane 
> *plane,
> 
>  		DRM_DEBUG_ATOMIC("PLANE %d released SSPP %d\n", plane->base.id,
> pstate->pipe_hw->idx);
>  		dpu_rm_release_sspp(&dpu_kms->rm, global_state, plane->base.id);
> -		pstate->pipe_hw = NULL;
> +		/* do not clear pipe_hw here, use it in atomic_disable to cleanup
> mutlirect */
>  	}
> 
>  	return 0;
> @@ -1199,7 +1214,7 @@ static void dpu_plane_sspp_atomic_update(struct
> drm_plane *plane)
>  				pstate->multirect_index);
>  	}
> 
> -	_dpu_plane_setup_scaler(pdpu, pstate, fmt, false, &pipe_cfg);
> +	_dpu_plane_setup_scaler(pdpu, pstate, fmt, &pipe_cfg);
> 
>  	if (pstate->pipe_hw->ops.setup_multirect)
>  		pstate->pipe_hw->ops.setup_multirect(
> @@ -1245,8 +1260,10 @@ 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);
> +	if (pstate->multirect_index != DPU_SSPP_RECT_1) {
> +		_dpu_plane_set_qos_lut(plane, fb, pstate->qos_src_w);
> +		_dpu_plane_set_danger_lut(plane, fb);
> +	}
> 
>  	if (plane->type != DRM_PLANE_TYPE_CURSOR) {
>  		_dpu_plane_set_qos_ctrl(plane, true, DPU_PLANE_QOS_PANIC_CTRL);
> @@ -1279,7 +1296,13 @@ static void _dpu_plane_atomic_disable(struct
> drm_plane *plane)
> 
>  	pstate->pending = true;
> 
> -	pstate->pipe_hw = NULL;
> +	if (pstate->multirect_index != DPU_SSPP_RECT_SOLO &&
> +	    pstate->pipe_hw &&
> +	    pstate->pipe_hw->ops.setup_multirect)
> +		pstate->pipe_hw->ops.setup_multirect(
> +				pstate->pipe_hw,
> +				DPU_SSPP_RECT_SOLO,
> +				DPU_SSPP_MULTIRECT_NONE);
>  }
> 
>  static void dpu_plane_atomic_update(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 0940ffbb8b28..6ec7f5edc06a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h
> @@ -23,6 +23,7 @@
>   * @multirect_index: index of the rectangle of SSPP
>   * @multirect_mode: parallel or time multiplex multirect mode
>   * @pending:	whether the current update is still pending
> + * @qos_src_w: src_width used for qos_lut setup
>   * @plane_fetch_bw: calculated BW per plane
>   * @plane_clk: calculated clk per plane
>   */
> @@ -35,22 +36,14 @@ struct dpu_plane_state {
>  	uint32_t multirect_mode;
>  	bool pending;
> 
> +	uint32_t qos_src_w;
> +
>  	struct dpu_hw_pipe *pipe_hw;
> 
>  	u64 plane_fetch_bw;
>  	u64 plane_clk;
>  };
> 
> -/**
> - * struct dpu_multirect_plane_states: Defines multirect pair of drm
> plane states
> - * @r0: drm plane configured on rect 0
> - * @r1: drm plane configured on rect 1
> - */
> -struct dpu_multirect_plane_states {
> -	const struct drm_plane_state *r0;
> -	const struct drm_plane_state *r1;
> -};
> -
>  #define to_dpu_plane_state(x) \
>  	container_of(x, struct dpu_plane_state, base)
> 
> @@ -78,19 +71,6 @@ struct drm_plane *dpu_plane_init(struct drm_device 
> *dev,
>  		uint32_t pipe, enum drm_plane_type type,
>  		unsigned long possible_crtcs);
> 
> -/**
> - * dpu_plane_validate_multirecti_v2 - validate the multirect planes
> - *				      against hw limitations
> - * @plane: drm plate states of the multirect pair
> - */
> -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
> @@ -107,7 +87,8 @@ void dpu_plane_danger_signal_ctrl(struct drm_plane
> *plane, bool enable);
>  static inline void dpu_plane_danger_signal_ctrl(struct drm_plane
> *plane, bool enable) {}
>  #endif
> 
> -int dpu_plane_set_pipe(struct drm_plane *plane, struct
> dpu_plane_state *pstate);
> +int dpu_plane_set_pipe(struct drm_plane *plane, struct dpu_plane_state 
> *pstate,
> +		struct dpu_plane_state *prev_plane_state);
> 
>  int dpu_plane_real_atomic_check(struct drm_plane *plane,
>  				struct drm_atomic_state *state);

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

end of thread, other threads:[~2021-11-10  2:22 UTC | newest]

Thread overview: 69+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-07-05  1:20 [PATCH v2 00/22] drm/msm/dpu: switch dpu_plane to be virtual Dmitry Baryshkov
2021-07-05  1:20 ` Dmitry Baryshkov
2021-07-05  1:20 ` [PATCH v2 01/22] drm/msm/dpu: move LUT levels out of QOS config Dmitry Baryshkov
2021-07-05  1:20   ` Dmitry Baryshkov
2021-07-05  1:20 ` [PATCH v2 02/22] drm/msm/dpu: remove pipe_qos_cfg from struct dpu_plane Dmitry Baryshkov
2021-07-05  1:20   ` Dmitry Baryshkov
2021-07-05  1:20 ` [PATCH v2 03/22] drm/msm/dpu: drop pipe_name " Dmitry Baryshkov
2021-07-05  1:20   ` Dmitry Baryshkov
2021-07-05  1:20 ` [PATCH v2 04/22] drm/msm/dpu: remove stage_cfg from struct dpu_crtc Dmitry Baryshkov
2021-07-05  1:20   ` Dmitry Baryshkov
2021-07-05  1:20 ` [PATCH v2 05/22] drm/msm/dpu: rip out master planes support Dmitry Baryshkov
2021-07-05  1:20   ` Dmitry Baryshkov
2021-07-05  1:20 ` [PATCH v2 06/22] drm/msm/dpu: move dpu_hw_pipe_cfg out of struct dpu_plane Dmitry Baryshkov
2021-07-05  1:20   ` Dmitry Baryshkov
2021-07-05  1:21 ` [PATCH v2 07/22] drm/msm/dpu: drop scaler config from plane state Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-07-05  1:21 ` [PATCH v2 08/22] drm/msm/dpu: drop dpu_csc_cfg from dpu_plane Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-07-05  1:21 ` [PATCH v2 09/22] drm/msm/dpu: remove dpu_hw_pipe_cdp_cfg " Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-07-05  1:21 ` [PATCH v2 10/22] drm/msm/dpu: don't cache pipe->cap->features in dpu_plane Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-07-05  1:21 ` [PATCH v2 11/22] drm/msm/dpu: don't cache pipe->cap->sblk " Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-07-05  1:21 ` [PATCH v2 12/22] drm/msm/dpu: rip out debugfs support from dpu_plane Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-07-05  1:21 ` [PATCH v2 13/22] drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-07-05  1:21 ` [PATCH v2 14/22] drm/msm/dpu: add list of supported formats to the DPU caps Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-11-09 20:05   ` [Freedreno] " abhinavk
2021-11-09 20:05     ` abhinavk
2021-07-05  1:21 ` [PATCH v2 15/22] drm/msm/dpu: simplify DPU_SSPP features checks Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-11-09 20:06   ` [Freedreno] " abhinavk
2021-11-09 20:06     ` abhinavk
2021-07-05  1:21 ` [PATCH v2 16/22] drm/msm/dpu: do not limit the zpos property Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-11-09 20:15   ` [Freedreno] " abhinavk
2021-11-09 20:15     ` abhinavk
2021-11-09 20:21     ` Dmitry Baryshkov
2021-11-09 20:21       ` Dmitry Baryshkov
2021-11-10  1:35       ` abhinavk
2021-11-10  1:35         ` abhinavk
2021-11-10  1:58         ` Dmitry Baryshkov
2021-11-10  1:58           ` Dmitry Baryshkov
2021-07-05  1:21 ` [PATCH v2 17/22] drm/msm/dpu: add support for SSPP allocation to RM Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-11-10  0:30   ` [Freedreno] " abhinavk
2021-11-10  0:30     ` abhinavk
2021-07-05  1:21 ` [PATCH v2 18/22] drm/msm/dpu: move pipe_hw to dpu_plane_state Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-07-05  1:21 ` [PATCH v2 19/22] drm/msm/dpu: add support for virtualized planes Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-07-05  1:21 ` [PATCH v2 20/22] drm/msm/dpu: fix smart dma support Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-11-10  2:06   ` [Freedreno] " abhinavk
2021-11-10  2:06     ` abhinavk
2021-07-05  1:21 ` [PATCH v2 21/22] drm/msm/dpu: fix CDP setup to account for multirect index Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-11-10  2:12   ` [Freedreno] " abhinavk
2021-11-10  2:12     ` abhinavk
2021-07-05  1:21 ` [PATCH v2 22/22] drm/msm/dpu: add multirect support Dmitry Baryshkov
2021-07-05  1:21   ` Dmitry Baryshkov
2021-11-10  2:22   ` [Freedreno] " abhinavk
2021-11-10  2:22     ` abhinavk
2021-09-30  2:19 ` [Freedreno] [PATCH v2 00/22] drm/msm/dpu: switch dpu_plane to be virtual abhinavk
2021-09-30 10:56   ` Dmitry Baryshkov
2021-09-30 10:56     ` 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.