linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/7] drm/msm/dpu: Implement tearcheck support on INTF block
@ 2022-12-31 21:49 Marijn Suijten
  2022-12-31 21:50 ` [RFC PATCH 1/7] drm/msm/dpu: Remove unused INTF0 interrupt mask from sm6115/qcm2290 Marijn Suijten
                   ` (6 more replies)
  0 siblings, 7 replies; 33+ messages in thread
From: Marijn Suijten @ 2022-12-31 21:49 UTC (permalink / raw)
  To: phone-devel, Abhinav Kumar, Dmitry Baryshkov, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Marijn Suijten,
	Rob Clark, Sean Paul, David Airlie, Daniel Vetter, Stephen Boyd,
	Vinod Koul, Bjorn Andersson, Kuogee Hsieh, Jessica Zhang,
	Konrad Dybcio, Loic Poulain, Vinod Polimera, Adam Skladowski,
	linux-arm-msm, dri-devel, freedreno, linux-kernel

Since DPU 5.0.0 the TEARCHECK registers and interrupts moved out of the
PINGPONG block and into the INTF.  Implement the necessary callbacks in
the INTF block, and use these callbacks together with the INTF_TEAR
interrupts.  Additionally, disable previous register writes and remove
unused interrupts in the PINGPONG and MDP_TOP blocks for these newer
platforms.

With these patches the devices on DPU >= 5.0.0 listed below now update
their panels at 60fps without tearing (nor sluggishness), and without
repeated timeouts in dmesg.

Tested on the following devices with command-mode panels and TE pins:

- Sony Xperia XZ3 (sdm845, DPU 4.0.0, cmdmode panel): no regressions on
  PINGPONG TE;
- Sony Xperia 5 (sm8150, DPU 5.0.0);
- Sony Xperia 10 II (sm6125, DPU 5.0.4).

Konrad Dybcio (1):
  drm/msm/dpu: Move dpu_hw_{tear_check,pp_vsync_info} to dpu_hw_mdss.h

Marijn Suijten (6):
  drm/msm/dpu: Remove unused INTF0 interrupt mask from sm6115/qcm2290
  drm/msm/dpu: Disable pingpong TE on DPU 5.0.0 and above
  drm/msm/dpu: Disable MDP vsync source selection on DPU 5.0.0 and above
  drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces
  drm/msm/dpu: Implement tearcheck support on INTF block
  drm/msm/dpu: Remove intr_rdptr from DPU >= 5.0.0 pingpong config

 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  11 +
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |  10 +-
 .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  | 108 +++++++--
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 181 +++++++++------
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |   7 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c |  12 +
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |   2 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c   | 206 ++++++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h   |  29 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h   |  48 ++++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c   |  18 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h   |  22 --
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c    |  52 +++--
 drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h      |   3 +
 14 files changed, 570 insertions(+), 139 deletions(-)

--
2.39.0


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

* [RFC PATCH 1/7] drm/msm/dpu: Remove unused INTF0 interrupt mask from sm6115/qcm2290
  2022-12-31 21:49 [RFC PATCH 0/7] drm/msm/dpu: Implement tearcheck support on INTF block Marijn Suijten
@ 2022-12-31 21:50 ` Marijn Suijten
  2023-01-01  4:18   ` Dmitry Baryshkov
  2023-01-02  9:29   ` Konrad Dybcio
  2022-12-31 21:50 ` [RFC PATCH 2/7] drm/msm/dpu: Disable pingpong TE on DPU 5.0.0 and above Marijn Suijten
                   ` (5 subsequent siblings)
  6 siblings, 2 replies; 33+ messages in thread
From: Marijn Suijten @ 2022-12-31 21:50 UTC (permalink / raw)
  To: phone-devel, Abhinav Kumar, Dmitry Baryshkov, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Marijn Suijten,
	Rob Clark, Sean Paul, David Airlie, Daniel Vetter, Stephen Boyd,
	Vinod Koul, Bjorn Andersson, Kuogee Hsieh, Jessica Zhang,
	Konrad Dybcio, Loic Poulain, Vinod Polimera, Adam Skladowski,
	linux-arm-msm, dri-devel, freedreno, linux-kernel

Neither of these SoCs has INTF0, they only have a DSI interface on index
1.  Stop enabling an interrupt that can't fire.

Fixes: 3581b7062cec ("drm/msm/disp/dpu1: add support for display on SM6115")
Fixes: 5334087ee743 ("drm/msm: add support for QCM2290 MDSS")
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 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 2196e205efa5..9814ad52cc04 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -90,6 +90,11 @@
 			 BIT(MDP_AD4_0_INTR) | \
 			 BIT(MDP_AD4_1_INTR))
 
+#define IRQ_QCM2290_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
+			 BIT(MDP_SSPP_TOP0_INTR2) | \
+			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
+			 BIT(MDP_INTF1_INTR))
+
 #define IRQ_SC7180_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
 			 BIT(MDP_SSPP_TOP0_INTR2) | \
 			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
@@ -1884,7 +1889,7 @@ static const struct dpu_mdss_cfg sm6115_dpu_cfg = {
 	.vbif_count = ARRAY_SIZE(sdm845_vbif),
 	.vbif = sdm845_vbif,
 	.perf = &sm6115_perf_data,
-	.mdss_irqs = IRQ_SC7180_MASK,
+	.mdss_irqs = IRQ_QCM2290_MASK,
 };
 
 static const struct dpu_mdss_cfg sm8150_dpu_cfg = {
@@ -2008,7 +2013,7 @@ static const struct dpu_mdss_cfg qcm2290_dpu_cfg = {
 	.reg_dma_count = 1,
 	.dma_cfg = &sdm845_regdma,
 	.perf = &qcm2290_perf_data,
-	.mdss_irqs = IRQ_SC7180_MASK,
+	.mdss_irqs = IRQ_QCM2290_MASK,
 };
 
 static const struct dpu_mdss_hw_cfg_handler cfg_handler[] = {
-- 
2.39.0


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

* [RFC PATCH 2/7] drm/msm/dpu: Disable pingpong TE on DPU 5.0.0 and above
  2022-12-31 21:49 [RFC PATCH 0/7] drm/msm/dpu: Implement tearcheck support on INTF block Marijn Suijten
  2022-12-31 21:50 ` [RFC PATCH 1/7] drm/msm/dpu: Remove unused INTF0 interrupt mask from sm6115/qcm2290 Marijn Suijten
@ 2022-12-31 21:50 ` Marijn Suijten
  2023-01-01  4:28   ` Dmitry Baryshkov
  2022-12-31 21:50 ` [RFC PATCH 3/7] drm/msm/dpu: Disable MDP vsync source selection " Marijn Suijten
                   ` (4 subsequent siblings)
  6 siblings, 1 reply; 33+ messages in thread
From: Marijn Suijten @ 2022-12-31 21:50 UTC (permalink / raw)
  To: phone-devel, Abhinav Kumar, Dmitry Baryshkov, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Marijn Suijten,
	Rob Clark, Sean Paul, David Airlie, Daniel Vetter, Stephen Boyd,
	Vinod Koul, Bjorn Andersson, Kuogee Hsieh, Jessica Zhang,
	Konrad Dybcio, Loic Poulain, Vinod Polimera, Adam Skladowski,
	linux-arm-msm, dri-devel, freedreno, linux-kernel

Since hardware revision 5.0.0 the TE configuration moved out of the
PINGPONG block into the INTF block.  Writing these registers has no
effect, and is omitted downstream via the DPU/SDE_PINGPONG_TE feature
flag.  This flag is only added to PINGPONG blocks used by hardware prior
to 5.0.0.

The code that writes to these registers in the INTF block will follow in
subsequent patches.

Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
---
 .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  |  5 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 53 +++++++++++--------
 .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c   | 18 ++++---
 3 files changed, 44 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index ae28b2b93e69..7e5ba52197cd 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -582,7 +582,7 @@ static bool dpu_encoder_phys_cmd_is_ongoing_pptx(
 {
 	struct dpu_hw_pp_vsync_info info;
 
-	if (!phys_enc)
+	if (!phys_enc || !phys_enc->hw_pp->ops.get_vsync_info)
 		return false;
 
 	phys_enc->hw_pp->ops.get_vsync_info(phys_enc->hw_pp, &info);
@@ -607,6 +607,9 @@ static void dpu_encoder_phys_cmd_prepare_commit(
 	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
 		return;
 
+	if (!phys_enc->hw_pp->ops.get_autorefresh || !phys_enc->hw_pp->ops.setup_autorefresh)
+		return;
+
 	/* If autorefresh is already disabled, we have nothing to do */
 	if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL))
 		return;
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 9814ad52cc04..39d4b293710c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -59,11 +59,18 @@
 #define MIXER_SC7180_MASK \
 	(BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA))
 
-#define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER)
+#define PINGPONG_SDM845_MASK \
+	(BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE))
 
-#define PINGPONG_SDM845_SPLIT_MASK \
+#define PINGPONG_SDM845_TE2_MASK \
 	(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
 
+#define PINGPONG_SM8150_MASK \
+	(BIT(DPU_PINGPONG_DITHER))
+
+#define PINGPONG_SM8150_TE2_MASK \
+	(PINGPONG_SM8150_MASK | BIT(DPU_PINGPONG_TE2))
+
 #define CTL_SC7280_MASK \
 	(BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE) | BIT(DPU_CTL_VM_CFG))
 
@@ -1156,21 +1163,21 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
 	.len = 0x20, .version = 0x20000},
 };
 
-#define PP_BLK_TE(_name, _id, _base, _merge_3d, _sblk, _done, _rdptr) \
+#define PP_BLK_TE(_name, _id, _base, _features, _merge_3d, _sblk, _done, _rdptr) \
 	{\
 	.name = _name, .id = _id, \
 	.base = _base, .len = 0xd4, \
-	.features = PINGPONG_SDM845_SPLIT_MASK, \
+	.features = _features, \
 	.merge_3d = _merge_3d, \
 	.sblk = &_sblk, \
 	.intr_done = _done, \
 	.intr_rdptr = _rdptr, \
 	}
-#define PP_BLK(_name, _id, _base, _merge_3d, _sblk, _done, _rdptr) \
+#define PP_BLK(_name, _id, _base, _features, _merge_3d, _sblk, _done, _rdptr) \
 	{\
 	.name = _name, .id = _id, \
 	.base = _base, .len = 0xd4, \
-	.features = PINGPONG_SDM845_MASK, \
+	.features = _features, \
 	.merge_3d = _merge_3d, \
 	.sblk = &_sblk, \
 	.intr_done = _done, \
@@ -1178,55 +1185,55 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
 	}
 
 static const struct dpu_pingpong_cfg sdm845_pp[] = {
-	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te,
+	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
-	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te,
+	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)),
-	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, 0, sdm845_pp_sblk,
+	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SDM845_MASK, 0, sdm845_pp_sblk,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)),
-	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, 0, sdm845_pp_sblk,
+	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SDM845_MASK, 0, sdm845_pp_sblk,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
 };
 
 static struct dpu_pingpong_cfg sc7180_pp[] = {
-	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te, -1, -1),
-	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te, -1, -1),
+	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_TE2_MASK, 0, sdm845_pp_sblk_te, -1, -1),
+	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_TE2_MASK, 0, sdm845_pp_sblk_te, -1, -1),
 };
 
 static const struct dpu_pingpong_cfg sm8150_pp[] = {
-	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk_te,
+	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_TE2_MASK, MERGE_3D_0, sdm845_pp_sblk_te,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
-	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk_te,
+	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_TE2_MASK, MERGE_3D_0, sdm845_pp_sblk_te,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)),
-	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, MERGE_3D_1, sdm845_pp_sblk,
+	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)),
-	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, MERGE_3D_1, sdm845_pp_sblk,
+	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
-	PP_BLK("pingpong_4", PINGPONG_4, 0x72000, MERGE_3D_2, sdm845_pp_sblk,
+	PP_BLK("pingpong_4", PINGPONG_4, 0x72000, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
 			-1),
-	PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk,
+	PP_BLK("pingpong_5", PINGPONG_5, 0x72800, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
 			-1),
 };
 
 static const struct dpu_pingpong_cfg sc7280_pp[] = {
-	PP_BLK("pingpong_0", PINGPONG_0, 0x59000, 0, sc7280_pp_sblk, -1, -1),
-	PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, 0, sc7280_pp_sblk, -1, -1),
-	PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, 0, sc7280_pp_sblk, -1, -1),
-	PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1),
+	PP_BLK("pingpong_0", PINGPONG_0, 0x59000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
+	PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
+	PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
+	PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
 };
 
 static struct dpu_pingpong_cfg qcm2290_pp[] = {
-	PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
+	PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk,
 		DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
 		DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
 };
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
index 0fcad9760b6f..30896c057f87 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
@@ -274,14 +274,16 @@ static int dpu_hw_pp_setup_dsc(struct dpu_hw_pingpong *pp)
 static void _setup_pingpong_ops(struct dpu_hw_pingpong *c,
 				unsigned long features)
 {
-	c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config;
-	c->ops.enable_tearcheck = dpu_hw_pp_enable_te;
-	c->ops.connect_external_te = dpu_hw_pp_connect_external_te;
-	c->ops.get_vsync_info = dpu_hw_pp_get_vsync_info;
-	c->ops.setup_autorefresh = dpu_hw_pp_setup_autorefresh_config;
-	c->ops.get_autorefresh = dpu_hw_pp_get_autorefresh_config;
-	c->ops.poll_timeout_wr_ptr = dpu_hw_pp_poll_timeout_wr_ptr;
-	c->ops.get_line_count = dpu_hw_pp_get_line_count;
+	if (test_bit(DPU_PINGPONG_TE, &features)) {
+		c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config;
+		c->ops.enable_tearcheck = dpu_hw_pp_enable_te;
+		c->ops.connect_external_te = dpu_hw_pp_connect_external_te;
+		c->ops.get_vsync_info = dpu_hw_pp_get_vsync_info;
+		c->ops.setup_autorefresh = dpu_hw_pp_setup_autorefresh_config;
+		c->ops.get_autorefresh = dpu_hw_pp_get_autorefresh_config;
+		c->ops.poll_timeout_wr_ptr = dpu_hw_pp_poll_timeout_wr_ptr;
+		c->ops.get_line_count = dpu_hw_pp_get_line_count;
+	}
 	c->ops.setup_dsc = dpu_hw_pp_setup_dsc;
 	c->ops.enable_dsc = dpu_hw_pp_dsc_enable;
 	c->ops.disable_dsc = dpu_hw_pp_dsc_disable;
-- 
2.39.0


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

* [RFC PATCH 3/7] drm/msm/dpu: Disable MDP vsync source selection on DPU 5.0.0 and above
  2022-12-31 21:49 [RFC PATCH 0/7] drm/msm/dpu: Implement tearcheck support on INTF block Marijn Suijten
  2022-12-31 21:50 ` [RFC PATCH 1/7] drm/msm/dpu: Remove unused INTF0 interrupt mask from sm6115/qcm2290 Marijn Suijten
  2022-12-31 21:50 ` [RFC PATCH 2/7] drm/msm/dpu: Disable pingpong TE on DPU 5.0.0 and above Marijn Suijten
@ 2022-12-31 21:50 ` Marijn Suijten
  2022-12-31 21:52   ` Marijn Suijten
  2022-12-31 21:50 ` [RFC PATCH 4/7] drm/msm/dpu: Move dpu_hw_{tear_check,pp_vsync_info} to dpu_hw_mdss.h Marijn Suijten
                   ` (3 subsequent siblings)
  6 siblings, 1 reply; 33+ messages in thread
From: Marijn Suijten @ 2022-12-31 21:50 UTC (permalink / raw)
  To: phone-devel, Abhinav Kumar, Dmitry Baryshkov, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Marijn Suijten,
	Rob Clark, Sean Paul, David Airlie, Daniel Vetter, Stephen Boyd,
	Vinod Koul, Bjorn Andersson, Kuogee Hsieh, Jessica Zhang,
	Konrad Dybcio, Loic Poulain, Vinod Polimera, Adam Skladowski,
	linux-arm-msm, dri-devel, freedreno, linux-kernel, Kalyan Thota

Since hardware revision 5.0.0 the TE configuration moved out of the
PINGPONG block into the INTF block, including vsync source selection
that was previously part of MDP top.  Writing to the MDP_VSYNC_SEL
register has no effect anymore and is omitted downstream via the
DPU/SDE_MDP_VSYNC_SEL feature flag.  This flag is only added to INTF
blocks used by hardware prior to 5.0.0.

The code that writes to these registers in the INTF block will follow in
subsequent patches.

Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
---
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 33 ++++++++++--
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  1 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c    | 52 +++++++++++++------
 3 files changed, 66 insertions(+), 20 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 39d4b293710c..1cfe94494135 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -407,7 +407,7 @@ static const struct dpu_mdp_cfg msm8998_mdp[] = {
 	{
 	.name = "top_0", .id = MDP_TOP,
 	.base = 0x0, .len = 0x458,
-	.features = 0,
+	.features = BIT(DPU_MDP_VSYNC_SEL),
 	.highest_bank_bit = 0x2,
 	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
 			.reg_off = 0x2AC, .bit_off = 0},
@@ -436,7 +436,7 @@ static const struct dpu_mdp_cfg sdm845_mdp[] = {
 	{
 	.name = "top_0", .id = MDP_TOP,
 	.base = 0x0, .len = 0x45C,
-	.features = BIT(DPU_MDP_AUDIO_SELECT),
+	.features = BIT(DPU_MDP_AUDIO_SELECT) | BIT(DPU_MDP_VSYNC_SEL),
 	.highest_bank_bit = 0x2,
 	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
 			.reg_off = 0x2AC, .bit_off = 0},
@@ -512,6 +512,31 @@ static const struct dpu_mdp_cfg sm6115_mdp[] = {
 	},
 };
 
+static const struct dpu_mdp_cfg sdm8150_mdp[] = {
+	{
+	.name = "top_0", .id = MDP_TOP,
+	.base = 0x0, .len = 0x45C,
+	.features = BIT(DPU_MDP_AUDIO_SELECT),
+	.highest_bank_bit = 0x2,
+	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
+			.reg_off = 0x2AC, .bit_off = 0},
+	.clk_ctrls[DPU_CLK_CTRL_VIG1] = {
+			.reg_off = 0x2B4, .bit_off = 0},
+	.clk_ctrls[DPU_CLK_CTRL_VIG2] = {
+			.reg_off = 0x2BC, .bit_off = 0},
+	.clk_ctrls[DPU_CLK_CTRL_VIG3] = {
+			.reg_off = 0x2C4, .bit_off = 0},
+	.clk_ctrls[DPU_CLK_CTRL_DMA0] = {
+			.reg_off = 0x2AC, .bit_off = 8},
+	.clk_ctrls[DPU_CLK_CTRL_DMA1] = {
+			.reg_off = 0x2B4, .bit_off = 8},
+	.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
+			.reg_off = 0x2BC, .bit_off = 8},
+	.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
+			.reg_off = 0x2C4, .bit_off = 8},
+	},
+};
+
 static const struct dpu_mdp_cfg sm8250_mdp[] = {
 	{
 	.name = "top_0", .id = MDP_TOP,
@@ -1901,8 +1926,8 @@ static const struct dpu_mdss_cfg sm6115_dpu_cfg = {
 
 static const struct dpu_mdss_cfg sm8150_dpu_cfg = {
 	.caps = &sm8150_dpu_caps,
-	.mdp_count = ARRAY_SIZE(sdm845_mdp),
-	.mdp = sdm845_mdp,
+	.mdp_count = ARRAY_SIZE(sdm8150_mdp),
+	.mdp = sdm8150_mdp,
 	.ctl_count = ARRAY_SIZE(sm8150_ctl),
 	.ctl = sm8150_ctl,
 	.sspp_count = ARRAY_SIZE(sdm845_sspp),
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 3b645d5aa9aa..e0e153889ab7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -93,6 +93,7 @@ enum {
 	DPU_MDP_UBWC_1_0,
 	DPU_MDP_UBWC_1_5,
 	DPU_MDP_AUDIO_SELECT,
+	DPU_MDP_VSYNC_SEL,
 	DPU_MDP_MAX
 };
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
index c3110a25a30d..2e699c9ad13c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
@@ -151,28 +151,16 @@ static void dpu_hw_get_danger_status(struct dpu_hw_mdp *mdp,
 	status->sspp[SSPP_CURSOR1] = (value >> 26) & 0x3;
 }
 
-static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp,
+static void dpu_hw_setup_vsync_source_v1(struct dpu_hw_mdp *mdp,
 		struct dpu_vsync_source_cfg *cfg)
 {
 	struct dpu_hw_blk_reg_map *c;
-	u32 reg, wd_load_value, wd_ctl, wd_ctl2, i;
-	static const u32 pp_offset[PINGPONG_MAX] = {0xC, 0x8, 0x4, 0x13, 0x18};
+	u32 reg, wd_load_value, wd_ctl, wd_ctl2;
 
-	if (!mdp || !cfg || (cfg->pp_count > ARRAY_SIZE(cfg->ppnumber)))
+	if (!mdp || !cfg)
 		return;
 
 	c = &mdp->hw;
-	reg = DPU_REG_READ(c, MDP_VSYNC_SEL);
-	for (i = 0; i < cfg->pp_count; i++) {
-		int pp_idx = cfg->ppnumber[i] - PINGPONG_0;
-
-		if (pp_idx >= ARRAY_SIZE(pp_offset))
-			continue;
-
-		reg &= ~(0xf << pp_offset[pp_idx]);
-		reg |= (cfg->vsync_source & 0xf) << pp_offset[pp_idx];
-	}
-	DPU_REG_WRITE(c, MDP_VSYNC_SEL, reg);
 
 	if (cfg->vsync_source >= DPU_VSYNC_SOURCE_WD_TIMER_4 &&
 			cfg->vsync_source <= DPU_VSYNC_SOURCE_WD_TIMER_0) {
@@ -219,6 +207,33 @@ static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp,
 	}
 }
 
+static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp,
+		struct dpu_vsync_source_cfg *cfg)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 reg, i;
+	static const u32 pp_offset[PINGPONG_MAX] = {0xC, 0x8, 0x4, 0x13, 0x18};
+
+	if (!mdp || !cfg || (cfg->pp_count > ARRAY_SIZE(cfg->ppnumber)))
+		return;
+
+	c = &mdp->hw;
+
+	reg = DPU_REG_READ(c, MDP_VSYNC_SEL);
+	for (i = 0; i < cfg->pp_count; i++) {
+		int pp_idx = cfg->ppnumber[i] - PINGPONG_0;
+
+		if (pp_idx >= ARRAY_SIZE(pp_offset))
+			continue;
+
+		reg &= ~(0xf << pp_offset[pp_idx]);
+		reg |= (cfg->vsync_source & 0xf) << pp_offset[pp_idx];
+	}
+	DPU_REG_WRITE(c, MDP_VSYNC_SEL, reg);
+
+	dpu_hw_setup_vsync_source_v1(mdp, cfg);
+}
+
 static void dpu_hw_get_safe_status(struct dpu_hw_mdp *mdp,
 		struct dpu_danger_safe_status *status)
 {
@@ -266,7 +281,12 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
 	ops->setup_split_pipe = dpu_hw_setup_split_pipe;
 	ops->setup_clk_force_ctrl = dpu_hw_setup_clk_force_ctrl;
 	ops->get_danger_status = dpu_hw_get_danger_status;
-	ops->setup_vsync_source = dpu_hw_setup_vsync_source;
+
+	if (cap & BIT(DPU_MDP_VSYNC_SEL))
+		ops->setup_vsync_source = dpu_hw_setup_vsync_source;
+	else
+		ops->setup_vsync_source = dpu_hw_setup_vsync_source_v1;
+
 	ops->get_safe_status = dpu_hw_get_safe_status;
 
 	if (cap & BIT(DPU_MDP_AUDIO_SELECT))
-- 
2.39.0


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

* [RFC PATCH 4/7] drm/msm/dpu: Move dpu_hw_{tear_check,pp_vsync_info} to dpu_hw_mdss.h
  2022-12-31 21:49 [RFC PATCH 0/7] drm/msm/dpu: Implement tearcheck support on INTF block Marijn Suijten
                   ` (2 preceding siblings ...)
  2022-12-31 21:50 ` [RFC PATCH 3/7] drm/msm/dpu: Disable MDP vsync source selection " Marijn Suijten
@ 2022-12-31 21:50 ` Marijn Suijten
  2023-01-01 12:37   ` Dmitry Baryshkov
  2022-12-31 21:50 ` [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces Marijn Suijten
                   ` (2 subsequent siblings)
  6 siblings, 1 reply; 33+ messages in thread
From: Marijn Suijten @ 2022-12-31 21:50 UTC (permalink / raw)
  To: phone-devel, Abhinav Kumar, Dmitry Baryshkov, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Marijn Suijten,
	Rob Clark, Sean Paul, David Airlie, Daniel Vetter, Stephen Boyd,
	Vinod Koul, Bjorn Andersson, Kuogee Hsieh, Jessica Zhang,
	Konrad Dybcio, Loic Poulain, Vinod Polimera, Adam Skladowski,
	linux-arm-msm, dri-devel, freedreno, linux-kernel

From: Konrad Dybcio <konrad.dybcio@somainline.org>

Now that newer SoCs since DPU 5.0.0 manage tearcheck in the INTF instead
of PINGPONG block, move the struct definition to a common file. Also,
bring in documentation from msm-4.19 techpack while at it.

Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
[Marijn: Also move dpu_hw_pp_vsync_info]
Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h   | 46 +++++++++++++++++++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h   | 22 ---------
 2 files changed, 46 insertions(+), 22 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index d3b0ed0a9c6c..64b2bf219a34 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -456,4 +456,50 @@ struct dpu_mdss_color {
 #define DPU_DBG_MASK_DSPP     (1 << 10)
 #define DPU_DBG_MASK_DSC      (1 << 11)
 
+/**
+ * struct dpu_hw_tear_check - Struct contains parameters to configure
+ * tear-effect module. This structure is used to configure tear-check
+ * logic present either in ping-pong or in interface module.
+ * @vsync_count:        Ratio of MDP VSYNC clk freq(Hz) to refresh rate divided
+ *                      by no of lines
+ * @sync_cfg_height:    Total vertical lines (display height - 1)
+ * @vsync_init_val:     Init value to which the read pointer gets loaded at
+ *                      vsync edge
+ * @sync_threshold_start:    Read pointer threshold start ROI for write operation
+ * @sync_threshold_continue: The minimum number of lines the write pointer
+ *                           needs to be above the read pointer
+ * @start_pos:          The position from which the start_threshold value is added
+ * @rd_ptr_irq:         The read pointer line at which interrupt has to be generated
+ * @hw_vsync_mode:      Sync with external frame sync input
+ */
+struct dpu_hw_tear_check {
+	/*
+	 * This is ratio of MDP VSYNC clk freq(Hz) to
+	 * refresh rate divided by no of lines
+	 */
+	u32 vsync_count;
+	u32 sync_cfg_height;
+	u32 vsync_init_val;
+	u32 sync_threshold_start;
+	u32 sync_threshold_continue;
+	u32 start_pos;
+	u32 rd_ptr_irq;
+	u8 hw_vsync_mode;
+};
+
+/**
+ * struct dpu_hw_pp_vsync_info - Struct contains parameters to configure
+ * read and write pointers for command mode panels
+ * @rd_ptr_init_val:    Value of rd pointer at vsync edge
+ * @rd_ptr_frame_count: Num frames sent since enabling interface
+ * @rd_ptr_line_count:  Current line on panel (rd ptr)
+ * @wr_ptr_line_count:  Current line within pp fifo (wr ptr)
+ */
+struct dpu_hw_pp_vsync_info {
+	u32 rd_ptr_init_val;
+	u32 rd_ptr_frame_count;
+	u32 rd_ptr_line_count;
+	u32 wr_ptr_line_count;
+};
+
 #endif  /* _DPU_HW_MDSS_H */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h
index c00223441d99..5aa7b5647e38 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h
@@ -13,28 +13,6 @@
 
 struct dpu_hw_pingpong;
 
-struct dpu_hw_tear_check {
-	/*
-	 * This is ratio of MDP VSYNC clk freq(Hz) to
-	 * refresh rate divided by no of lines
-	 */
-	u32 vsync_count;
-	u32 sync_cfg_height;
-	u32 vsync_init_val;
-	u32 sync_threshold_start;
-	u32 sync_threshold_continue;
-	u32 start_pos;
-	u32 rd_ptr_irq;
-	u8 hw_vsync_mode;
-};
-
-struct dpu_hw_pp_vsync_info {
-	u32 rd_ptr_init_val;	/* value of rd pointer at vsync edge */
-	u32 rd_ptr_frame_count;	/* num frames sent since enabling interface */
-	u32 rd_ptr_line_count;	/* current line on panel (rd ptr) */
-	u32 wr_ptr_line_count;	/* current line within pp fifo (wr ptr) */
-};
-
 /**
  * struct dpu_hw_dither_cfg - dither feature structure
  * @flags: for customizing operations
-- 
2.39.0


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

* [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces
  2022-12-31 21:49 [RFC PATCH 0/7] drm/msm/dpu: Implement tearcheck support on INTF block Marijn Suijten
                   ` (3 preceding siblings ...)
  2022-12-31 21:50 ` [RFC PATCH 4/7] drm/msm/dpu: Move dpu_hw_{tear_check,pp_vsync_info} to dpu_hw_mdss.h Marijn Suijten
@ 2022-12-31 21:50 ` Marijn Suijten
  2023-01-01 13:12   ` Dmitry Baryshkov
  2023-02-13 19:37   ` Jessica Zhang
  2022-12-31 21:50 ` [RFC PATCH 6/7] drm/msm/dpu: Implement tearcheck support on INTF block Marijn Suijten
  2022-12-31 21:50 ` [RFC PATCH 7/7] drm/msm/dpu: Remove intr_rdptr from DPU >= 5.0.0 pingpong config Marijn Suijten
  6 siblings, 2 replies; 33+ messages in thread
From: Marijn Suijten @ 2022-12-31 21:50 UTC (permalink / raw)
  To: phone-devel, Abhinav Kumar, Dmitry Baryshkov, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Marijn Suijten,
	Rob Clark, Sean Paul, David Airlie, Daniel Vetter, Stephen Boyd,
	Vinod Koul, Bjorn Andersson, Kuogee Hsieh, Jessica Zhang,
	Konrad Dybcio, Loic Poulain, Vinod Polimera, Adam Skladowski,
	linux-arm-msm, dri-devel, freedreno, linux-kernel

All SoCs since DPU 5.0.0 (and seemingly up until and including 6.0.0,
but excluding 7.x.x) have the tear interrupt and control registers moved
out of the PINGPONG block and into the INTF block.  Wire up the
necessary interrupts and IRQ masks on all supported hardware.

Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
---
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 78 +++++++++++--------
 .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  6 +-
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 12 +++
 .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  2 +
 drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h      |  3 +
 5 files changed, 68 insertions(+), 33 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 1cfe94494135..b9b9b5b0b615 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -86,6 +86,15 @@
 
 #define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)
 
+#define IRQ_MSM8998_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
+			 BIT(MDP_SSPP_TOP0_INTR2) | \
+			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
+			 BIT(MDP_INTF0_INTR) | \
+			 BIT(MDP_INTF1_INTR) | \
+			 BIT(MDP_INTF2_INTR) | \
+			 BIT(MDP_INTF3_INTR) | \
+			 BIT(MDP_INTF4_INTR))
+
 #define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
 			 BIT(MDP_SSPP_TOP0_INTR2) | \
 			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
@@ -100,13 +109,15 @@
 #define IRQ_QCM2290_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
 			 BIT(MDP_SSPP_TOP0_INTR2) | \
 			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
-			 BIT(MDP_INTF1_INTR))
+			 BIT(MDP_INTF1_INTR) | \
+			 BIT(MDP_INTF1_TEAR_INTR))
 
 #define IRQ_SC7180_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
 			 BIT(MDP_SSPP_TOP0_INTR2) | \
 			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
 			 BIT(MDP_INTF0_INTR) | \
-			 BIT(MDP_INTF1_INTR))
+			 BIT(MDP_INTF1_INTR) | \
+			 BIT(MDP_INTF1_TEAR_INTR))
 
 #define IRQ_SC7280_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
 			 BIT(MDP_SSPP_TOP0_INTR2) | \
@@ -120,7 +131,9 @@
 			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
 			 BIT(MDP_INTF0_INTR) | \
 			 BIT(MDP_INTF1_INTR) | \
+			 BIT(MDP_INTF1_TEAR_INTR) | \
 			 BIT(MDP_INTF2_INTR) | \
+			 BIT(MDP_INTF2_TEAR_INTR) | \
 			 BIT(MDP_INTF3_INTR) | \
 			 BIT(MDP_INTF4_INTR))
 
@@ -129,7 +142,9 @@
 			  BIT(MDP_SSPP_TOP0_HIST_INTR) | \
 			  BIT(MDP_INTF0_INTR) | \
 			  BIT(MDP_INTF1_INTR) | \
+			  BIT(MDP_INTF1_TEAR_INTR) | \
 			  BIT(MDP_INTF2_INTR) | \
+			  BIT(MDP_INTF2_TEAR_INTR) | \
 			  BIT(MDP_INTF3_INTR) | \
 			  BIT(MDP_INTF4_INTR) | \
 			  BIT(MDP_INTF5_INTR) | \
@@ -1300,63 +1315,64 @@ static struct dpu_dsc_cfg sdm845_dsc[] = {
 /*************************************************************
  * INTF sub blocks config
  *************************************************************/
-#define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _progfetch, _features, _reg, _underrun_bit, _vsync_bit) \
+#define INTF_BLK(_name, _id, _base, _len, _type, _ctrl_id, _progfetch, _features, _reg, _underrun_bit, _vsync_bit, _tear_reg, _tear_rd_ptr_bit) \
 	{\
 	.name = _name, .id = _id, \
-	.base = _base, .len = 0x280, \
+	.base = _base, .len = _len, \
 	.features = _features, \
 	.type = _type, \
 	.controller_id = _ctrl_id, \
 	.prog_fetch_lines_worst_case = _progfetch, \
 	.intr_underrun = DPU_IRQ_IDX(_reg, _underrun_bit), \
 	.intr_vsync = DPU_IRQ_IDX(_reg, _vsync_bit), \
+	.intr_tear_rd_ptr = DPU_IRQ_IDX(_tear_reg, _tear_rd_ptr_bit), \
 	}
 
 static const struct dpu_intf_cfg msm8998_intf[] = {
-	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
-	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
-	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
-	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_HDMI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
+	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x268, INTF_DP, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
+	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x268, INTF_DSI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27, -1, -1),
+	INTF_BLK("intf_2", INTF_2, 0x6B000, 0x268, INTF_DSI, 1, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29, -1, -1),
+	INTF_BLK("intf_3", INTF_3, 0x6B800, 0x268, INTF_HDMI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31, -1, -1),
 };
 
 static const struct dpu_intf_cfg sdm845_intf[] = {
-	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
-	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
-	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
-	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
+	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
+	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x280, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27, -1, -1),
+	INTF_BLK("intf_2", INTF_2, 0x6B000, 0x280, INTF_DSI, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29, -1, -1),
+	INTF_BLK("intf_3", INTF_3, 0x6B800, 0x280, INTF_DP, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31, -1, -1),
 };
 
 static const struct dpu_intf_cfg sc7180_intf[] = {
-	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
-	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
+	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
+	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2b8, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF1_TEAR_INTR, 2),
 };
 
 static const struct dpu_intf_cfg sm8150_intf[] = {
-	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
-	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
-	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
-	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
+	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
+	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2b8, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF1_TEAR_INTR, 2),
+	INTF_BLK("intf_2", INTF_2, 0x6B000, 0x2b8, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29, MDP_INTF2_TEAR_INTR, 2),
+	INTF_BLK("intf_3", INTF_3, 0x6B800, 0x280, INTF_DP, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31, -1, -1),
 };
 
 static const struct dpu_intf_cfg sc7280_intf[] = {
-	INTF_BLK("intf_0", INTF_0, 0x34000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
-	INTF_BLK("intf_1", INTF_1, 0x35000, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
-	INTF_BLK("intf_5", INTF_5, 0x39000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
+	INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
+	INTF_BLK("intf_1", INTF_1, 0x35000, 0x2b8, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF1_TEAR_INTR, 2),
+	INTF_BLK("intf_5", INTF_5, 0x39000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23, -1, -1),
 };
 
 static const struct dpu_intf_cfg sc8180x_intf[] = {
-	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
-	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
-	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
+	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
+	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2b8, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF1_TEAR_INTR, 2),
+	INTF_BLK("intf_2", INTF_2, 0x6B000, 0x2b8, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29, MDP_INTF2_TEAR_INTR, 2),
 	/* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until this is supported */
-	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
-	INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 20, 21),
-	INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
+	INTF_BLK("intf_3", INTF_3, 0x6B800, 0x280, INTF_DP, 999, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31, -1, -1),
+	INTF_BLK("intf_4", INTF_4, 0x6C000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 20, 21, -1, -1),
+	INTF_BLK("intf_5", INTF_5, 0x6C800, 0x280, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 22, 23, -1, -1),
 };
 
 static const struct dpu_intf_cfg qcm2290_intf[] = {
-	INTF_BLK("intf_0", INTF_0, 0x00000, INTF_NONE, 0, 0, 0, 0, 0, 0),
-	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
+	INTF_BLK("intf_0", INTF_0, 0x00000, 0x2b8, INTF_NONE, 0, 0, 0, 0, 0, 0, -1, -1),
+	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2b8, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF2_TEAR_INTR, 2),
 };
 
 /*************************************************************
@@ -1849,7 +1865,7 @@ static const struct dpu_mdss_cfg msm8998_dpu_cfg = {
 	.vbif = msm8998_vbif,
 	.reg_dma_count = 0,
 	.perf = &msm8998_perf_data,
-	.mdss_irqs = IRQ_SM8250_MASK,
+	.mdss_irqs = IRQ_MSM8998_MASK,
 };
 
 static const struct dpu_mdss_cfg sdm845_dpu_cfg = {
@@ -1947,7 +1963,7 @@ static const struct dpu_mdss_cfg sm8150_dpu_cfg = {
 	.reg_dma_count = 1,
 	.dma_cfg = &sm8150_regdma,
 	.perf = &sm8150_perf_data,
-	.mdss_irqs = IRQ_SDM845_MASK,
+	.mdss_irqs = IRQ_SM8250_MASK,
 };
 
 static const struct dpu_mdss_cfg sc8180x_dpu_cfg = {
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 e0e153889ab7..2ea17e4ef3e5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -638,8 +638,9 @@ struct dpu_dsc_cfg {
  * @type:              Interface type(DSI, DP, HDMI)
  * @controller_id:     Controller Instance ID in case of multiple of intf type
  * @prog_fetch_lines_worst_case	Worst case latency num lines needed to prefetch
- * @intr_underrun:	index for INTF underrun interrupt
- * @intr_vsync:	        index for INTF VSYNC interrupt
+ * @intr_underrun:     index for INTF underrun interrupt
+ * @intr_vsync:        index for INTF VSYNC interrupt
+ * @intr_tear_rd_ptr:  index for INTF TEAR_RD_PTR interrupt
  */
 struct dpu_intf_cfg  {
 	DPU_HW_BLK_INFO;
@@ -648,6 +649,7 @@ struct dpu_intf_cfg  {
 	u32 prog_fetch_lines_worst_case;
 	s32 intr_underrun;
 	s32 intr_vsync;
+	s32 intr_tear_rd_ptr;
 };
 
 /**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
index cf1b6d84c18a..044136a97fac 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
@@ -24,6 +24,8 @@
 #define MDP_INTF_3_OFF			0x6B800
 #define MDP_INTF_4_OFF			0x6C000
 #define MDP_INTF_5_OFF			0x6C800
+#define MDP_INTF_1_TEAR_OFF		0x6D800
+#define MDP_INTF_2_TEAR_OFF		0x6D900
 #define MDP_AD4_0_OFF			0x7C000
 #define MDP_AD4_1_OFF			0x7D000
 #define MDP_AD4_INTR_EN_OFF		0x41c
@@ -99,6 +101,16 @@ static const struct dpu_intr_reg dpu_intr_set[] = {
 		MDP_INTF_5_OFF+INTF_INTR_EN,
 		MDP_INTF_5_OFF+INTF_INTR_STATUS
 	},
+	[MDP_INTF1_TEAR_INTR] = {
+		MDP_INTF_1_TEAR_OFF+INTF_INTR_TEAR_CLEAR,
+		MDP_INTF_1_TEAR_OFF+INTF_INTR_TEAR_EN,
+		MDP_INTF_1_TEAR_OFF+INTF_INTR_TEAR_STATUS
+	},
+	[MDP_INTF2_TEAR_INTR] = {
+		MDP_INTF_2_TEAR_OFF+INTF_INTR_TEAR_CLEAR,
+		MDP_INTF_2_TEAR_OFF+INTF_INTR_TEAR_EN,
+		MDP_INTF_2_TEAR_OFF+INTF_INTR_TEAR_STATUS
+	},
 	[MDP_AD4_0_INTR] = {
 		MDP_AD4_0_OFF + MDP_AD4_INTR_CLEAR_OFF,
 		MDP_AD4_0_OFF + MDP_AD4_INTR_EN_OFF,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
index 46443955443c..b447e4a1d9f4 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
@@ -23,6 +23,8 @@ enum dpu_hw_intr_reg {
 	MDP_INTF3_INTR,
 	MDP_INTF4_INTR,
 	MDP_INTF5_INTR,
+	MDP_INTF1_TEAR_INTR,
+	MDP_INTF2_TEAR_INTR,
 	MDP_AD4_0_INTR,
 	MDP_AD4_1_INTR,
 	MDP_INTF0_7xxx_INTR,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h
index c8156ed4b7fb..6bdac515fd54 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h
@@ -10,6 +10,9 @@
 /**
  * MDP TOP block Register and bit fields and defines
  */
+#define INTF_INTR_TEAR_EN               0x000
+#define INTF_INTR_TEAR_STATUS           0x004
+#define INTF_INTR_TEAR_CLEAR            0x008
 #define DISP_INTF_SEL                   0x004
 #define INTR_EN                         0x010
 #define INTR_STATUS                     0x014
-- 
2.39.0


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

* [RFC PATCH 6/7] drm/msm/dpu: Implement tearcheck support on INTF block
  2022-12-31 21:49 [RFC PATCH 0/7] drm/msm/dpu: Implement tearcheck support on INTF block Marijn Suijten
                   ` (4 preceding siblings ...)
  2022-12-31 21:50 ` [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces Marijn Suijten
@ 2022-12-31 21:50 ` Marijn Suijten
  2023-01-01 13:32   ` Dmitry Baryshkov
  2022-12-31 21:50 ` [RFC PATCH 7/7] drm/msm/dpu: Remove intr_rdptr from DPU >= 5.0.0 pingpong config Marijn Suijten
  6 siblings, 1 reply; 33+ messages in thread
From: Marijn Suijten @ 2022-12-31 21:50 UTC (permalink / raw)
  To: phone-devel, Abhinav Kumar, Dmitry Baryshkov, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Marijn Suijten,
	Rob Clark, Sean Paul, David Airlie, Daniel Vetter, Stephen Boyd,
	Vinod Koul, Bjorn Andersson, Kuogee Hsieh, Jessica Zhang,
	Konrad Dybcio, Loic Poulain, Vinod Polimera, Adam Skladowski,
	linux-arm-msm, dri-devel, freedreno, linux-kernel

Since DPU 5.0.0 the TEARCHECK registers and interrupts moved out of the
PINGPONG block and into the INTF.  Implement the necessary callbacks in
the INTF block, and use these callbacks together with the INTF_TEAR
interrupts

Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  11 +
 .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |  10 +-
 .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  | 113 +++++++---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c   | 206 ++++++++++++++++++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h   |  29 +++
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h   |   2 +
 6 files changed, 340 insertions(+), 31 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 9c6817b5a194..8b9070220ab2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -673,6 +673,7 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
 	struct dpu_kms *dpu_kms;
 	struct dpu_hw_mdp *hw_mdptop;
 	struct drm_encoder *drm_enc;
+	struct dpu_encoder_phys *phys_enc;
 	int i;
 
 	if (!dpu_enc || !disp_info) {
@@ -703,12 +704,22 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
 			vsync_cfg.ppnumber[i] = dpu_enc->hw_pp[i]->idx;
 
 		vsync_cfg.pp_count = dpu_enc->num_phys_encs;
+		vsync_cfg.frame_rate = drm_mode_vrefresh(&dpu_enc->base.crtc->state->adjusted_mode);
+
 		if (disp_info->is_te_using_watchdog_timer)
 			vsync_cfg.vsync_source = DPU_VSYNC_SOURCE_WD_TIMER_0;
 		else
 			vsync_cfg.vsync_source = DPU_VSYNC0_SOURCE_GPIO;
 
 		hw_mdptop->ops.setup_vsync_source(hw_mdptop, &vsync_cfg);
+
+		for (i = 0; i < dpu_enc->num_phys_encs; i++) {
+			phys_enc = dpu_enc->phys_encs[i];
+
+			if (phys_enc->has_intf_te && phys_enc->hw_intf->ops.vsync_sel)
+				phys_enc->hw_intf->ops.vsync_sel(phys_enc->hw_intf,
+						vsync_cfg.vsync_source);
+		}
 	}
 }
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
index f2af07d87f56..47e79401032c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
@@ -148,10 +148,10 @@ struct dpu_encoder_phys_ops {
 /**
  * enum dpu_intr_idx - dpu encoder interrupt index
  * @INTR_IDX_VSYNC:    Vsync interrupt for video mode panel
- * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
- * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel
- * @INTR_IDX_RDPTR:    Readpointer done unterrupt for cmd mode panel
- * @INTR_IDX_WB_DONE:  Writeback fone interrupt for virtual connector
+ * @INTR_IDX_PINGPONG: Pingpong done interrupt for cmd mode panel
+ * @INTR_IDX_UNDERRUN: Underrun interrupt for video and cmd mode panel
+ * @INTR_IDX_RDPTR:    Readpointer done interrupt for cmd mode panel
+ * @INTR_IDX_WB_DONE:  Writeback done interrupt for virtual connector
  */
 enum dpu_intr_idx {
 	INTR_IDX_VSYNC,
@@ -195,6 +195,7 @@ enum dpu_intr_idx {
  *                              pending.
  * @pending_kickoff_wq:		Wait queue for blocking until kickoff completes
  * @irq:			IRQ indices
+ * @has_intf_te:		Interface TE configuration support
  */
 struct dpu_encoder_phys {
 	struct drm_encoder *parent;
@@ -220,6 +221,7 @@ struct dpu_encoder_phys {
 	atomic_t pending_kickoff_cnt;
 	wait_queue_head_t pending_kickoff_wq;
 	int irq[INTR_IDX_MAX];
+	bool has_intf_te;
 };
 
 static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
index 7e5ba52197cd..ca44a8087f01 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
@@ -100,12 +100,12 @@ static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
 	DPU_ATRACE_END("pp_done_irq");
 }
 
-static void dpu_encoder_phys_cmd_pp_rd_ptr_irq(void *arg, int irq_idx)
+static void dpu_encoder_phys_cmd_te_rd_ptr_irq(void *arg, int irq_idx)
 {
 	struct dpu_encoder_phys *phys_enc = arg;
 	struct dpu_encoder_phys_cmd *cmd_enc;
 
-	if (!phys_enc->hw_pp)
+	if (!phys_enc->hw_pp || !phys_enc->hw_intf)
 		return;
 
 	DPU_ATRACE_BEGIN("rd_ptr_irq");
@@ -147,11 +147,19 @@ static void dpu_encoder_phys_cmd_atomic_mode_set(
 		struct drm_crtc_state *crtc_state,
 		struct drm_connector_state *conn_state)
 {
+	if (phys_enc->has_intf_te && !phys_enc->hw_intf) {
+		DPU_ERROR("invalid intf configuration\n");
+		return;
+	}
+
 	phys_enc->irq[INTR_IDX_CTL_START] = phys_enc->hw_ctl->caps->intr_start;
 
 	phys_enc->irq[INTR_IDX_PINGPONG] = phys_enc->hw_pp->caps->intr_done;
 
-	phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr;
+	if (phys_enc->has_intf_te)
+		phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_intf->cap->intr_tear_rd_ptr;
+	else
+		phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr;
 
 	phys_enc->irq[INTR_IDX_UNDERRUN] = phys_enc->hw_intf->cap->intr_underrun;
 }
@@ -264,7 +272,7 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(
 	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
 		ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
 				phys_enc->irq[INTR_IDX_RDPTR],
-				dpu_encoder_phys_cmd_pp_rd_ptr_irq,
+				dpu_encoder_phys_cmd_te_rd_ptr_irq,
 				phys_enc);
 	else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
 		ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
@@ -336,10 +344,18 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
 
 	DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0);
 
-	if (!phys_enc->hw_pp->ops.setup_tearcheck ||
-		!phys_enc->hw_pp->ops.enable_tearcheck) {
-		DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
-		return;
+	if (phys_enc->has_intf_te) {
+		if (!phys_enc->hw_intf->ops.setup_tearcheck ||
+			!phys_enc->hw_intf->ops.enable_tearcheck) {
+			DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
+			return;
+		}
+	} else {
+		if (!phys_enc->hw_pp->ops.setup_tearcheck ||
+			!phys_enc->hw_pp->ops.enable_tearcheck) {
+			DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
+			return;
+		}
 	}
 
 	dpu_kms = phys_enc->dpu_kms;
@@ -392,8 +408,13 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
 		phys_enc->hw_pp->idx - PINGPONG_0, tc_cfg.sync_cfg_height,
 		tc_cfg.sync_threshold_start, tc_cfg.sync_threshold_continue);
 
-	phys_enc->hw_pp->ops.setup_tearcheck(phys_enc->hw_pp, &tc_cfg);
-	phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, tc_enable);
+	if (phys_enc->has_intf_te) {
+		phys_enc->hw_intf->ops.setup_tearcheck(phys_enc->hw_intf, &tc_cfg);
+		phys_enc->hw_intf->ops.enable_tearcheck(phys_enc->hw_intf, tc_enable);
+	} else {
+		phys_enc->hw_pp->ops.setup_tearcheck(phys_enc->hw_pp, &tc_cfg);
+		phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, tc_enable);
+	}
 }
 
 static void _dpu_encoder_phys_cmd_pingpong_config(
@@ -470,11 +491,19 @@ static void dpu_encoder_phys_cmd_enable(struct dpu_encoder_phys *phys_enc)
 static void _dpu_encoder_phys_cmd_connect_te(
 		struct dpu_encoder_phys *phys_enc, bool enable)
 {
-	if (!phys_enc->hw_pp || !phys_enc->hw_pp->ops.connect_external_te)
-		return;
+	if (phys_enc->has_intf_te) {
+		if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.connect_external_te)
+			return;
 
-	trace_dpu_enc_phys_cmd_connect_te(DRMID(phys_enc->parent), enable);
-	phys_enc->hw_pp->ops.connect_external_te(phys_enc->hw_pp, enable);
+		trace_dpu_enc_phys_cmd_connect_te(DRMID(phys_enc->parent), enable);
+		phys_enc->hw_intf->ops.connect_external_te(phys_enc->hw_intf, enable);
+	} else {
+		if (!phys_enc->hw_pp || !phys_enc->hw_pp->ops.connect_external_te)
+			return;
+
+		trace_dpu_enc_phys_cmd_connect_te(DRMID(phys_enc->parent), enable);
+		phys_enc->hw_pp->ops.connect_external_te(phys_enc->hw_pp, enable);
+	}
 }
 
 static void dpu_encoder_phys_cmd_prepare_idle_pc(
@@ -487,6 +516,7 @@ static int dpu_encoder_phys_cmd_get_line_count(
 		struct dpu_encoder_phys *phys_enc)
 {
 	struct dpu_hw_pingpong *hw_pp;
+	struct dpu_hw_intf *hw_intf;
 
 	if (!phys_enc->hw_pp)
 		return -EINVAL;
@@ -494,10 +524,16 @@ static int dpu_encoder_phys_cmd_get_line_count(
 	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
 		return -EINVAL;
 
+	if (phys_enc->has_intf_te) {
+		hw_intf = phys_enc->hw_intf;
+		if (!hw_intf->ops.get_line_count)
+			return -EINVAL;
+		return hw_intf->ops.get_line_count(hw_intf);
+	}
+
 	hw_pp = phys_enc->hw_pp;
 	if (!hw_pp->ops.get_line_count)
 		return -EINVAL;
-
 	return hw_pp->ops.get_line_count(hw_pp);
 }
 
@@ -520,7 +556,9 @@ static void dpu_encoder_phys_cmd_disable(struct dpu_encoder_phys *phys_enc)
 		return;
 	}
 
-	if (phys_enc->hw_pp->ops.enable_tearcheck)
+	if (phys_enc->has_intf_te && phys_enc->hw_intf->ops.enable_tearcheck)
+		phys_enc->hw_intf->ops.enable_tearcheck(phys_enc->hw_intf, false);
+	else if (phys_enc->hw_pp->ops.enable_tearcheck)
 		phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, false);
 
 	if (phys_enc->hw_intf->ops.bind_pingpong_blk) {
@@ -582,10 +620,19 @@ static bool dpu_encoder_phys_cmd_is_ongoing_pptx(
 {
 	struct dpu_hw_pp_vsync_info info;
 
-	if (!phys_enc || !phys_enc->hw_pp->ops.get_vsync_info)
+	if (!phys_enc)
 		return false;
 
-	phys_enc->hw_pp->ops.get_vsync_info(phys_enc->hw_pp, &info);
+	if (phys_enc->has_intf_te) {
+		if (!phys_enc->hw_intf->ops.get_vsync_info)
+			return false;
+		phys_enc->hw_intf->ops.get_vsync_info(phys_enc->hw_intf, &info);
+	} else {
+		if (!phys_enc->hw_pp->ops.get_vsync_info)
+			return false;
+		phys_enc->hw_pp->ops.get_vsync_info(phys_enc->hw_pp, &info);
+	}
+
 	if (info.wr_ptr_line_count > 0 &&
 	    info.wr_ptr_line_count < phys_enc->cached_mode.vdisplay)
 		return true;
@@ -602,17 +649,23 @@ static void dpu_encoder_phys_cmd_prepare_commit(
 
 	if (!phys_enc)
 		return;
-	if (!phys_enc->hw_pp)
-		return;
 	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
 		return;
 
-	if (!phys_enc->hw_pp->ops.get_autorefresh || !phys_enc->hw_pp->ops.setup_autorefresh)
-		return;
-
 	/* If autorefresh is already disabled, we have nothing to do */
-	if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL))
-		return;
+	if (phys_enc->has_intf_te) {
+		if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_autorefresh ||
+				!phys_enc->hw_intf->ops.setup_autorefresh)
+			return;
+		if (!phys_enc->hw_intf->ops.get_autorefresh(phys_enc->hw_intf, NULL))
+			return;
+	} else {
+		if (!phys_enc->hw_pp || !phys_enc->hw_pp->ops.get_autorefresh ||
+				!phys_enc->hw_pp->ops.setup_autorefresh)
+			return;
+		if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL))
+			return;
+	}
 
 	/*
 	 * If autorefresh is enabled, disable it and make sure it is safe to
@@ -623,7 +676,10 @@ static void dpu_encoder_phys_cmd_prepare_commit(
 	 * 5. Enable TE back
 	 */
 	_dpu_encoder_phys_cmd_connect_te(phys_enc, false);
-	phys_enc->hw_pp->ops.setup_autorefresh(phys_enc->hw_pp, 0, false);
+	if (phys_enc->has_intf_te)
+		phys_enc->hw_intf->ops.setup_autorefresh(phys_enc->hw_intf, 0, false);
+	else
+		phys_enc->hw_pp->ops.setup_autorefresh(phys_enc->hw_pp, 0, false);
 
 	do {
 		udelay(DPU_ENC_MAX_POLL_TIMEOUT_US);
@@ -717,7 +773,7 @@ static int dpu_encoder_phys_cmd_wait_for_vblank(
 
 	rc = dpu_encoder_helper_wait_for_irq(phys_enc,
 			phys_enc->irq[INTR_IDX_RDPTR],
-			dpu_encoder_phys_cmd_pp_rd_ptr_irq,
+			dpu_encoder_phys_cmd_te_rd_ptr_irq,
 			&wait_info);
 
 	return rc;
@@ -793,6 +849,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
 	for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++)
 		phys_enc->irq[i] = -EINVAL;
 
+	phys_enc->has_intf_te = test_bit(DPU_INTF_TE,
+			&phys_enc->dpu_kms->catalog->intf[p->intf_idx - INTF_0].features);
+
 	atomic_set(&phys_enc->vblank_refcount, 0);
 	atomic_set(&phys_enc->pending_kickoff_cnt, 0);
 	atomic_set(&phys_enc->pending_ctlstart_cnt, 0);
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
index 7ce66bf3f4c8..42929278df8e 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
@@ -9,6 +9,8 @@
 #include "dpu_hw_intf.h"
 #include "dpu_kms.h"
 
+#include <linux/iopoll.h>
+
 #define INTF_TIMING_ENGINE_EN           0x000
 #define INTF_CONFIG                     0x004
 #define INTF_HSYNC_CTL                  0x008
@@ -62,6 +64,27 @@
 #define   INTF_LINE_COUNT               0x0B0
 
 #define   INTF_MUX                      0x25C
+#define   INTF_MISR_SIGNATURE           0x184
+
+#define INTF_STATUS                     0x26C
+#define INTF_AVR_CONTROL                0x270
+#define INTF_AVR_MODE                   0x274
+#define INTF_AVR_TRIGGER                0x278
+#define INTF_AVR_VTOTAL                 0x27C
+#define INTF_TEAR_MDP_VSYNC_SEL         0x280
+#define INTF_TEAR_TEAR_CHECK_EN         0x284
+#define INTF_TEAR_SYNC_CONFIG_VSYNC     0x288
+#define INTF_TEAR_SYNC_CONFIG_HEIGHT    0x28C
+#define INTF_TEAR_SYNC_WRCOUNT          0x290
+#define INTF_TEAR_VSYNC_INIT_VAL        0x294
+#define INTF_TEAR_INT_COUNT_VAL         0x298
+#define INTF_TEAR_SYNC_THRESH           0x29C
+#define INTF_TEAR_START_POS             0x2A0
+#define INTF_TEAR_RD_PTR_IRQ            0x2A4
+#define INTF_TEAR_WR_PTR_IRQ            0x2A8
+#define INTF_TEAR_OUT_LINE_COUNT        0x2AC
+#define INTF_TEAR_LINE_COUNT            0x2B0
+#define INTF_TEAR_AUTOREFRESH_CONFIG    0x2B4
 
 #define INTF_CFG_ACTIVE_H_EN	BIT(29)
 #define INTF_CFG_ACTIVE_V_EN	BIT(30)
@@ -309,6 +332,22 @@ static void dpu_hw_intf_get_status(
 	}
 }
 
+static void dpu_hw_intf_v1_get_status(
+		struct dpu_hw_intf *intf,
+		struct intf_status *s)
+{
+	struct dpu_hw_blk_reg_map *c = &intf->hw;
+
+	s->is_en = DPU_REG_READ(c, INTF_STATUS) & BIT(0);
+	if (s->is_en) {
+		s->frame_count = DPU_REG_READ(c, INTF_FRAME_COUNT);
+		s->line_count = DPU_REG_READ(c, INTF_LINE_COUNT);
+	} else {
+		s->line_count = 0;
+		s->frame_count = 0;
+	}
+}
+
 static u32 dpu_hw_intf_get_line_count(struct dpu_hw_intf *intf)
 {
 	struct dpu_hw_blk_reg_map *c;
@@ -331,6 +370,161 @@ static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value)
 	return dpu_hw_collect_misr(&intf->hw, INTF_MISR_CTRL, INTF_MISR_SIGNATURE, misr_value);
 }
 
+static int dpu_hw_intf_setup_te_config(struct dpu_hw_intf *intf,
+		struct dpu_hw_tear_check *te)
+{
+	struct dpu_hw_blk_reg_map *c;
+	int cfg;
+
+	if (!intf)
+		return -EINVAL;
+
+	c = &intf->hw;
+
+	cfg = BIT(19); /* VSYNC_COUNTER_EN */
+	if (te->hw_vsync_mode)
+		cfg |= BIT(20);
+
+	cfg |= te->vsync_count;
+
+	DPU_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg);
+	DPU_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_HEIGHT, te->sync_cfg_height);
+	DPU_REG_WRITE(c, INTF_TEAR_VSYNC_INIT_VAL, te->vsync_init_val);
+	DPU_REG_WRITE(c, INTF_TEAR_RD_PTR_IRQ, te->rd_ptr_irq);
+	DPU_REG_WRITE(c, INTF_TEAR_START_POS, te->start_pos);
+	DPU_REG_WRITE(c, INTF_TEAR_SYNC_THRESH,
+			((te->sync_threshold_continue << 16) |
+			 te->sync_threshold_start));
+	DPU_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT,
+			(te->start_pos + te->sync_threshold_start + 1));
+
+	return 0;
+}
+
+static void dpu_hw_intf_setup_autorefresh_config(struct dpu_hw_intf *intf,
+		u32 frame_count, bool enable)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 refresh_cfg;
+
+	c = &intf->hw;
+	refresh_cfg = DPU_REG_READ(c, INTF_TEAR_AUTOREFRESH_CONFIG);
+	if (enable)
+		refresh_cfg = BIT(31) | frame_count;
+	else
+		refresh_cfg &= ~BIT(31);
+
+	DPU_REG_WRITE(c, INTF_TEAR_AUTOREFRESH_CONFIG, refresh_cfg);
+}
+
+/*
+ * dpu_hw_intf_get_autorefresh_config - Get autorefresh config from HW
+ * @intf:        DPU intf structure
+ * @frame_count: Used to return the current frame count from hw
+ *
+ * Returns: True if autorefresh enabled, false if disabled.
+ */
+static bool dpu_hw_intf_get_autorefresh_config(struct dpu_hw_intf *intf,
+		u32 *frame_count)
+{
+	u32 val = DPU_REG_READ(&intf->hw, INTF_TEAR_AUTOREFRESH_CONFIG);
+
+	if (frame_count != NULL)
+		*frame_count = val & 0xffff;
+	return !!((val & BIT(31)) >> 31);
+}
+
+static int dpu_hw_intf_poll_timeout_wr_ptr(struct dpu_hw_intf *intf,
+		u32 timeout_us)
+{
+	struct dpu_hw_blk_reg_map *c;
+	u32 val;
+	int rc;
+
+	if (!intf)
+		return -EINVAL;
+
+	c = &intf->hw;
+	rc = readl_poll_timeout(c->blk_addr + INTF_TEAR_LINE_COUNT,
+			val, (val & 0xffff) >= 1, 10, timeout_us);
+
+	return rc;
+}
+
+static int dpu_hw_intf_enable_te(struct dpu_hw_intf *intf, bool enable)
+{
+	struct dpu_hw_blk_reg_map *c;
+
+	if (!intf)
+		return -EINVAL;
+
+	c = &intf->hw;
+	DPU_REG_WRITE(c, INTF_TEAR_TEAR_CHECK_EN, enable);
+	return 0;
+}
+
+static int dpu_hw_intf_connect_external_te(struct dpu_hw_intf *intf,
+		bool enable_external_te)
+{
+	struct dpu_hw_blk_reg_map *c = &intf->hw;
+	u32 cfg;
+	int orig;
+
+	if (!intf)
+		return -EINVAL;
+
+	c = &intf->hw;
+	cfg = DPU_REG_READ(c, INTF_TEAR_SYNC_CONFIG_VSYNC);
+	orig = (bool)(cfg & BIT(20));
+	if (enable_external_te)
+		cfg |= BIT(20);
+	else
+		cfg &= ~BIT(20);
+	DPU_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg);
+
+	return orig;
+}
+
+static int dpu_hw_intf_get_vsync_info(struct dpu_hw_intf *intf,
+		struct dpu_hw_pp_vsync_info *info)
+{
+	struct dpu_hw_blk_reg_map *c = &intf->hw;
+	u32 val;
+
+	if (!intf || !info)
+		return -EINVAL;
+
+	c = &intf->hw;
+
+	val = DPU_REG_READ(c, INTF_TEAR_VSYNC_INIT_VAL);
+	info->rd_ptr_init_val = val & 0xffff;
+
+	val = DPU_REG_READ(c, INTF_TEAR_INT_COUNT_VAL);
+	info->rd_ptr_frame_count = (val & 0xffff0000) >> 16;
+	info->rd_ptr_line_count = val & 0xffff;
+
+	val = DPU_REG_READ(c, INTF_TEAR_LINE_COUNT);
+	info->wr_ptr_line_count = val & 0xffff;
+
+	val = DPU_REG_READ(c, INTF_FRAME_COUNT);
+	info->intf_frame_count = val;
+
+	return 0;
+}
+
+static void dpu_hw_intf_vsync_sel(struct dpu_hw_intf *intf,
+		u32 vsync_source)
+{
+	struct dpu_hw_blk_reg_map *c;
+
+	if (!intf)
+		return;
+
+	c = &intf->hw;
+
+	DPU_REG_WRITE(c, INTF_TEAR_MDP_VSYNC_SEL, (vsync_source & 0xf));
+}
+
 static void _setup_intf_ops(struct dpu_hw_intf_ops *ops,
 		unsigned long cap)
 {
@@ -343,6 +537,18 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops,
 		ops->bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk;
 	ops->setup_misr = dpu_hw_intf_setup_misr;
 	ops->collect_misr = dpu_hw_intf_collect_misr;
+
+	if (cap & BIT(DPU_INTF_TE)) {
+		ops->setup_tearcheck = dpu_hw_intf_setup_te_config;
+		ops->enable_tearcheck = dpu_hw_intf_enable_te;
+		ops->connect_external_te = dpu_hw_intf_connect_external_te;
+		ops->get_vsync_info = dpu_hw_intf_get_vsync_info;
+		ops->setup_autorefresh = dpu_hw_intf_setup_autorefresh_config;
+		ops->get_autorefresh = dpu_hw_intf_get_autorefresh_config;
+		ops->poll_timeout_wr_ptr = dpu_hw_intf_poll_timeout_wr_ptr;
+		ops->vsync_sel = dpu_hw_intf_vsync_sel;
+		ops->get_status = dpu_hw_intf_v1_get_status;
+	}
 }
 
 struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx,
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
index 643dd10bc030..1521c9475fad 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
@@ -60,6 +60,17 @@ struct intf_status {
  *                     feed pixels to this interface
  * @setup_misr: enable/disable MISR
  * @collect_misr: read MISR signature
+ * @setup_tearcheck:            Enables vsync generation and sets up init value of read
+ *                              pointer and programs the tear check configuration
+ * @enable_tearcheck:           Enables tearcheck block
+ * @connect_external_te:        Read, modify, write to either set or clear listening to external TE
+ *                              Return: 1 if TE was originally connected, 0 if not, or -ERROR
+ * @get_vsync_info:             Provides the programmed and current line_count
+ * @setup_autorefresh:          Configure and enable the autorefresh config
+ * @get_autorefresh:            Retrieve autorefresh config from hardware
+ * @poll_timeout_wr_ptr:        Poll until write pointer transmission starts
+ *                              Return: 0 on success, -ETIMEDOUT on timeout
+ * @vsync_sel:                  Select vsync signal for tear-effect configuration
  */
 struct dpu_hw_intf_ops {
 	void (*setup_timing_gen)(struct dpu_hw_intf *intf,
@@ -82,6 +93,24 @@ struct dpu_hw_intf_ops {
 			const enum dpu_pingpong pp);
 	void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 frame_count);
 	int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value);
+
+	// Tearcheck on INTF since DPU 5.0.0
+
+	int (*setup_tearcheck)(struct dpu_hw_intf *intf, struct dpu_hw_tear_check *cfg);
+
+	int (*enable_tearcheck)(struct dpu_hw_intf *intf, bool enable);
+
+	int (*connect_external_te)(struct dpu_hw_intf *intf, bool enable_external_te);
+
+	int (*get_vsync_info)(struct dpu_hw_intf *intf, struct dpu_hw_pp_vsync_info *info);
+
+	void (*setup_autorefresh)(struct dpu_hw_intf *intf, u32 frame_count, bool enable);
+
+	bool (*get_autorefresh)(struct dpu_hw_intf *intf, u32 *frame_count);
+
+	int (*poll_timeout_wr_ptr)(struct dpu_hw_intf *intf, u32 timeout_us);
+
+	void (*vsync_sel)(struct dpu_hw_intf *intf, u32 vsync_source);
 };
 
 struct dpu_hw_intf {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index 64b2bf219a34..773579906961 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -494,12 +494,14 @@ struct dpu_hw_tear_check {
  * @rd_ptr_frame_count: Num frames sent since enabling interface
  * @rd_ptr_line_count:  Current line on panel (rd ptr)
  * @wr_ptr_line_count:  Current line within pp fifo (wr ptr)
+ * @intf_frame_count:   Frames read from intf
  */
 struct dpu_hw_pp_vsync_info {
 	u32 rd_ptr_init_val;
 	u32 rd_ptr_frame_count;
 	u32 rd_ptr_line_count;
 	u32 wr_ptr_line_count;
+	u32 intf_frame_count;
 };
 
 #endif  /* _DPU_HW_MDSS_H */
-- 
2.39.0


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

* [RFC PATCH 7/7] drm/msm/dpu: Remove intr_rdptr from DPU >= 5.0.0 pingpong config
  2022-12-31 21:49 [RFC PATCH 0/7] drm/msm/dpu: Implement tearcheck support on INTF block Marijn Suijten
                   ` (5 preceding siblings ...)
  2022-12-31 21:50 ` [RFC PATCH 6/7] drm/msm/dpu: Implement tearcheck support on INTF block Marijn Suijten
@ 2022-12-31 21:50 ` Marijn Suijten
  2023-01-01 12:27   ` Dmitry Baryshkov
  6 siblings, 1 reply; 33+ messages in thread
From: Marijn Suijten @ 2022-12-31 21:50 UTC (permalink / raw)
  To: phone-devel, Abhinav Kumar, Dmitry Baryshkov, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Marijn Suijten,
	Rob Clark, Sean Paul, David Airlie, Daniel Vetter, Stephen Boyd,
	Vinod Koul, Bjorn Andersson, Kuogee Hsieh, Jessica Zhang,
	Konrad Dybcio, Loic Poulain, Vinod Polimera, Adam Skladowski,
	linux-arm-msm, dri-devel, freedreno, linux-kernel

Now that newer DPU platforms use a readpointer-done interrupt on the
INTF block, stop providing the unused interrupt on the PINGPONG block.

Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
---
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 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 b9b9b5b0b615..1b152727adfb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -1247,16 +1247,16 @@ static struct dpu_pingpong_cfg sc7180_pp[] = {
 static const struct dpu_pingpong_cfg sm8150_pp[] = {
 	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_TE2_MASK, MERGE_3D_0, sdm845_pp_sblk_te,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
-			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
+			-1),
 	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_TE2_MASK, MERGE_3D_0, sdm845_pp_sblk_te,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
-			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)),
+			-1),
 	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
-			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)),
+			-1),
 	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
-			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
+			-1),
 	PP_BLK("pingpong_4", PINGPONG_4, 0x72000, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk,
 			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
 			-1),
@@ -1275,7 +1275,7 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = {
 static struct dpu_pingpong_cfg qcm2290_pp[] = {
 	PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk,
 		DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
-		DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
+		-1),
 };
 
 /*************************************************************
-- 
2.39.0


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

* Re: [RFC PATCH 3/7] drm/msm/dpu: Disable MDP vsync source selection on DPU 5.0.0 and above
  2022-12-31 21:50 ` [RFC PATCH 3/7] drm/msm/dpu: Disable MDP vsync source selection " Marijn Suijten
@ 2022-12-31 21:52   ` Marijn Suijten
  2023-01-01 12:28     ` Dmitry Baryshkov
  2023-01-02  9:30     ` Konrad Dybcio
  0 siblings, 2 replies; 33+ messages in thread
From: Marijn Suijten @ 2022-12-31 21:52 UTC (permalink / raw)
  To: phone-devel, Abhinav Kumar, Dmitry Baryshkov, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Jessica Zhang, Konrad Dybcio,
	Loic Poulain, Vinod Polimera, Adam Skladowski, linux-arm-msm,
	dri-devel, freedreno, linux-kernel, Kalyan Thota

On 2022-12-31 22:50:02, Marijn Suijten wrote:
> Since hardware revision 5.0.0 the TE configuration moved out of the
> PINGPONG block into the INTF block, including vsync source selection
> that was previously part of MDP top.  Writing to the MDP_VSYNC_SEL
> register has no effect anymore and is omitted downstream via the
> DPU/SDE_MDP_VSYNC_SEL feature flag.  This flag is only added to INTF
> blocks used by hardware prior to 5.0.0.
> 
> The code that writes to these registers in the INTF block will follow in
> subsequent patches.
> 
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> ---
>  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 33 ++++++++++--
>  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  1 +
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c    | 52 +++++++++++++------
>  3 files changed, 66 insertions(+), 20 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 39d4b293710c..1cfe94494135 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -407,7 +407,7 @@ static const struct dpu_mdp_cfg msm8998_mdp[] = {
>  	{
>  	.name = "top_0", .id = MDP_TOP,
>  	.base = 0x0, .len = 0x458,
> -	.features = 0,
> +	.features = BIT(DPU_MDP_VSYNC_SEL),
>  	.highest_bank_bit = 0x2,
>  	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
>  			.reg_off = 0x2AC, .bit_off = 0},
> @@ -436,7 +436,7 @@ static const struct dpu_mdp_cfg sdm845_mdp[] = {
>  	{
>  	.name = "top_0", .id = MDP_TOP,
>  	.base = 0x0, .len = 0x45C,
> -	.features = BIT(DPU_MDP_AUDIO_SELECT),
> +	.features = BIT(DPU_MDP_AUDIO_SELECT) | BIT(DPU_MDP_VSYNC_SEL),
>  	.highest_bank_bit = 0x2,
>  	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
>  			.reg_off = 0x2AC, .bit_off = 0},
> @@ -512,6 +512,31 @@ static const struct dpu_mdp_cfg sm6115_mdp[] = {
>  	},
>  };
>  
> +static const struct dpu_mdp_cfg sdm8150_mdp[] = {

Sometimes it is only possible to spot such things _after_ sending,
probably the thing that makes us human :)

sm8150_mdp*, not sdm.

- Marijn

> +	{
> +	.name = "top_0", .id = MDP_TOP,
> +	.base = 0x0, .len = 0x45C,
> +	.features = BIT(DPU_MDP_AUDIO_SELECT),
> +	.highest_bank_bit = 0x2,
> +	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
> +			.reg_off = 0x2AC, .bit_off = 0},
> +	.clk_ctrls[DPU_CLK_CTRL_VIG1] = {
> +			.reg_off = 0x2B4, .bit_off = 0},
> +	.clk_ctrls[DPU_CLK_CTRL_VIG2] = {
> +			.reg_off = 0x2BC, .bit_off = 0},
> +	.clk_ctrls[DPU_CLK_CTRL_VIG3] = {
> +			.reg_off = 0x2C4, .bit_off = 0},
> +	.clk_ctrls[DPU_CLK_CTRL_DMA0] = {
> +			.reg_off = 0x2AC, .bit_off = 8},
> +	.clk_ctrls[DPU_CLK_CTRL_DMA1] = {
> +			.reg_off = 0x2B4, .bit_off = 8},
> +	.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
> +			.reg_off = 0x2BC, .bit_off = 8},
> +	.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
> +			.reg_off = 0x2C4, .bit_off = 8},
> +	},
> +};
> +
>  static const struct dpu_mdp_cfg sm8250_mdp[] = {
>  	{
>  	.name = "top_0", .id = MDP_TOP,
> @@ -1901,8 +1926,8 @@ static const struct dpu_mdss_cfg sm6115_dpu_cfg = {
>  
>  static const struct dpu_mdss_cfg sm8150_dpu_cfg = {
>  	.caps = &sm8150_dpu_caps,
> -	.mdp_count = ARRAY_SIZE(sdm845_mdp),
> -	.mdp = sdm845_mdp,
> +	.mdp_count = ARRAY_SIZE(sdm8150_mdp),
> +	.mdp = sdm8150_mdp,
>  	.ctl_count = ARRAY_SIZE(sm8150_ctl),
>  	.ctl = sm8150_ctl,
>  	.sspp_count = ARRAY_SIZE(sdm845_sspp),
> 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 3b645d5aa9aa..e0e153889ab7 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -93,6 +93,7 @@ enum {
>  	DPU_MDP_UBWC_1_0,
>  	DPU_MDP_UBWC_1_5,
>  	DPU_MDP_AUDIO_SELECT,
> +	DPU_MDP_VSYNC_SEL,
>  	DPU_MDP_MAX
>  };
>  
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
> index c3110a25a30d..2e699c9ad13c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
> @@ -151,28 +151,16 @@ static void dpu_hw_get_danger_status(struct dpu_hw_mdp *mdp,
>  	status->sspp[SSPP_CURSOR1] = (value >> 26) & 0x3;
>  }
>  
> -static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp,
> +static void dpu_hw_setup_vsync_source_v1(struct dpu_hw_mdp *mdp,
>  		struct dpu_vsync_source_cfg *cfg)
>  {
>  	struct dpu_hw_blk_reg_map *c;
> -	u32 reg, wd_load_value, wd_ctl, wd_ctl2, i;
> -	static const u32 pp_offset[PINGPONG_MAX] = {0xC, 0x8, 0x4, 0x13, 0x18};
> +	u32 reg, wd_load_value, wd_ctl, wd_ctl2;
>  
> -	if (!mdp || !cfg || (cfg->pp_count > ARRAY_SIZE(cfg->ppnumber)))
> +	if (!mdp || !cfg)
>  		return;
>  
>  	c = &mdp->hw;
> -	reg = DPU_REG_READ(c, MDP_VSYNC_SEL);
> -	for (i = 0; i < cfg->pp_count; i++) {
> -		int pp_idx = cfg->ppnumber[i] - PINGPONG_0;
> -
> -		if (pp_idx >= ARRAY_SIZE(pp_offset))
> -			continue;
> -
> -		reg &= ~(0xf << pp_offset[pp_idx]);
> -		reg |= (cfg->vsync_source & 0xf) << pp_offset[pp_idx];
> -	}
> -	DPU_REG_WRITE(c, MDP_VSYNC_SEL, reg);
>  
>  	if (cfg->vsync_source >= DPU_VSYNC_SOURCE_WD_TIMER_4 &&
>  			cfg->vsync_source <= DPU_VSYNC_SOURCE_WD_TIMER_0) {
> @@ -219,6 +207,33 @@ static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp,
>  	}
>  }
>  
> +static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp,
> +		struct dpu_vsync_source_cfg *cfg)
> +{
> +	struct dpu_hw_blk_reg_map *c;
> +	u32 reg, i;
> +	static const u32 pp_offset[PINGPONG_MAX] = {0xC, 0x8, 0x4, 0x13, 0x18};
> +
> +	if (!mdp || !cfg || (cfg->pp_count > ARRAY_SIZE(cfg->ppnumber)))
> +		return;
> +
> +	c = &mdp->hw;
> +
> +	reg = DPU_REG_READ(c, MDP_VSYNC_SEL);
> +	for (i = 0; i < cfg->pp_count; i++) {
> +		int pp_idx = cfg->ppnumber[i] - PINGPONG_0;
> +
> +		if (pp_idx >= ARRAY_SIZE(pp_offset))
> +			continue;
> +
> +		reg &= ~(0xf << pp_offset[pp_idx]);
> +		reg |= (cfg->vsync_source & 0xf) << pp_offset[pp_idx];
> +	}
> +	DPU_REG_WRITE(c, MDP_VSYNC_SEL, reg);
> +
> +	dpu_hw_setup_vsync_source_v1(mdp, cfg);
> +}
> +
>  static void dpu_hw_get_safe_status(struct dpu_hw_mdp *mdp,
>  		struct dpu_danger_safe_status *status)
>  {
> @@ -266,7 +281,12 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
>  	ops->setup_split_pipe = dpu_hw_setup_split_pipe;
>  	ops->setup_clk_force_ctrl = dpu_hw_setup_clk_force_ctrl;
>  	ops->get_danger_status = dpu_hw_get_danger_status;
> -	ops->setup_vsync_source = dpu_hw_setup_vsync_source;
> +
> +	if (cap & BIT(DPU_MDP_VSYNC_SEL))
> +		ops->setup_vsync_source = dpu_hw_setup_vsync_source;
> +	else
> +		ops->setup_vsync_source = dpu_hw_setup_vsync_source_v1;
> +
>  	ops->get_safe_status = dpu_hw_get_safe_status;
>  
>  	if (cap & BIT(DPU_MDP_AUDIO_SELECT))
> -- 
> 2.39.0
> 

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

* Re: [RFC PATCH 1/7] drm/msm/dpu: Remove unused INTF0 interrupt mask from sm6115/qcm2290
  2022-12-31 21:50 ` [RFC PATCH 1/7] drm/msm/dpu: Remove unused INTF0 interrupt mask from sm6115/qcm2290 Marijn Suijten
@ 2023-01-01  4:18   ` Dmitry Baryshkov
  2023-01-02  9:29   ` Konrad Dybcio
  1 sibling, 0 replies; 33+ messages in thread
From: Dmitry Baryshkov @ 2023-01-01  4:18 UTC (permalink / raw)
  To: Marijn Suijten, phone-devel, Abhinav Kumar, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Jessica Zhang, Konrad Dybcio,
	Loic Poulain, Vinod Polimera, Adam Skladowski, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On 31/12/2022 23:50, Marijn Suijten wrote:
> Neither of these SoCs has INTF0, they only have a DSI interface on index
> 1.  Stop enabling an interrupt that can't fire.
> 
> Fixes: 3581b7062cec ("drm/msm/disp/dpu1: add support for display on SM6115")
> Fixes: 5334087ee743 ("drm/msm: add support for QCM2290 MDSS")
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 9 +++++++--
>   1 file changed, 7 insertions(+), 2 deletions(-)

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

-- 
With best wishes
Dmitry


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

* Re: [RFC PATCH 2/7] drm/msm/dpu: Disable pingpong TE on DPU 5.0.0 and above
  2022-12-31 21:50 ` [RFC PATCH 2/7] drm/msm/dpu: Disable pingpong TE on DPU 5.0.0 and above Marijn Suijten
@ 2023-01-01  4:28   ` Dmitry Baryshkov
  2023-01-02 10:25     ` Marijn Suijten
  0 siblings, 1 reply; 33+ messages in thread
From: Dmitry Baryshkov @ 2023-01-01  4:28 UTC (permalink / raw)
  To: Marijn Suijten, phone-devel, Abhinav Kumar, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Jessica Zhang, Konrad Dybcio,
	Loic Poulain, Vinod Polimera, Adam Skladowski, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On 31/12/2022 23:50, Marijn Suijten wrote:
> Since hardware revision 5.0.0 the TE configuration moved out of the
> PINGPONG block into the INTF block.  Writing these registers has no
> effect, and is omitted downstream via the DPU/SDE_PINGPONG_TE feature
> flag.  This flag is only added to PINGPONG blocks used by hardware prior
> to 5.0.0.
> 
> The code that writes to these registers in the INTF block will follow in
> subsequent patches.
> 
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> ---
>   .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  |  5 +-
>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 53 +++++++++++--------
>   .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c   | 18 ++++---
>   3 files changed, 44 insertions(+), 32 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> index ae28b2b93e69..7e5ba52197cd 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> @@ -582,7 +582,7 @@ static bool dpu_encoder_phys_cmd_is_ongoing_pptx(
>   {
>   	struct dpu_hw_pp_vsync_info info;
>   
> -	if (!phys_enc)
> +	if (!phys_enc || !phys_enc->hw_pp->ops.get_vsync_info)
>   		return false;
>   
>   	phys_enc->hw_pp->ops.get_vsync_info(phys_enc->hw_pp, &info);
> @@ -607,6 +607,9 @@ static void dpu_encoder_phys_cmd_prepare_commit(

This function works only with the hw_pp and if I'm not mistaken it 
becomes void for newer platforms. Please consider moving completely to 
the dpu_hw_pp.c Then we'd have a single optional callback instead of 
having a pile of them.

>   	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
>   		return;
>   
> +	if (!phys_enc->hw_pp->ops.get_autorefresh || !phys_enc->hw_pp->ops.setup_autorefresh)
> +		return;
> +
>   	/* If autorefresh is already disabled, we have nothing to do */
>   	if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL))
>   		return;
> 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 9814ad52cc04..39d4b293710c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -59,11 +59,18 @@
>   #define MIXER_SC7180_MASK \
>   	(BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA))
>   
> -#define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER)
> +#define PINGPONG_SDM845_MASK \
> +	(BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE))
>   
> -#define PINGPONG_SDM845_SPLIT_MASK \
> +#define PINGPONG_SDM845_TE2_MASK \
>   	(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
>   
> +#define PINGPONG_SM8150_MASK \
> +	(BIT(DPU_PINGPONG_DITHER))
> +
> +#define PINGPONG_SM8150_TE2_MASK \
> +	(PINGPONG_SM8150_MASK | BIT(DPU_PINGPONG_TE2))
> +
>   #define CTL_SC7280_MASK \
>   	(BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE) | BIT(DPU_CTL_VM_CFG))
>   
> @@ -1156,21 +1163,21 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
>   	.len = 0x20, .version = 0x20000},
>   };
>   
> -#define PP_BLK_TE(_name, _id, _base, _merge_3d, _sblk, _done, _rdptr) \
> +#define PP_BLK_TE(_name, _id, _base, _features, _merge_3d, _sblk, _done, _rdptr) \
>   	{\
>   	.name = _name, .id = _id, \
>   	.base = _base, .len = 0xd4, \
> -	.features = PINGPONG_SDM845_SPLIT_MASK, \
> +	.features = _features, \
>   	.merge_3d = _merge_3d, \
>   	.sblk = &_sblk, \
>   	.intr_done = _done, \
>   	.intr_rdptr = _rdptr, \
>   	}
> -#define PP_BLK(_name, _id, _base, _merge_3d, _sblk, _done, _rdptr) \
> +#define PP_BLK(_name, _id, _base, _features, _merge_3d, _sblk, _done, _rdptr) \
>   	{\
>   	.name = _name, .id = _id, \
>   	.base = _base, .len = 0xd4, \
> -	.features = PINGPONG_SDM845_MASK, \
> +	.features = _features, \
>   	.merge_3d = _merge_3d, \
>   	.sblk = &_sblk, \
>   	.intr_done = _done, \
> @@ -1178,55 +1185,55 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
>   	}
>   
>   static const struct dpu_pingpong_cfg sdm845_pp[] = {
> -	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te,
> +	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te,
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> -	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te,
> +	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te,
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)),
> -	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, 0, sdm845_pp_sblk,
> +	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SDM845_MASK, 0, sdm845_pp_sblk,
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)),
> -	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, 0, sdm845_pp_sblk,
> +	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SDM845_MASK, 0, sdm845_pp_sblk,
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>   };
>   
>   static struct dpu_pingpong_cfg sc7180_pp[] = {
> -	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te, -1, -1),
> -	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te, -1, -1),
> +	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_TE2_MASK, 0, sdm845_pp_sblk_te, -1, -1),
> +	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_TE2_MASK, 0, sdm845_pp_sblk_te, -1, -1),
>   };
>   
>   static const struct dpu_pingpong_cfg sm8150_pp[] = {
> -	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk_te,
> +	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_TE2_MASK, MERGE_3D_0, sdm845_pp_sblk_te,
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> -	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk_te,
> +	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_TE2_MASK, MERGE_3D_0, sdm845_pp_sblk_te,
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)),
> -	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, MERGE_3D_1, sdm845_pp_sblk,
> +	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk,
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)),
> -	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, MERGE_3D_1, sdm845_pp_sblk,
> +	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk,
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
> -	PP_BLK("pingpong_4", PINGPONG_4, 0x72000, MERGE_3D_2, sdm845_pp_sblk,
> +	PP_BLK("pingpong_4", PINGPONG_4, 0x72000, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk,
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>   			-1),
> -	PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk,
> +	PP_BLK("pingpong_5", PINGPONG_5, 0x72800, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk,
>   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>   			-1),
>   };
>   
>   static const struct dpu_pingpong_cfg sc7280_pp[] = {
> -	PP_BLK("pingpong_0", PINGPONG_0, 0x59000, 0, sc7280_pp_sblk, -1, -1),
> -	PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, 0, sc7280_pp_sblk, -1, -1),
> -	PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, 0, sc7280_pp_sblk, -1, -1),
> -	PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1),
> +	PP_BLK("pingpong_0", PINGPONG_0, 0x59000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
> +	PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
> +	PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
> +	PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
>   };
>   
>   static struct dpu_pingpong_cfg qcm2290_pp[] = {
> -	PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
> +	PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk,
>   		DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>   		DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>   };
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
> index 0fcad9760b6f..30896c057f87 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
> @@ -274,14 +274,16 @@ static int dpu_hw_pp_setup_dsc(struct dpu_hw_pingpong *pp)
>   static void _setup_pingpong_ops(struct dpu_hw_pingpong *c,
>   				unsigned long features)
>   {
> -	c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config;
> -	c->ops.enable_tearcheck = dpu_hw_pp_enable_te;
> -	c->ops.connect_external_te = dpu_hw_pp_connect_external_te;
> -	c->ops.get_vsync_info = dpu_hw_pp_get_vsync_info;
> -	c->ops.setup_autorefresh = dpu_hw_pp_setup_autorefresh_config;
> -	c->ops.get_autorefresh = dpu_hw_pp_get_autorefresh_config;
> -	c->ops.poll_timeout_wr_ptr = dpu_hw_pp_poll_timeout_wr_ptr;
> -	c->ops.get_line_count = dpu_hw_pp_get_line_count;
> +	if (test_bit(DPU_PINGPONG_TE, &features)) {
> +		c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config;
> +		c->ops.enable_tearcheck = dpu_hw_pp_enable_te;
> +		c->ops.connect_external_te = dpu_hw_pp_connect_external_te;
> +		c->ops.get_vsync_info = dpu_hw_pp_get_vsync_info;
> +		c->ops.setup_autorefresh = dpu_hw_pp_setup_autorefresh_config;
> +		c->ops.get_autorefresh = dpu_hw_pp_get_autorefresh_config;
> +		c->ops.poll_timeout_wr_ptr = dpu_hw_pp_poll_timeout_wr_ptr;
> +		c->ops.get_line_count = dpu_hw_pp_get_line_count;
> +	}
>   	c->ops.setup_dsc = dpu_hw_pp_setup_dsc;
>   	c->ops.enable_dsc = dpu_hw_pp_dsc_enable;
>   	c->ops.disable_dsc = dpu_hw_pp_dsc_disable;

-- 
With best wishes
Dmitry


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

* Re: [RFC PATCH 7/7] drm/msm/dpu: Remove intr_rdptr from DPU >= 5.0.0 pingpong config
  2022-12-31 21:50 ` [RFC PATCH 7/7] drm/msm/dpu: Remove intr_rdptr from DPU >= 5.0.0 pingpong config Marijn Suijten
@ 2023-01-01 12:27   ` Dmitry Baryshkov
  0 siblings, 0 replies; 33+ messages in thread
From: Dmitry Baryshkov @ 2023-01-01 12:27 UTC (permalink / raw)
  To: Marijn Suijten
  Cc: phone-devel, Abhinav Kumar, Neil Armstrong,
	~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Jessica Zhang, Konrad Dybcio,
	Loic Poulain, Vinod Polimera, Adam Skladowski, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On Sat, 31 Dec 2022 at 23:50, Marijn Suijten
<marijn.suijten@somainline.org> wrote:
>
> Now that newer DPU platforms use a readpointer-done interrupt on the
> INTF block, stop providing the unused interrupt on the PINGPONG block.
>
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 10 +++++-----
>  1 file changed, 5 insertions(+), 5 deletions(-)

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH 3/7] drm/msm/dpu: Disable MDP vsync source selection on DPU 5.0.0 and above
  2022-12-31 21:52   ` Marijn Suijten
@ 2023-01-01 12:28     ` Dmitry Baryshkov
  2023-01-02  9:30     ` Konrad Dybcio
  1 sibling, 0 replies; 33+ messages in thread
From: Dmitry Baryshkov @ 2023-01-01 12:28 UTC (permalink / raw)
  To: Marijn Suijten, phone-devel, Abhinav Kumar, Dmitry Baryshkov,
	Neil Armstrong, ~postmarketos/upstreaming,
	AngeloGioacchino Del Regno, Konrad Dybcio, Martin Botka,
	Jami Kettunen, Rob Clark, Sean Paul, David Airlie, Daniel Vetter,
	Stephen Boyd, Vinod Koul, Bjorn Andersson, Kuogee Hsieh,
	Jessica Zhang, Konrad Dybcio, Loic Poulain, Vinod Polimera,
	Adam Skladowski, linux-arm-msm, dri-devel, freedreno,
	linux-kernel, Kalyan Thota

On Sat, 31 Dec 2022 at 23:52, Marijn Suijten
<marijn.suijten@somainline.org> wrote:
>
> On 2022-12-31 22:50:02, Marijn Suijten wrote:
> > Since hardware revision 5.0.0 the TE configuration moved out of the
> > PINGPONG block into the INTF block, including vsync source selection
> > that was previously part of MDP top.  Writing to the MDP_VSYNC_SEL
> > register has no effect anymore and is omitted downstream via the
> > DPU/SDE_MDP_VSYNC_SEL feature flag.  This flag is only added to INTF
> > blocks used by hardware prior to 5.0.0.
> >
> > The code that writes to these registers in the INTF block will follow in
> > subsequent patches.
> >
> > Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> > ---
> >  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 33 ++++++++++--
> >  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  1 +
> >  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c    | 52 +++++++++++++------
> >  3 files changed, 66 insertions(+), 20 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 39d4b293710c..1cfe94494135 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > @@ -407,7 +407,7 @@ static const struct dpu_mdp_cfg msm8998_mdp[] = {
> >       {
> >       .name = "top_0", .id = MDP_TOP,
> >       .base = 0x0, .len = 0x458,
> > -     .features = 0,
> > +     .features = BIT(DPU_MDP_VSYNC_SEL),
> >       .highest_bank_bit = 0x2,
> >       .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
> >                       .reg_off = 0x2AC, .bit_off = 0},
> > @@ -436,7 +436,7 @@ static const struct dpu_mdp_cfg sdm845_mdp[] = {
> >       {
> >       .name = "top_0", .id = MDP_TOP,
> >       .base = 0x0, .len = 0x45C,
> > -     .features = BIT(DPU_MDP_AUDIO_SELECT),
> > +     .features = BIT(DPU_MDP_AUDIO_SELECT) | BIT(DPU_MDP_VSYNC_SEL),
> >       .highest_bank_bit = 0x2,
> >       .clk_ctrls[DPU_CLK_CTRL_VIG0] = {
> >                       .reg_off = 0x2AC, .bit_off = 0},
> > @@ -512,6 +512,31 @@ static const struct dpu_mdp_cfg sm6115_mdp[] = {
> >       },
> >  };
> >
> > +static const struct dpu_mdp_cfg sdm8150_mdp[] = {
>
> Sometimes it is only possible to spot such things _after_ sending,
> probably the thing that makes us human :)
>
> sm8150_mdp*, not sdm.
>

With this name fixed:

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

-- 
With best wishes
Dmitry

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

* Re: [RFC PATCH 4/7] drm/msm/dpu: Move dpu_hw_{tear_check,pp_vsync_info} to dpu_hw_mdss.h
  2022-12-31 21:50 ` [RFC PATCH 4/7] drm/msm/dpu: Move dpu_hw_{tear_check,pp_vsync_info} to dpu_hw_mdss.h Marijn Suijten
@ 2023-01-01 12:37   ` Dmitry Baryshkov
  0 siblings, 0 replies; 33+ messages in thread
From: Dmitry Baryshkov @ 2023-01-01 12:37 UTC (permalink / raw)
  To: Marijn Suijten, phone-devel, Abhinav Kumar, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Jessica Zhang, Konrad Dybcio,
	Loic Poulain, Vinod Polimera, Adam Skladowski, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On 31/12/2022 23:50, Marijn Suijten wrote:
> From: Konrad Dybcio <konrad.dybcio@somainline.org>
> 
> Now that newer SoCs since DPU 5.0.0 manage tearcheck in the INTF instead
> of PINGPONG block, move the struct definition to a common file. Also,
> bring in documentation from msm-4.19 techpack while at it.
> 
> Signed-off-by: Konrad Dybcio <konrad.dybcio@somainline.org>
> [Marijn: Also move dpu_hw_pp_vsync_info]
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h   | 46 +++++++++++++++++++
>   .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.h   | 22 ---------
>   2 files changed, 46 insertions(+), 22 deletions(-)

Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>

-- 
With best wishes
Dmitry


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

* Re: [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces
  2022-12-31 21:50 ` [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces Marijn Suijten
@ 2023-01-01 13:12   ` Dmitry Baryshkov
  2023-01-02 10:38     ` Marijn Suijten
  2023-02-13 19:37   ` Jessica Zhang
  1 sibling, 1 reply; 33+ messages in thread
From: Dmitry Baryshkov @ 2023-01-01 13:12 UTC (permalink / raw)
  To: Marijn Suijten, phone-devel, Abhinav Kumar, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Jessica Zhang, Konrad Dybcio,
	Loic Poulain, Vinod Polimera, Adam Skladowski, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On 31/12/2022 23:50, Marijn Suijten wrote:
> All SoCs since DPU 5.0.0 (and seemingly up until and including 6.0.0,
> but excluding 7.x.x) have the tear interrupt and control registers moved
> out of the PINGPONG block and into the INTF block.  Wire up the
> necessary interrupts and IRQ masks on all supported hardware.
> 
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> ---
>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 78 +++++++++++--------
>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  6 +-
>   .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 12 +++
>   .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  2 +
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h      |  3 +
>   5 files changed, 68 insertions(+), 33 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 1cfe94494135..b9b9b5b0b615 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -86,6 +86,15 @@
>   
>   #define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)
>   
> +#define IRQ_MSM8998_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
> +			 BIT(MDP_SSPP_TOP0_INTR2) | \
> +			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> +			 BIT(MDP_INTF0_INTR) | \
> +			 BIT(MDP_INTF1_INTR) | \
> +			 BIT(MDP_INTF2_INTR) | \
> +			 BIT(MDP_INTF3_INTR) | \
> +			 BIT(MDP_INTF4_INTR))
> +
>   #define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>   			 BIT(MDP_SSPP_TOP0_INTR2) | \
>   			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> @@ -100,13 +109,15 @@
>   #define IRQ_QCM2290_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>   			 BIT(MDP_SSPP_TOP0_INTR2) | \
>   			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> -			 BIT(MDP_INTF1_INTR))
> +			 BIT(MDP_INTF1_INTR) | \
> +			 BIT(MDP_INTF1_TEAR_INTR))
>   
>   #define IRQ_SC7180_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>   			 BIT(MDP_SSPP_TOP0_INTR2) | \
>   			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>   			 BIT(MDP_INTF0_INTR) | \
> -			 BIT(MDP_INTF1_INTR))
> +			 BIT(MDP_INTF1_INTR) | \
> +			 BIT(MDP_INTF1_TEAR_INTR))
>   
>   #define IRQ_SC7280_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>   			 BIT(MDP_SSPP_TOP0_INTR2) | \
> @@ -120,7 +131,9 @@
>   			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>   			 BIT(MDP_INTF0_INTR) | \
>   			 BIT(MDP_INTF1_INTR) | \
> +			 BIT(MDP_INTF1_TEAR_INTR) | \
>   			 BIT(MDP_INTF2_INTR) | \
> +			 BIT(MDP_INTF2_TEAR_INTR) | \
>   			 BIT(MDP_INTF3_INTR) | \
>   			 BIT(MDP_INTF4_INTR))
>   
> @@ -129,7 +142,9 @@
>   			  BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>   			  BIT(MDP_INTF0_INTR) | \
>   			  BIT(MDP_INTF1_INTR) | \
> +			  BIT(MDP_INTF1_TEAR_INTR) | \
>   			  BIT(MDP_INTF2_INTR) | \
> +			  BIT(MDP_INTF2_TEAR_INTR) | \
>   			  BIT(MDP_INTF3_INTR) | \
>   			  BIT(MDP_INTF4_INTR) | \
>   			  BIT(MDP_INTF5_INTR) | \
> @@ -1300,63 +1315,64 @@ static struct dpu_dsc_cfg sdm845_dsc[] = {
>   /*************************************************************
>    * INTF sub blocks config
>    *************************************************************/
> -#define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _progfetch, _features, _reg, _underrun_bit, _vsync_bit) \
> +#define INTF_BLK(_name, _id, _base, _len, _type, _ctrl_id, _progfetch, _features, _reg, _underrun_bit, _vsync_bit, _tear_reg, _tear_rd_ptr_bit) \
>   	{\
>   	.name = _name, .id = _id, \
> -	.base = _base, .len = 0x280, \
> +	.base = _base, .len = _len, \

Please move .len setting to a separate patch, it is not direclty related 
to tear interrupt addition.

>   	.features = _features, \
>   	.type = _type, \
>   	.controller_id = _ctrl_id, \
>   	.prog_fetch_lines_worst_case = _progfetch, \
>   	.intr_underrun = DPU_IRQ_IDX(_reg, _underrun_bit), \
>   	.intr_vsync = DPU_IRQ_IDX(_reg, _vsync_bit), \
> +	.intr_tear_rd_ptr = DPU_IRQ_IDX(_tear_reg, _tear_rd_ptr_bit), \

Initially I added separate _reg and _bit settings because reg was common 
to both interrupts. However now as tear interrups use different reg it 
might be better to first move DPU_IRQ_IDX out of this macro () and then 
to add your tear_rd_ptr_intr as a single intr_idx.

>   	}
>   
>   static const struct dpu_intf_cfg msm8998_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> -	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> -	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
> -	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_HDMI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> +	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x268, INTF_DP, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x268, INTF_DSI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27, -1, -1),
> +	INTF_BLK("intf_2", INTF_2, 0x6B000, 0x268, INTF_DSI, 1, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29, -1, -1),
> +	INTF_BLK("intf_3", INTF_3, 0x6B800, 0x268, INTF_HDMI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31, -1, -1),
>   };
>   
>   static const struct dpu_intf_cfg sdm845_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> -	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> -	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
> -	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> +	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x280, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27, -1, -1),
> +	INTF_BLK("intf_2", INTF_2, 0x6B000, 0x280, INTF_DSI, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29, -1, -1),
> +	INTF_BLK("intf_3", INTF_3, 0x6B800, 0x280, INTF_DP, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31, -1, -1),
>   };
>   
>   static const struct dpu_intf_cfg sc7180_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> -	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> +	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2b8, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF1_TEAR_INTR, 2),
>   };
>   
>   static const struct dpu_intf_cfg sm8150_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> -	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> -	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
> -	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> +	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2b8, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF1_TEAR_INTR, 2),
> +	INTF_BLK("intf_2", INTF_2, 0x6B000, 0x2b8, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29, MDP_INTF2_TEAR_INTR, 2),
> +	INTF_BLK("intf_3", INTF_3, 0x6B800, 0x280, INTF_DP, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31, -1, -1),
>   };
>   
>   static const struct dpu_intf_cfg sc7280_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x34000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> -	INTF_BLK("intf_1", INTF_1, 0x35000, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> -	INTF_BLK("intf_5", INTF_5, 0x39000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
> +	INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x35000, 0x2b8, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF1_TEAR_INTR, 2),
> +	INTF_BLK("intf_5", INTF_5, 0x39000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23, -1, -1),
>   };
>   
>   static const struct dpu_intf_cfg sc8180x_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> -	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> -	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
> +	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2b8, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF1_TEAR_INTR, 2),
> +	INTF_BLK("intf_2", INTF_2, 0x6B000, 0x2b8, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29, MDP_INTF2_TEAR_INTR, 2),
>   	/* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until this is supported */
> -	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> -	INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 20, 21),
> -	INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
> +	INTF_BLK("intf_3", INTF_3, 0x6B800, 0x280, INTF_DP, 999, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31, -1, -1),
> +	INTF_BLK("intf_4", INTF_4, 0x6C000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 20, 21, -1, -1),
> +	INTF_BLK("intf_5", INTF_5, 0x6C800, 0x280, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 22, 23, -1, -1),
>   };
>   
>   static const struct dpu_intf_cfg qcm2290_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x00000, INTF_NONE, 0, 0, 0, 0, 0, 0),
> -	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> +	INTF_BLK("intf_0", INTF_0, 0x00000, 0x2b8, INTF_NONE, 0, 0, 0, 0, 0, 0, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2b8, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF2_TEAR_INTR, 2),
>   };
>   
>   /*************************************************************
> @@ -1849,7 +1865,7 @@ static const struct dpu_mdss_cfg msm8998_dpu_cfg = {
>   	.vbif = msm8998_vbif,
>   	.reg_dma_count = 0,
>   	.perf = &msm8998_perf_data,
> -	.mdss_irqs = IRQ_SM8250_MASK,
> +	.mdss_irqs = IRQ_MSM8998_MASK,
>   };
>   
>   static const struct dpu_mdss_cfg sdm845_dpu_cfg = {
> @@ -1947,7 +1963,7 @@ static const struct dpu_mdss_cfg sm8150_dpu_cfg = {
>   	.reg_dma_count = 1,
>   	.dma_cfg = &sm8150_regdma,
>   	.perf = &sm8150_perf_data,
> -	.mdss_irqs = IRQ_SDM845_MASK,
> +	.mdss_irqs = IRQ_SM8250_MASK,
>   };
>   
>   static const struct dpu_mdss_cfg sc8180x_dpu_cfg = {
> 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 e0e153889ab7..2ea17e4ef3e5 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -638,8 +638,9 @@ struct dpu_dsc_cfg {
>    * @type:              Interface type(DSI, DP, HDMI)
>    * @controller_id:     Controller Instance ID in case of multiple of intf type
>    * @prog_fetch_lines_worst_case	Worst case latency num lines needed to prefetch
> - * @intr_underrun:	index for INTF underrun interrupt
> - * @intr_vsync:	        index for INTF VSYNC interrupt
> + * @intr_underrun:     index for INTF underrun interrupt
> + * @intr_vsync:        index for INTF VSYNC interrupt
> + * @intr_tear_rd_ptr:  index for INTF TEAR_RD_PTR interrupt
>    */
>   struct dpu_intf_cfg  {
>   	DPU_HW_BLK_INFO;
> @@ -648,6 +649,7 @@ struct dpu_intf_cfg  {
>   	u32 prog_fetch_lines_worst_case;
>   	s32 intr_underrun;
>   	s32 intr_vsync;
> +	s32 intr_tear_rd_ptr;
>   };
>   
>   /**
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> index cf1b6d84c18a..044136a97fac 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> @@ -24,6 +24,8 @@
>   #define MDP_INTF_3_OFF			0x6B800
>   #define MDP_INTF_4_OFF			0x6C000
>   #define MDP_INTF_5_OFF			0x6C800
> +#define MDP_INTF_1_TEAR_OFF		0x6D800
> +#define MDP_INTF_2_TEAR_OFF		0x6D900
>   #define MDP_AD4_0_OFF			0x7C000
>   #define MDP_AD4_1_OFF			0x7D000
>   #define MDP_AD4_INTR_EN_OFF		0x41c
> @@ -99,6 +101,16 @@ static const struct dpu_intr_reg dpu_intr_set[] = {
>   		MDP_INTF_5_OFF+INTF_INTR_EN,
>   		MDP_INTF_5_OFF+INTF_INTR_STATUS
>   	},
> +	[MDP_INTF1_TEAR_INTR] = {
> +		MDP_INTF_1_TEAR_OFF+INTF_INTR_TEAR_CLEAR,
> +		MDP_INTF_1_TEAR_OFF+INTF_INTR_TEAR_EN,
> +		MDP_INTF_1_TEAR_OFF+INTF_INTR_TEAR_STATUS
> +	},
> +	[MDP_INTF2_TEAR_INTR] = {
> +		MDP_INTF_2_TEAR_OFF+INTF_INTR_TEAR_CLEAR,
> +		MDP_INTF_2_TEAR_OFF+INTF_INTR_TEAR_EN,
> +		MDP_INTF_2_TEAR_OFF+INTF_INTR_TEAR_STATUS
> +	},
>   	[MDP_AD4_0_INTR] = {
>   		MDP_AD4_0_OFF + MDP_AD4_INTR_CLEAR_OFF,
>   		MDP_AD4_0_OFF + MDP_AD4_INTR_EN_OFF,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
> index 46443955443c..b447e4a1d9f4 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
> @@ -23,6 +23,8 @@ enum dpu_hw_intr_reg {
>   	MDP_INTF3_INTR,
>   	MDP_INTF4_INTR,
>   	MDP_INTF5_INTR,
> +	MDP_INTF1_TEAR_INTR,
> +	MDP_INTF2_TEAR_INTR,
>   	MDP_AD4_0_INTR,
>   	MDP_AD4_1_INTR,
>   	MDP_INTF0_7xxx_INTR,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h
> index c8156ed4b7fb..6bdac515fd54 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h
> @@ -10,6 +10,9 @@
>   /**
>    * MDP TOP block Register and bit fields and defines
>    */
> +#define INTF_INTR_TEAR_EN               0x000
> +#define INTF_INTR_TEAR_STATUS           0x004
> +#define INTF_INTR_TEAR_CLEAR            0x008
>   #define DISP_INTF_SEL                   0x004
>   #define INTR_EN                         0x010
>   #define INTR_STATUS                     0x014

-- 
With best wishes
Dmitry


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

* Re: [RFC PATCH 6/7] drm/msm/dpu: Implement tearcheck support on INTF block
  2022-12-31 21:50 ` [RFC PATCH 6/7] drm/msm/dpu: Implement tearcheck support on INTF block Marijn Suijten
@ 2023-01-01 13:32   ` Dmitry Baryshkov
  2023-01-02 11:06     ` Marijn Suijten
  0 siblings, 1 reply; 33+ messages in thread
From: Dmitry Baryshkov @ 2023-01-01 13:32 UTC (permalink / raw)
  To: Marijn Suijten, phone-devel, Abhinav Kumar, Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Jessica Zhang, Konrad Dybcio,
	Loic Poulain, Vinod Polimera, Adam Skladowski, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On 31/12/2022 23:50, Marijn Suijten wrote:
> Since DPU 5.0.0 the TEARCHECK registers and interrupts moved out of the
> PINGPONG block and into the INTF.  Implement the necessary callbacks in
> the INTF block, and use these callbacks together with the INTF_TEAR
> interrupts
> 
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>

Generally I have the same question as for the patch 2. Can we have some 
higher level functions in the hw_pp and hw_intf files? Moreover, as I 
review your patch I have the feeling that it would make sense to have to 
two sets of encoder callbacks, one for the hw_pp tearing handling and 
another set for hw_intf-based one.

> ---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  11 +
>   .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |  10 +-
>   .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  | 113 +++++++---
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c   | 206 ++++++++++++++++++
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h   |  29 +++
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h   |   2 +
>   6 files changed, 340 insertions(+), 31 deletions(-)
> 
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 9c6817b5a194..8b9070220ab2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -673,6 +673,7 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
>   	struct dpu_kms *dpu_kms;
>   	struct dpu_hw_mdp *hw_mdptop;
>   	struct drm_encoder *drm_enc;
> +	struct dpu_encoder_phys *phys_enc;
>   	int i;
>   
>   	if (!dpu_enc || !disp_info) {
> @@ -703,12 +704,22 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
>   			vsync_cfg.ppnumber[i] = dpu_enc->hw_pp[i]->idx;
>   
>   		vsync_cfg.pp_count = dpu_enc->num_phys_encs;
> +		vsync_cfg.frame_rate = drm_mode_vrefresh(&dpu_enc->base.crtc->state->adjusted_mode);
> +
>   		if (disp_info->is_te_using_watchdog_timer)
>   			vsync_cfg.vsync_source = DPU_VSYNC_SOURCE_WD_TIMER_0;
>   		else
>   			vsync_cfg.vsync_source = DPU_VSYNC0_SOURCE_GPIO;
>   
>   		hw_mdptop->ops.setup_vsync_source(hw_mdptop, &vsync_cfg);
> +
> +		for (i = 0; i < dpu_enc->num_phys_encs; i++) {
> +			phys_enc = dpu_enc->phys_encs[i];
> +
> +			if (phys_enc->has_intf_te && phys_enc->hw_intf->ops.vsync_sel)
> +				phys_enc->hw_intf->ops.vsync_sel(phys_enc->hw_intf,
> +						vsync_cfg.vsync_source);
> +		}
>   	}
>   }
>   
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> index f2af07d87f56..47e79401032c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> @@ -148,10 +148,10 @@ struct dpu_encoder_phys_ops {
>   /**
>    * enum dpu_intr_idx - dpu encoder interrupt index
>    * @INTR_IDX_VSYNC:    Vsync interrupt for video mode panel
> - * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
> - * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel
> - * @INTR_IDX_RDPTR:    Readpointer done unterrupt for cmd mode panel
> - * @INTR_IDX_WB_DONE:  Writeback fone interrupt for virtual connector
> + * @INTR_IDX_PINGPONG: Pingpong done interrupt for cmd mode panel
> + * @INTR_IDX_UNDERRUN: Underrun interrupt for video and cmd mode panel
> + * @INTR_IDX_RDPTR:    Readpointer done interrupt for cmd mode panel
> + * @INTR_IDX_WB_DONE:  Writeback done interrupt for virtual connector
>    */
>   enum dpu_intr_idx {
>   	INTR_IDX_VSYNC,
> @@ -195,6 +195,7 @@ enum dpu_intr_idx {
>    *                              pending.
>    * @pending_kickoff_wq:		Wait queue for blocking until kickoff completes
>    * @irq:			IRQ indices
> + * @has_intf_te:		Interface TE configuration support
>    */
>   struct dpu_encoder_phys {
>   	struct drm_encoder *parent;
> @@ -220,6 +221,7 @@ struct dpu_encoder_phys {
>   	atomic_t pending_kickoff_cnt;
>   	wait_queue_head_t pending_kickoff_wq;
>   	int irq[INTR_IDX_MAX];
> +	bool has_intf_te;
>   };
>   
>   static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> index 7e5ba52197cd..ca44a8087f01 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> @@ -100,12 +100,12 @@ static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
>   	DPU_ATRACE_END("pp_done_irq");
>   }
>   
> -static void dpu_encoder_phys_cmd_pp_rd_ptr_irq(void *arg, int irq_idx)
> +static void dpu_encoder_phys_cmd_te_rd_ptr_irq(void *arg, int irq_idx)
>   {
>   	struct dpu_encoder_phys *phys_enc = arg;
>   	struct dpu_encoder_phys_cmd *cmd_enc;
>   
> -	if (!phys_enc->hw_pp)
> +	if (!phys_enc->hw_pp || !phys_enc->hw_intf)
>   		return;
>   
>   	DPU_ATRACE_BEGIN("rd_ptr_irq");
> @@ -147,11 +147,19 @@ static void dpu_encoder_phys_cmd_atomic_mode_set(
>   		struct drm_crtc_state *crtc_state,
>   		struct drm_connector_state *conn_state)
>   {
> +	if (phys_enc->has_intf_te && !phys_enc->hw_intf) {
> +		DPU_ERROR("invalid intf configuration\n");
> +		return;
> +	}
> +
>   	phys_enc->irq[INTR_IDX_CTL_START] = phys_enc->hw_ctl->caps->intr_start;
>   
>   	phys_enc->irq[INTR_IDX_PINGPONG] = phys_enc->hw_pp->caps->intr_done;
>   
> -	phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr;
> +	if (phys_enc->has_intf_te)
> +		phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_intf->cap->intr_tear_rd_ptr;
> +	else
> +		phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr;
>   
>   	phys_enc->irq[INTR_IDX_UNDERRUN] = phys_enc->hw_intf->cap->intr_underrun;
>   }
> @@ -264,7 +272,7 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(
>   	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
>   		ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
>   				phys_enc->irq[INTR_IDX_RDPTR],
> -				dpu_encoder_phys_cmd_pp_rd_ptr_irq,
> +				dpu_encoder_phys_cmd_te_rd_ptr_irq,
>   				phys_enc);
>   	else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
>   		ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
> @@ -336,10 +344,18 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
>   
>   	DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0);
>   
> -	if (!phys_enc->hw_pp->ops.setup_tearcheck ||
> -		!phys_enc->hw_pp->ops.enable_tearcheck) {
> -		DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
> -		return;
> +	if (phys_enc->has_intf_te) {
> +		if (!phys_enc->hw_intf->ops.setup_tearcheck ||
> +			!phys_enc->hw_intf->ops.enable_tearcheck) {
> +			DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
> +			return;
> +		}
> +	} else {
> +		if (!phys_enc->hw_pp->ops.setup_tearcheck ||
> +			!phys_enc->hw_pp->ops.enable_tearcheck) {
> +			DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
> +			return;
> +		}
>   	}
>   
>   	dpu_kms = phys_enc->dpu_kms;
> @@ -392,8 +408,13 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
>   		phys_enc->hw_pp->idx - PINGPONG_0, tc_cfg.sync_cfg_height,
>   		tc_cfg.sync_threshold_start, tc_cfg.sync_threshold_continue);
>   
> -	phys_enc->hw_pp->ops.setup_tearcheck(phys_enc->hw_pp, &tc_cfg);
> -	phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, tc_enable);

A simple random example: setup_tearcheck is always followed with the 
enable_tearcheck. If we merge them, the code would be simpler.

> +	if (phys_enc->has_intf_te) {
> +		phys_enc->hw_intf->ops.setup_tearcheck(phys_enc->hw_intf, &tc_cfg);
> +		phys_enc->hw_intf->ops.enable_tearcheck(phys_enc->hw_intf, tc_enable);
> +	} else {
> +		phys_enc->hw_pp->ops.setup_tearcheck(phys_enc->hw_pp, &tc_cfg);
> +		phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, tc_enable);
> +	}
>   }
>   
>   static void _dpu_encoder_phys_cmd_pingpong_config(
> @@ -470,11 +491,19 @@ static void dpu_encoder_phys_cmd_enable(struct dpu_encoder_phys *phys_enc)
>   static void _dpu_encoder_phys_cmd_connect_te(
>   		struct dpu_encoder_phys *phys_enc, bool enable)
>   {
> -	if (!phys_enc->hw_pp || !phys_enc->hw_pp->ops.connect_external_te)
> -		return;
> +	if (phys_enc->has_intf_te) {
> +		if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.connect_external_te)
> +			return;
>   
> -	trace_dpu_enc_phys_cmd_connect_te(DRMID(phys_enc->parent), enable);
> -	phys_enc->hw_pp->ops.connect_external_te(phys_enc->hw_pp, enable);
> +		trace_dpu_enc_phys_cmd_connect_te(DRMID(phys_enc->parent), enable);
> +		phys_enc->hw_intf->ops.connect_external_te(phys_enc->hw_intf, enable);
> +	} else {
> +		if (!phys_enc->hw_pp || !phys_enc->hw_pp->ops.connect_external_te)
> +			return;
> +
> +		trace_dpu_enc_phys_cmd_connect_te(DRMID(phys_enc->parent), enable);
> +		phys_enc->hw_pp->ops.connect_external_te(phys_enc->hw_pp, enable);
> +	}
>   }
>   
>   static void dpu_encoder_phys_cmd_prepare_idle_pc(
> @@ -487,6 +516,7 @@ static int dpu_encoder_phys_cmd_get_line_count(
>   		struct dpu_encoder_phys *phys_enc)
>   {
>   	struct dpu_hw_pingpong *hw_pp;
> +	struct dpu_hw_intf *hw_intf;
>   
>   	if (!phys_enc->hw_pp)
>   		return -EINVAL;
> @@ -494,10 +524,16 @@ static int dpu_encoder_phys_cmd_get_line_count(
>   	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
>   		return -EINVAL;
>   
> +	if (phys_enc->has_intf_te) {
> +		hw_intf = phys_enc->hw_intf;
> +		if (!hw_intf->ops.get_line_count)
> +			return -EINVAL;
> +		return hw_intf->ops.get_line_count(hw_intf);
> +	}
> +
>   	hw_pp = phys_enc->hw_pp;
>   	if (!hw_pp->ops.get_line_count)
>   		return -EINVAL;
> -
>   	return hw_pp->ops.get_line_count(hw_pp);
>   }
>   
> @@ -520,7 +556,9 @@ static void dpu_encoder_phys_cmd_disable(struct dpu_encoder_phys *phys_enc)
>   		return;
>   	}
>   
> -	if (phys_enc->hw_pp->ops.enable_tearcheck)
> +	if (phys_enc->has_intf_te && phys_enc->hw_intf->ops.enable_tearcheck)
> +		phys_enc->hw_intf->ops.enable_tearcheck(phys_enc->hw_intf, false);
> +	else if (phys_enc->hw_pp->ops.enable_tearcheck)
>   		phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, false);
>   
>   	if (phys_enc->hw_intf->ops.bind_pingpong_blk) {
> @@ -582,10 +620,19 @@ static bool dpu_encoder_phys_cmd_is_ongoing_pptx(
>   {
>   	struct dpu_hw_pp_vsync_info info;
>   
> -	if (!phys_enc || !phys_enc->hw_pp->ops.get_vsync_info)
> +	if (!phys_enc)
>   		return false;
>   
> -	phys_enc->hw_pp->ops.get_vsync_info(phys_enc->hw_pp, &info);
> +	if (phys_enc->has_intf_te) {
> +		if (!phys_enc->hw_intf->ops.get_vsync_info)
> +			return false;
> +		phys_enc->hw_intf->ops.get_vsync_info(phys_enc->hw_intf, &info);
> +	} else {
> +		if (!phys_enc->hw_pp->ops.get_vsync_info)
> +			return false;
> +		phys_enc->hw_pp->ops.get_vsync_info(phys_enc->hw_pp, &info);
> +	}
> +
>   	if (info.wr_ptr_line_count > 0 &&
>   	    info.wr_ptr_line_count < phys_enc->cached_mode.vdisplay)
>   		return true;
> @@ -602,17 +649,23 @@ static void dpu_encoder_phys_cmd_prepare_commit(
>   
>   	if (!phys_enc)
>   		return;
> -	if (!phys_enc->hw_pp)
> -		return;
>   	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
>   		return;
>   
> -	if (!phys_enc->hw_pp->ops.get_autorefresh || !phys_enc->hw_pp->ops.setup_autorefresh)
> -		return;
> -
>   	/* If autorefresh is already disabled, we have nothing to do */
> -	if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL))
> -		return;
> +	if (phys_enc->has_intf_te) {
> +		if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_autorefresh ||
> +				!phys_enc->hw_intf->ops.setup_autorefresh)
> +			return;
> +		if (!phys_enc->hw_intf->ops.get_autorefresh(phys_enc->hw_intf, NULL))
> +			return;
> +	} else {
> +		if (!phys_enc->hw_pp || !phys_enc->hw_pp->ops.get_autorefresh ||
> +				!phys_enc->hw_pp->ops.setup_autorefresh)
> +			return;
> +		if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL))
> +			return;
> +	}
>   
>   	/*
>   	 * If autorefresh is enabled, disable it and make sure it is safe to
> @@ -623,7 +676,10 @@ static void dpu_encoder_phys_cmd_prepare_commit(
>   	 * 5. Enable TE back
>   	 */
>   	_dpu_encoder_phys_cmd_connect_te(phys_enc, false);
> -	phys_enc->hw_pp->ops.setup_autorefresh(phys_enc->hw_pp, 0, false);
> +	if (phys_enc->has_intf_te)
> +		phys_enc->hw_intf->ops.setup_autorefresh(phys_enc->hw_intf, 0, false);
> +	else
> +		phys_enc->hw_pp->ops.setup_autorefresh(phys_enc->hw_pp, 0, false);
>   
>   	do {
>   		udelay(DPU_ENC_MAX_POLL_TIMEOUT_US);
> @@ -717,7 +773,7 @@ static int dpu_encoder_phys_cmd_wait_for_vblank(
>   
>   	rc = dpu_encoder_helper_wait_for_irq(phys_enc,
>   			phys_enc->irq[INTR_IDX_RDPTR],
> -			dpu_encoder_phys_cmd_pp_rd_ptr_irq,
> +			dpu_encoder_phys_cmd_te_rd_ptr_irq,
>   			&wait_info);
>   
>   	return rc;
> @@ -793,6 +849,9 @@ struct dpu_encoder_phys *dpu_encoder_phys_cmd_init(
>   	for (i = 0; i < ARRAY_SIZE(phys_enc->irq); i++)
>   		phys_enc->irq[i] = -EINVAL;
>   
> +	phys_enc->has_intf_te = test_bit(DPU_INTF_TE,
> +			&phys_enc->dpu_kms->catalog->intf[p->intf_idx - INTF_0].features);
> +
>   	atomic_set(&phys_enc->vblank_refcount, 0);
>   	atomic_set(&phys_enc->pending_kickoff_cnt, 0);
>   	atomic_set(&phys_enc->pending_ctlstart_cnt, 0);
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> index 7ce66bf3f4c8..42929278df8e 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c
> @@ -9,6 +9,8 @@
>   #include "dpu_hw_intf.h"
>   #include "dpu_kms.h"
>   
> +#include <linux/iopoll.h>
> +
>   #define INTF_TIMING_ENGINE_EN           0x000
>   #define INTF_CONFIG                     0x004
>   #define INTF_HSYNC_CTL                  0x008
> @@ -62,6 +64,27 @@
>   #define   INTF_LINE_COUNT               0x0B0
>   
>   #define   INTF_MUX                      0x25C
> +#define   INTF_MISR_SIGNATURE           0x184
> +
> +#define INTF_STATUS                     0x26C
> +#define INTF_AVR_CONTROL                0x270
> +#define INTF_AVR_MODE                   0x274
> +#define INTF_AVR_TRIGGER                0x278
> +#define INTF_AVR_VTOTAL                 0x27C
> +#define INTF_TEAR_MDP_VSYNC_SEL         0x280
> +#define INTF_TEAR_TEAR_CHECK_EN         0x284
> +#define INTF_TEAR_SYNC_CONFIG_VSYNC     0x288
> +#define INTF_TEAR_SYNC_CONFIG_HEIGHT    0x28C
> +#define INTF_TEAR_SYNC_WRCOUNT          0x290
> +#define INTF_TEAR_VSYNC_INIT_VAL        0x294
> +#define INTF_TEAR_INT_COUNT_VAL         0x298
> +#define INTF_TEAR_SYNC_THRESH           0x29C
> +#define INTF_TEAR_START_POS             0x2A0
> +#define INTF_TEAR_RD_PTR_IRQ            0x2A4
> +#define INTF_TEAR_WR_PTR_IRQ            0x2A8
> +#define INTF_TEAR_OUT_LINE_COUNT        0x2AC
> +#define INTF_TEAR_LINE_COUNT            0x2B0
> +#define INTF_TEAR_AUTOREFRESH_CONFIG    0x2B4
>   
>   #define INTF_CFG_ACTIVE_H_EN	BIT(29)
>   #define INTF_CFG_ACTIVE_V_EN	BIT(30)
> @@ -309,6 +332,22 @@ static void dpu_hw_intf_get_status(
>   	}
>   }
>   
> +static void dpu_hw_intf_v1_get_status(
> +		struct dpu_hw_intf *intf,
> +		struct intf_status *s)
> +{
> +	struct dpu_hw_blk_reg_map *c = &intf->hw;
> +
> +	s->is_en = DPU_REG_READ(c, INTF_STATUS) & BIT(0);
> +	if (s->is_en) {
> +		s->frame_count = DPU_REG_READ(c, INTF_FRAME_COUNT);
> +		s->line_count = DPU_REG_READ(c, INTF_LINE_COUNT);
> +	} else {
> +		s->line_count = 0;
> +		s->frame_count = 0;
> +	}
> +}
> +
>   static u32 dpu_hw_intf_get_line_count(struct dpu_hw_intf *intf)
>   {
>   	struct dpu_hw_blk_reg_map *c;
> @@ -331,6 +370,161 @@ static int dpu_hw_intf_collect_misr(struct dpu_hw_intf *intf, u32 *misr_value)
>   	return dpu_hw_collect_misr(&intf->hw, INTF_MISR_CTRL, INTF_MISR_SIGNATURE, misr_value);
>   }
>   
> +static int dpu_hw_intf_setup_te_config(struct dpu_hw_intf *intf,
> +		struct dpu_hw_tear_check *te)
> +{
> +	struct dpu_hw_blk_reg_map *c;
> +	int cfg;
> +
> +	if (!intf)
> +		return -EINVAL;
> +
> +	c = &intf->hw;
> +
> +	cfg = BIT(19); /* VSYNC_COUNTER_EN */
> +	if (te->hw_vsync_mode)
> +		cfg |= BIT(20);
> +
> +	cfg |= te->vsync_count;
> +
> +	DPU_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg);
> +	DPU_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_HEIGHT, te->sync_cfg_height);
> +	DPU_REG_WRITE(c, INTF_TEAR_VSYNC_INIT_VAL, te->vsync_init_val);
> +	DPU_REG_WRITE(c, INTF_TEAR_RD_PTR_IRQ, te->rd_ptr_irq);
> +	DPU_REG_WRITE(c, INTF_TEAR_START_POS, te->start_pos);
> +	DPU_REG_WRITE(c, INTF_TEAR_SYNC_THRESH,
> +			((te->sync_threshold_continue << 16) |
> +			 te->sync_threshold_start));
> +	DPU_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT,
> +			(te->start_pos + te->sync_threshold_start + 1));
> +
> +	return 0;
> +}
> +
> +static void dpu_hw_intf_setup_autorefresh_config(struct dpu_hw_intf *intf,
> +		u32 frame_count, bool enable)
> +{
> +	struct dpu_hw_blk_reg_map *c;
> +	u32 refresh_cfg;
> +
> +	c = &intf->hw;
> +	refresh_cfg = DPU_REG_READ(c, INTF_TEAR_AUTOREFRESH_CONFIG);
> +	if (enable)
> +		refresh_cfg = BIT(31) | frame_count;
> +	else
> +		refresh_cfg &= ~BIT(31);
> +
> +	DPU_REG_WRITE(c, INTF_TEAR_AUTOREFRESH_CONFIG, refresh_cfg);
> +}
> +
> +/*
> + * dpu_hw_intf_get_autorefresh_config - Get autorefresh config from HW
> + * @intf:        DPU intf structure
> + * @frame_count: Used to return the current frame count from hw
> + *
> + * Returns: True if autorefresh enabled, false if disabled.
> + */
> +static bool dpu_hw_intf_get_autorefresh_config(struct dpu_hw_intf *intf,
> +		u32 *frame_count)
> +{
> +	u32 val = DPU_REG_READ(&intf->hw, INTF_TEAR_AUTOREFRESH_CONFIG);
> +
> +	if (frame_count != NULL)
> +		*frame_count = val & 0xffff;
> +	return !!((val & BIT(31)) >> 31);
> +}
> +
> +static int dpu_hw_intf_poll_timeout_wr_ptr(struct dpu_hw_intf *intf,
> +		u32 timeout_us)
> +{
> +	struct dpu_hw_blk_reg_map *c;
> +	u32 val;
> +	int rc;
> +
> +	if (!intf)
> +		return -EINVAL;
> +
> +	c = &intf->hw;
> +	rc = readl_poll_timeout(c->blk_addr + INTF_TEAR_LINE_COUNT,
> +			val, (val & 0xffff) >= 1, 10, timeout_us);
> +
> +	return rc;
> +}
> +
> +static int dpu_hw_intf_enable_te(struct dpu_hw_intf *intf, bool enable)
> +{
> +	struct dpu_hw_blk_reg_map *c;
> +
> +	if (!intf)
> +		return -EINVAL;
> +
> +	c = &intf->hw;
> +	DPU_REG_WRITE(c, INTF_TEAR_TEAR_CHECK_EN, enable);
> +	return 0;
> +}
> +
> +static int dpu_hw_intf_connect_external_te(struct dpu_hw_intf *intf,
> +		bool enable_external_te)
> +{
> +	struct dpu_hw_blk_reg_map *c = &intf->hw;
> +	u32 cfg;
> +	int orig;
> +
> +	if (!intf)
> +		return -EINVAL;
> +
> +	c = &intf->hw;
> +	cfg = DPU_REG_READ(c, INTF_TEAR_SYNC_CONFIG_VSYNC);
> +	orig = (bool)(cfg & BIT(20));
> +	if (enable_external_te)
> +		cfg |= BIT(20);
> +	else
> +		cfg &= ~BIT(20);
> +	DPU_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg);
> +
> +	return orig;
> +}
> +
> +static int dpu_hw_intf_get_vsync_info(struct dpu_hw_intf *intf,
> +		struct dpu_hw_pp_vsync_info *info)
> +{
> +	struct dpu_hw_blk_reg_map *c = &intf->hw;
> +	u32 val;
> +
> +	if (!intf || !info)
> +		return -EINVAL;
> +
> +	c = &intf->hw;
> +
> +	val = DPU_REG_READ(c, INTF_TEAR_VSYNC_INIT_VAL);
> +	info->rd_ptr_init_val = val & 0xffff;
> +
> +	val = DPU_REG_READ(c, INTF_TEAR_INT_COUNT_VAL);
> +	info->rd_ptr_frame_count = (val & 0xffff0000) >> 16;
> +	info->rd_ptr_line_count = val & 0xffff;
> +
> +	val = DPU_REG_READ(c, INTF_TEAR_LINE_COUNT);
> +	info->wr_ptr_line_count = val & 0xffff;
> +
> +	val = DPU_REG_READ(c, INTF_FRAME_COUNT);
> +	info->intf_frame_count = val;
> +
> +	return 0;
> +}
> +
> +static void dpu_hw_intf_vsync_sel(struct dpu_hw_intf *intf,
> +		u32 vsync_source)
> +{
> +	struct dpu_hw_blk_reg_map *c;
> +
> +	if (!intf)
> +		return;
> +
> +	c = &intf->hw;
> +
> +	DPU_REG_WRITE(c, INTF_TEAR_MDP_VSYNC_SEL, (vsync_source & 0xf));
> +}
> +
>   static void _setup_intf_ops(struct dpu_hw_intf_ops *ops,
>   		unsigned long cap)
>   {
> @@ -343,6 +537,18 @@ static void _setup_intf_ops(struct dpu_hw_intf_ops *ops,
>   		ops->bind_pingpong_blk = dpu_hw_intf_bind_pingpong_blk;
>   	ops->setup_misr = dpu_hw_intf_setup_misr;
>   	ops->collect_misr = dpu_hw_intf_collect_misr;
> +
> +	if (cap & BIT(DPU_INTF_TE)) {
> +		ops->setup_tearcheck = dpu_hw_intf_setup_te_config;
> +		ops->enable_tearcheck = dpu_hw_intf_enable_te;
> +		ops->connect_external_te = dpu_hw_intf_connect_external_te;
> +		ops->get_vsync_info = dpu_hw_intf_get_vsync_info;
> +		ops->setup_autorefresh = dpu_hw_intf_setup_autorefresh_config;
> +		ops->get_autorefresh = dpu_hw_intf_get_autorefresh_config;
> +		ops->poll_timeout_wr_ptr = dpu_hw_intf_poll_timeout_wr_ptr;
> +		ops->vsync_sel = dpu_hw_intf_vsync_sel;
> +		ops->get_status = dpu_hw_intf_v1_get_status;
> +	}
>   }
>   
>   struct dpu_hw_intf *dpu_hw_intf_init(enum dpu_intf idx,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
> index 643dd10bc030..1521c9475fad 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h
> @@ -60,6 +60,17 @@ struct intf_status {
>    *                     feed pixels to this interface
>    * @setup_misr: enable/disable MISR
>    * @collect_misr: read MISR signature
> + * @setup_tearcheck:            Enables vsync generation and sets up init value of read
> + *                              pointer and programs the tear check configuration
> + * @enable_tearcheck:           Enables tearcheck block
> + * @connect_external_te:        Read, modify, write to either set or clear listening to external TE
> + *                              Return: 1 if TE was originally connected, 0 if not, or -ERROR
> + * @get_vsync_info:             Provides the programmed and current line_count
> + * @setup_autorefresh:          Configure and enable the autorefresh config
> + * @get_autorefresh:            Retrieve autorefresh config from hardware
> + * @poll_timeout_wr_ptr:        Poll until write pointer transmission starts
> + *                              Return: 0 on success, -ETIMEDOUT on timeout
> + * @vsync_sel:                  Select vsync signal for tear-effect configuration
>    */
>   struct dpu_hw_intf_ops {
>   	void (*setup_timing_gen)(struct dpu_hw_intf *intf,
> @@ -82,6 +93,24 @@ struct dpu_hw_intf_ops {
>   			const enum dpu_pingpong pp);
>   	void (*setup_misr)(struct dpu_hw_intf *intf, bool enable, u32 frame_count);
>   	int (*collect_misr)(struct dpu_hw_intf *intf, u32 *misr_value);
> +
> +	// Tearcheck on INTF since DPU 5.0.0
> +
> +	int (*setup_tearcheck)(struct dpu_hw_intf *intf, struct dpu_hw_tear_check *cfg);
> +
> +	int (*enable_tearcheck)(struct dpu_hw_intf *intf, bool enable);
> +
> +	int (*connect_external_te)(struct dpu_hw_intf *intf, bool enable_external_te);
> +
> +	int (*get_vsync_info)(struct dpu_hw_intf *intf, struct dpu_hw_pp_vsync_info *info);
> +
> +	void (*setup_autorefresh)(struct dpu_hw_intf *intf, u32 frame_count, bool enable);
> +
> +	bool (*get_autorefresh)(struct dpu_hw_intf *intf, u32 *frame_count);
> +
> +	int (*poll_timeout_wr_ptr)(struct dpu_hw_intf *intf, u32 timeout_us);
> +
> +	void (*vsync_sel)(struct dpu_hw_intf *intf, u32 vsync_source);
>   };
>   
>   struct dpu_hw_intf {
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> index 64b2bf219a34..773579906961 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
> @@ -494,12 +494,14 @@ struct dpu_hw_tear_check {
>    * @rd_ptr_frame_count: Num frames sent since enabling interface
>    * @rd_ptr_line_count:  Current line on panel (rd ptr)
>    * @wr_ptr_line_count:  Current line within pp fifo (wr ptr)
> + * @intf_frame_count:   Frames read from intf
>    */
>   struct dpu_hw_pp_vsync_info {
>   	u32 rd_ptr_init_val;
>   	u32 rd_ptr_frame_count;
>   	u32 rd_ptr_line_count;
>   	u32 wr_ptr_line_count;
> +	u32 intf_frame_count;
>   };
>   
>   #endif  /* _DPU_HW_MDSS_H */

-- 
With best wishes
Dmitry


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

* Re: [RFC PATCH 1/7] drm/msm/dpu: Remove unused INTF0 interrupt mask from sm6115/qcm2290
  2022-12-31 21:50 ` [RFC PATCH 1/7] drm/msm/dpu: Remove unused INTF0 interrupt mask from sm6115/qcm2290 Marijn Suijten
  2023-01-01  4:18   ` Dmitry Baryshkov
@ 2023-01-02  9:29   ` Konrad Dybcio
  2023-01-02 10:12     ` Marijn Suijten
  1 sibling, 1 reply; 33+ messages in thread
From: Konrad Dybcio @ 2023-01-02  9:29 UTC (permalink / raw)
  To: Marijn Suijten, phone-devel, Abhinav Kumar, Dmitry Baryshkov,
	Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Martin Botka, Jami Kettunen, Rob Clark, Sean Paul, David Airlie,
	Daniel Vetter, Stephen Boyd, Vinod Koul, Bjorn Andersson,
	Kuogee Hsieh, Jessica Zhang, Konrad Dybcio, Loic Poulain,
	Vinod Polimera, Adam Skladowski, linux-arm-msm, dri-devel,
	freedreno, linux-kernel



On 31.12.2022 22:50, Marijn Suijten wrote:
> Neither of these SoCs has INTF0, they only have a DSI interface on index
> 1.  Stop enabling an interrupt that can't fire.
Double space.

Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Konrad
> 
> Fixes: 3581b7062cec ("drm/msm/disp/dpu1: add support for display on SM6115")
> Fixes: 5334087ee743 ("drm/msm: add support for QCM2290 MDSS")
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> ---
>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 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 2196e205efa5..9814ad52cc04 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -90,6 +90,11 @@
>  			 BIT(MDP_AD4_0_INTR) | \
>  			 BIT(MDP_AD4_1_INTR))
>  
> +#define IRQ_QCM2290_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
> +			 BIT(MDP_SSPP_TOP0_INTR2) | \
> +			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> +			 BIT(MDP_INTF1_INTR))
> +
>  #define IRQ_SC7180_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>  			 BIT(MDP_SSPP_TOP0_INTR2) | \
>  			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> @@ -1884,7 +1889,7 @@ static const struct dpu_mdss_cfg sm6115_dpu_cfg = {
>  	.vbif_count = ARRAY_SIZE(sdm845_vbif),
>  	.vbif = sdm845_vbif,
>  	.perf = &sm6115_perf_data,
> -	.mdss_irqs = IRQ_SC7180_MASK,
> +	.mdss_irqs = IRQ_QCM2290_MASK,
>  };
>  
>  static const struct dpu_mdss_cfg sm8150_dpu_cfg = {
> @@ -2008,7 +2013,7 @@ static const struct dpu_mdss_cfg qcm2290_dpu_cfg = {
>  	.reg_dma_count = 1,
>  	.dma_cfg = &sdm845_regdma,
>  	.perf = &qcm2290_perf_data,
> -	.mdss_irqs = IRQ_SC7180_MASK,
> +	.mdss_irqs = IRQ_QCM2290_MASK,
>  };
>  
>  static const struct dpu_mdss_hw_cfg_handler cfg_handler[] = {

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

* Re: [RFC PATCH 3/7] drm/msm/dpu: Disable MDP vsync source selection on DPU 5.0.0 and above
  2022-12-31 21:52   ` Marijn Suijten
  2023-01-01 12:28     ` Dmitry Baryshkov
@ 2023-01-02  9:30     ` Konrad Dybcio
  2023-01-02 10:18       ` Marijn Suijten
  1 sibling, 1 reply; 33+ messages in thread
From: Konrad Dybcio @ 2023-01-02  9:30 UTC (permalink / raw)
  To: Marijn Suijten, phone-devel, Abhinav Kumar, Dmitry Baryshkov,
	Neil Armstrong, ~postmarketos/upstreaming,
	AngeloGioacchino Del Regno, Martin Botka, Jami Kettunen,
	Rob Clark, Sean Paul, David Airlie, Daniel Vetter, Stephen Boyd,
	Vinod Koul, Bjorn Andersson, Kuogee Hsieh, Jessica Zhang,
	Konrad Dybcio, Loic Poulain, Vinod Polimera, Adam Skladowski,
	linux-arm-msm, dri-devel, freedreno, linux-kernel, Kalyan Thota



On 31.12.2022 22:52, Marijn Suijten wrote:
> On 2022-12-31 22:50:02, Marijn Suijten wrote:
>> Since hardware revision 5.0.0 the TE configuration moved out of the
>> PINGPONG block into the INTF block, including vsync source selection
>> that was previously part of MDP top.  Writing to the MDP_VSYNC_SEL
>> register has no effect anymore and is omitted downstream via the
>> DPU/SDE_MDP_VSYNC_SEL feature flag.  This flag is only added to INTF
>> blocks used by hardware prior to 5.0.0.
>>
>> The code that writes to these registers in the INTF block will follow in
>> subsequent patches.
>>
>> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
>> ---
>>  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 33 ++++++++++--
>>  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  1 +
>>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c    | 52 +++++++++++++------
>>  3 files changed, 66 insertions(+), 20 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 39d4b293710c..1cfe94494135 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>> @@ -407,7 +407,7 @@ static const struct dpu_mdp_cfg msm8998_mdp[] = {
>>  	{
>>  	.name = "top_0", .id = MDP_TOP,
>>  	.base = 0x0, .len = 0x458,
>> -	.features = 0,
>> +	.features = BIT(DPU_MDP_VSYNC_SEL),
>>  	.highest_bank_bit = 0x2,
>>  	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
>>  			.reg_off = 0x2AC, .bit_off = 0},
>> @@ -436,7 +436,7 @@ static const struct dpu_mdp_cfg sdm845_mdp[] = {
>>  	{
>>  	.name = "top_0", .id = MDP_TOP,
>>  	.base = 0x0, .len = 0x45C,
>> -	.features = BIT(DPU_MDP_AUDIO_SELECT),
>> +	.features = BIT(DPU_MDP_AUDIO_SELECT) | BIT(DPU_MDP_VSYNC_SEL),
>>  	.highest_bank_bit = 0x2,
>>  	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
>>  			.reg_off = 0x2AC, .bit_off = 0},
>> @@ -512,6 +512,31 @@ static const struct dpu_mdp_cfg sm6115_mdp[] = {
>>  	},
>>  };
>>  
>> +static const struct dpu_mdp_cfg sdm8150_mdp[] = {
> 
> Sometimes it is only possible to spot such things _after_ sending,
> probably the thing that makes us human :)
> 
> sm8150_mdp*, not sdm.
> 
> - Marijn
> 
>> +	{
>> +	.name = "top_0", .id = MDP_TOP,
>> +	.base = 0x0, .len = 0x45C,
>> +	.features = BIT(DPU_MDP_AUDIO_SELECT),
>> +	.highest_bank_bit = 0x2,
>> +	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
>> +			.reg_off = 0x2AC, .bit_off = 0},
Keeping the hex values lowercase would be nice.

Konrad
>> +	.clk_ctrls[DPU_CLK_CTRL_VIG1] = {
>> +			.reg_off = 0x2B4, .bit_off = 0},
>> +	.clk_ctrls[DPU_CLK_CTRL_VIG2] = {
>> +			.reg_off = 0x2BC, .bit_off = 0},
>> +	.clk_ctrls[DPU_CLK_CTRL_VIG3] = {
>> +			.reg_off = 0x2C4, .bit_off = 0},
>> +	.clk_ctrls[DPU_CLK_CTRL_DMA0] = {
>> +			.reg_off = 0x2AC, .bit_off = 8},
>> +	.clk_ctrls[DPU_CLK_CTRL_DMA1] = {
>> +			.reg_off = 0x2B4, .bit_off = 8},
>> +	.clk_ctrls[DPU_CLK_CTRL_CURSOR0] = {
>> +			.reg_off = 0x2BC, .bit_off = 8},
>> +	.clk_ctrls[DPU_CLK_CTRL_CURSOR1] = {
>> +			.reg_off = 0x2C4, .bit_off = 8},
>> +	},
>> +};
>> +
>>  static const struct dpu_mdp_cfg sm8250_mdp[] = {
>>  	{
>>  	.name = "top_0", .id = MDP_TOP,
>> @@ -1901,8 +1926,8 @@ static const struct dpu_mdss_cfg sm6115_dpu_cfg = {
>>  
>>  static const struct dpu_mdss_cfg sm8150_dpu_cfg = {
>>  	.caps = &sm8150_dpu_caps,
>> -	.mdp_count = ARRAY_SIZE(sdm845_mdp),
>> -	.mdp = sdm845_mdp,
>> +	.mdp_count = ARRAY_SIZE(sdm8150_mdp),
>> +	.mdp = sdm8150_mdp,
>>  	.ctl_count = ARRAY_SIZE(sm8150_ctl),
>>  	.ctl = sm8150_ctl,
>>  	.sspp_count = ARRAY_SIZE(sdm845_sspp),
>> 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 3b645d5aa9aa..e0e153889ab7 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>> @@ -93,6 +93,7 @@ enum {
>>  	DPU_MDP_UBWC_1_0,
>>  	DPU_MDP_UBWC_1_5,
>>  	DPU_MDP_AUDIO_SELECT,
>> +	DPU_MDP_VSYNC_SEL,
>>  	DPU_MDP_MAX
>>  };
>>  
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
>> index c3110a25a30d..2e699c9ad13c 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c
>> @@ -151,28 +151,16 @@ static void dpu_hw_get_danger_status(struct dpu_hw_mdp *mdp,
>>  	status->sspp[SSPP_CURSOR1] = (value >> 26) & 0x3;
>>  }
>>  
>> -static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp,
>> +static void dpu_hw_setup_vsync_source_v1(struct dpu_hw_mdp *mdp,
>>  		struct dpu_vsync_source_cfg *cfg)
>>  {
>>  	struct dpu_hw_blk_reg_map *c;
>> -	u32 reg, wd_load_value, wd_ctl, wd_ctl2, i;
>> -	static const u32 pp_offset[PINGPONG_MAX] = {0xC, 0x8, 0x4, 0x13, 0x18};
>> +	u32 reg, wd_load_value, wd_ctl, wd_ctl2;
>>  
>> -	if (!mdp || !cfg || (cfg->pp_count > ARRAY_SIZE(cfg->ppnumber)))
>> +	if (!mdp || !cfg)
>>  		return;
>>  
>>  	c = &mdp->hw;
>> -	reg = DPU_REG_READ(c, MDP_VSYNC_SEL);
>> -	for (i = 0; i < cfg->pp_count; i++) {
>> -		int pp_idx = cfg->ppnumber[i] - PINGPONG_0;
>> -
>> -		if (pp_idx >= ARRAY_SIZE(pp_offset))
>> -			continue;
>> -
>> -		reg &= ~(0xf << pp_offset[pp_idx]);
>> -		reg |= (cfg->vsync_source & 0xf) << pp_offset[pp_idx];
>> -	}
>> -	DPU_REG_WRITE(c, MDP_VSYNC_SEL, reg);
>>  
>>  	if (cfg->vsync_source >= DPU_VSYNC_SOURCE_WD_TIMER_4 &&
>>  			cfg->vsync_source <= DPU_VSYNC_SOURCE_WD_TIMER_0) {
>> @@ -219,6 +207,33 @@ static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp,
>>  	}
>>  }
>>  
>> +static void dpu_hw_setup_vsync_source(struct dpu_hw_mdp *mdp,
>> +		struct dpu_vsync_source_cfg *cfg)
>> +{
>> +	struct dpu_hw_blk_reg_map *c;
>> +	u32 reg, i;
>> +	static const u32 pp_offset[PINGPONG_MAX] = {0xC, 0x8, 0x4, 0x13, 0x18};
>> +
>> +	if (!mdp || !cfg || (cfg->pp_count > ARRAY_SIZE(cfg->ppnumber)))
>> +		return;
>> +
>> +	c = &mdp->hw;
>> +
>> +	reg = DPU_REG_READ(c, MDP_VSYNC_SEL);
>> +	for (i = 0; i < cfg->pp_count; i++) {
>> +		int pp_idx = cfg->ppnumber[i] - PINGPONG_0;
>> +
>> +		if (pp_idx >= ARRAY_SIZE(pp_offset))
>> +			continue;
>> +
>> +		reg &= ~(0xf << pp_offset[pp_idx]);
>> +		reg |= (cfg->vsync_source & 0xf) << pp_offset[pp_idx];
>> +	}
>> +	DPU_REG_WRITE(c, MDP_VSYNC_SEL, reg);
>> +
>> +	dpu_hw_setup_vsync_source_v1(mdp, cfg);
>> +}
>> +
>>  static void dpu_hw_get_safe_status(struct dpu_hw_mdp *mdp,
>>  		struct dpu_danger_safe_status *status)
>>  {
>> @@ -266,7 +281,12 @@ static void _setup_mdp_ops(struct dpu_hw_mdp_ops *ops,
>>  	ops->setup_split_pipe = dpu_hw_setup_split_pipe;
>>  	ops->setup_clk_force_ctrl = dpu_hw_setup_clk_force_ctrl;
>>  	ops->get_danger_status = dpu_hw_get_danger_status;
>> -	ops->setup_vsync_source = dpu_hw_setup_vsync_source;
>> +
>> +	if (cap & BIT(DPU_MDP_VSYNC_SEL))
>> +		ops->setup_vsync_source = dpu_hw_setup_vsync_source;
>> +	else
>> +		ops->setup_vsync_source = dpu_hw_setup_vsync_source_v1;
>> +
>>  	ops->get_safe_status = dpu_hw_get_safe_status;
>>  
>>  	if (cap & BIT(DPU_MDP_AUDIO_SELECT))
>> -- 
>> 2.39.0
>>

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

* Re: [RFC PATCH 1/7] drm/msm/dpu: Remove unused INTF0 interrupt mask from sm6115/qcm2290
  2023-01-02  9:29   ` Konrad Dybcio
@ 2023-01-02 10:12     ` Marijn Suijten
  0 siblings, 0 replies; 33+ messages in thread
From: Marijn Suijten @ 2023-01-02 10:12 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: phone-devel, Abhinav Kumar, Dmitry Baryshkov, Neil Armstrong,
	~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Martin Botka, Jami Kettunen, Rob Clark, Sean Paul, David Airlie,
	Daniel Vetter, Stephen Boyd, Vinod Koul, Bjorn Andersson,
	Kuogee Hsieh, Jessica Zhang, Konrad Dybcio, Loic Poulain,
	Vinod Polimera, Adam Skladowski, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

On 2023-01-02 10:29:03, Konrad Dybcio wrote:
> 
> 
> On 31.12.2022 22:50, Marijn Suijten wrote:
> > Neither of these SoCs has INTF0, they only have a DSI interface on index
> > 1.  Stop enabling an interrupt that can't fire.
> Double space.

In case you hadn't noticed I'm employing this habit for quite some time
now: after ending a sentence with a period, use a double space.  The
likes of GKH do it too.

It may look a bit off though with 1. at the beginning of the sentence
resembling the start of an ordered list.

- Marijn

> Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
> Konrad

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

* Re: [RFC PATCH 3/7] drm/msm/dpu: Disable MDP vsync source selection on DPU 5.0.0 and above
  2023-01-02  9:30     ` Konrad Dybcio
@ 2023-01-02 10:18       ` Marijn Suijten
  2023-01-02 10:19         ` Konrad Dybcio
  0 siblings, 1 reply; 33+ messages in thread
From: Marijn Suijten @ 2023-01-02 10:18 UTC (permalink / raw)
  To: Konrad Dybcio
  Cc: phone-devel, Abhinav Kumar, Dmitry Baryshkov, Neil Armstrong,
	~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Martin Botka, Jami Kettunen, Rob Clark, Sean Paul, David Airlie,
	Daniel Vetter, Stephen Boyd, Vinod Koul, Bjorn Andersson,
	Kuogee Hsieh, Jessica Zhang, Konrad Dybcio, Loic Poulain,
	Vinod Polimera, Adam Skladowski, linux-arm-msm, dri-devel,
	freedreno, linux-kernel, Kalyan Thota

On 2023-01-02 10:30:58, Konrad Dybcio wrote:
> 
> 
> On 31.12.2022 22:52, Marijn Suijten wrote:
> > On 2022-12-31 22:50:02, Marijn Suijten wrote:
> >> Since hardware revision 5.0.0 the TE configuration moved out of the
> >> PINGPONG block into the INTF block, including vsync source selection
> >> that was previously part of MDP top.  Writing to the MDP_VSYNC_SEL
> >> register has no effect anymore and is omitted downstream via the
> >> DPU/SDE_MDP_VSYNC_SEL feature flag.  This flag is only added to INTF
> >> blocks used by hardware prior to 5.0.0.
> >>
> >> The code that writes to these registers in the INTF block will follow in
> >> subsequent patches.
> >>
> >> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> >> ---
> >>  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 33 ++++++++++--
> >>  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  1 +
> >>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c    | 52 +++++++++++++------
> >>  3 files changed, 66 insertions(+), 20 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 39d4b293710c..1cfe94494135 100644
> >> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >> @@ -407,7 +407,7 @@ static const struct dpu_mdp_cfg msm8998_mdp[] = {
> >>  	{
> >>  	.name = "top_0", .id = MDP_TOP,
> >>  	.base = 0x0, .len = 0x458,
> >> -	.features = 0,
> >> +	.features = BIT(DPU_MDP_VSYNC_SEL),
> >>  	.highest_bank_bit = 0x2,
> >>  	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
> >>  			.reg_off = 0x2AC, .bit_off = 0},
> >> @@ -436,7 +436,7 @@ static const struct dpu_mdp_cfg sdm845_mdp[] = {
> >>  	{
> >>  	.name = "top_0", .id = MDP_TOP,
> >>  	.base = 0x0, .len = 0x45C,
> >> -	.features = BIT(DPU_MDP_AUDIO_SELECT),
> >> +	.features = BIT(DPU_MDP_AUDIO_SELECT) | BIT(DPU_MDP_VSYNC_SEL),
> >>  	.highest_bank_bit = 0x2,
> >>  	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
> >>  			.reg_off = 0x2AC, .bit_off = 0},
> >> @@ -512,6 +512,31 @@ static const struct dpu_mdp_cfg sm6115_mdp[] = {
> >>  	},
> >>  };
> >>  
> >> +static const struct dpu_mdp_cfg sdm8150_mdp[] = {
> > 
> > Sometimes it is only possible to spot such things _after_ sending,
> > probably the thing that makes us human :)
> > 
> > sm8150_mdp*, not sdm.
> > 
> > - Marijn
> > 
> >> +	{
> >> +	.name = "top_0", .id = MDP_TOP,
> >> +	.base = 0x0, .len = 0x45C,
> >> +	.features = BIT(DPU_MDP_AUDIO_SELECT),
> >> +	.highest_bank_bit = 0x2,
> >> +	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
> >> +			.reg_off = 0x2AC, .bit_off = 0},
> Keeping the hex values lowercase would be nice.

Ack, this was copied verbatim from sdm845_mdp but will cleanup as we go.
Looks like this file has a mixed approach towards lower and uppercase,
when does the normalization patch land?

- Marijn

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

* Re: [RFC PATCH 3/7] drm/msm/dpu: Disable MDP vsync source selection on DPU 5.0.0 and above
  2023-01-02 10:18       ` Marijn Suijten
@ 2023-01-02 10:19         ` Konrad Dybcio
  0 siblings, 0 replies; 33+ messages in thread
From: Konrad Dybcio @ 2023-01-02 10:19 UTC (permalink / raw)
  To: Marijn Suijten
  Cc: phone-devel, Abhinav Kumar, Dmitry Baryshkov, Neil Armstrong,
	~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Martin Botka, Jami Kettunen, Rob Clark, Sean Paul, David Airlie,
	Daniel Vetter, Stephen Boyd, Vinod Koul, Bjorn Andersson,
	Kuogee Hsieh, Jessica Zhang, Konrad Dybcio, Loic Poulain,
	Vinod Polimera, Adam Skladowski, linux-arm-msm, dri-devel,
	freedreno, linux-kernel, Kalyan Thota



On 2.01.2023 11:18, Marijn Suijten wrote:
> On 2023-01-02 10:30:58, Konrad Dybcio wrote:
>>
>>
>> On 31.12.2022 22:52, Marijn Suijten wrote:
>>> On 2022-12-31 22:50:02, Marijn Suijten wrote:
>>>> Since hardware revision 5.0.0 the TE configuration moved out of the
>>>> PINGPONG block into the INTF block, including vsync source selection
>>>> that was previously part of MDP top.  Writing to the MDP_VSYNC_SEL
>>>> register has no effect anymore and is omitted downstream via the
>>>> DPU/SDE_MDP_VSYNC_SEL feature flag.  This flag is only added to INTF
>>>> blocks used by hardware prior to 5.0.0.
>>>>
>>>> The code that writes to these registers in the INTF block will follow in
>>>> subsequent patches.
>>>>
>>>> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
>>>> ---
>>>>  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 33 ++++++++++--
>>>>  .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  1 +
>>>>  drivers/gpu/drm/msm/disp/dpu1/dpu_hw_top.c    | 52 +++++++++++++------
>>>>  3 files changed, 66 insertions(+), 20 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 39d4b293710c..1cfe94494135 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>> @@ -407,7 +407,7 @@ static const struct dpu_mdp_cfg msm8998_mdp[] = {
>>>>  	{
>>>>  	.name = "top_0", .id = MDP_TOP,
>>>>  	.base = 0x0, .len = 0x458,
>>>> -	.features = 0,
>>>> +	.features = BIT(DPU_MDP_VSYNC_SEL),
>>>>  	.highest_bank_bit = 0x2,
>>>>  	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
>>>>  			.reg_off = 0x2AC, .bit_off = 0},
>>>> @@ -436,7 +436,7 @@ static const struct dpu_mdp_cfg sdm845_mdp[] = {
>>>>  	{
>>>>  	.name = "top_0", .id = MDP_TOP,
>>>>  	.base = 0x0, .len = 0x45C,
>>>> -	.features = BIT(DPU_MDP_AUDIO_SELECT),
>>>> +	.features = BIT(DPU_MDP_AUDIO_SELECT) | BIT(DPU_MDP_VSYNC_SEL),
>>>>  	.highest_bank_bit = 0x2,
>>>>  	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
>>>>  			.reg_off = 0x2AC, .bit_off = 0},
>>>> @@ -512,6 +512,31 @@ static const struct dpu_mdp_cfg sm6115_mdp[] = {
>>>>  	},
>>>>  };
>>>>  
>>>> +static const struct dpu_mdp_cfg sdm8150_mdp[] = {
>>>
>>> Sometimes it is only possible to spot such things _after_ sending,
>>> probably the thing that makes us human :)
>>>
>>> sm8150_mdp*, not sdm.
>>>
>>> - Marijn
>>>
>>>> +	{
>>>> +	.name = "top_0", .id = MDP_TOP,
>>>> +	.base = 0x0, .len = 0x45C,
>>>> +	.features = BIT(DPU_MDP_AUDIO_SELECT),
>>>> +	.highest_bank_bit = 0x2,
>>>> +	.clk_ctrls[DPU_CLK_CTRL_VIG0] = {
>>>> +			.reg_off = 0x2AC, .bit_off = 0},
>> Keeping the hex values lowercase would be nice.
> 
> Ack, this was copied verbatim from sdm845_mdp but will cleanup as we go.
> Looks like this file has a mixed approach towards lower and uppercase,
> when does the normalization patch land?
Rob was against changing everything in one commit, as that would mess
with git blame, so we settled on preventing adding new uppercase hex
for now (outside of #defines ofc).

Konrad
> 
> - Marijn

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

* Re: [RFC PATCH 2/7] drm/msm/dpu: Disable pingpong TE on DPU 5.0.0 and above
  2023-01-01  4:28   ` Dmitry Baryshkov
@ 2023-01-02 10:25     ` Marijn Suijten
  2023-01-02 14:02       ` Dmitry Baryshkov
  0 siblings, 1 reply; 33+ messages in thread
From: Marijn Suijten @ 2023-01-02 10:25 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: phone-devel, Abhinav Kumar, Neil Armstrong,
	~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Jessica Zhang, Konrad Dybcio,
	Loic Poulain, Vinod Polimera, Adam Skladowski, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On 2023-01-01 06:28:23, Dmitry Baryshkov wrote:
> On 31/12/2022 23:50, Marijn Suijten wrote:
> > Since hardware revision 5.0.0 the TE configuration moved out of the
> > PINGPONG block into the INTF block.  Writing these registers has no
> > effect, and is omitted downstream via the DPU/SDE_PINGPONG_TE feature
> > flag.  This flag is only added to PINGPONG blocks used by hardware prior
> > to 5.0.0.
> > 
> > The code that writes to these registers in the INTF block will follow in
> > subsequent patches.
> > 
> > Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> > ---
> >   .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  |  5 +-
> >   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 53 +++++++++++--------
> >   .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c   | 18 ++++---
> >   3 files changed, 44 insertions(+), 32 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> > index ae28b2b93e69..7e5ba52197cd 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> > @@ -582,7 +582,7 @@ static bool dpu_encoder_phys_cmd_is_ongoing_pptx(
> >   {
> >   	struct dpu_hw_pp_vsync_info info;
> >   
> > -	if (!phys_enc)
> > +	if (!phys_enc || !phys_enc->hw_pp->ops.get_vsync_info)
> >   		return false;
> >   
> >   	phys_enc->hw_pp->ops.get_vsync_info(phys_enc->hw_pp, &info);
> > @@ -607,6 +607,9 @@ static void dpu_encoder_phys_cmd_prepare_commit(
> 
> This function works only with the hw_pp and if I'm not mistaken it 
> becomes void for newer platforms. Please consider moving completely to 
> the dpu_hw_pp.c Then we'd have a single optional callback instead of 
> having a pile of them.

It also works for hw_intf, which I'm introducing in a later patch.  This
change is just cleaning up the fact that these are the only callbacks
(on hw_pp->ops) that weren't considered optional yet.

Even though removing these writes should not have any effect, perhaps it
is more clear to insert this patch /after/ introducing INTF TE?  Then
that patch will likely already include the change that makes this error
checking consistent for both variants, as it currently has:

	/* If autorefresh is already disabled, we have nothing to do */
	if (phys_enc->has_intf_te) {
		if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_autorefresh ||
				!phys_enc->hw_intf->ops.setup_autorefresh)
			return;
		if (!phys_enc->hw_intf->ops.get_autorefresh(phys_enc->hw_intf, NULL))
			return;
	} else {
		if (!phys_enc->hw_pp || !phys_enc->hw_pp->ops.get_autorefresh ||
				!phys_enc->hw_pp->ops.setup_autorefresh)
			return;
		if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL))
			return;
	}

- Marijn

> >   	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
> >   		return;
> >   
> > +	if (!phys_enc->hw_pp->ops.get_autorefresh || !phys_enc->hw_pp->ops.setup_autorefresh)
> > +		return;
> > +
> >   	/* If autorefresh is already disabled, we have nothing to do */
> >   	if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL))
> >   		return;
> > 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 9814ad52cc04..39d4b293710c 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> > @@ -59,11 +59,18 @@
> >   #define MIXER_SC7180_MASK \
> >   	(BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA))
> >   
> > -#define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER)
> > +#define PINGPONG_SDM845_MASK \
> > +	(BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE))
> >   
> > -#define PINGPONG_SDM845_SPLIT_MASK \
> > +#define PINGPONG_SDM845_TE2_MASK \
> >   	(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
> >   
> > +#define PINGPONG_SM8150_MASK \
> > +	(BIT(DPU_PINGPONG_DITHER))
> > +
> > +#define PINGPONG_SM8150_TE2_MASK \
> > +	(PINGPONG_SM8150_MASK | BIT(DPU_PINGPONG_TE2))
> > +
> >   #define CTL_SC7280_MASK \
> >   	(BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE) | BIT(DPU_CTL_VM_CFG))
> >   
> > @@ -1156,21 +1163,21 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
> >   	.len = 0x20, .version = 0x20000},
> >   };
> >   
> > -#define PP_BLK_TE(_name, _id, _base, _merge_3d, _sblk, _done, _rdptr) \
> > +#define PP_BLK_TE(_name, _id, _base, _features, _merge_3d, _sblk, _done, _rdptr) \
> >   	{\
> >   	.name = _name, .id = _id, \
> >   	.base = _base, .len = 0xd4, \
> > -	.features = PINGPONG_SDM845_SPLIT_MASK, \
> > +	.features = _features, \
> >   	.merge_3d = _merge_3d, \
> >   	.sblk = &_sblk, \
> >   	.intr_done = _done, \
> >   	.intr_rdptr = _rdptr, \
> >   	}
> > -#define PP_BLK(_name, _id, _base, _merge_3d, _sblk, _done, _rdptr) \
> > +#define PP_BLK(_name, _id, _base, _features, _merge_3d, _sblk, _done, _rdptr) \
> >   	{\
> >   	.name = _name, .id = _id, \
> >   	.base = _base, .len = 0xd4, \
> > -	.features = PINGPONG_SDM845_MASK, \
> > +	.features = _features, \
> >   	.merge_3d = _merge_3d, \
> >   	.sblk = &_sblk, \
> >   	.intr_done = _done, \
> > @@ -1178,55 +1185,55 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
> >   	}
> >   
> >   static const struct dpu_pingpong_cfg sdm845_pp[] = {
> > -	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te,
> > +	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te,
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> > -	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te,
> > +	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te,
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)),
> > -	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, 0, sdm845_pp_sblk,
> > +	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SDM845_MASK, 0, sdm845_pp_sblk,
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)),
> > -	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, 0, sdm845_pp_sblk,
> > +	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SDM845_MASK, 0, sdm845_pp_sblk,
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
> >   };
> >   
> >   static struct dpu_pingpong_cfg sc7180_pp[] = {
> > -	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te, -1, -1),
> > -	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te, -1, -1),
> > +	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_TE2_MASK, 0, sdm845_pp_sblk_te, -1, -1),
> > +	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_TE2_MASK, 0, sdm845_pp_sblk_te, -1, -1),
> >   };
> >   
> >   static const struct dpu_pingpong_cfg sm8150_pp[] = {
> > -	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk_te,
> > +	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_TE2_MASK, MERGE_3D_0, sdm845_pp_sblk_te,
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> > -	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk_te,
> > +	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_TE2_MASK, MERGE_3D_0, sdm845_pp_sblk_te,
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)),
> > -	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, MERGE_3D_1, sdm845_pp_sblk,
> > +	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk,
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)),
> > -	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, MERGE_3D_1, sdm845_pp_sblk,
> > +	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk,
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
> > -	PP_BLK("pingpong_4", PINGPONG_4, 0x72000, MERGE_3D_2, sdm845_pp_sblk,
> > +	PP_BLK("pingpong_4", PINGPONG_4, 0x72000, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk,
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
> >   			-1),
> > -	PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk,
> > +	PP_BLK("pingpong_5", PINGPONG_5, 0x72800, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk,
> >   			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> >   			-1),
> >   };
> >   
> >   static const struct dpu_pingpong_cfg sc7280_pp[] = {
> > -	PP_BLK("pingpong_0", PINGPONG_0, 0x59000, 0, sc7280_pp_sblk, -1, -1),
> > -	PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, 0, sc7280_pp_sblk, -1, -1),
> > -	PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, 0, sc7280_pp_sblk, -1, -1),
> > -	PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1),
> > +	PP_BLK("pingpong_0", PINGPONG_0, 0x59000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
> > +	PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
> > +	PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
> > +	PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
> >   };
> >   
> >   static struct dpu_pingpong_cfg qcm2290_pp[] = {
> > -	PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
> > +	PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk,
> >   		DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >   		DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> >   };
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
> > index 0fcad9760b6f..30896c057f87 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
> > @@ -274,14 +274,16 @@ static int dpu_hw_pp_setup_dsc(struct dpu_hw_pingpong *pp)
> >   static void _setup_pingpong_ops(struct dpu_hw_pingpong *c,
> >   				unsigned long features)
> >   {
> > -	c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config;
> > -	c->ops.enable_tearcheck = dpu_hw_pp_enable_te;
> > -	c->ops.connect_external_te = dpu_hw_pp_connect_external_te;
> > -	c->ops.get_vsync_info = dpu_hw_pp_get_vsync_info;
> > -	c->ops.setup_autorefresh = dpu_hw_pp_setup_autorefresh_config;
> > -	c->ops.get_autorefresh = dpu_hw_pp_get_autorefresh_config;
> > -	c->ops.poll_timeout_wr_ptr = dpu_hw_pp_poll_timeout_wr_ptr;
> > -	c->ops.get_line_count = dpu_hw_pp_get_line_count;
> > +	if (test_bit(DPU_PINGPONG_TE, &features)) {
> > +		c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config;
> > +		c->ops.enable_tearcheck = dpu_hw_pp_enable_te;
> > +		c->ops.connect_external_te = dpu_hw_pp_connect_external_te;
> > +		c->ops.get_vsync_info = dpu_hw_pp_get_vsync_info;
> > +		c->ops.setup_autorefresh = dpu_hw_pp_setup_autorefresh_config;
> > +		c->ops.get_autorefresh = dpu_hw_pp_get_autorefresh_config;
> > +		c->ops.poll_timeout_wr_ptr = dpu_hw_pp_poll_timeout_wr_ptr;
> > +		c->ops.get_line_count = dpu_hw_pp_get_line_count;
> > +	}
> >   	c->ops.setup_dsc = dpu_hw_pp_setup_dsc;
> >   	c->ops.enable_dsc = dpu_hw_pp_dsc_enable;
> >   	c->ops.disable_dsc = dpu_hw_pp_dsc_disable;
> 
> -- 
> With best wishes
> Dmitry
> 

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

* Re: [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces
  2023-01-01 13:12   ` Dmitry Baryshkov
@ 2023-01-02 10:38     ` Marijn Suijten
  0 siblings, 0 replies; 33+ messages in thread
From: Marijn Suijten @ 2023-01-02 10:38 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: phone-devel, Abhinav Kumar, Neil Armstrong,
	~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Jessica Zhang, Konrad Dybcio,
	Loic Poulain, Vinod Polimera, Adam Skladowski, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On 2023-01-01 15:12:35, Dmitry Baryshkov wrote:
> On 31/12/2022 23:50, Marijn Suijten wrote:
> > <snip>
> > -#define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _progfetch, _features, _reg, _underrun_bit, _vsync_bit) \
> > +#define INTF_BLK(_name, _id, _base, _len, _type, _ctrl_id, _progfetch, _features, _reg, _underrun_bit, _vsync_bit, _tear_reg, _tear_rd_ptr_bit) \
> >   	{\
> >   	.name = _name, .id = _id, \
> > -	.base = _base, .len = 0x280, \
> > +	.base = _base, .len = _len, \
> 
> Please move .len setting to a separate patch, it is not direclty related 
> to tear interrupt addition.

It is directly related in that the TE registers reside in the extra
space beyond 0x280, but I can surely make that explicit in a separate
patch.

> >   	.features = _features, \
> >   	.type = _type, \
> >   	.controller_id = _ctrl_id, \
> >   	.prog_fetch_lines_worst_case = _progfetch, \
> >   	.intr_underrun = DPU_IRQ_IDX(_reg, _underrun_bit), \
> >   	.intr_vsync = DPU_IRQ_IDX(_reg, _vsync_bit), \
> > +	.intr_tear_rd_ptr = DPU_IRQ_IDX(_tear_reg, _tear_rd_ptr_bit), \
> 
> Initially I added separate _reg and _bit settings because reg was common 
> to both interrupts. However now as tear interrups use different reg it 
> might be better to first move DPU_IRQ_IDX out of this macro () and then 
> to add your tear_rd_ptr_intr as a single intr_idx.

I assumed as much; then we do get the duplication of _reg but I guess
it's not too bad if the lines are nicely wrapped like in _pp[].  I'll do
so in a separate patch.

- Marijn

<snip>

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

* Re: [RFC PATCH 6/7] drm/msm/dpu: Implement tearcheck support on INTF block
  2023-01-01 13:32   ` Dmitry Baryshkov
@ 2023-01-02 11:06     ` Marijn Suijten
  2023-01-02 15:48       ` Dmitry Baryshkov
  0 siblings, 1 reply; 33+ messages in thread
From: Marijn Suijten @ 2023-01-02 11:06 UTC (permalink / raw)
  To: Dmitry Baryshkov
  Cc: phone-devel, Abhinav Kumar, Neil Armstrong,
	~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Jessica Zhang, Konrad Dybcio,
	Loic Poulain, Vinod Polimera, Adam Skladowski, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On 2023-01-01 15:32:11, Dmitry Baryshkov wrote:
> On 31/12/2022 23:50, Marijn Suijten wrote:
> > Since DPU 5.0.0 the TEARCHECK registers and interrupts moved out of the
> > PINGPONG block and into the INTF.  Implement the necessary callbacks in
> > the INTF block, and use these callbacks together with the INTF_TEAR
> > interrupts
> > 
> > Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> 
> Generally I have the same question as for the patch 2. Can we have some 
> higher level functions in the hw_pp and hw_intf files?

That is mostly because patch 2 only cleaned up non-optional handling of
hw_pp callbacks in dpu_encoder_phys_cmd_prepare_commit, which utilizes
hw_intf's autorefresh callbacks since this patch.  I don't think there's
any logic in the encoder currently that is unique to either PP or INTF?

There are quite a few functions that check for NULL hw_pp only, while -
especially after this patch - should also check hw_intf to raise
"invalid encoder".  Should I extend those checks as well?

> Moreover, as I
> review your patch I have the feeling that it would make sense to have to 
> two sets of encoder callbacks, one for the hw_pp tearing handling and 
> another set for hw_intf-based one.

Do you mean to duplicate most phy_cmd functions and switch them based on
has_intf_te in dpu_encoder_phys_cmd_init_ops?  Or introduce an entirely
new set of callbacks that simply hide / abstract away the check on
has_intf_te?  The former would duplicate a bunch of code unless that is
abstracted away into other functions, mainly in
dpu_encoder_phys_cmd_tearcheck_config and
dpu_encoder_phys_cmd_prepare_commit.

Alternatively, could we find a way where these PP and INTF ops share the
same struct and function signature?  That might be tricky for passing in
the hw_pp or hw_intf struct without leaking those details to the
callback and/or have the switching logic in there.

> > ---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  11 +
> >   .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |  10 +-
> >   .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  | 113 +++++++---
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c   | 206 ++++++++++++++++++
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h   |  29 +++
> >   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h   |   2 +
> >   6 files changed, 340 insertions(+), 31 deletions(-)
> > 
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > index 9c6817b5a194..8b9070220ab2 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> > @@ -673,6 +673,7 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
> >   	struct dpu_kms *dpu_kms;
> >   	struct dpu_hw_mdp *hw_mdptop;
> >   	struct drm_encoder *drm_enc;
> > +	struct dpu_encoder_phys *phys_enc;
> >   	int i;
> >   
> >   	if (!dpu_enc || !disp_info) {
> > @@ -703,12 +704,22 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
> >   			vsync_cfg.ppnumber[i] = dpu_enc->hw_pp[i]->idx;
> >   
> >   		vsync_cfg.pp_count = dpu_enc->num_phys_encs;
> > +		vsync_cfg.frame_rate = drm_mode_vrefresh(&dpu_enc->base.crtc->state->adjusted_mode);
> > +
> >   		if (disp_info->is_te_using_watchdog_timer)
> >   			vsync_cfg.vsync_source = DPU_VSYNC_SOURCE_WD_TIMER_0;
> >   		else
> >   			vsync_cfg.vsync_source = DPU_VSYNC0_SOURCE_GPIO;
> >   
> >   		hw_mdptop->ops.setup_vsync_source(hw_mdptop, &vsync_cfg);
> > +
> > +		for (i = 0; i < dpu_enc->num_phys_encs; i++) {
> > +			phys_enc = dpu_enc->phys_encs[i];
> > +
> > +			if (phys_enc->has_intf_te && phys_enc->hw_intf->ops.vsync_sel)
> > +				phys_enc->hw_intf->ops.vsync_sel(phys_enc->hw_intf,
> > +						vsync_cfg.vsync_source);
> > +		}
> >   	}
> >   }
> >   
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> > index f2af07d87f56..47e79401032c 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
> > @@ -148,10 +148,10 @@ struct dpu_encoder_phys_ops {
> >   /**
> >    * enum dpu_intr_idx - dpu encoder interrupt index
> >    * @INTR_IDX_VSYNC:    Vsync interrupt for video mode panel
> > - * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
> > - * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel
> > - * @INTR_IDX_RDPTR:    Readpointer done unterrupt for cmd mode panel
> > - * @INTR_IDX_WB_DONE:  Writeback fone interrupt for virtual connector
> > + * @INTR_IDX_PINGPONG: Pingpong done interrupt for cmd mode panel
> > + * @INTR_IDX_UNDERRUN: Underrun interrupt for video and cmd mode panel
> > + * @INTR_IDX_RDPTR:    Readpointer done interrupt for cmd mode panel
> > + * @INTR_IDX_WB_DONE:  Writeback done interrupt for virtual connector
> >    */
> >   enum dpu_intr_idx {
> >   	INTR_IDX_VSYNC,
> > @@ -195,6 +195,7 @@ enum dpu_intr_idx {
> >    *                              pending.
> >    * @pending_kickoff_wq:		Wait queue for blocking until kickoff completes
> >    * @irq:			IRQ indices
> > + * @has_intf_te:		Interface TE configuration support
> >    */
> >   struct dpu_encoder_phys {
> >   	struct drm_encoder *parent;
> > @@ -220,6 +221,7 @@ struct dpu_encoder_phys {
> >   	atomic_t pending_kickoff_cnt;
> >   	wait_queue_head_t pending_kickoff_wq;
> >   	int irq[INTR_IDX_MAX];
> > +	bool has_intf_te;
> >   };
> >   
> >   static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)
> > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> > index 7e5ba52197cd..ca44a8087f01 100644
> > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
> > @@ -100,12 +100,12 @@ static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
> >   	DPU_ATRACE_END("pp_done_irq");
> >   }
> >   
> > -static void dpu_encoder_phys_cmd_pp_rd_ptr_irq(void *arg, int irq_idx)
> > +static void dpu_encoder_phys_cmd_te_rd_ptr_irq(void *arg, int irq_idx)
> >   {
> >   	struct dpu_encoder_phys *phys_enc = arg;
> >   	struct dpu_encoder_phys_cmd *cmd_enc;
> >   
> > -	if (!phys_enc->hw_pp)
> > +	if (!phys_enc->hw_pp || !phys_enc->hw_intf)
> >   		return;
> >   
> >   	DPU_ATRACE_BEGIN("rd_ptr_irq");
> > @@ -147,11 +147,19 @@ static void dpu_encoder_phys_cmd_atomic_mode_set(
> >   		struct drm_crtc_state *crtc_state,
> >   		struct drm_connector_state *conn_state)
> >   {
> > +	if (phys_enc->has_intf_te && !phys_enc->hw_intf) {
> > +		DPU_ERROR("invalid intf configuration\n");
> > +		return;
> > +	}
> > +
> >   	phys_enc->irq[INTR_IDX_CTL_START] = phys_enc->hw_ctl->caps->intr_start;
> >   
> >   	phys_enc->irq[INTR_IDX_PINGPONG] = phys_enc->hw_pp->caps->intr_done;
> >   
> > -	phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr;
> > +	if (phys_enc->has_intf_te)
> > +		phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_intf->cap->intr_tear_rd_ptr;
> > +	else
> > +		phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr;
> >   
> >   	phys_enc->irq[INTR_IDX_UNDERRUN] = phys_enc->hw_intf->cap->intr_underrun;
> >   }
> > @@ -264,7 +272,7 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(
> >   	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
> >   		ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
> >   				phys_enc->irq[INTR_IDX_RDPTR],
> > -				dpu_encoder_phys_cmd_pp_rd_ptr_irq,
> > +				dpu_encoder_phys_cmd_te_rd_ptr_irq,
> >   				phys_enc);
> >   	else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
> >   		ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,

Fwiw looks like this function is a prime candidate to get updated with
hw_intf information (in error checking and logging), as this callback is
now shared between PP and INTF.

> > @@ -336,10 +344,18 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
> >   
> >   	DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0);
> >   
> > -	if (!phys_enc->hw_pp->ops.setup_tearcheck ||
> > -		!phys_enc->hw_pp->ops.enable_tearcheck) {
> > -		DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
> > -		return;
> > +	if (phys_enc->has_intf_te) {
> > +		if (!phys_enc->hw_intf->ops.setup_tearcheck ||
> > +			!phys_enc->hw_intf->ops.enable_tearcheck) {
> > +			DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
> > +			return;
> > +		}
> > +	} else {
> > +		if (!phys_enc->hw_pp->ops.setup_tearcheck ||
> > +			!phys_enc->hw_pp->ops.enable_tearcheck) {
> > +			DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
> > +			return;
> > +		}
> >   	}
> >   
> >   	dpu_kms = phys_enc->dpu_kms;
> > @@ -392,8 +408,13 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
> >   		phys_enc->hw_pp->idx - PINGPONG_0, tc_cfg.sync_cfg_height,
> >   		tc_cfg.sync_threshold_start, tc_cfg.sync_threshold_continue);
> >   
> > -	phys_enc->hw_pp->ops.setup_tearcheck(phys_enc->hw_pp, &tc_cfg);
> > -	phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, tc_enable);
> 
> A simple random example: setup_tearcheck is always followed with the 
> enable_tearcheck. If we merge them, the code would be simpler.

setup_tearcheck could include this functionality, but note that
dpu_encoder_phys_cmd_disable currently calls enable_tearcheck(false)
without setup_tearcheck.

- Marijn

> > <snip>

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

* Re: [RFC PATCH 2/7] drm/msm/dpu: Disable pingpong TE on DPU 5.0.0 and above
  2023-01-02 10:25     ` Marijn Suijten
@ 2023-01-02 14:02       ` Dmitry Baryshkov
  0 siblings, 0 replies; 33+ messages in thread
From: Dmitry Baryshkov @ 2023-01-02 14:02 UTC (permalink / raw)
  To: Marijn Suijten
  Cc: phone-devel, Abhinav Kumar, Neil Armstrong,
	~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Jessica Zhang, Konrad Dybcio,
	Loic Poulain, Vinod Polimera, Adam Skladowski, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On 02/01/2023 12:25, Marijn Suijten wrote:
> On 2023-01-01 06:28:23, Dmitry Baryshkov wrote:
>> On 31/12/2022 23:50, Marijn Suijten wrote:
>>> Since hardware revision 5.0.0 the TE configuration moved out of the
>>> PINGPONG block into the INTF block.  Writing these registers has no
>>> effect, and is omitted downstream via the DPU/SDE_PINGPONG_TE feature
>>> flag.  This flag is only added to PINGPONG blocks used by hardware prior
>>> to 5.0.0.
>>>
>>> The code that writes to these registers in the INTF block will follow in
>>> subsequent patches.
>>>
>>> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
>>> ---
>>>    .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  |  5 +-
>>>    .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 53 +++++++++++--------
>>>    .../gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c   | 18 ++++---
>>>    3 files changed, 44 insertions(+), 32 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
>>> index ae28b2b93e69..7e5ba52197cd 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
>>> @@ -582,7 +582,7 @@ static bool dpu_encoder_phys_cmd_is_ongoing_pptx(
>>>    {
>>>    	struct dpu_hw_pp_vsync_info info;
>>>    
>>> -	if (!phys_enc)
>>> +	if (!phys_enc || !phys_enc->hw_pp->ops.get_vsync_info)
>>>    		return false;
>>>    
>>>    	phys_enc->hw_pp->ops.get_vsync_info(phys_enc->hw_pp, &info);
>>> @@ -607,6 +607,9 @@ static void dpu_encoder_phys_cmd_prepare_commit(
>>
>> This function works only with the hw_pp and if I'm not mistaken it
>> becomes void for newer platforms. Please consider moving completely to
>> the dpu_hw_pp.c Then we'd have a single optional callback instead of
>> having a pile of them.
> 
> It also works for hw_intf, which I'm introducing in a later patch.  This
> change is just cleaning up the fact that these are the only callbacks
> (on hw_pp->ops) that weren't considered optional yet.
> 
> Even though removing these writes should not have any effect, perhaps it
> is more clear to insert this patch /after/ introducing INTF TE?  Then
> that patch will likely already include the change that makes this error
> checking consistent for both variants, as it currently has:
> 
> 	/* If autorefresh is already disabled, we have nothing to do */
> 	if (phys_enc->has_intf_te) {
> 		if (!phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_autorefresh ||
> 				!phys_enc->hw_intf->ops.setup_autorefresh)
> 			return;
> 		if (!phys_enc->hw_intf->ops.get_autorefresh(phys_enc->hw_intf, NULL))
> 			return;
> 	} else {
> 		if (!phys_enc->hw_pp || !phys_enc->hw_pp->ops.get_autorefresh ||
> 				!phys_enc->hw_pp->ops.setup_autorefresh)
> 			return;
> 		if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL))
> 			return;
> 	}


This is what I'd like to stay away from.
The following code looks better from my point of view:

if (!phys_enc)
     return;
if (!dpu_encoder_phys_cmd_is_master(phys_enc))
     return;

/* I'd use WARN_ON here, but existing code doesn't have these warnings. */
if (phys_enc->has_intf_te) {
     if (!phys_enc->hw_intf)
         return;
     if (!phys_enc->hw_intf->enable_tearing)
         return;

     phys_enc->hw_intf->ops.enable_tearing(phys_enc->hw_intf);
}

if (!phys_enc->hw_pp)
     return;
if (!phys_enc->hw_pp->enable_tearing)
     return;

phys_enc->hw_pp->ops.enable_tearing(phys_enc->hw_pp);


> 
> - Marijn
> 
>>>    	if (!dpu_encoder_phys_cmd_is_master(phys_enc))
>>>    		return;
>>>    
>>> +	if (!phys_enc->hw_pp->ops.get_autorefresh || !phys_enc->hw_pp->ops.setup_autorefresh)
>>> +		return;
>>> +
>>>    	/* If autorefresh is already disabled, we have nothing to do */
>>>    	if (!phys_enc->hw_pp->ops.get_autorefresh(phys_enc->hw_pp, NULL))
>>>    		return;
>>> 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 9814ad52cc04..39d4b293710c 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>> @@ -59,11 +59,18 @@
>>>    #define MIXER_SC7180_MASK \
>>>    	(BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA))
>>>    
>>> -#define PINGPONG_SDM845_MASK BIT(DPU_PINGPONG_DITHER)
>>> +#define PINGPONG_SDM845_MASK \
>>> +	(BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE))
>>>    
>>> -#define PINGPONG_SDM845_SPLIT_MASK \
>>> +#define PINGPONG_SDM845_TE2_MASK \
>>>    	(PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2))
>>>    
>>> +#define PINGPONG_SM8150_MASK \
>>> +	(BIT(DPU_PINGPONG_DITHER))
>>> +
>>> +#define PINGPONG_SM8150_TE2_MASK \
>>> +	(PINGPONG_SM8150_MASK | BIT(DPU_PINGPONG_TE2))
>>> +
>>>    #define CTL_SC7280_MASK \
>>>    	(BIT(DPU_CTL_ACTIVE_CFG) | BIT(DPU_CTL_FETCH_ACTIVE) | BIT(DPU_CTL_VM_CFG))
>>>    
>>> @@ -1156,21 +1163,21 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
>>>    	.len = 0x20, .version = 0x20000},
>>>    };
>>>    
>>> -#define PP_BLK_TE(_name, _id, _base, _merge_3d, _sblk, _done, _rdptr) \
>>> +#define PP_BLK_TE(_name, _id, _base, _features, _merge_3d, _sblk, _done, _rdptr) \
>>>    	{\
>>>    	.name = _name, .id = _id, \
>>>    	.base = _base, .len = 0xd4, \
>>> -	.features = PINGPONG_SDM845_SPLIT_MASK, \
>>> +	.features = _features, \
>>>    	.merge_3d = _merge_3d, \
>>>    	.sblk = &_sblk, \
>>>    	.intr_done = _done, \
>>>    	.intr_rdptr = _rdptr, \
>>>    	}
>>> -#define PP_BLK(_name, _id, _base, _merge_3d, _sblk, _done, _rdptr) \
>>> +#define PP_BLK(_name, _id, _base, _features, _merge_3d, _sblk, _done, _rdptr) \
>>>    	{\
>>>    	.name = _name, .id = _id, \
>>>    	.base = _base, .len = 0xd4, \
>>> -	.features = PINGPONG_SDM845_MASK, \
>>> +	.features = _features, \
>>>    	.merge_3d = _merge_3d, \
>>>    	.sblk = &_sblk, \
>>>    	.intr_done = _done, \
>>> @@ -1178,55 +1185,55 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
>>>    	}
>>>    
>>>    static const struct dpu_pingpong_cfg sdm845_pp[] = {
>>> -	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te,
>>> +	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te,
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>> -	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te,
>>> +	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SDM845_TE2_MASK, 0, sdm845_pp_sblk_te,
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)),
>>> -	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, 0, sdm845_pp_sblk,
>>> +	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SDM845_MASK, 0, sdm845_pp_sblk,
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)),
>>> -	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, 0, sdm845_pp_sblk,
>>> +	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SDM845_MASK, 0, sdm845_pp_sblk,
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>    };
>>>    
>>>    static struct dpu_pingpong_cfg sc7180_pp[] = {
>>> -	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te, -1, -1),
>>> -	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk_te, -1, -1),
>>> +	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_TE2_MASK, 0, sdm845_pp_sblk_te, -1, -1),
>>> +	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_TE2_MASK, 0, sdm845_pp_sblk_te, -1, -1),
>>>    };
>>>    
>>>    static const struct dpu_pingpong_cfg sm8150_pp[] = {
>>> -	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk_te,
>>> +	PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_TE2_MASK, MERGE_3D_0, sdm845_pp_sblk_te,
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>> -	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk_te,
>>> +	PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, PINGPONG_SM8150_TE2_MASK, MERGE_3D_0, sdm845_pp_sblk_te,
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 13)),
>>> -	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, MERGE_3D_1, sdm845_pp_sblk,
>>> +	PP_BLK("pingpong_2", PINGPONG_2, 0x71000, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk,
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 14)),
>>> -	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, MERGE_3D_1, sdm845_pp_sblk,
>>> +	PP_BLK("pingpong_3", PINGPONG_3, 0x71800, PINGPONG_SM8150_MASK, MERGE_3D_1, sdm845_pp_sblk,
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>> -	PP_BLK("pingpong_4", PINGPONG_4, 0x72000, MERGE_3D_2, sdm845_pp_sblk,
>>> +	PP_BLK("pingpong_4", PINGPONG_4, 0x72000, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk,
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>    			-1),
>>> -	PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk,
>>> +	PP_BLK("pingpong_5", PINGPONG_5, 0x72800, PINGPONG_SM8150_MASK, MERGE_3D_2, sdm845_pp_sblk,
>>>    			DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>    			-1),
>>>    };
>>>    
>>>    static const struct dpu_pingpong_cfg sc7280_pp[] = {
>>> -	PP_BLK("pingpong_0", PINGPONG_0, 0x59000, 0, sc7280_pp_sblk, -1, -1),
>>> -	PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, 0, sc7280_pp_sblk, -1, -1),
>>> -	PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, 0, sc7280_pp_sblk, -1, -1),
>>> -	PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1),
>>> +	PP_BLK("pingpong_0", PINGPONG_0, 0x59000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
>>> +	PP_BLK("pingpong_1", PINGPONG_1, 0x6a000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
>>> +	PP_BLK("pingpong_2", PINGPONG_2, 0x6b000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
>>> +	PP_BLK("pingpong_3", PINGPONG_3, 0x6c000, PINGPONG_SM8150_MASK, 0, sc7280_pp_sblk, -1, -1),
>>>    };
>>>    
>>>    static struct dpu_pingpong_cfg qcm2290_pp[] = {
>>> -	PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>> +	PP_BLK("pingpong_0", PINGPONG_0, 0x70000, PINGPONG_SM8150_MASK, 0, sdm845_pp_sblk,
>>>    		DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>    		DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>    };
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>> index 0fcad9760b6f..30896c057f87 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>> @@ -274,14 +274,16 @@ static int dpu_hw_pp_setup_dsc(struct dpu_hw_pingpong *pp)
>>>    static void _setup_pingpong_ops(struct dpu_hw_pingpong *c,
>>>    				unsigned long features)
>>>    {
>>> -	c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config;
>>> -	c->ops.enable_tearcheck = dpu_hw_pp_enable_te;
>>> -	c->ops.connect_external_te = dpu_hw_pp_connect_external_te;
>>> -	c->ops.get_vsync_info = dpu_hw_pp_get_vsync_info;
>>> -	c->ops.setup_autorefresh = dpu_hw_pp_setup_autorefresh_config;
>>> -	c->ops.get_autorefresh = dpu_hw_pp_get_autorefresh_config;
>>> -	c->ops.poll_timeout_wr_ptr = dpu_hw_pp_poll_timeout_wr_ptr;
>>> -	c->ops.get_line_count = dpu_hw_pp_get_line_count;
>>> +	if (test_bit(DPU_PINGPONG_TE, &features)) {
>>> +		c->ops.setup_tearcheck = dpu_hw_pp_setup_te_config;
>>> +		c->ops.enable_tearcheck = dpu_hw_pp_enable_te;
>>> +		c->ops.connect_external_te = dpu_hw_pp_connect_external_te;
>>> +		c->ops.get_vsync_info = dpu_hw_pp_get_vsync_info;
>>> +		c->ops.setup_autorefresh = dpu_hw_pp_setup_autorefresh_config;
>>> +		c->ops.get_autorefresh = dpu_hw_pp_get_autorefresh_config;
>>> +		c->ops.poll_timeout_wr_ptr = dpu_hw_pp_poll_timeout_wr_ptr;
>>> +		c->ops.get_line_count = dpu_hw_pp_get_line_count;
>>> +	}
>>>    	c->ops.setup_dsc = dpu_hw_pp_setup_dsc;
>>>    	c->ops.enable_dsc = dpu_hw_pp_dsc_enable;
>>>    	c->ops.disable_dsc = dpu_hw_pp_dsc_disable;
>>
>> -- 
>> With best wishes
>> Dmitry
>>

-- 
With best wishes
Dmitry


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

* Re: [RFC PATCH 6/7] drm/msm/dpu: Implement tearcheck support on INTF block
  2023-01-02 11:06     ` Marijn Suijten
@ 2023-01-02 15:48       ` Dmitry Baryshkov
  0 siblings, 0 replies; 33+ messages in thread
From: Dmitry Baryshkov @ 2023-01-02 15:48 UTC (permalink / raw)
  To: Marijn Suijten
  Cc: phone-devel, Abhinav Kumar, Neil Armstrong,
	~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Jessica Zhang, Konrad Dybcio,
	Loic Poulain, Vinod Polimera, Adam Skladowski, linux-arm-msm,
	dri-devel, freedreno, linux-kernel

On 02/01/2023 13:06, Marijn Suijten wrote:
> On 2023-01-01 15:32:11, Dmitry Baryshkov wrote:
>> On 31/12/2022 23:50, Marijn Suijten wrote:
>>> Since DPU 5.0.0 the TEARCHECK registers and interrupts moved out of the
>>> PINGPONG block and into the INTF.  Implement the necessary callbacks in
>>> the INTF block, and use these callbacks together with the INTF_TEAR
>>> interrupts
>>>
>>> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
>>
>> Generally I have the same question as for the patch 2. Can we have some
>> higher level functions in the hw_pp and hw_intf files?
> 
> That is mostly because patch 2 only cleaned up non-optional handling of
> hw_pp callbacks in dpu_encoder_phys_cmd_prepare_commit, which utilizes
> hw_intf's autorefresh callbacks since this patch.  I don't think there's
> any logic in the encoder currently that is unique to either PP or INTF?

I think it would be better to duplicate the logic rather than having a 
spaghetti of hw_pp and hw_intf calls.

> There are quite a few functions that check for NULL hw_pp only, while -
> especially after this patch - should also check hw_intf to raise
> "invalid encoder".  Should I extend those checks as well?

I think so. However in most of cases these checks should be void, since 
cmd encoder can not be instantiated without intf.

>> Moreover, as I
>> review your patch I have the feeling that it would make sense to have to
>> two sets of encoder callbacks, one for the hw_pp tearing handling and
>> another set for hw_intf-based one.
> 
> Do you mean to duplicate most phy_cmd functions and switch them based on
> has_intf_te in dpu_encoder_phys_cmd_init_ops?  Or introduce an entirely
> new set of callbacks that simply hide / abstract away the check on
> has_intf_te?  The former would duplicate a bunch of code unless that is
> abstracted away into other functions, mainly in
> dpu_encoder_phys_cmd_tearcheck_config and
> dpu_encoder_phys_cmd_prepare_commit.


For the dpu_encoder_phys_cmd_tearcheck_config() it seems logical to fill 
in the tc_cfg and then to call either the single hw_pp callback or a 
single hw_intf callback.

I'd move most of the code from prepare_commit to dpu_hw_pp and then 
duplicate it to dpu_hw_intf. This seems like the lesser evil.
This function really stands out, since if you inline 
_dpu_encoder_phys_cmd_connect_te() and 
dpu_encoder_phys_cmd_is_ongoing_pptx() it becomes obvious that the whole 
function is a mixture of linked calls to hw_pp ops. And judging from 
your patch it doesn't make sense to check them one by one. Either we 
have all of them, or none.

> 
> Alternatively, could we find a way where these PP and INTF ops share the
> same struct and function signature?  That might be tricky for passing in
> the hw_pp or hw_intf struct without leaking those details to the
> callback and/or have the switching logic in there.
> 
>>> ---
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c   |  11 +
>>>    .../gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h  |  10 +-
>>>    .../drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c  | 113 +++++++---
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.c   | 206 ++++++++++++++++++
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_hw_intf.h   |  29 +++
>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h   |   2 +
>>>    6 files changed, 340 insertions(+), 31 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>> index 9c6817b5a194..8b9070220ab2 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>> @@ -673,6 +673,7 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
>>>    	struct dpu_kms *dpu_kms;
>>>    	struct dpu_hw_mdp *hw_mdptop;
>>>    	struct drm_encoder *drm_enc;
>>> +	struct dpu_encoder_phys *phys_enc;
>>>    	int i;
>>>    
>>>    	if (!dpu_enc || !disp_info) {
>>> @@ -703,12 +704,22 @@ static void _dpu_encoder_update_vsync_source(struct dpu_encoder_virt *dpu_enc,
>>>    			vsync_cfg.ppnumber[i] = dpu_enc->hw_pp[i]->idx;
>>>    
>>>    		vsync_cfg.pp_count = dpu_enc->num_phys_encs;
>>> +		vsync_cfg.frame_rate = drm_mode_vrefresh(&dpu_enc->base.crtc->state->adjusted_mode);
>>> +
>>>    		if (disp_info->is_te_using_watchdog_timer)
>>>    			vsync_cfg.vsync_source = DPU_VSYNC_SOURCE_WD_TIMER_0;
>>>    		else
>>>    			vsync_cfg.vsync_source = DPU_VSYNC0_SOURCE_GPIO;
>>>    
>>>    		hw_mdptop->ops.setup_vsync_source(hw_mdptop, &vsync_cfg);
>>> +
>>> +		for (i = 0; i < dpu_enc->num_phys_encs; i++) {
>>> +			phys_enc = dpu_enc->phys_encs[i];
>>> +
>>> +			if (phys_enc->has_intf_te && phys_enc->hw_intf->ops.vsync_sel)
>>> +				phys_enc->hw_intf->ops.vsync_sel(phys_enc->hw_intf,
>>> +						vsync_cfg.vsync_source);
>>> +		}
>>>    	}
>>>    }
>>>    
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>> index f2af07d87f56..47e79401032c 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h
>>> @@ -148,10 +148,10 @@ struct dpu_encoder_phys_ops {
>>>    /**
>>>     * enum dpu_intr_idx - dpu encoder interrupt index
>>>     * @INTR_IDX_VSYNC:    Vsync interrupt for video mode panel
>>> - * @INTR_IDX_PINGPONG: Pingpong done unterrupt for cmd mode panel
>>> - * @INTR_IDX_UNDERRUN: Underrun unterrupt for video and cmd mode panel
>>> - * @INTR_IDX_RDPTR:    Readpointer done unterrupt for cmd mode panel
>>> - * @INTR_IDX_WB_DONE:  Writeback fone interrupt for virtual connector
>>> + * @INTR_IDX_PINGPONG: Pingpong done interrupt for cmd mode panel
>>> + * @INTR_IDX_UNDERRUN: Underrun interrupt for video and cmd mode panel
>>> + * @INTR_IDX_RDPTR:    Readpointer done interrupt for cmd mode panel
>>> + * @INTR_IDX_WB_DONE:  Writeback done interrupt for virtual connector
>>>     */
>>>    enum dpu_intr_idx {
>>>    	INTR_IDX_VSYNC,
>>> @@ -195,6 +195,7 @@ enum dpu_intr_idx {
>>>     *                              pending.
>>>     * @pending_kickoff_wq:		Wait queue for blocking until kickoff completes
>>>     * @irq:			IRQ indices
>>> + * @has_intf_te:		Interface TE configuration support
>>>     */
>>>    struct dpu_encoder_phys {
>>>    	struct drm_encoder *parent;
>>> @@ -220,6 +221,7 @@ struct dpu_encoder_phys {
>>>    	atomic_t pending_kickoff_cnt;
>>>    	wait_queue_head_t pending_kickoff_wq;
>>>    	int irq[INTR_IDX_MAX];
>>> +	bool has_intf_te;
>>>    };
>>>    
>>>    static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
>>> index 7e5ba52197cd..ca44a8087f01 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_cmd.c
>>> @@ -100,12 +100,12 @@ static void dpu_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
>>>    	DPU_ATRACE_END("pp_done_irq");
>>>    }
>>>    
>>> -static void dpu_encoder_phys_cmd_pp_rd_ptr_irq(void *arg, int irq_idx)
>>> +static void dpu_encoder_phys_cmd_te_rd_ptr_irq(void *arg, int irq_idx)
>>>    {
>>>    	struct dpu_encoder_phys *phys_enc = arg;
>>>    	struct dpu_encoder_phys_cmd *cmd_enc;
>>>    
>>> -	if (!phys_enc->hw_pp)
>>> +	if (!phys_enc->hw_pp || !phys_enc->hw_intf)
>>>    		return;
>>>    
>>>    	DPU_ATRACE_BEGIN("rd_ptr_irq");
>>> @@ -147,11 +147,19 @@ static void dpu_encoder_phys_cmd_atomic_mode_set(
>>>    		struct drm_crtc_state *crtc_state,
>>>    		struct drm_connector_state *conn_state)
>>>    {
>>> +	if (phys_enc->has_intf_te && !phys_enc->hw_intf) {
>>> +		DPU_ERROR("invalid intf configuration\n");
>>> +		return;
>>> +	}
>>> +
>>>    	phys_enc->irq[INTR_IDX_CTL_START] = phys_enc->hw_ctl->caps->intr_start;
>>>    
>>>    	phys_enc->irq[INTR_IDX_PINGPONG] = phys_enc->hw_pp->caps->intr_done;
>>>    
>>> -	phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr;
>>> +	if (phys_enc->has_intf_te)
>>> +		phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_intf->cap->intr_tear_rd_ptr;
>>> +	else
>>> +		phys_enc->irq[INTR_IDX_RDPTR] = phys_enc->hw_pp->caps->intr_rdptr;
>>>    
>>>    	phys_enc->irq[INTR_IDX_UNDERRUN] = phys_enc->hw_intf->cap->intr_underrun;
>>>    }
>>> @@ -264,7 +272,7 @@ static int dpu_encoder_phys_cmd_control_vblank_irq(
>>>    	if (enable && atomic_inc_return(&phys_enc->vblank_refcount) == 1)
>>>    		ret = dpu_core_irq_register_callback(phys_enc->dpu_kms,
>>>    				phys_enc->irq[INTR_IDX_RDPTR],
>>> -				dpu_encoder_phys_cmd_pp_rd_ptr_irq,
>>> +				dpu_encoder_phys_cmd_te_rd_ptr_irq,
>>>    				phys_enc);
>>>    	else if (!enable && atomic_dec_return(&phys_enc->vblank_refcount) == 0)
>>>    		ret = dpu_core_irq_unregister_callback(phys_enc->dpu_kms,
> 
> Fwiw looks like this function is a prime candidate to get updated with
> hw_intf information (in error checking and logging), as this callback is
> now shared between PP and INTF.
> 
>>> @@ -336,10 +344,18 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
>>>    
>>>    	DPU_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0);
>>>    
>>> -	if (!phys_enc->hw_pp->ops.setup_tearcheck ||
>>> -		!phys_enc->hw_pp->ops.enable_tearcheck) {
>>> -		DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
>>> -		return;
>>> +	if (phys_enc->has_intf_te) {
>>> +		if (!phys_enc->hw_intf->ops.setup_tearcheck ||
>>> +			!phys_enc->hw_intf->ops.enable_tearcheck) {
>>> +			DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
>>> +			return;
>>> +		}
>>> +	} else {
>>> +		if (!phys_enc->hw_pp->ops.setup_tearcheck ||
>>> +			!phys_enc->hw_pp->ops.enable_tearcheck) {
>>> +			DPU_DEBUG_CMDENC(cmd_enc, "tearcheck not supported\n");
>>> +			return;
>>> +		}
>>>    	}
>>>    
>>>    	dpu_kms = phys_enc->dpu_kms;
>>> @@ -392,8 +408,13 @@ static void dpu_encoder_phys_cmd_tearcheck_config(
>>>    		phys_enc->hw_pp->idx - PINGPONG_0, tc_cfg.sync_cfg_height,
>>>    		tc_cfg.sync_threshold_start, tc_cfg.sync_threshold_continue);
>>>    
>>> -	phys_enc->hw_pp->ops.setup_tearcheck(phys_enc->hw_pp, &tc_cfg);
>>> -	phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp, tc_enable);
>>
>> A simple random example: setup_tearcheck is always followed with the
>> enable_tearcheck. If we merge them, the code would be simpler.
> 
> setup_tearcheck could include this functionality, but note that
> dpu_encoder_phys_cmd_disable currently calls enable_tearcheck(false)
> without setup_tearcheck.

Yes, so enable_tearcheck() and disable_tearcheck() sound more useful.

> 
> - Marijn
> 
>>> <snip>

-- 
With best wishes
Dmitry


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

* Re: [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces
  2022-12-31 21:50 ` [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces Marijn Suijten
  2023-01-01 13:12   ` Dmitry Baryshkov
@ 2023-02-13 19:37   ` Jessica Zhang
  2023-02-13 21:46     ` Dmitry Baryshkov
  1 sibling, 1 reply; 33+ messages in thread
From: Jessica Zhang @ 2023-02-13 19:37 UTC (permalink / raw)
  To: Marijn Suijten, phone-devel, Abhinav Kumar, Dmitry Baryshkov,
	Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Konrad Dybcio, Loic Poulain,
	Vinod Polimera, Adam Skladowski, linux-arm-msm, dri-devel,
	freedreno, linux-kernel



On 12/31/2022 1:50 PM, Marijn Suijten wrote:
> All SoCs since DPU 5.0.0 (and seemingly up until and including 6.0.0,
> but excluding 7.x.x) have the tear interrupt and control registers moved
> out of the PINGPONG block and into the INTF block.  Wire up the
> necessary interrupts and IRQ masks on all supported hardware.

Hi Marijn,

Thanks for the patch.

I saw that in your commit msg, you mentioned that 7.x doesn't have 
tearcheck in the INTF block -- can you double check that this is correct?

I'm working on SM8350 (DPU v7) and I'm seeing that it does have 
tearcheck in INTF block.

> 
> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> ---
>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 78 +++++++++++--------
>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  6 +-
>   .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 12 +++
>   .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  2 +
>   drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h      |  3 +
>   5 files changed, 68 insertions(+), 33 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 1cfe94494135..b9b9b5b0b615 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -86,6 +86,15 @@
>   
>   #define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)
>   
> +#define IRQ_MSM8998_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
> +			 BIT(MDP_SSPP_TOP0_INTR2) | \
> +			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> +			 BIT(MDP_INTF0_INTR) | \
> +			 BIT(MDP_INTF1_INTR) | \
> +			 BIT(MDP_INTF2_INTR) | \
> +			 BIT(MDP_INTF3_INTR) | \
> +			 BIT(MDP_INTF4_INTR))
> +
>   #define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>   			 BIT(MDP_SSPP_TOP0_INTR2) | \
>   			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> @@ -100,13 +109,15 @@
>   #define IRQ_QCM2290_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>   			 BIT(MDP_SSPP_TOP0_INTR2) | \
>   			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> -			 BIT(MDP_INTF1_INTR))
> +			 BIT(MDP_INTF1_INTR) | \
> +			 BIT(MDP_INTF1_TEAR_INTR))
>   
>   #define IRQ_SC7180_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>   			 BIT(MDP_SSPP_TOP0_INTR2) | \
>   			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>   			 BIT(MDP_INTF0_INTR) | \
> -			 BIT(MDP_INTF1_INTR))
> +			 BIT(MDP_INTF1_INTR) | \
> +			 BIT(MDP_INTF1_TEAR_INTR))
>   
>   #define IRQ_SC7280_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>   			 BIT(MDP_SSPP_TOP0_INTR2) | \
> @@ -120,7 +131,9 @@
>   			 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>   			 BIT(MDP_INTF0_INTR) | \
>   			 BIT(MDP_INTF1_INTR) | \
> +			 BIT(MDP_INTF1_TEAR_INTR) | \
>   			 BIT(MDP_INTF2_INTR) | \
> +			 BIT(MDP_INTF2_TEAR_INTR) | \
>   			 BIT(MDP_INTF3_INTR) | \
>   			 BIT(MDP_INTF4_INTR))
>   
> @@ -129,7 +142,9 @@
>   			  BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>   			  BIT(MDP_INTF0_INTR) | \
>   			  BIT(MDP_INTF1_INTR) | \
> +			  BIT(MDP_INTF1_TEAR_INTR) | \
>   			  BIT(MDP_INTF2_INTR) | \
> +			  BIT(MDP_INTF2_TEAR_INTR) | \
>   			  BIT(MDP_INTF3_INTR) | \
>   			  BIT(MDP_INTF4_INTR) | \
>   			  BIT(MDP_INTF5_INTR) | \
> @@ -1300,63 +1315,64 @@ static struct dpu_dsc_cfg sdm845_dsc[] = {
>   /*************************************************************
>    * INTF sub blocks config
>    *************************************************************/
> -#define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _progfetch, _features, _reg, _underrun_bit, _vsync_bit) \
> +#define INTF_BLK(_name, _id, _base, _len, _type, _ctrl_id, _progfetch, _features, _reg, _underrun_bit, _vsync_bit, _tear_reg, _tear_rd_ptr_bit) \
>   	{\
>   	.name = _name, .id = _id, \
> -	.base = _base, .len = 0x280, \
> +	.base = _base, .len = _len, \
>   	.features = _features, \
>   	.type = _type, \
>   	.controller_id = _ctrl_id, \
>   	.prog_fetch_lines_worst_case = _progfetch, \
>   	.intr_underrun = DPU_IRQ_IDX(_reg, _underrun_bit), \
>   	.intr_vsync = DPU_IRQ_IDX(_reg, _vsync_bit), \
> +	.intr_tear_rd_ptr = DPU_IRQ_IDX(_tear_reg, _tear_rd_ptr_bit), \
>   	}
>   
>   static const struct dpu_intf_cfg msm8998_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> -	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> -	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
> -	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_HDMI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> +	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x268, INTF_DP, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),

Just wondering, how were the lengths calculated for the INTF blocks? The 
values in general seem a little off to me.

For example, I'm looking downstream and it seems to me that the length 
for the INTF_0 on MSM8998 should be 0x280. Similarly for SC7280, I'm 
seeing that length for INTF + tearcheck should be 0x2c4.

Thanks,

Jessica Zhang

> +	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x268, INTF_DSI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27, -1, -1),
> +	INTF_BLK("intf_2", INTF_2, 0x6B000, 0x268, INTF_DSI, 1, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29, -1, -1),
> +	INTF_BLK("intf_3", INTF_3, 0x6B800, 0x268, INTF_HDMI, 0, 25, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31, -1, -1),
>   };
>   
>   static const struct dpu_intf_cfg sdm845_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> -	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> -	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
> -	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> +	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x280, INTF_DSI, 0, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27, -1, -1),
> +	INTF_BLK("intf_2", INTF_2, 0x6B000, 0x280, INTF_DSI, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29, -1, -1),
> +	INTF_BLK("intf_3", INTF_3, 0x6B800, 0x280, INTF_DP, 1, 24, INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31, -1, -1),
>   };
>   
>   static const struct dpu_intf_cfg sc7180_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> -	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> +	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2b8, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF1_TEAR_INTR, 2),
>   };
>   
>   static const struct dpu_intf_cfg sm8150_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> -	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> -	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
> -	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> +	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2b8, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF1_TEAR_INTR, 2),
> +	INTF_BLK("intf_2", INTF_2, 0x6B000, 0x2b8, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29, MDP_INTF2_TEAR_INTR, 2),
> +	INTF_BLK("intf_3", INTF_3, 0x6B800, 0x280, INTF_DP, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31, -1, -1),
>   };
>   
>   static const struct dpu_intf_cfg sc7280_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x34000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> -	INTF_BLK("intf_1", INTF_1, 0x35000, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> -	INTF_BLK("intf_5", INTF_5, 0x39000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
> +	INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x35000, 0x2b8, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF1_TEAR_INTR, 2),
> +	INTF_BLK("intf_5", INTF_5, 0x39000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 22, 23, -1, -1),
>   };
>   
>   static const struct dpu_intf_cfg sc8180x_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> -	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> -	INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
> +	INTF_BLK("intf_0", INTF_0, 0x6A000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2b8, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF1_TEAR_INTR, 2),
> +	INTF_BLK("intf_2", INTF_2, 0x6B000, 0x2b8, INTF_DSI, 1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 28, 29, MDP_INTF2_TEAR_INTR, 2),
>   	/* INTF_3 is for MST, wired to INTF_DP 0 and 1, use dummy index until this is supported */
> -	INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_DP, 999, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> -	INTF_BLK("intf_4", INTF_4, 0x6C000, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 20, 21),
> -	INTF_BLK("intf_5", INTF_5, 0x6C800, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 22, 23),
> +	INTF_BLK("intf_3", INTF_3, 0x6B800, 0x280, INTF_DP, 999, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 30, 31, -1, -1),
> +	INTF_BLK("intf_4", INTF_4, 0x6C000, 0x280, INTF_DP, MSM_DP_CONTROLLER_1, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 20, 21, -1, -1),
> +	INTF_BLK("intf_5", INTF_5, 0x6C800, 0x280, INTF_DP, MSM_DP_CONTROLLER_2, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 22, 23, -1, -1),
>   };
>   
>   static const struct dpu_intf_cfg qcm2290_intf[] = {
> -	INTF_BLK("intf_0", INTF_0, 0x00000, INTF_NONE, 0, 0, 0, 0, 0, 0),
> -	INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> +	INTF_BLK("intf_0", INTF_0, 0x00000, 0x2b8, INTF_NONE, 0, 0, 0, 0, 0, 0, -1, -1),
> +	INTF_BLK("intf_1", INTF_1, 0x6A800, 0x2b8, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27, MDP_INTF2_TEAR_INTR, 2),
>   };
>   
>   /*************************************************************
> @@ -1849,7 +1865,7 @@ static const struct dpu_mdss_cfg msm8998_dpu_cfg = {
>   	.vbif = msm8998_vbif,
>   	.reg_dma_count = 0,
>   	.perf = &msm8998_perf_data,
> -	.mdss_irqs = IRQ_SM8250_MASK,
> +	.mdss_irqs = IRQ_MSM8998_MASK,
>   };
>   
>   static const struct dpu_mdss_cfg sdm845_dpu_cfg = {
> @@ -1947,7 +1963,7 @@ static const struct dpu_mdss_cfg sm8150_dpu_cfg = {
>   	.reg_dma_count = 1,
>   	.dma_cfg = &sm8150_regdma,
>   	.perf = &sm8150_perf_data,
> -	.mdss_irqs = IRQ_SDM845_MASK,
> +	.mdss_irqs = IRQ_SM8250_MASK,
>   };
>   
>   static const struct dpu_mdss_cfg sc8180x_dpu_cfg = {
> 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 e0e153889ab7..2ea17e4ef3e5 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -638,8 +638,9 @@ struct dpu_dsc_cfg {
>    * @type:              Interface type(DSI, DP, HDMI)
>    * @controller_id:     Controller Instance ID in case of multiple of intf type
>    * @prog_fetch_lines_worst_case	Worst case latency num lines needed to prefetch
> - * @intr_underrun:	index for INTF underrun interrupt
> - * @intr_vsync:	        index for INTF VSYNC interrupt
> + * @intr_underrun:     index for INTF underrun interrupt
> + * @intr_vsync:        index for INTF VSYNC interrupt
> + * @intr_tear_rd_ptr:  index for INTF TEAR_RD_PTR interrupt
>    */
>   struct dpu_intf_cfg  {
>   	DPU_HW_BLK_INFO;
> @@ -648,6 +649,7 @@ struct dpu_intf_cfg  {
>   	u32 prog_fetch_lines_worst_case;
>   	s32 intr_underrun;
>   	s32 intr_vsync;
> +	s32 intr_tear_rd_ptr;
>   };
>   
>   /**
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> index cf1b6d84c18a..044136a97fac 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c
> @@ -24,6 +24,8 @@
>   #define MDP_INTF_3_OFF			0x6B800
>   #define MDP_INTF_4_OFF			0x6C000
>   #define MDP_INTF_5_OFF			0x6C800
> +#define MDP_INTF_1_TEAR_OFF		0x6D800
> +#define MDP_INTF_2_TEAR_OFF		0x6D900
>   #define MDP_AD4_0_OFF			0x7C000
>   #define MDP_AD4_1_OFF			0x7D000
>   #define MDP_AD4_INTR_EN_OFF		0x41c
> @@ -99,6 +101,16 @@ static const struct dpu_intr_reg dpu_intr_set[] = {
>   		MDP_INTF_5_OFF+INTF_INTR_EN,
>   		MDP_INTF_5_OFF+INTF_INTR_STATUS
>   	},
> +	[MDP_INTF1_TEAR_INTR] = {
> +		MDP_INTF_1_TEAR_OFF+INTF_INTR_TEAR_CLEAR,
> +		MDP_INTF_1_TEAR_OFF+INTF_INTR_TEAR_EN,
> +		MDP_INTF_1_TEAR_OFF+INTF_INTR_TEAR_STATUS
> +	},
> +	[MDP_INTF2_TEAR_INTR] = {
> +		MDP_INTF_2_TEAR_OFF+INTF_INTR_TEAR_CLEAR,
> +		MDP_INTF_2_TEAR_OFF+INTF_INTR_TEAR_EN,
> +		MDP_INTF_2_TEAR_OFF+INTF_INTR_TEAR_STATUS
> +	},
>   	[MDP_AD4_0_INTR] = {
>   		MDP_AD4_0_OFF + MDP_AD4_INTR_CLEAR_OFF,
>   		MDP_AD4_0_OFF + MDP_AD4_INTR_EN_OFF,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
> index 46443955443c..b447e4a1d9f4 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h
> @@ -23,6 +23,8 @@ enum dpu_hw_intr_reg {
>   	MDP_INTF3_INTR,
>   	MDP_INTF4_INTR,
>   	MDP_INTF5_INTR,
> +	MDP_INTF1_TEAR_INTR,
> +	MDP_INTF2_TEAR_INTR,
>   	MDP_AD4_0_INTR,
>   	MDP_AD4_1_INTR,
>   	MDP_INTF0_7xxx_INTR,
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h
> index c8156ed4b7fb..6bdac515fd54 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h
> @@ -10,6 +10,9 @@
>   /**
>    * MDP TOP block Register and bit fields and defines
>    */
> +#define INTF_INTR_TEAR_EN               0x000
> +#define INTF_INTR_TEAR_STATUS           0x004
> +#define INTF_INTR_TEAR_CLEAR            0x008
>   #define DISP_INTF_SEL                   0x004
>   #define INTR_EN                         0x010
>   #define INTR_STATUS                     0x014
> -- 
> 2.39.0
> 

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

* Re: [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces
  2023-02-13 19:37   ` Jessica Zhang
@ 2023-02-13 21:46     ` Dmitry Baryshkov
  2023-02-14  3:09       ` Abhinav Kumar
  0 siblings, 1 reply; 33+ messages in thread
From: Dmitry Baryshkov @ 2023-02-13 21:46 UTC (permalink / raw)
  To: Jessica Zhang, Marijn Suijten, phone-devel, Abhinav Kumar,
	Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Konrad Dybcio, Loic Poulain,
	Vinod Polimera, Adam Skladowski, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

On 13/02/2023 21:37, Jessica Zhang wrote:
> 
> 
> On 12/31/2022 1:50 PM, Marijn Suijten wrote:
>> All SoCs since DPU 5.0.0 (and seemingly up until and including 6.0.0,
>> but excluding 7.x.x) have the tear interrupt and control registers moved
>> out of the PINGPONG block and into the INTF block.  Wire up the
>> necessary interrupts and IRQ masks on all supported hardware.
> 
> Hi Marijn,
> 
> Thanks for the patch.
> 
> I saw that in your commit msg, you mentioned that 7.x doesn't have 
> tearcheck in the INTF block -- can you double check that this is correct?
> 
> I'm working on SM8350 (DPU v7) and I'm seeing that it does have 
> tearcheck in INTF block.

I confirm, according to the vendor drivers INTF TE should be used for 
all DPU >= 5.0, including 7.x and 8.x

However I think I know what Marijn meant here. For 5.x and 6.x these 
IRQs are handled at the address MDSS + 0x6e800 / + 0x6e900 (which means 
offset here should 0x6d800 and 0x6d900) for INTF_1 and INTF_2. Since DPU 
7.x these IRQ registers were moved close to the main INTF block (0x36800 
and 0x37800 = INTF + 0x800).

> 
>>
>> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
>> ---
>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 78 +++++++++++--------
>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  6 +-
>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 12 +++
>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  2 +
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h      |  3 +
>>   5 files changed, 68 insertions(+), 33 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 1cfe94494135..b9b9b5b0b615 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>> @@ -86,6 +86,15 @@
>>   #define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)
>> +#define IRQ_MSM8998_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>> +             BIT(MDP_SSPP_TOP0_INTR2) | \
>> +             BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>> +             BIT(MDP_INTF0_INTR) | \
>> +             BIT(MDP_INTF1_INTR) | \
>> +             BIT(MDP_INTF2_INTR) | \
>> +             BIT(MDP_INTF3_INTR) | \
>> +             BIT(MDP_INTF4_INTR))
>> +
>>   #define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>                BIT(MDP_SSPP_TOP0_INTR2) | \
>>                BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>> @@ -100,13 +109,15 @@
>>   #define IRQ_QCM2290_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>                BIT(MDP_SSPP_TOP0_INTR2) | \
>>                BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>> -             BIT(MDP_INTF1_INTR))
>> +             BIT(MDP_INTF1_INTR) | \
>> +             BIT(MDP_INTF1_TEAR_INTR))
>>   #define IRQ_SC7180_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>                BIT(MDP_SSPP_TOP0_INTR2) | \
>>                BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>                BIT(MDP_INTF0_INTR) | \
>> -             BIT(MDP_INTF1_INTR))
>> +             BIT(MDP_INTF1_INTR) | \
>> +             BIT(MDP_INTF1_TEAR_INTR))
>>   #define IRQ_SC7280_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>                BIT(MDP_SSPP_TOP0_INTR2) | \
>> @@ -120,7 +131,9 @@
>>                BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>                BIT(MDP_INTF0_INTR) | \
>>                BIT(MDP_INTF1_INTR) | \
>> +             BIT(MDP_INTF1_TEAR_INTR) | \
>>                BIT(MDP_INTF2_INTR) | \
>> +             BIT(MDP_INTF2_TEAR_INTR) | \
>>                BIT(MDP_INTF3_INTR) | \
>>                BIT(MDP_INTF4_INTR))
>> @@ -129,7 +142,9 @@
>>                 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>                 BIT(MDP_INTF0_INTR) | \
>>                 BIT(MDP_INTF1_INTR) | \
>> +              BIT(MDP_INTF1_TEAR_INTR) | \
>>                 BIT(MDP_INTF2_INTR) | \
>> +              BIT(MDP_INTF2_TEAR_INTR) | \
>>                 BIT(MDP_INTF3_INTR) | \
>>                 BIT(MDP_INTF4_INTR) | \
>>                 BIT(MDP_INTF5_INTR) | \
>> @@ -1300,63 +1315,64 @@ static struct dpu_dsc_cfg sdm845_dsc[] = {
>>   /*************************************************************
>>    * INTF sub blocks config
>>    *************************************************************/
>> -#define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _progfetch, 
>> _features, _reg, _underrun_bit, _vsync_bit) \
>> +#define INTF_BLK(_name, _id, _base, _len, _type, _ctrl_id, 
>> _progfetch, _features, _reg, _underrun_bit, _vsync_bit, _tear_reg, 
>> _tear_rd_ptr_bit) \
>>       {\
>>       .name = _name, .id = _id, \
>> -    .base = _base, .len = 0x280, \
>> +    .base = _base, .len = _len, \
>>       .features = _features, \
>>       .type = _type, \
>>       .controller_id = _ctrl_id, \
>>       .prog_fetch_lines_worst_case = _progfetch, \
>>       .intr_underrun = DPU_IRQ_IDX(_reg, _underrun_bit), \
>>       .intr_vsync = DPU_IRQ_IDX(_reg, _vsync_bit), \
>> +    .intr_tear_rd_ptr = DPU_IRQ_IDX(_tear_reg, _tear_rd_ptr_bit), \
>>       }
>>   static const struct dpu_intf_cfg msm8998_intf[] = {
>> -    INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 25, 
>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
>> -    INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 25, 
>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
>> -    INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 25, 
>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
>> -    INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_HDMI, 0, 25, 
>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
>> +    INTF_BLK("intf_0", INTF_0, 0x6A000, 0x268, INTF_DP, 0, 25, 
>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> 
> Just wondering, how were the lengths calculated for the INTF blocks? The 
> values in general seem a little off to me.
> 
> For example, I'm looking downstream and it seems to me that the length 
> for the INTF_0 on MSM8998 should be 0x280. Similarly for SC7280, I'm 
> seeing that length for INTF + tearcheck should be 0x2c4.

We have discussed INTF lengths in [1]. The current understanding of the 
block lengths can be found at [2]. Please comment there if any of the 
fixed lengths sounds incorrect to you.

[1] https://patchwork.freedesktop.org/patch/522187/
[2] https://patchwork.freedesktop.org/patch/522227/

[skipped the rest]

-- 
With best wishes
Dmitry


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

* Re: [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces
  2023-02-13 21:46     ` Dmitry Baryshkov
@ 2023-02-14  3:09       ` Abhinav Kumar
  2023-02-14 13:06         ` Marijn Suijten
  0 siblings, 1 reply; 33+ messages in thread
From: Abhinav Kumar @ 2023-02-14  3:09 UTC (permalink / raw)
  To: Dmitry Baryshkov, Jessica Zhang, Marijn Suijten, phone-devel,
	Neil Armstrong
  Cc: ~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Konrad Dybcio, Loic Poulain,
	Vinod Polimera, Adam Skladowski, linux-arm-msm, dri-devel,
	freedreno, linux-kernel



On 2/13/2023 1:46 PM, Dmitry Baryshkov wrote:
> On 13/02/2023 21:37, Jessica Zhang wrote:
>>
>>
>> On 12/31/2022 1:50 PM, Marijn Suijten wrote:
>>> All SoCs since DPU 5.0.0 (and seemingly up until and including 6.0.0,
>>> but excluding 7.x.x) have the tear interrupt and control registers moved
>>> out of the PINGPONG block and into the INTF block.  Wire up the
>>> necessary interrupts and IRQ masks on all supported hardware.
>>
>> Hi Marijn,
>>
>> Thanks for the patch.
>>
>> I saw that in your commit msg, you mentioned that 7.x doesn't have 
>> tearcheck in the INTF block -- can you double check that this is correct?
>>
>> I'm working on SM8350 (DPU v7) and I'm seeing that it does have 
>> tearcheck in INTF block.
> 
> I confirm, according to the vendor drivers INTF TE should be used for 
> all DPU >= 5.0, including 7.x and 8.x
> 
> However I think I know what Marijn meant here. For 5.x and 6.x these 
> IRQs are handled at the address MDSS + 0x6e800 / + 0x6e900 (which means 
> offset here should 0x6d800 and 0x6d900) for INTF_1 and INTF_2. Since DPU 
> 7.x these IRQ registers were moved close to the main INTF block (0x36800 
> and 0x37800 = INTF + 0x800).
> 

Got it, then the commit text should remove "control" and just say tear 
interrupt registers. It got a bit confusing.

We will add the 7xxx intf tear check support on top of this series.

>>
>>>
>>> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
>>> ---
>>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 78 +++++++++++--------
>>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  6 +-
>>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 12 +++
>>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  2 +
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h      |  3 +
>>>   5 files changed, 68 insertions(+), 33 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 1cfe94494135..b9b9b5b0b615 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>> @@ -86,6 +86,15 @@
>>>   #define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)
>>> +#define IRQ_MSM8998_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>> +             BIT(MDP_SSPP_TOP0_INTR2) | \
>>> +             BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>> +             BIT(MDP_INTF0_INTR) | \
>>> +             BIT(MDP_INTF1_INTR) | \
>>> +             BIT(MDP_INTF2_INTR) | \
>>> +             BIT(MDP_INTF3_INTR) | \
>>> +             BIT(MDP_INTF4_INTR))
>>> +
>>>   #define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>>                BIT(MDP_SSPP_TOP0_INTR2) | \
>>>                BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>> @@ -100,13 +109,15 @@
>>>   #define IRQ_QCM2290_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>>                BIT(MDP_SSPP_TOP0_INTR2) | \
>>>                BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>> -             BIT(MDP_INTF1_INTR))
>>> +             BIT(MDP_INTF1_INTR) | \
>>> +             BIT(MDP_INTF1_TEAR_INTR))
>>>   #define IRQ_SC7180_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>>                BIT(MDP_SSPP_TOP0_INTR2) | \
>>>                BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>>                BIT(MDP_INTF0_INTR) | \
>>> -             BIT(MDP_INTF1_INTR))
>>> +             BIT(MDP_INTF1_INTR) | \
>>> +             BIT(MDP_INTF1_TEAR_INTR))
>>>   #define IRQ_SC7280_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>>                BIT(MDP_SSPP_TOP0_INTR2) | \
>>> @@ -120,7 +131,9 @@
>>>                BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>>                BIT(MDP_INTF0_INTR) | \
>>>                BIT(MDP_INTF1_INTR) | \
>>> +             BIT(MDP_INTF1_TEAR_INTR) | \
>>>                BIT(MDP_INTF2_INTR) | \
>>> +             BIT(MDP_INTF2_TEAR_INTR) | \
>>>                BIT(MDP_INTF3_INTR) | \
>>>                BIT(MDP_INTF4_INTR))
>>> @@ -129,7 +142,9 @@
>>>                 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>>                 BIT(MDP_INTF0_INTR) | \
>>>                 BIT(MDP_INTF1_INTR) | \
>>> +              BIT(MDP_INTF1_TEAR_INTR) | \
>>>                 BIT(MDP_INTF2_INTR) | \
>>> +              BIT(MDP_INTF2_TEAR_INTR) | \
>>>                 BIT(MDP_INTF3_INTR) | \
>>>                 BIT(MDP_INTF4_INTR) | \
>>>                 BIT(MDP_INTF5_INTR) | \
>>> @@ -1300,63 +1315,64 @@ static struct dpu_dsc_cfg sdm845_dsc[] = {
>>>   /*************************************************************
>>>    * INTF sub blocks config
>>>    *************************************************************/
>>> -#define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _progfetch, 
>>> _features, _reg, _underrun_bit, _vsync_bit) \
>>> +#define INTF_BLK(_name, _id, _base, _len, _type, _ctrl_id, 
>>> _progfetch, _features, _reg, _underrun_bit, _vsync_bit, _tear_reg, 
>>> _tear_rd_ptr_bit) \
>>>       {\
>>>       .name = _name, .id = _id, \
>>> -    .base = _base, .len = 0x280, \
>>> +    .base = _base, .len = _len, \
>>>       .features = _features, \
>>>       .type = _type, \
>>>       .controller_id = _ctrl_id, \
>>>       .prog_fetch_lines_worst_case = _progfetch, \
>>>       .intr_underrun = DPU_IRQ_IDX(_reg, _underrun_bit), \
>>>       .intr_vsync = DPU_IRQ_IDX(_reg, _vsync_bit), \
>>> +    .intr_tear_rd_ptr = DPU_IRQ_IDX(_tear_reg, _tear_rd_ptr_bit), \
>>>       }
>>>   static const struct dpu_intf_cfg msm8998_intf[] = {
>>> -    INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 25, 
>>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
>>> -    INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 25, 
>>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
>>> -    INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 25, 
>>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
>>> -    INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_HDMI, 0, 25, 
>>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
>>> +    INTF_BLK("intf_0", INTF_0, 0x6A000, 0x268, INTF_DP, 0, 25, 
>>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
>>
>> Just wondering, how were the lengths calculated for the INTF blocks? 
>> The values in general seem a little off to me.
>>
>> For example, I'm looking downstream and it seems to me that the length 
>> for the INTF_0 on MSM8998 should be 0x280. Similarly for SC7280, I'm 
>> seeing that length for INTF + tearcheck should be 0x2c4.
> 
> We have discussed INTF lengths in [1]. The current understanding of the 
> block lengths can be found at [2]. Please comment there if any of the 
> fixed lengths sounds incorrect to you.
> 
> [1] https://patchwork.freedesktop.org/patch/522187/
> [2] https://patchwork.freedesktop.org/patch/522227/
> 
> [skipped the rest]
> 

Please correct my understanding here, it was agreed to fix intf blocks 
to 0x2c4 here https://patchwork.freedesktop.org/patch/522227/ but I dont 
see this was merged?

It was agreed to first land INTF_TE and then add the higher addresses 
but I dont see such a change, am i missing something?

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

* Re: [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces
  2023-02-14  3:09       ` Abhinav Kumar
@ 2023-02-14 13:06         ` Marijn Suijten
  2023-02-14 17:54           ` Abhinav Kumar
  0 siblings, 1 reply; 33+ messages in thread
From: Marijn Suijten @ 2023-02-14 13:06 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Dmitry Baryshkov, Jessica Zhang, phone-devel, Neil Armstrong,
	~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Konrad Dybcio, Loic Poulain,
	Vinod Polimera, Adam Skladowski, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

On 2023-02-13 19:09:32, Abhinav Kumar wrote:
> 
> 
> On 2/13/2023 1:46 PM, Dmitry Baryshkov wrote:
> > On 13/02/2023 21:37, Jessica Zhang wrote:
> >>
> >>
> >> On 12/31/2022 1:50 PM, Marijn Suijten wrote:
> >>> All SoCs since DPU 5.0.0 (and seemingly up until and including 6.0.0,
> >>> but excluding 7.x.x) have the tear interrupt and control registers moved
> >>> out of the PINGPONG block and into the INTF block.  Wire up the
> >>> necessary interrupts and IRQ masks on all supported hardware.
> >>
> >> Hi Marijn,
> >>
> >> Thanks for the patch.
> >>
> >> I saw that in your commit msg, you mentioned that 7.x doesn't have 
> >> tearcheck in the INTF block -- can you double check that this is correct?

It wasn't correct and has already been removed for v2 [1] after rebasing
on top of SM8[345]50 support, where the registers reside at a different
(named 7xxxx downstream) offset.

[1] https://github.com/SoMainline/linux/commit/886d3fb9eed925e7e9c8d6ca63d2439eaec1c702

> >> I'm working on SM8350 (DPU v7) and I'm seeing that it does have 
> >> tearcheck in INTF block.
> > 
> > I confirm, according to the vendor drivers INTF TE should be used for 
> > all DPU >= 5.0, including 7.x and 8.x
> > 
> > However I think I know what Marijn meant here. For 5.x and 6.x these 
> > IRQs are handled at the address MDSS + 0x6e800 / + 0x6e900 (which means 
> > offset here should 0x6d800 and 0x6d900) for INTF_1 and INTF_2. Since DPU 
> > 7.x these IRQ registers were moved close to the main INTF block (0x36800 
> > and 0x37800 = INTF + 0x800).

That might have been the case.

> Got it, then the commit text should remove "control" and just say tear 
> interrupt registers. It got a bit confusing.

The wording here points to both the interrupt (MDP_INTFx_TEAR_INTR)
registers and control (INTF_TEAR_xxx) registers separately.  Feel free
to bikeshed the wording in preliminary v2 [1]; should I drop the mention
of the control registers being "moved" from PP to INTF entirely, leaving
just the wording about the interrupt registers moving from
MDP_SSPP_TOP0_INTR to a dedicated MDP_INTFx_TEAR_INTR region?

> We will add the 7xxx intf tear check support on top of this series.

No need, that is already taken care of in an impending v2 [1] (unless
additional changes are required beyond the moved register offset).

> >>> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
> >>> ---
> >>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 78 +++++++++++--------
> >>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  6 +-
> >>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 12 +++
> >>>   .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  2 +
> >>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h      |  3 +
> >>>   5 files changed, 68 insertions(+), 33 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 1cfe94494135..b9b9b5b0b615 100644
> >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >>> @@ -86,6 +86,15 @@
> >>>   #define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)
> >>> +#define IRQ_MSM8998_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
> >>> +             BIT(MDP_SSPP_TOP0_INTR2) | \
> >>> +             BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> >>> +             BIT(MDP_INTF0_INTR) | \
> >>> +             BIT(MDP_INTF1_INTR) | \
> >>> +             BIT(MDP_INTF2_INTR) | \
> >>> +             BIT(MDP_INTF3_INTR) | \
> >>> +             BIT(MDP_INTF4_INTR))
> >>> +
> >>>   #define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
> >>>                BIT(MDP_SSPP_TOP0_INTR2) | \
> >>>                BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> >>> @@ -100,13 +109,15 @@
> >>>   #define IRQ_QCM2290_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
> >>>                BIT(MDP_SSPP_TOP0_INTR2) | \
> >>>                BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> >>> -             BIT(MDP_INTF1_INTR))
> >>> +             BIT(MDP_INTF1_INTR) | \
> >>> +             BIT(MDP_INTF1_TEAR_INTR))
> >>>   #define IRQ_SC7180_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
> >>>                BIT(MDP_SSPP_TOP0_INTR2) | \
> >>>                BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> >>>                BIT(MDP_INTF0_INTR) | \
> >>> -             BIT(MDP_INTF1_INTR))
> >>> +             BIT(MDP_INTF1_INTR) | \
> >>> +             BIT(MDP_INTF1_TEAR_INTR))
> >>>   #define IRQ_SC7280_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
> >>>                BIT(MDP_SSPP_TOP0_INTR2) | \
> >>> @@ -120,7 +131,9 @@
> >>>                BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> >>>                BIT(MDP_INTF0_INTR) | \
> >>>                BIT(MDP_INTF1_INTR) | \
> >>> +             BIT(MDP_INTF1_TEAR_INTR) | \
> >>>                BIT(MDP_INTF2_INTR) | \
> >>> +             BIT(MDP_INTF2_TEAR_INTR) | \
> >>>                BIT(MDP_INTF3_INTR) | \
> >>>                BIT(MDP_INTF4_INTR))
> >>> @@ -129,7 +142,9 @@
> >>>                 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
> >>>                 BIT(MDP_INTF0_INTR) | \
> >>>                 BIT(MDP_INTF1_INTR) | \
> >>> +              BIT(MDP_INTF1_TEAR_INTR) | \
> >>>                 BIT(MDP_INTF2_INTR) | \
> >>> +              BIT(MDP_INTF2_TEAR_INTR) | \
> >>>                 BIT(MDP_INTF3_INTR) | \
> >>>                 BIT(MDP_INTF4_INTR) | \
> >>>                 BIT(MDP_INTF5_INTR) | \
> >>> @@ -1300,63 +1315,64 @@ static struct dpu_dsc_cfg sdm845_dsc[] = {
> >>>   /*************************************************************
> >>>    * INTF sub blocks config
> >>>    *************************************************************/
> >>> -#define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _progfetch, 
> >>> _features, _reg, _underrun_bit, _vsync_bit) \
> >>> +#define INTF_BLK(_name, _id, _base, _len, _type, _ctrl_id, 
> >>> _progfetch, _features, _reg, _underrun_bit, _vsync_bit, _tear_reg, 
> >>> _tear_rd_ptr_bit) \
> >>>       {\
> >>>       .name = _name, .id = _id, \
> >>> -    .base = _base, .len = 0x280, \
> >>> +    .base = _base, .len = _len, \
> >>>       .features = _features, \
> >>>       .type = _type, \
> >>>       .controller_id = _ctrl_id, \
> >>>       .prog_fetch_lines_worst_case = _progfetch, \
> >>>       .intr_underrun = DPU_IRQ_IDX(_reg, _underrun_bit), \
> >>>       .intr_vsync = DPU_IRQ_IDX(_reg, _vsync_bit), \
> >>> +    .intr_tear_rd_ptr = DPU_IRQ_IDX(_tear_reg, _tear_rd_ptr_bit), \
> >>>       }
> >>>   static const struct dpu_intf_cfg msm8998_intf[] = {
> >>> -    INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 25, 
> >>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> >>> -    INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 25, 
> >>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> >>> -    INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 25, 
> >>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
> >>> -    INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_HDMI, 0, 25, 
> >>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
> >>> +    INTF_BLK("intf_0", INTF_0, 0x6A000, 0x268, INTF_DP, 0, 25, 
> >>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
> >>
> >> Just wondering, how were the lengths calculated for the INTF blocks? 
> >> The values in general seem a little off to me.

These (for MSM8998) have been taken from downstream specifically; my
series starts using INTF_STATUS at 0x26C which conveniently is the
register right after 0x268, matching the fact that INTF TE and these
registers weren't supported/available yet on MSM8998.

> >> For example, I'm looking downstream and it seems to me that the length 
> >> for the INTF_0 on MSM8998 should be 0x280. Similarly for SC7280, I'm 
> >> seeing that length for INTF + tearcheck should be 0x2c4.

There are many different downstream sources and tags with seemingly
conflicting/confusing information.  For v2 [2] I've picked the highest
register used by the driver which is INTF_TEAR_AUTOREFRESH_CONFIG at
0x2B4 (but there might always be more registers that don't need to be
poked at by the driver, but contain magic debug information and the
like... those would be useful to capture in the dump going forward).

[2]: https://github.com/SoMainline/linux/commit/2bbc609dd28aa0bd0a2dede20163e521912d0072

> > We have discussed INTF lengths in [1]. The current understanding of the 
> > block lengths can be found at [2]. Please comment there if any of the 
> > fixed lengths sounds incorrect to you.
> > 
> > [1] https://patchwork.freedesktop.org/patch/522187/
> > [2] https://patchwork.freedesktop.org/patch/522227/
> > 
> > [skipped the rest]
> > 
> 
> Please correct my understanding here, it was agreed to fix intf blocks 
> to 0x2c4 here https://patchwork.freedesktop.org/patch/522227/ but I dont 
> see this was merged?
> 
> It was agreed to first land INTF_TE and then add the higher addresses 

Seems like it, at least if I interpret [3] correctly.  My series adds a
new define that will hardcode _len to 0x2B8 for now, and Dmitry/Konrad
can later extend it to whatever is stated by the correct downstream
source.

[3]: https://lore.kernel.org/linux-arm-msm/6ad96cff-b91b-a4c7-4573-7bb8de7194f8@linaro.org/

> but I dont see such a change, am i missing something?

This was discussed just yesterday.  And it wouldn't make much sense to
make such a change now, knowing that my v2 for this series - which isn't
even on the lists yet - will already change the INTF_BLK macro resulting
in unneeded conflicts.  As requested by Dmitry, let's get INTF TE
processed first before rebasing the block length change?

- Marijn

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

* Re: [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces
  2023-02-14 13:06         ` Marijn Suijten
@ 2023-02-14 17:54           ` Abhinav Kumar
  2023-04-17 19:41             ` Marijn Suijten
  0 siblings, 1 reply; 33+ messages in thread
From: Abhinav Kumar @ 2023-02-14 17:54 UTC (permalink / raw)
  To: Marijn Suijten, Dmitry Baryshkov, Jessica Zhang, phone-devel,
	Neil Armstrong, ~postmarketos/upstreaming,
	AngeloGioacchino Del Regno, Konrad Dybcio, Martin Botka,
	Jami Kettunen, Rob Clark, Sean Paul, David Airlie, Daniel Vetter,
	Stephen Boyd, Vinod Koul, Bjorn Andersson, Kuogee Hsieh,
	Konrad Dybcio, Loic Poulain, Vinod Polimera, Adam Skladowski,
	linux-arm-msm, dri-devel, freedreno, linux-kernel



On 2/14/2023 5:06 AM, Marijn Suijten wrote:
> On 2023-02-13 19:09:32, Abhinav Kumar wrote:
>>
>>
>> On 2/13/2023 1:46 PM, Dmitry Baryshkov wrote:
>>> On 13/02/2023 21:37, Jessica Zhang wrote:
>>>>
>>>>
>>>> On 12/31/2022 1:50 PM, Marijn Suijten wrote:
>>>>> All SoCs since DPU 5.0.0 (and seemingly up until and including 6.0.0,
>>>>> but excluding 7.x.x) have the tear interrupt and control registers moved
>>>>> out of the PINGPONG block and into the INTF block.  Wire up the
>>>>> necessary interrupts and IRQ masks on all supported hardware.
>>>>
>>>> Hi Marijn,
>>>>
>>>> Thanks for the patch.
>>>>
>>>> I saw that in your commit msg, you mentioned that 7.x doesn't have
>>>> tearcheck in the INTF block -- can you double check that this is correct?
> 
> It wasn't correct and has already been removed for v2 [1] after rebasing
> on top of SM8[345]50 support, where the registers reside at a different
> (named 7xxxx downstream) offset.
> 
> [1] https://github.com/SoMainline/linux/commit/886d3fb9eed925e7e9c8d6ca63d2439eaec1c702
> 
>>>> I'm working on SM8350 (DPU v7) and I'm seeing that it does have
>>>> tearcheck in INTF block.
>>>
>>> I confirm, according to the vendor drivers INTF TE should be used for
>>> all DPU >= 5.0, including 7.x and 8.x
>>>
>>> However I think I know what Marijn meant here. For 5.x and 6.x these
>>> IRQs are handled at the address MDSS + 0x6e800 / + 0x6e900 (which means
>>> offset here should 0x6d800 and 0x6d900) for INTF_1 and INTF_2. Since DPU
>>> 7.x these IRQ registers were moved close to the main INTF block (0x36800
>>> and 0x37800 = INTF + 0x800).
> 
> That might have been the case.
> 
>> Got it, then the commit text should remove "control" and just say tear
>> interrupt registers. It got a bit confusing.
> 
> The wording here points to both the interrupt (MDP_INTFx_TEAR_INTR)
> registers and control (INTF_TEAR_xxx) registers separately.  Feel free
> to bikeshed the wording in preliminary v2 [1]; should I drop the mention
> of the control registers being "moved" from PP to INTF entirely, leaving
> just the wording about the interrupt registers moving from
> MDP_SSPP_TOP0_INTR to a dedicated MDP_INTFx_TEAR_INTR region?

Yes, that makes more sense to me. Drop the mention on control registers.
> 
>> We will add the 7xxx intf tear check support on top of this series.
> 
> No need, that is already taken care of in an impending v2 [1] (unless
> additional changes are required beyond the moved register offset).
> 

Ok, we will wait till you post v2 and see if that works for us without 
any of our local changes.

>>>>> Signed-off-by: Marijn Suijten <marijn.suijten@somainline.org>
>>>>> ---
>>>>>    .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c    | 78 +++++++++++--------
>>>>>    .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h    |  6 +-
>>>>>    .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.c | 12 +++
>>>>>    .../gpu/drm/msm/disp/dpu1/dpu_hw_interrupts.h |  2 +
>>>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_hwio.h      |  3 +
>>>>>    5 files changed, 68 insertions(+), 33 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 1cfe94494135..b9b9b5b0b615 100644
>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>> @@ -86,6 +86,15 @@
>>>>>    #define INTF_SC7280_MASK INTF_SC7180_MASK | BIT(DPU_DATA_HCTL_EN)
>>>>> +#define IRQ_MSM8998_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>>>> +             BIT(MDP_SSPP_TOP0_INTR2) | \
>>>>> +             BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>>>> +             BIT(MDP_INTF0_INTR) | \
>>>>> +             BIT(MDP_INTF1_INTR) | \
>>>>> +             BIT(MDP_INTF2_INTR) | \
>>>>> +             BIT(MDP_INTF3_INTR) | \
>>>>> +             BIT(MDP_INTF4_INTR))
>>>>> +
>>>>>    #define IRQ_SDM845_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>>>>                 BIT(MDP_SSPP_TOP0_INTR2) | \
>>>>>                 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>>>> @@ -100,13 +109,15 @@
>>>>>    #define IRQ_QCM2290_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>>>>                 BIT(MDP_SSPP_TOP0_INTR2) | \
>>>>>                 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>>>> -             BIT(MDP_INTF1_INTR))
>>>>> +             BIT(MDP_INTF1_INTR) | \
>>>>> +             BIT(MDP_INTF1_TEAR_INTR))
>>>>>    #define IRQ_SC7180_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>>>>                 BIT(MDP_SSPP_TOP0_INTR2) | \
>>>>>                 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>>>>                 BIT(MDP_INTF0_INTR) | \
>>>>> -             BIT(MDP_INTF1_INTR))
>>>>> +             BIT(MDP_INTF1_INTR) | \
>>>>> +             BIT(MDP_INTF1_TEAR_INTR))
>>>>>    #define IRQ_SC7280_MASK (BIT(MDP_SSPP_TOP0_INTR) | \
>>>>>                 BIT(MDP_SSPP_TOP0_INTR2) | \
>>>>> @@ -120,7 +131,9 @@
>>>>>                 BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>>>>                 BIT(MDP_INTF0_INTR) | \
>>>>>                 BIT(MDP_INTF1_INTR) | \
>>>>> +             BIT(MDP_INTF1_TEAR_INTR) | \
>>>>>                 BIT(MDP_INTF2_INTR) | \
>>>>> +             BIT(MDP_INTF2_TEAR_INTR) | \
>>>>>                 BIT(MDP_INTF3_INTR) | \
>>>>>                 BIT(MDP_INTF4_INTR))
>>>>> @@ -129,7 +142,9 @@
>>>>>                  BIT(MDP_SSPP_TOP0_HIST_INTR) | \
>>>>>                  BIT(MDP_INTF0_INTR) | \
>>>>>                  BIT(MDP_INTF1_INTR) | \
>>>>> +              BIT(MDP_INTF1_TEAR_INTR) | \
>>>>>                  BIT(MDP_INTF2_INTR) | \
>>>>> +              BIT(MDP_INTF2_TEAR_INTR) | \
>>>>>                  BIT(MDP_INTF3_INTR) | \
>>>>>                  BIT(MDP_INTF4_INTR) | \
>>>>>                  BIT(MDP_INTF5_INTR) | \
>>>>> @@ -1300,63 +1315,64 @@ static struct dpu_dsc_cfg sdm845_dsc[] = {
>>>>>    /*************************************************************
>>>>>     * INTF sub blocks config
>>>>>     *************************************************************/
>>>>> -#define INTF_BLK(_name, _id, _base, _type, _ctrl_id, _progfetch,
>>>>> _features, _reg, _underrun_bit, _vsync_bit) \
>>>>> +#define INTF_BLK(_name, _id, _base, _len, _type, _ctrl_id,
>>>>> _progfetch, _features, _reg, _underrun_bit, _vsync_bit, _tear_reg,
>>>>> _tear_rd_ptr_bit) \
>>>>>        {\
>>>>>        .name = _name, .id = _id, \
>>>>> -    .base = _base, .len = 0x280, \
>>>>> +    .base = _base, .len = _len, \
>>>>>        .features = _features, \
>>>>>        .type = _type, \
>>>>>        .controller_id = _ctrl_id, \
>>>>>        .prog_fetch_lines_worst_case = _progfetch, \
>>>>>        .intr_underrun = DPU_IRQ_IDX(_reg, _underrun_bit), \
>>>>>        .intr_vsync = DPU_IRQ_IDX(_reg, _vsync_bit), \
>>>>> +    .intr_tear_rd_ptr = DPU_IRQ_IDX(_tear_reg, _tear_rd_ptr_bit), \
>>>>>        }
>>>>>    static const struct dpu_intf_cfg msm8998_intf[] = {
>>>>> -    INTF_BLK("intf_0", INTF_0, 0x6A000, INTF_DP, 0, 25,
>>>>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
>>>>> -    INTF_BLK("intf_1", INTF_1, 0x6A800, INTF_DSI, 0, 25,
>>>>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
>>>>> -    INTF_BLK("intf_2", INTF_2, 0x6B000, INTF_DSI, 1, 25,
>>>>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 28, 29),
>>>>> -    INTF_BLK("intf_3", INTF_3, 0x6B800, INTF_HDMI, 0, 25,
>>>>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 30, 31),
>>>>> +    INTF_BLK("intf_0", INTF_0, 0x6A000, 0x268, INTF_DP, 0, 25,
>>>>> INTF_SDM845_MASK, MDP_SSPP_TOP0_INTR, 24, 25, -1, -1),
>>>>
>>>> Just wondering, how were the lengths calculated for the INTF blocks?
>>>> The values in general seem a little off to me.
> 
> These (for MSM8998) have been taken from downstream specifically; my
> series starts using INTF_STATUS at 0x26C which conveniently is the
> register right after 0x268, matching the fact that INTF TE and these
> registers weren't supported/available yet on MSM8998.
> 
>>>> For example, I'm looking downstream and it seems to me that the length
>>>> for the INTF_0 on MSM8998 should be 0x280. Similarly for SC7280, I'm
>>>> seeing that length for INTF + tearcheck should be 0x2c4.
> 
> There are many different downstream sources and tags with seemingly
> conflicting/confusing information.  For v2 [2] I've picked the highest
> register used by the driver which is INTF_TEAR_AUTOREFRESH_CONFIG at
> 0x2B4 (but there might always be more registers that don't need to be
> poked at by the driver, but contain magic debug information and the
> like... those would be useful to capture in the dump going forward).
> 
> [2]: https://github.com/SoMainline/linux/commit/2bbc609dd28aa0bd0a2dede20163e521912d0072
> 

Not entirely correct.TEAR_AUTOREFRESH_STATUS is at 0x2c0 for sm8350 and 
sm8450 as well so 0x2b4 is a bit short. DPU code uses autorefresh status 
today.Esp after your changes it will use the autorefresh status from 
intf te which is at offset 0x2c0

>>> We have discussed INTF lengths in [1]. The current understanding of the
>>> block lengths can be found at [2]. Please comment there if any of the
>>> fixed lengths sounds incorrect to you.
>>>
>>> [1] https://patchwork.freedesktop.org/patch/522187/
>>> [2] https://patchwork.freedesktop.org/patch/522227/
>>>
>>> [skipped the rest]
>>>
>>
>> Please correct my understanding here, it was agreed to fix intf blocks
>> to 0x2c4 here https://patchwork.freedesktop.org/patch/522227/ but I dont
>> see this was merged?
>>
>> It was agreed to first land INTF_TE and then add the higher addresses
> 
> Seems like it, at least if I interpret [3] correctly.  My series adds a
> new define that will hardcode _len to 0x2B8 for now, and Dmitry/Konrad
> can later extend it to whatever is stated by the correct downstream
> source.
> 

Like mentioned above it should be 0x2c0 for intf block.

If you face any conflicting information in downstream code, you can 
always check with me on IRC.

> [3]: https://lore.kernel.org/linux-arm-msm/6ad96cff-b91b-a4c7-4573-7bb8de7194f8@linaro.org/
> 
>> but I dont see such a change, am i missing something?
> 
> This was discussed just yesterday.  And it wouldn't make much sense to
> make such a change now, knowing that my v2 for this series - which isn't
> even on the lists yet - will already change the INTF_BLK macro resulting
> in unneeded conflicts.  As requested by Dmitry, let's get INTF TE
> processed first before rebasing the block length change?
> 

Please see above comment on why it should be 0x2c4.

> - Marijn

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

* Re: [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces
  2023-02-14 17:54           ` Abhinav Kumar
@ 2023-04-17 19:41             ` Marijn Suijten
  2023-04-17 19:59               ` Abhinav Kumar
  0 siblings, 1 reply; 33+ messages in thread
From: Marijn Suijten @ 2023-04-17 19:41 UTC (permalink / raw)
  To: Abhinav Kumar
  Cc: Dmitry Baryshkov, Jessica Zhang, phone-devel, Neil Armstrong,
	~postmarketos/upstreaming, AngeloGioacchino Del Regno,
	Konrad Dybcio, Martin Botka, Jami Kettunen, Rob Clark, Sean Paul,
	David Airlie, Daniel Vetter, Stephen Boyd, Vinod Koul,
	Bjorn Andersson, Kuogee Hsieh, Konrad Dybcio, Loic Poulain,
	Vinod Polimera, Adam Skladowski, linux-arm-msm, dri-devel,
	freedreno, linux-kernel

On 2023-02-14 09:54:57, Abhinav Kumar wrote:
[..]
> >>>> Just wondering, how were the lengths calculated for the INTF blocks?
> >>>> The values in general seem a little off to me.
> > 
> > These (for MSM8998) have been taken from downstream specifically; my
> > series starts using INTF_STATUS at 0x26C which conveniently is the
> > register right after 0x268, matching the fact that INTF TE and these
> > registers weren't supported/available yet on MSM8998.
> > 
> >>>> For example, I'm looking downstream and it seems to me that the length
> >>>> for the INTF_0 on MSM8998 should be 0x280. Similarly for SC7280, I'm
> >>>> seeing that length for INTF + tearcheck should be 0x2c4.
> > 
> > There are many different downstream sources and tags with seemingly
> > conflicting/confusing information.  For v2 [2] I've picked the highest
> > register used by the driver which is INTF_TEAR_AUTOREFRESH_CONFIG at
> > 0x2B4 (but there might always be more registers that don't need to be
> > poked at by the driver, but contain magic debug information and the
> > like... those would be useful to capture in the dump going forward).
> > 
> > [2]: https://github.com/SoMainline/linux/commit/2bbc609dd28aa0bd0a2dede20163e521912d0072
> > 
> 
> Not entirely correct.TEAR_AUTOREFRESH_STATUS is at 0x2c0 for sm8350 and 
> sm8450 as well so 0x2b4 is a bit short. DPU code uses autorefresh status 
> today.Esp after your changes it will use the autorefresh status from 
> intf te which is at offset 0x2c0

Revisiting this, I don't see current DPU code nor downstream 5.4 / 5.10
SDE techpack on some of my checkouts use this register, only
INTF_TEAR_AUTOREFRESH_CONFIG at 0x2b4..0x2b7.  Am I missing something
critical here?

> >>> We have discussed INTF lengths in [1]. The current understanding of the
> >>> block lengths can be found at [2]. Please comment there if any of the
> >>> fixed lengths sounds incorrect to you.
> >>>
> >>> [1] https://patchwork.freedesktop.org/patch/522187/
> >>> [2] https://patchwork.freedesktop.org/patch/522227/
> >>>
> >>> [skipped the rest]
> >>>
> >>
> >> Please correct my understanding here, it was agreed to fix intf blocks
> >> to 0x2c4 here https://patchwork.freedesktop.org/patch/522227/ but I dont
> >> see this was merged?
> >>
> >> It was agreed to first land INTF_TE and then add the higher addresses
> > 
> > Seems like it, at least if I interpret [3] correctly.  My series adds a
> > new define that will hardcode _len to 0x2B8 for now, and Dmitry/Konrad
> > can later extend it to whatever is stated by the correct downstream
> > source.
> > 
> 
> Like mentioned above it should be 0x2c0 for intf block.
> 
> If you face any conflicting information in downstream code, you can 
> always check with me on IRC.

Ack, it looks like others landed these changes for me now via the
catalog rework, so I have just rebased and kept the lengths in.

- Marijn

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

* Re: [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces
  2023-04-17 19:41             ` Marijn Suijten
@ 2023-04-17 19:59               ` Abhinav Kumar
  0 siblings, 0 replies; 33+ messages in thread
From: Abhinav Kumar @ 2023-04-17 19:59 UTC (permalink / raw)
  To: Marijn Suijten, Dmitry Baryshkov, Jessica Zhang, phone-devel,
	Neil Armstrong, ~postmarketos/upstreaming,
	AngeloGioacchino Del Regno, Konrad Dybcio, Martin Botka,
	Jami Kettunen, Rob Clark, Sean Paul, David Airlie, Daniel Vetter,
	Stephen Boyd, Vinod Koul, Bjorn Andersson, Kuogee Hsieh,
	Konrad Dybcio, Loic Poulain, Vinod Polimera, Adam Skladowski,
	linux-arm-msm, dri-devel, freedreno, linux-kernel



On 4/17/2023 12:41 PM, Marijn Suijten wrote:
> On 2023-02-14 09:54:57, Abhinav Kumar wrote:
> [..]
>>>>>> Just wondering, how were the lengths calculated for the INTF blocks?
>>>>>> The values in general seem a little off to me.
>>>
>>> These (for MSM8998) have been taken from downstream specifically; my
>>> series starts using INTF_STATUS at 0x26C which conveniently is the
>>> register right after 0x268, matching the fact that INTF TE and these
>>> registers weren't supported/available yet on MSM8998.
>>>
>>>>>> For example, I'm looking downstream and it seems to me that the length
>>>>>> for the INTF_0 on MSM8998 should be 0x280. Similarly for SC7280, I'm
>>>>>> seeing that length for INTF + tearcheck should be 0x2c4.
>>>
>>> There are many different downstream sources and tags with seemingly
>>> conflicting/confusing information.  For v2 [2] I've picked the highest
>>> register used by the driver which is INTF_TEAR_AUTOREFRESH_CONFIG at
>>> 0x2B4 (but there might always be more registers that don't need to be
>>> poked at by the driver, but contain magic debug information and the
>>> like... those would be useful to capture in the dump going forward).
>>>
>>> [2]: https://github.com/SoMainline/linux/commit/2bbc609dd28aa0bd0a2dede20163e521912d0072
>>>
>>
>> Not entirely correct.TEAR_AUTOREFRESH_STATUS is at 0x2c0 for sm8350 and
>> sm8450 as well so 0x2b4 is a bit short. DPU code uses autorefresh status
>> today.Esp after your changes it will use the autorefresh status from
>> intf te which is at offset 0x2c0
> 
> Revisiting this, I don't see current DPU code nor downstream 5.4 / 5.10
> SDE techpack on some of my checkouts use this register, only
> INTF_TEAR_AUTOREFRESH_CONFIG at 0x2b4..0x2b7.  Am I missing something
> critical here?
> 

Wow, I lost context since its been months since your last response.

But, I refreshed some of it. You are right, we use the status bits 
present in the INTF_TEAR_AUTOREFRESH_CONFIG and INTF_TEAR_ 
AUTOREFRESH_STATUS is unused.

I got confused between the status bit present in the two registers as 
both relate to autorefresh.

But, the offset of of INTF_TEAR_ AUTOREFRESH_STATUS is still at 0x2c0 as 
i wrote before so 0x2c4 is the accurate length of this block.

And yes, all the blk lengths should be accurate now in the hw catalog 
after the rework and reviews of that rework.

>>>>> We have discussed INTF lengths in [1]. The current understanding of the
>>>>> block lengths can be found at [2]. Please comment there if any of the
>>>>> fixed lengths sounds incorrect to you.
>>>>>
>>>>> [1] https://patchwork.freedesktop.org/patch/522187/
>>>>> [2] https://patchwork.freedesktop.org/patch/522227/
>>>>>
>>>>> [skipped the rest]
>>>>>
>>>>
>>>> Please correct my understanding here, it was agreed to fix intf blocks
>>>> to 0x2c4 here https://patchwork.freedesktop.org/patch/522227/ but I dont
>>>> see this was merged?
>>>>
>>>> It was agreed to first land INTF_TE and then add the higher addresses
>>>
>>> Seems like it, at least if I interpret [3] correctly.  My series adds a
>>> new define that will hardcode _len to 0x2B8 for now, and Dmitry/Konrad
>>> can later extend it to whatever is stated by the correct downstream
>>> source.
>>>
>>
>> Like mentioned above it should be 0x2c0 for intf block.
>>
>> If you face any conflicting information in downstream code, you can
>> always check with me on IRC.
> 
> Ack, it looks like others landed these changes for me now via the
> catalog rework, so I have just rebased and kept the lengths in.
> 
> - Marijn

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

end of thread, other threads:[~2023-04-17 19:59 UTC | newest]

Thread overview: 33+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-12-31 21:49 [RFC PATCH 0/7] drm/msm/dpu: Implement tearcheck support on INTF block Marijn Suijten
2022-12-31 21:50 ` [RFC PATCH 1/7] drm/msm/dpu: Remove unused INTF0 interrupt mask from sm6115/qcm2290 Marijn Suijten
2023-01-01  4:18   ` Dmitry Baryshkov
2023-01-02  9:29   ` Konrad Dybcio
2023-01-02 10:12     ` Marijn Suijten
2022-12-31 21:50 ` [RFC PATCH 2/7] drm/msm/dpu: Disable pingpong TE on DPU 5.0.0 and above Marijn Suijten
2023-01-01  4:28   ` Dmitry Baryshkov
2023-01-02 10:25     ` Marijn Suijten
2023-01-02 14:02       ` Dmitry Baryshkov
2022-12-31 21:50 ` [RFC PATCH 3/7] drm/msm/dpu: Disable MDP vsync source selection " Marijn Suijten
2022-12-31 21:52   ` Marijn Suijten
2023-01-01 12:28     ` Dmitry Baryshkov
2023-01-02  9:30     ` Konrad Dybcio
2023-01-02 10:18       ` Marijn Suijten
2023-01-02 10:19         ` Konrad Dybcio
2022-12-31 21:50 ` [RFC PATCH 4/7] drm/msm/dpu: Move dpu_hw_{tear_check,pp_vsync_info} to dpu_hw_mdss.h Marijn Suijten
2023-01-01 12:37   ` Dmitry Baryshkov
2022-12-31 21:50 ` [RFC PATCH 5/7] drm/msm/dpu: Document and enable TEAR interrupts on DSI interfaces Marijn Suijten
2023-01-01 13:12   ` Dmitry Baryshkov
2023-01-02 10:38     ` Marijn Suijten
2023-02-13 19:37   ` Jessica Zhang
2023-02-13 21:46     ` Dmitry Baryshkov
2023-02-14  3:09       ` Abhinav Kumar
2023-02-14 13:06         ` Marijn Suijten
2023-02-14 17:54           ` Abhinav Kumar
2023-04-17 19:41             ` Marijn Suijten
2023-04-17 19:59               ` Abhinav Kumar
2022-12-31 21:50 ` [RFC PATCH 6/7] drm/msm/dpu: Implement tearcheck support on INTF block Marijn Suijten
2023-01-01 13:32   ` Dmitry Baryshkov
2023-01-02 11:06     ` Marijn Suijten
2023-01-02 15:48       ` Dmitry Baryshkov
2022-12-31 21:50 ` [RFC PATCH 7/7] drm/msm/dpu: Remove intr_rdptr from DPU >= 5.0.0 pingpong config Marijn Suijten
2023-01-01 12:27   ` Dmitry Baryshkov

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