2023-04-28 23:46:13

by Kuogee Hsieh

[permalink] [raw]
Subject: [PATCH v2 0/7] add DSC 1.2 dpu supports

This series adds the DPU side changes to support DSC 1.2 encoder. This
was validated with both DSI DSC 1.2 panel and DP DSC 1.2 monitor.
The DSI and DP parts will be pushed later on top of this change.
This seriel is rebase on [1], [2] and catalog fixes from [3].

[1]: https://patchwork.freedesktop.org/series/116851/
[2]: https://patchwork.freedesktop.org/series/116615/
[3]: https://patchwork.freedesktop.org/series/112332/

Abhinav Kumar (2):
drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
drm/msm/dpu: add dsc blocks for remaining chipsets in catalog

Kuogee Hsieh (5):
drm/msm/dpu: add support for DSC encoder v1.2 engine
drm/msm/dpu: separate DSC flush update out of interface
drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE
drm/msm/dpu: save dpu topology configuration
drm/msm/dpu: calculate DSC encoder parameters dynamically

drivers/gpu/drm/msm/Makefile | 1 +
.../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 19 +-
.../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 +-
.../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26 +-
.../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 35 ++-
.../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26 +-
.../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 +-
.../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +-
.../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +-
.../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 +
.../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 +
.../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 +
.../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 +
.../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 +
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 102 ++++---
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 35 ++-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 36 ++-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 22 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 10 +
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 335 +++++++++++++++++++++
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +-
23 files changed, 642 insertions(+), 116 deletions(-)
create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c

--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project


2023-04-28 23:46:29

by Kuogee Hsieh

[permalink] [raw]
Subject: [PATCH v2 3/7] drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets

From: Abhinav Kumar <[email protected]>

Add DSC 1.2 hardware blocks to the catalog with necessary sub-block and
feature flag information. Each display compression engine (DCE) contains
dual hard slice DSC encoders so both share same base address but with
its own different sub block address.

Signed-off-by: Abhinav Kumar <[email protected]>
Signed-off-by: Kuogee Hsieh <[email protected]>
---
.../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 +++++++++++
.../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 ++++++
.../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 +++++++++++++
.../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 +++++++++++
.../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 +++++++++++
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 27 ++++++++++++++++++++--
6 files changed, 90 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h
index 4f6a965..f98c2a5 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h
@@ -153,6 +153,18 @@ static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = {
MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x50000),
};

+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg sm8350_dsc[] = {
+ DSC_BLK_1_2("dce_0", DSC_0, 0x80000, 0x100, 0, dsc_sblk_0),
+ DSC_BLK_1_2("dce_0", DSC_1, 0x80000, 0x100, 0, dsc_sblk_1),
+ DSC_BLK_1_2("dce_1", DSC_2, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0),
+ DSC_BLK_1_2("dce_1", DSC_3, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_1),
+};
+
static const struct dpu_intf_cfg sm8350_intf[] = {
INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
INTF_BLK("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
@@ -205,6 +217,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = {
.dspp = sm8350_dspp,
.pingpong_count = ARRAY_SIZE(sm8350_pp),
.pingpong = sm8350_pp,
+ .dsc = sm8350_dsc,
+ .dsc_count = ARRAY_SIZE(sm8350_dsc),
.merge_3d_count = ARRAY_SIZE(sm8350_merge_3d),
.merge_3d = sm8350_merge_3d,
.intf_count = ARRAY_SIZE(sm8350_intf),
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h
index 6b2c7ea..3fd0498a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h
@@ -93,6 +93,11 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = {
PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1),
};

+/* NOTE: sc7280 only has one dsc hard slice encoder */
+static const struct dpu_dsc_cfg sc7280_dsc[] = {
+ DSC_BLK_1_2("dce_0", DSC_0, 0x80000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0),
+};
+
static const struct dpu_intf_cfg sc7280_intf[] = {
INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
INTF_BLK("intf_1", INTF_1, 0x35000, 0x2c4, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
@@ -142,6 +147,8 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = {
.mixer = sc7280_lm,
.pingpong_count = ARRAY_SIZE(sc7280_pp),
.pingpong = sc7280_pp,
+ .dsc_count = ARRAY_SIZE(sc7280_dsc),
+ .dsc = sc7280_dsc,
.intf_count = ARRAY_SIZE(sc7280_intf),
.intf = sc7280_intf,
.vbif_count = ARRAY_SIZE(sdm845_vbif),
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h
index 706d0f1..ce583eb 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h
@@ -141,6 +141,20 @@ static const struct dpu_merge_3d_cfg sc8280xp_merge_3d[] = {
MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x50000),
};

+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg sc8280xp_dsc[] = {
+ DSC_BLK_1_2("dce_0", DSC_0, 0x80000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0),
+ DSC_BLK_1_2("dce_0", DSC_1, 0x80000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_1),
+ DSC_BLK_1_2("dce_1", DSC_2, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0),
+ DSC_BLK_1_2("dce_1", DSC_3, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_1),
+ DSC_BLK_1_2("dce_2", DSC_4, 0x82000, 0x100, 0, dsc_sblk_0),
+ DSC_BLK_1_2("dce_2", DSC_5, 0x82000, 0x100, 0, dsc_sblk_1),
+};
+
/* TODO: INTF 3, 8 and 7 are used for MST, marked as INTF_NONE for now */
static const struct dpu_intf_cfg sc8280xp_intf[] = {
INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
@@ -196,6 +210,8 @@ const struct dpu_mdss_cfg dpu_sc8280xp_cfg = {
.dspp = sc8280xp_dspp,
.pingpong_count = ARRAY_SIZE(sc8280xp_pp),
.pingpong = sc8280xp_pp,
+ .dsc = sc8280xp_dsc,
+ .dsc_count = ARRAY_SIZE(sc8280xp_dsc),
.merge_3d_count = ARRAY_SIZE(sc8280xp_merge_3d),
.merge_3d = sc8280xp_merge_3d,
.intf_count = ARRAY_SIZE(sc8280xp_intf),
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h
index 4ecb3df..3950e7b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h
@@ -161,6 +161,18 @@ static const struct dpu_merge_3d_cfg sm8450_merge_3d[] = {
MERGE_3D_BLK("merge_3d_3", MERGE_3D_3, 0x65f00),
};

+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg sm8450_dsc[] = {
+ DSC_BLK_1_2("dce_0", DSC_0, 0x80000, 0x100, 0, dsc_sblk_0),
+ DSC_BLK_1_2("dce_0", DSC_1, 0x80000, 0x100, 0, dsc_sblk_1),
+ DSC_BLK_1_2("dce_1", DSC_2, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0),
+ DSC_BLK_1_2("dce_1", DSC_3, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_1),
+};
+
static const struct dpu_intf_cfg sm8450_intf[] = {
INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
INTF_BLK("intf_1", INTF_1, 0x35000, 0x300, INTF_DSI, 0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
@@ -213,6 +225,8 @@ const struct dpu_mdss_cfg dpu_sm8450_cfg = {
.dspp = sm8450_dspp,
.pingpong_count = ARRAY_SIZE(sm8450_pp),
.pingpong = sm8450_pp,
+ .dsc = sm8450_dsc,
+ .dsc_count = ARRAY_SIZE(sm8450_dsc),
.merge_3d_count = ARRAY_SIZE(sm8450_merge_3d),
.merge_3d = sm8450_merge_3d,
.intf_count = ARRAY_SIZE(sm8450_intf),
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
index d0ab351..1b3f542 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h
@@ -165,6 +165,18 @@ static const struct dpu_merge_3d_cfg sm8550_merge_3d[] = {
MERGE_3D_BLK("merge_3d_3", MERGE_3D_3, 0x66700),
};

+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+static const struct dpu_dsc_cfg sm8550_dsc[] = {
+ DSC_BLK_1_2("dce_0", DSC_0, 0x80000, 0x100, 0, dsc_sblk_0),
+ DSC_BLK_1_2("dce_0", DSC_1, 0x80000, 0x100, 0, dsc_sblk_1),
+ DSC_BLK_1_2("dce_1", DSC_2, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0),
+ DSC_BLK_1_2("dce_1", DSC_3, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_1),
+};
+
static const struct dpu_intf_cfg sm8550_intf[] = {
INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
/* TODO TE sub-blocks for intf1 & intf2 */
@@ -218,6 +230,8 @@ const struct dpu_mdss_cfg dpu_sm8550_cfg = {
.dspp = sm8550_dspp,
.pingpong_count = ARRAY_SIZE(sm8550_pp),
.pingpong = sm8550_pp,
+ .dsc = sm8550_dsc,
+ .dsc_count = ARRAY_SIZE(sm8550_dsc),
.merge_3d_count = ARRAY_SIZE(sm8550_merge_3d),
.merge_3d = sm8550_merge_3d,
.intf_count = ARRAY_SIZE(sm8550_intf),
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 ca8a02d..91bfc8a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
- * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/

#define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__
@@ -536,11 +536,34 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
/*************************************************************
* DSC sub blocks config
*************************************************************/
+static const struct dpu_dsc_sub_blks dsc_sblk_0 = {
+ .enc = {.base = 0x100, .len = 0x100},
+ .ctl = {.base = 0xF00, .len = 0x10},
+};
+
+static const struct dpu_dsc_sub_blks dsc_sblk_1 = {
+ .enc = {.base = 0x200, .len = 0x100},
+ .ctl = {.base = 0xF80, .len = 0x10},
+};
+
#define DSC_BLK(_name, _id, _base, _features) \
{\
.name = _name, .id = _id, \
.base = _base, .len = 0x140, \
- .features = _features, \
+ .features = BIT(DPU_DSC_HW_REV_1_1) | _features, \
+ }
+
+/*
+ * NOTE: Each display compression engine (DCE) contains dual hard
+ * slice DSC encoders so both share same base address but with
+ * its own different sub block address.
+ */
+#define DSC_BLK_1_2(_name, _id, _base, _len, _features, _sblk) \
+ {\
+ .name = _name, .id = _id, \
+ .base = _base, .len = _len, \
+ .features = BIT(DPU_DSC_HW_REV_1_2) | _features, \
+ .sblk = &_sblk, \
}

/*************************************************************
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

2023-04-28 23:46:33

by Kuogee Hsieh

[permalink] [raw]
Subject: [PATCH v2 4/7] drm/msm/dpu: add dsc blocks for remaining chipsets in catalog

From: Abhinav Kumar <[email protected]>

In preparation of calling ping-pong DSC related functions only
for chipsets which have such a design add the dsc blocks for the
chipsets for which DSC is present but was not added in the catalog.

Signed-off-by: Abhinav Kumar <[email protected]>
---
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 7 +++++++
drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 11 +++++++++++
2 files changed, 18 insertions(+)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
index 2b3ae84..17f821c 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
@@ -126,6 +126,11 @@ static const struct dpu_pingpong_cfg msm8998_pp[] = {
DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
};

+static const struct dpu_dsc_cfg msm8998_dsc[] = {
+ DSC_BLK("dsc_0", DSC_0, 0x80000, 0),
+ DSC_BLK("dsc_1", DSC_1, 0x80400, 0),
+};
+
static const struct dpu_dspp_cfg msm8998_dspp[] = {
DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_MSM8998_MASK,
&msm8998_dspp_sblk),
@@ -191,6 +196,8 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = {
.dspp = msm8998_dspp,
.pingpong_count = ARRAY_SIZE(msm8998_pp),
.pingpong = msm8998_pp,
+ .dsc_count = ARRAY_SIZE(msm8998_dsc),
+ .dsc = msm8998_dsc,
.intf_count = ARRAY_SIZE(msm8998_intf),
.intf = msm8998_intf,
.vbif_count = ARRAY_SIZE(msm8998_vbif),
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
index e3bdfe7..5bb9882 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
@@ -142,6 +142,15 @@ static const struct dpu_merge_3d_cfg sc8180x_merge_3d[] = {
MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x83200),
};

+static const struct dpu_dsc_cfg sc8180x_dsc[] = {
+ DSC_BLK("dsc_0", DSC_0, 0x80000, BIT(DPU_DSC_OUTPUT_CTRL)),
+ DSC_BLK("dsc_1", DSC_1, 0x80400, BIT(DPU_DSC_OUTPUT_CTRL)),
+ DSC_BLK("dsc_2", DSC_2, 0x80800, BIT(DPU_DSC_OUTPUT_CTRL)),
+ DSC_BLK("dsc_3", DSC_3, 0x80c00, BIT(DPU_DSC_OUTPUT_CTRL)),
+ DSC_BLK("dsc_4", DSC_4, 0x81000, BIT(DPU_DSC_OUTPUT_CTRL)),
+ DSC_BLK("dsc_5", DSC_5, 0x81400, BIT(DPU_DSC_OUTPUT_CTRL)),
+};
+
static const struct dpu_intf_cfg sc8180x_intf[] = {
INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
@@ -192,6 +201,8 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = {
.mixer = sc8180x_lm,
.pingpong_count = ARRAY_SIZE(sc8180x_pp),
.pingpong = sc8180x_pp,
+ .dsc_count = ARRAY_SIZE(sc8180x_dsc),
+ .dsc = sc8180x_dsc,
.merge_3d_count = ARRAY_SIZE(sc8180x_merge_3d),
.merge_3d = sc8180x_merge_3d,
.intf_count = ARRAY_SIZE(sc8180x_intf),
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

2023-04-28 23:46:40

by Kuogee Hsieh

[permalink] [raw]
Subject: [PATCH v2 1/7] drm/msm/dpu: add support for DSC encoder v1.2 engine

Add support for DSC 1.2 by providing the necessary hooks to program
the DPU DSC 1.2 encoder.

Reported-by: kernel test robot <[email protected]>
Signed-off-by: Kuogee Hsieh <[email protected]>
---
drivers/gpu/drm/msm/Makefile | 1 +
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 34 ++-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 335 +++++++++++++++++++++++++
drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +-
5 files changed, 387 insertions(+), 4 deletions(-)
create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c

diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
index b814fc8..b9af5e4 100644
--- a/drivers/gpu/drm/msm/Makefile
+++ b/drivers/gpu/drm/msm/Makefile
@@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
disp/dpu1/dpu_hw_catalog.o \
disp/dpu1/dpu_hw_ctl.o \
disp/dpu1/dpu_hw_dsc.o \
+ disp/dpu1/dpu_hw_dsc_1_2.o \
disp/dpu1/dpu_hw_interrupts.o \
disp/dpu1/dpu_hw_intf.o \
disp/dpu1/dpu_hw_lm.o \
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 71584cd..fc87db1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
- * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
+ * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
*/

@@ -241,12 +241,20 @@ enum {
};

/**
- * DSC features
+ * DSC sub-blocks/features
* @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets
* the pixel output from this DSC.
+ * @DPU_DSC_HW_REV_1_1 DSC block supports dsc 1.1 only
+ * @DPU_DSC_HW_REV_1_2 DSC block supports dsc 1.1 and 1.2
+ * @DPU_DSC_NATIVE_422_EN Supports native422 and native420 encoding
+ * @DPU_DSC_MAX
*/
enum {
DPU_DSC_OUTPUT_CTRL = 0x1,
+ DPU_DSC_HW_REV_1_1,
+ DPU_DSC_HW_REV_1_2,
+ DPU_DSC_NATIVE_422_EN,
+ DPU_DSC_MAX
};

/**
@@ -311,6 +319,14 @@ struct dpu_pp_blk {
};

/**
+ * struct dpu_dsc_blk - DSC Encoder sub-blk information
+ * @info: HW register and features supported by this sub-blk
+ */
+struct dpu_dsc_blk {
+ DPU_HW_SUBBLK_INFO;
+};
+
+/**
* enum dpu_qos_lut_usage - define QoS LUT use cases
*/
enum dpu_qos_lut_usage {
@@ -459,6 +475,17 @@ struct dpu_pingpong_sub_blks {
};

/**
+ * struct dpu_dsc_sub_blks - DSC sub-blks
+ * @enc: DSC encoder sub block
+ * @ctl: DSC controller sub block
+ *
+ */
+struct dpu_dsc_sub_blks {
+ struct dpu_dsc_blk enc;
+ struct dpu_dsc_blk ctl;
+};
+
+/**
* dpu_clk_ctrl_type - Defines top level clock control signals
*/
enum dpu_clk_ctrl_type {
@@ -612,10 +639,13 @@ struct dpu_merge_3d_cfg {
* struct dpu_dsc_cfg - information of DSC blocks
* @id enum identifying this block
* @base register offset of this block
+ * @len: length of hardware block
* @features bit mask identifying sub-blocks/features
+ * @sblk sub-blocks information
*/
struct dpu_dsc_cfg {
DPU_HW_BLK_INFO;
+ const struct dpu_dsc_sub_blks *sblk;
};

/**
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
index 287ec5f..e11240a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
@@ -1,5 +1,8 @@
/* SPDX-License-Identifier: GPL-2.0-only */
-/* Copyright (c) 2020-2022, Linaro Limited */
+/*
+ * Copyright (c) 2020-2022, Linaro Limited
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved
+ */

#ifndef _DPU_HW_DSC_H
#define _DPU_HW_DSC_H
@@ -70,6 +73,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg,
void __iomem *addr);

/**
+ * dpu_hw_dsc_init_1_2 - initializes the v1.2 DSC hw driver block
+ * @cfg: DSC catalog entry for which driver object is required
+ * @addr: Mapped register io address of MDP
+ * Returns: Error code or allocated dpu_hw_dsc context
+ */
+struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
+ void __iomem *addr);
+
+/**
* dpu_hw_dsc_destroy - destroys dsc driver context
* @dsc: Pointer to dsc driver context returned by dpu_hw_dsc_init
*/
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
new file mode 100644
index 00000000..a777c7b
--- /dev/null
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
@@ -0,0 +1,335 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved
+ */
+
+#include <drm/display/drm_dsc_helper.h>
+
+#include "dpu_kms.h"
+#include "dpu_hw_catalog.h"
+#include "dpu_hwio.h"
+#include "dpu_hw_mdss.h"
+#include "dpu_hw_dsc.h"
+
+
+#define DSC_CMN_MAIN_CNF 0x00
+
+/* DPU_DSC_ENC register offsets */
+#define ENC_DF_CTRL 0x00
+#define ENC_GENERAL_STATUS 0x04
+#define ENC_HSLICE_STATUS 0x08
+#define ENC_OUT_STATUS 0x0C
+#define ENC_INT_STAT 0x10
+#define ENC_INT_CLR 0x14
+#define ENC_INT_MASK 0x18
+#define DSC_MAIN_CONF 0x30
+#define DSC_PICTURE_SIZE 0x34
+#define DSC_SLICE_SIZE 0x38
+#define DSC_MISC_SIZE 0x3C
+#define DSC_HRD_DELAYS 0x40
+#define DSC_RC_SCALE 0x44
+#define DSC_RC_SCALE_INC_DEC 0x48
+#define DSC_RC_OFFSETS_1 0x4C
+#define DSC_RC_OFFSETS_2 0x50
+#define DSC_RC_OFFSETS_3 0x54
+#define DSC_RC_OFFSETS_4 0x58
+#define DSC_FLATNESS_QP 0x5C
+#define DSC_RC_MODEL_SIZE 0x60
+#define DSC_RC_CONFIG 0x64
+#define DSC_RC_BUF_THRESH_0 0x68
+#define DSC_RC_MIN_QP_0 0x78
+#define DSC_RC_MAX_QP_0 0x84
+#define DSC_RC_RANGE_BPG_OFFSETS_0 0x90
+
+/* DPU_DSC_CTL register offsets */
+#define DSC_CTL 0x00
+#define DSC_CFG 0x04
+#define DSC_DATA_IN_SWAP 0x08
+#define DSC_CLK_CTRL 0x0C
+
+static inline int _dsc_calc_ob_max_addr(struct dpu_hw_dsc *hw_dsc, int num_ss, bool native_422)
+{
+ int max_addr = 2400 / num_ss;
+
+ if ((hw_dsc->caps->features & BIT(DPU_DSC_NATIVE_422_EN)) && native_422)
+ max_addr /= 2;
+
+ return max_addr - 1;
+};
+
+static void dpu_hw_dsc_disable_1_2(struct dpu_hw_dsc *hw_dsc)
+{
+ struct dpu_hw_blk_reg_map *hw;
+ u32 offset;
+
+ if (!hw_dsc)
+ return;
+
+ hw = &hw_dsc->hw;
+ offset = hw_dsc->caps->sblk->ctl.base;
+ DPU_REG_WRITE(hw, offset + DSC_CFG, 0);
+
+ offset = hw_dsc->caps->sblk->enc.base;
+ DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, 0);
+ DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, 0);
+}
+
+static void dpu_hw_dsc_config_1_2(struct dpu_hw_dsc *hw_dsc,
+ struct drm_dsc_config *dsc,
+ u32 mode,
+ u32 initial_lines)
+{
+ struct dpu_hw_blk_reg_map *hw;
+ u32 offset;
+ u32 data = 0;
+ u32 det_thresh_flatness;
+ u32 num_active_ss_per_enc;
+ u32 bpp;
+
+ if (!hw_dsc || !dsc)
+ return;
+
+ hw = &hw_dsc->hw;
+
+ offset = hw_dsc->caps->sblk->enc.base;
+
+ if (mode & DSC_MODE_SPLIT_PANEL)
+ data |= BIT(0);
+
+ if (mode & DSC_MODE_MULTIPLEX)
+ data |= BIT(1);
+
+ num_active_ss_per_enc = dsc->slice_count;
+ if (mode & DSC_MODE_MULTIPLEX)
+ num_active_ss_per_enc = dsc->slice_count >> 1;
+
+ data |= (num_active_ss_per_enc & 0x3) << 7;
+
+ DPU_REG_WRITE(hw, DSC_CMN_MAIN_CNF, data);
+
+ data = (initial_lines & 0xff);
+
+ if (mode & DSC_MODE_VIDEO)
+ data |= BIT(9);
+
+ data |= (_dsc_calc_ob_max_addr(hw_dsc, num_active_ss_per_enc, dsc->native_422) << 18);
+
+ DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, data);
+
+ data = (dsc->dsc_version_minor & 0xf) << 28;
+ if (dsc->dsc_version_minor == 0x2) {
+ if (dsc->native_422)
+ data |= BIT(22);
+ if (dsc->native_420)
+ data |= BIT(21);
+ }
+
+ bpp = dsc->bits_per_pixel;
+ /* as per hw requirement bpp should be programmed
+ * twice the actual value in case of 420 or 422 encoding
+ */
+ if (dsc->native_422 || dsc->native_420)
+ bpp = 2 * bpp;
+ data |= (dsc->block_pred_enable ? 1 : 0) << 20;
+ data |= bpp << 10;
+ data |= (dsc->line_buf_depth & 0xf) << 6;
+ data |= dsc->convert_rgb << 4;
+ data |= dsc->bits_per_component & 0xf;
+
+ DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, data);
+
+ data = (dsc->pic_width & 0xffff) |
+ ((dsc->pic_height & 0xffff) << 16);
+
+ DPU_REG_WRITE(hw, offset + DSC_PICTURE_SIZE, data);
+
+ data = (dsc->slice_width & 0xffff) |
+ ((dsc->slice_height & 0xffff) << 16);
+
+ DPU_REG_WRITE(hw, offset + DSC_SLICE_SIZE, data);
+
+ DPU_REG_WRITE(hw, offset + DSC_MISC_SIZE,
+ (dsc->slice_chunk_size) & 0xffff);
+
+ data = (dsc->initial_xmit_delay & 0xffff) |
+ ((dsc->initial_dec_delay & 0xffff) << 16);
+
+ DPU_REG_WRITE(hw, offset + DSC_HRD_DELAYS, data);
+
+ DPU_REG_WRITE(hw, offset + DSC_RC_SCALE,
+ dsc->initial_scale_value & 0x3f);
+
+ data = (dsc->scale_increment_interval & 0xffff) |
+ ((dsc->scale_decrement_interval & 0x7ff) << 16);
+
+ DPU_REG_WRITE(hw, offset + DSC_RC_SCALE_INC_DEC, data);
+
+ data = (dsc->first_line_bpg_offset & 0x1f) |
+ ((dsc->second_line_bpg_offset & 0x1f) << 5);
+
+ DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_1, data);
+
+ data = (dsc->nfl_bpg_offset & 0xffff) |
+ ((dsc->slice_bpg_offset & 0xffff) << 16);
+
+ DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_2, data);
+
+ data = (dsc->initial_offset & 0xffff) |
+ ((dsc->final_offset & 0xffff) << 16);
+
+ DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_3, data);
+
+ data = (dsc->nsl_bpg_offset & 0xffff) |
+ ((dsc->second_line_offset_adj & 0xffff) << 16);
+
+ DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_4, data);
+
+ data = (dsc->flatness_min_qp & 0x1f);
+ data |= (dsc->flatness_max_qp & 0x1f) << 5;
+
+ det_thresh_flatness = drm_dsc_calculate_flatness_det_thresh(dsc);
+ data |= (det_thresh_flatness & 0xff) << 10;
+
+ DPU_REG_WRITE(hw, offset + DSC_FLATNESS_QP, data);
+
+ DPU_REG_WRITE(hw, offset + DSC_RC_MODEL_SIZE,
+ (dsc->rc_model_size) & 0xffff);
+
+ data = dsc->rc_edge_factor & 0xf;
+ data |= (dsc->rc_quant_incr_limit0 & 0x1f) << 8;
+ data |= (dsc->rc_quant_incr_limit1 & 0x1f) << 13;
+ data |= (dsc->rc_tgt_offset_high & 0xf) << 20;
+ data |= (dsc->rc_tgt_offset_low & 0xf) << 24;
+
+ DPU_REG_WRITE(hw, offset + DSC_RC_CONFIG, data);
+
+ /* program the dsc wrapper */
+ offset = hw_dsc->caps->sblk->ctl.base;
+
+ data = BIT(0); /* encoder enable */
+ if (dsc->native_422)
+ data |= BIT(8);
+ else if (dsc->native_420)
+ data |= BIT(9);
+ if (!dsc->convert_rgb)
+ data |= BIT(10);
+ if (dsc->bits_per_component == 8)
+ data |= BIT(11);
+ if (mode & DSC_MODE_SPLIT_PANEL)
+ data |= BIT(12);
+ if (mode & DSC_MODE_MULTIPLEX)
+ data |= BIT(13);
+ if (!(mode & DSC_MODE_VIDEO))
+ data |= BIT(17);
+
+ DPU_REG_WRITE(hw, offset + DSC_CFG, data);
+}
+
+static void dpu_hw_dsc_config_thresh_1_2(struct dpu_hw_dsc *hw_dsc,
+ struct drm_dsc_config *dsc)
+{
+ struct dpu_hw_blk_reg_map *hw;
+ u32 offset, off;
+ int i, j = 0;
+ struct drm_dsc_rc_range_parameters *rc;
+ u32 data = 0, min_qp = 0, max_qp = 0, bpg_off = 0;
+
+ if (!hw_dsc || !dsc)
+ return;
+
+ offset = hw_dsc->caps->sblk->enc.base;
+
+ hw = &hw_dsc->hw;
+
+ rc = dsc->rc_range_params;
+
+ /*
+ * With BUF_THRESH -- 14 in total
+ * each register contains 4 thresh values with the last register
+ * containing only 2 thresh values
+ */
+ off = 0;
+ for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) {
+ data |= dsc->rc_buf_thresh[i] << (8 * j);
+ j++;
+ if ((j == 4) || (i == DSC_NUM_BUF_RANGES - 2)) {
+ DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0 + off, data);
+ off += 4;
+ j = 0;
+ data = 0;
+ }
+ }
+
+
+ /*
+ * with min/max_QP -- 5 bits each
+ * each register contains 5 min_qp or max_qp for total of 15
+ *
+ * With BPG_OFFSET -- 6 bits each
+ * each register contains 5 BPG_offset for total of 15
+ */
+ off = 0;
+ for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
+ min_qp |= rc[i].range_min_qp << (5 * j);
+ max_qp |= rc[i].range_max_qp << (5 * j);
+ bpg_off |= rc[i].range_bpg_offset << (6 * j);
+ j++;
+ if (j == 5) {
+ DPU_REG_WRITE(hw, offset + DSC_RC_MIN_QP_0 + off, min_qp);
+ DPU_REG_WRITE(hw, offset + DSC_RC_MAX_QP_0 + off, max_qp);
+ DPU_REG_WRITE(hw, offset + DSC_RC_RANGE_BPG_OFFSETS_0 + off, bpg_off);
+ off += 4;
+ j = 0;
+ min_qp = 0;
+ max_qp = 0;
+ bpg_off = 0;
+ }
+ }
+}
+
+static void dpu_hw_dsc_bind_pingpong_blk_1_2(
+ struct dpu_hw_dsc *hw_dsc,
+ bool enable,
+ const enum dpu_pingpong pp)
+{
+ struct dpu_hw_blk_reg_map *hw;
+ int offset;
+ int mux_cfg = 0xf; /* Disabled */
+
+ offset = hw_dsc->caps->sblk->ctl.base;
+
+ hw = &hw_dsc->hw;
+ if (enable)
+ mux_cfg = (pp - PINGPONG_0) & 0x7;
+
+ DPU_REG_WRITE(hw, offset + DSC_CTL, mux_cfg);
+}
+
+static void _setup_dcs_ops_1_2(struct dpu_hw_dsc_ops *ops,
+ const unsigned long features)
+{
+ ops->dsc_disable = dpu_hw_dsc_disable_1_2;
+ ops->dsc_config = dpu_hw_dsc_config_1_2;
+ ops->dsc_config_thresh = dpu_hw_dsc_config_thresh_1_2;
+ ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2;
+}
+
+struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
+ void __iomem *addr)
+{
+ struct dpu_hw_dsc *c;
+
+ c = kzalloc(sizeof(*c), GFP_KERNEL);
+ if (!c)
+ return ERR_PTR(-ENOMEM);
+
+ c->hw.blk_addr = addr + cfg->base;
+ c->hw.log_mask = DPU_DBG_MASK_DSC;
+
+ c->idx = cfg->id;
+ c->caps = cfg;
+ _setup_dcs_ops_1_2(&c->ops, c->caps->features);
+
+ return c;
+}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
index 3452f88..b2f618f6 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
+ * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
*/

#define pr_fmt(fmt) "[drm:%s] " fmt, __func__
@@ -250,7 +251,11 @@ int dpu_rm_init(struct dpu_rm *rm,
struct dpu_hw_dsc *hw;
const struct dpu_dsc_cfg *dsc = &cat->dsc[i];

- hw = dpu_hw_dsc_init(dsc, mmio);
+ if (test_bit(DPU_DSC_HW_REV_1_2, &dsc->features))
+ hw = dpu_hw_dsc_init_1_2(dsc, mmio);
+ else
+ hw = dpu_hw_dsc_init(dsc, mmio);
+
if (IS_ERR_OR_NULL(hw)) {
rc = PTR_ERR(hw);
DPU_ERROR("failed dsc object creation: err %d\n", rc);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

2023-04-28 23:47:55

by Kuogee Hsieh

[permalink] [raw]
Subject: [PATCH v2 2/7] drm/msm/dpu: separate DSC flush update out of interface

Current DSC flush update is piggyback inside dpu_hw_ctl_intf_cfg_v1().
This patch separate DSC flush away from dpu_hw_ctl_intf_cfg_v1() by
adding dpu_hw_ctl_update_pending_flush_dsc_v1() to handle both per
DSC engine and DSC flush bits at same time to make it consistent with
the location of flush programming of other dpu sub blocks.

Signed-off-by: Kuogee Hsieh <[email protected]>
Reviewed-by: Dmitry Baryshkov <[email protected]>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 14 ++++++++++++--
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 22 ++++++++++++++++------
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 10 ++++++++++
3 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 1dc5dbe..ecb87bc 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -1823,12 +1823,18 @@ dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config *dsc,
return DIV_ROUND_UP(total_pixels, dsc->slice_width);
}

-static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,
+static void dpu_encoder_dsc_pipe_cfg(struct dpu_encoder_virt *dpu_enc,
+ struct dpu_hw_dsc *hw_dsc,
struct dpu_hw_pingpong *hw_pp,
struct drm_dsc_config *dsc,
u32 common_mode,
u32 initial_lines)
{
+ struct dpu_encoder_phys *cur_master = dpu_enc->cur_master;
+ struct dpu_hw_ctl *ctl;
+
+ ctl = cur_master->hw_ctl;
+
if (hw_dsc->ops.dsc_config)
hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, initial_lines);

@@ -1843,6 +1849,9 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,

if (hw_pp->ops.enable_dsc)
hw_pp->ops.enable_dsc(hw_pp);
+
+ if (ctl->ops.update_pending_flush_dsc)
+ ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx);
}

static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
@@ -1887,7 +1896,8 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w);

for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
- dpu_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], dsc, dsc_common_mode, initial_lines);
+ dpu_encoder_dsc_pipe_cfg(dpu_enc, hw_dsc[i], hw_pp[i], dsc,
+ dsc_common_mode, initial_lines);
}

void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc)
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
index 4f7cfa9..832a6a7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
@@ -139,6 +139,11 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
CTL_DSPP_n_FLUSH(dspp - DSPP_0),
ctx->pending_dspp_flush_mask[dspp - DSPP_0]);
}
+
+ if (ctx->pending_flush_mask & BIT(DSC_IDX))
+ DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH,
+ ctx->pending_dsc_flush_mask);
+
DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
}

@@ -285,6 +290,13 @@ static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx,
ctx->pending_flush_mask |= BIT(MERGE_3D_IDX);
}

+static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx,
+ enum dpu_dsc dsc_num)
+{
+ ctx->pending_dsc_flush_mask |= BIT(dsc_num - DSC_0);
+ ctx->pending_flush_mask |= BIT(DSC_IDX);
+}
+
static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
enum dpu_dspp dspp, u32 dspp_sub_blk)
{
@@ -502,9 +514,6 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
if ((test_bit(DPU_CTL_VM_CFG, &ctx->caps->features)))
mode_sel = CTL_DEFAULT_GROUP_ID << 28;

- if (cfg->dsc)
- DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH, cfg->dsc);
-
if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD)
mode_sel |= BIT(17);

@@ -524,10 +533,8 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
if (cfg->merge_3d)
DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
BIT(cfg->merge_3d - MERGE_3D_0));
- if (cfg->dsc) {
- DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, DSC_IDX);
+ if (cfg->dsc)
DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc);
- }
}

static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
@@ -630,6 +637,9 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
ops->update_pending_flush_merge_3d =
dpu_hw_ctl_update_pending_flush_merge_3d_v1;
ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1;
+
+ ops->update_pending_flush_dsc =
+ dpu_hw_ctl_update_pending_flush_dsc_v1;
} else {
ops->trigger_flush = dpu_hw_ctl_trigger_flush;
ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg;
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
index 6292002..5762752 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
@@ -158,6 +158,15 @@ struct dpu_hw_ctl_ops {
enum dpu_dspp blk, u32 dspp_sub_blk);

/**
+ * OR in the given flushbits to the cached pending_(dsc_)flush_mask
+ * No effect on hardware
+ * @ctx : ctl path ctx pointer
+ * @blk : interface block index
+ */
+ void (*update_pending_flush_dsc)(struct dpu_hw_ctl *ctx,
+ enum dpu_dsc blk);
+
+ /**
* Write the value of the pending_flush_mask to hardware
* @ctx : ctl path ctx pointer
*/
@@ -245,6 +254,7 @@ struct dpu_hw_ctl {
u32 pending_wb_flush_mask;
u32 pending_merge_3d_flush_mask;
u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0];
+ u32 pending_dsc_flush_mask;

/* ops */
struct dpu_hw_ctl_ops ops;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

2023-04-28 23:48:37

by Kuogee Hsieh

[permalink] [raw]
Subject: [PATCH v2 5/7] drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE

Legacy DPU requires PP hardware block involved into setting up DSC
data path. This patch add DDPU_PINGPONG_DSC feature bit to both
PP_BLK and PP_BLK_TE so that both dpu_hw_pp_setup_dsc() and
dpu_hw_pp_dsc_enable() will be executed during DSC path setup.

Reported-by : Marijn Suijten <[email protected]>
Signed-off-by: Kuogee Hsieh <[email protected]>
---
.../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 12 +++++-----
.../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 +++----
.../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26 ++++++++++------------
.../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 24 ++++++++++----------
.../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26 ++++++++++------------
.../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 ++--
.../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +-
.../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +-
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 8 +++----
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++
drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 +++++---
11 files changed, 62 insertions(+), 61 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
index 17f821c..b7cd746 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
@@ -112,16 +112,16 @@ static const struct dpu_lm_cfg msm8998_lm[] = {
};

static const struct dpu_pingpong_cfg msm8998_pp[] = {
- PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+ PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC), 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,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+ PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC), 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, 0, 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, 0, 0, sdm845_pp_sblk,
DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
};
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
index ceca741..8888bd9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
@@ -110,16 +110,16 @@ static const struct dpu_lm_cfg sdm845_lm[] = {
};

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, BIT(DPU_PINGPONG_DSC), 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, BIT(DPU_PINGPONG_DSC), 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, BIT(DPU_PINGPONG_DSC), 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, BIT(DPU_PINGPONG_DSC), 0, sdm845_pp_sblk,
DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
};
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
index 42b0e58..3a7dffa 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
@@ -128,24 +128,22 @@ static const struct dpu_dspp_cfg sm8150_dspp[] = {
};

static const struct dpu_pingpong_cfg sm8150_pp[] = {
- PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+ PP_BLK("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
+ sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
- PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+ PP_BLK("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
+ sdm845_pp_sblk, 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,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+ PP_BLK("pingpong_2", PINGPONG_2, 0x71000, BIT(DPU_PINGPONG_DSC), 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,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+ PP_BLK("pingpong_3", PINGPONG_3, 0x71800, BIT(DPU_PINGPONG_DSC), 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,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
- -1),
- PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
- -1),
+ PP_BLK("pingpong_4", PINGPONG_4, 0x72000, BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
+ sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
+ PP_BLK("pingpong_5", PINGPONG_5, 0x72800, BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
+ sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
};

static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
index 5bb9882..e766a2d 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
@@ -116,23 +116,23 @@ static const struct dpu_lm_cfg sc8180x_lm[] = {
};

static const struct dpu_pingpong_cfg sc8180x_pp[] = {
- PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+ PP_BLK("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
+ sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
- PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+ PP_BLK("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
+ sdm845_pp_sblk, 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,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+ PP_BLK("pingpong_2", PINGPONG_2, 0x71000, BIT(DPU_PINGPONG_DSC), 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,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+ PP_BLK("pingpong_3", PINGPONG_3, 0x71800, BIT(DPU_PINGPONG_DSC), 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,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
+ PP_BLK("pingpong_4", PINGPONG_4, 0x72000, BIT(DPU_PINGPONG_DSC), 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,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
+ PP_BLK("pingpong_5", PINGPONG_5, 0x72800, BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
+ sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
-1),
};

diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
index ed130582..137b151 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
@@ -129,24 +129,22 @@ static const struct dpu_dspp_cfg sm8250_dspp[] = {
};

static const struct dpu_pingpong_cfg sm8250_pp[] = {
- PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
+ PP_BLK("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
+ sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
- PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
+ PP_BLK("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
+ sdm845_pp_sblk, 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,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
+ PP_BLK("pingpong_2", PINGPONG_2, 0x71000, BIT(DPU_PINGPONG_DSC), 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,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
+ PP_BLK("pingpong_3", PINGPONG_3, 0x71800, BIT(DPU_PINGPONG_DSC), 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,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
- -1),
- PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk,
- DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
- -1),
+ PP_BLK("pingpong_4", PINGPONG_4, 0x72000, BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
+ sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
+ PP_BLK("pingpong_5", PINGPONG_5, 0x72800, BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
+ sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
};

static const struct dpu_merge_3d_cfg sm8250_merge_3d[] = {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
index a46b117..e5631a2 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
@@ -80,8 +80,8 @@ static const struct dpu_dspp_cfg sc7180_dspp[] = {
};

static const struct dpu_pingpong_cfg sc7180_pp[] = {
- PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk, -1, -1),
- PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk, -1, -1),
+ PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 0, sdm845_pp_sblk, -1, -1),
+ PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, 0, sdm845_pp_sblk, -1, -1),
};

static const struct dpu_intf_cfg sc7180_intf[] = {
diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
index 988d820..7b4ad0f 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
@@ -60,7 +60,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[] = {
};

static const struct dpu_pingpong_cfg sm6115_pp[] = {
- PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
+ PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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/catalog/dpu_6_5_qcm2290.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
index c9003dc..20d4d14 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
@@ -57,7 +57,7 @@ static const struct dpu_dspp_cfg qcm2290_dspp[] = {
};

static const struct dpu_pingpong_cfg qcm2290_pp[] = {
- PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
+ PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
index 91bfc8a..83c0cd9 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
@@ -501,21 +501,21 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
.intr_done = _done, \
.intr_rdptr = _rdptr, \
}
-#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 = PINGPONG_SDM845_SPLIT_MASK | _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 = PINGPONG_SDM845_MASK | _features, \
.merge_3d = _merge_3d, \
.sblk = &_sblk, \
.intr_done = _done, \
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 fc87db1..6b49171 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
@@ -144,6 +144,7 @@ enum {
* @DPU_PINGPONG_SPLIT PP block supports split fifo
* @DPU_PINGPONG_SLAVE PP block is a suitable slave for split fifo
* @DPU_PINGPONG_DITHER, Dither blocks
+ * @DPU_PINGPONG_DSC, PP block binding to DSC
* @DPU_PINGPONG_MAX
*/
enum {
@@ -152,6 +153,7 @@ enum {
DPU_PINGPONG_SPLIT,
DPU_PINGPONG_SLAVE,
DPU_PINGPONG_DITHER,
+ DPU_PINGPONG_DSC,
DPU_PINGPONG_MAX
};

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 3822e06..f255a04 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
@@ -264,9 +264,12 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong *c,
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;
+
+ if (features & BIT(DPU_PINGPONG_DSC)) {
+ 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;
+ }

if (test_bit(DPU_PINGPONG_DITHER, &features))
c->ops.setup_dither = dpu_hw_pp_setup_dither;
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

2023-04-28 23:49:25

by Kuogee Hsieh

[permalink] [raw]
Subject: [PATCH v2 6/7] drm/msm/dpu: save dpu topology configuration

At current implementation, topology configuration is thrown away after
dpu_rm_reserve(). This patch save the topology so that it can be used
for DSC related calculation later.

Signed-off-by: Kuogee Hsieh <[email protected]>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 32 ++++++++++++++---------------
1 file changed, 16 insertions(+), 16 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index ecb87bc..2fdacf1 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -542,13 +542,13 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
return (num_dsc > 0) && (num_dsc > intf_count);
}

-static struct msm_display_topology dpu_encoder_get_topology(
+static void dpu_encoder_get_topology(
struct dpu_encoder_virt *dpu_enc,
struct dpu_kms *dpu_kms,
struct drm_display_mode *mode,
- struct drm_crtc_state *crtc_state)
+ struct drm_crtc_state *crtc_state,
+ struct msm_display_topology *topology)
{
- struct msm_display_topology topology = {0};
int i, intf_count = 0;

for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
@@ -567,16 +567,16 @@ static struct msm_display_topology dpu_encoder_get_topology(
* Add dspps to the reservation requirements if ctm is requested
*/
if (intf_count == 2)
- topology.num_lm = 2;
+ topology->num_lm = 2;
else if (!dpu_kms->catalog->caps->has_3d_merge)
- topology.num_lm = 1;
+ topology->num_lm = 1;
else
- topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
+ topology->num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;

if (crtc_state->ctm)
- topology.num_dspp = topology.num_lm;
+ topology->num_dspp = topology->num_lm;

- topology.num_intf = intf_count;
+ topology->num_intf = intf_count;

if (dpu_enc->dsc) {
/*
@@ -585,12 +585,10 @@ static struct msm_display_topology dpu_encoder_get_topology(
* this is power optimal and can drive up to (including) 4k
* screens
*/
- topology.num_dsc = 2;
- topology.num_lm = 2;
- topology.num_intf = 1;
+ topology->num_dsc = 2;
+ topology->num_lm = 2;
+ topology->num_intf = 1;
}
-
- return topology;
}

static int dpu_encoder_virt_atomic_check(
@@ -602,7 +600,7 @@ static int dpu_encoder_virt_atomic_check(
struct msm_drm_private *priv;
struct dpu_kms *dpu_kms;
struct drm_display_mode *adj_mode;
- struct msm_display_topology topology;
+ struct msm_display_topology *topology;
struct dpu_global_state *global_state;
int i = 0;
int ret = 0;
@@ -639,7 +637,9 @@ static int dpu_encoder_virt_atomic_check(
}
}

- topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state);
+ topology = &dpu_enc->topology;
+ memset(topology, 0, sizeof (*topology));
+ dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, topology);

/*
* Release and Allocate resources on every modeset
@@ -650,7 +650,7 @@ static int dpu_encoder_virt_atomic_check(

if (!crtc_state->active_changed || crtc_state->enable)
ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
- drm_enc, crtc_state, topology);
+ drm_enc, crtc_state, *topology);
}

trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

2023-04-29 00:05:54

by Kuogee Hsieh

[permalink] [raw]
Subject: [PATCH v2 7/7] drm/msm/dpu: calculate DSC encoder parameters dynamically

During DSC preparation, add run time calculation to figure out what
usage modes, split mode and merge mode, is going to be setup.

Signed-off-by: Kuogee Hsieh <[email protected]>
---
drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 56 ++++++++++++++++-------------
1 file changed, 31 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
index 2fdacf1..3d18642 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
@@ -529,17 +529,9 @@ void dpu_encoder_helper_split_config(
bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
{
struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
- int i, intf_count = 0, num_dsc = 0;
+ struct msm_display_topology *topology = &dpu_enc->topology;

- for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
- if (dpu_enc->phys_encs[i])
- intf_count++;
-
- /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
- if (dpu_enc->dsc)
- num_dsc = 2;
-
- return (num_dsc > 0) && (num_dsc > intf_count);
+ return (topology->num_dsc > topology->num_intf);
}

static void dpu_encoder_get_topology(
@@ -1861,41 +1853,55 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
struct dpu_encoder_phys *enc_master = dpu_enc->cur_master;
struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
- int this_frame_slices;
+ struct msm_display_topology *topology = &dpu_enc->topology;
int intf_ip_w, enc_ip_w;
- int dsc_common_mode;
- int pic_width;
+ int dsc_common_mode = 0;
u32 initial_lines;
+ int num_dsc = topology->num_dsc;
+ int num_intf = topology->num_intf;
int i;

- for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
+ for (i = 0; i < num_dsc; i++) {
hw_pp[i] = dpu_enc->hw_pp[i];
hw_dsc[i] = dpu_enc->hw_dsc[i];

if (!hw_pp[i] || !hw_dsc[i]) {
DPU_ERROR_ENC(dpu_enc, "invalid params for DSC\n");
return;
- }
+ }
}

- dsc_common_mode = 0;
- pic_width = dsc->pic_width;
+ intf_ip_w = dsc->pic_width;

- dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL;
if (enc_master->intf_mode == INTF_MODE_VIDEO)
dsc_common_mode |= DSC_MODE_VIDEO;

- this_frame_slices = pic_width / dsc->slice_width;
- intf_ip_w = this_frame_slices * dsc->slice_width;
-
/*
- * dsc merge case: when using 2 encoders for the same stream,
- * no. of slices need to be same on both the encoders.
+ * If this encoder is driving more than one DSC encoder, they
+ * operate in tandem, same pic dimension needs to be used by
+ * each of them.(pp-split is assumed to be not supported)
+ *
*/
- enc_ip_w = intf_ip_w / 2;
+ enc_ip_w = intf_ip_w;
+
+ intf_ip_w /= num_intf;
+
+ if (num_dsc > 1)
+ dsc_common_mode |= DSC_MODE_SPLIT_PANEL;
+
+ if (dpu_encoder_use_dsc_merge(&dpu_enc->base)) {
+ dsc_common_mode |= DSC_MODE_MULTIPLEX;
+ /*
+ * in dsc merge case: when using 2 encoders for the same
+ * stream, no. of slices need to be same on both the
+ * encoders.
+ */
+ enc_ip_w = intf_ip_w / 2;
+ }
+
initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w);

- for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
+ for (i = 0; i < num_dsc; i++)
dpu_encoder_dsc_pipe_cfg(dpu_enc, hw_dsc[i], hw_pp[i], dsc,
dsc_common_mode, initial_lines);
}
--
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
a Linux Foundation Collaborative Project

2023-04-29 00:37:09

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 0/7] add DSC 1.2 dpu supports

On 29/04/2023 02:45, Kuogee Hsieh wrote:
> This series adds the DPU side changes to support DSC 1.2 encoder. This
> was validated with both DSI DSC 1.2 panel and DP DSC 1.2 monitor.
> The DSI and DP parts will be pushed later on top of this change.
> This seriel is rebase on [1], [2] and catalog fixes from [3].
>
> [1]: https://patchwork.freedesktop.org/series/116851/
> [2]: https://patchwork.freedesktop.org/series/116615/
> [3]: https://patchwork.freedesktop.org/series/112332/

Changelogs? There must be one, either in the cover letter or in the
patch commit messages (following the DRM subsystem custom).

--
With best wishes
Dmitry

2023-04-29 00:37:34

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 2/7] drm/msm/dpu: separate DSC flush update out of interface

On 29/04/2023 02:45, Kuogee Hsieh wrote:
> Current DSC flush update is piggyback inside dpu_hw_ctl_intf_cfg_v1().
> This patch separate DSC flush away from dpu_hw_ctl_intf_cfg_v1() by

Nit: separates

> adding dpu_hw_ctl_update_pending_flush_dsc_v1() to handle both per
> DSC engine and DSC flush bits at same time to make it consistent with
> the location of flush programming of other dpu sub blocks.
>
> Signed-off-by: Kuogee Hsieh <[email protected]>
> Reviewed-by: Dmitry Baryshkov <[email protected]>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 14 ++++++++++++--
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 22 ++++++++++++++++------
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 10 ++++++++++
> 3 files changed, 38 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 1dc5dbe..ecb87bc 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -1823,12 +1823,18 @@ dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config *dsc,
> return DIV_ROUND_UP(total_pixels, dsc->slice_width);
> }
>
> -static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,
> +static void dpu_encoder_dsc_pipe_cfg(struct dpu_encoder_virt *dpu_enc,
> + struct dpu_hw_dsc *hw_dsc,
> struct dpu_hw_pingpong *hw_pp,
> struct drm_dsc_config *dsc,
> u32 common_mode,
> u32 initial_lines)
> {
> + struct dpu_encoder_phys *cur_master = dpu_enc->cur_master;
> + struct dpu_hw_ctl *ctl;
> +
> + ctl = cur_master->hw_ctl;
> +
> if (hw_dsc->ops.dsc_config)
> hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, initial_lines);
>
> @@ -1843,6 +1849,9 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc,
>
> if (hw_pp->ops.enable_dsc)
> hw_pp->ops.enable_dsc(hw_pp);
> +
> + if (ctl->ops.update_pending_flush_dsc)
> + ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx);
> }
>
> static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
> @@ -1887,7 +1896,8 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
> initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
>
> for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
> - dpu_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], dsc, dsc_common_mode, initial_lines);
> + dpu_encoder_dsc_pipe_cfg(dpu_enc, hw_dsc[i], hw_pp[i], dsc,
> + dsc_common_mode, initial_lines);
> }
>
> void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc)
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> index 4f7cfa9..832a6a7 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c
> @@ -139,6 +139,11 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx)
> CTL_DSPP_n_FLUSH(dspp - DSPP_0),
> ctx->pending_dspp_flush_mask[dspp - DSPP_0]);
> }
> +
> + if (ctx->pending_flush_mask & BIT(DSC_IDX))
> + DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH,
> + ctx->pending_dsc_flush_mask);
> +
> DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask);
> }
>
> @@ -285,6 +290,13 @@ static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx,
> ctx->pending_flush_mask |= BIT(MERGE_3D_IDX);
> }
>
> +static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx,
> + enum dpu_dsc dsc_num)
> +{
> + ctx->pending_dsc_flush_mask |= BIT(dsc_num - DSC_0);
> + ctx->pending_flush_mask |= BIT(DSC_IDX);
> +}
> +
> static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx,
> enum dpu_dspp dspp, u32 dspp_sub_blk)
> {
> @@ -502,9 +514,6 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
> if ((test_bit(DPU_CTL_VM_CFG, &ctx->caps->features)))
> mode_sel = CTL_DEFAULT_GROUP_ID << 28;
>
> - if (cfg->dsc)
> - DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH, cfg->dsc);
> -
> if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD)
> mode_sel |= BIT(17);
>
> @@ -524,10 +533,8 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
> if (cfg->merge_3d)
> DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE,
> BIT(cfg->merge_3d - MERGE_3D_0));
> - if (cfg->dsc) {
> - DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, DSC_IDX);
> + if (cfg->dsc)
> DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc);
> - }
> }
>
> static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx,
> @@ -630,6 +637,9 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops,
> ops->update_pending_flush_merge_3d =
> dpu_hw_ctl_update_pending_flush_merge_3d_v1;
> ops->update_pending_flush_wb = dpu_hw_ctl_update_pending_flush_wb_v1;
> +
> + ops->update_pending_flush_dsc =
> + dpu_hw_ctl_update_pending_flush_dsc_v1;
> } else {
> ops->trigger_flush = dpu_hw_ctl_trigger_flush;
> ops->setup_intf_cfg = dpu_hw_ctl_intf_cfg;
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
> index 6292002..5762752 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h
> @@ -158,6 +158,15 @@ struct dpu_hw_ctl_ops {
> enum dpu_dspp blk, u32 dspp_sub_blk);
>
> /**
> + * OR in the given flushbits to the cached pending_(dsc_)flush_mask
> + * No effect on hardware
> + * @ctx : ctl path ctx pointer
> + * @blk : interface block index
> + */
> + void (*update_pending_flush_dsc)(struct dpu_hw_ctl *ctx,
> + enum dpu_dsc blk);
> +
> + /**
> * Write the value of the pending_flush_mask to hardware
> * @ctx : ctl path ctx pointer
> */
> @@ -245,6 +254,7 @@ struct dpu_hw_ctl {
> u32 pending_wb_flush_mask;
> u32 pending_merge_3d_flush_mask;
> u32 pending_dspp_flush_mask[DSPP_MAX - DSPP_0];
> + u32 pending_dsc_flush_mask;
>
> /* ops */
> struct dpu_hw_ctl_ops ops;

--
With best wishes
Dmitry

2023-04-29 00:38:10

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 1/7] drm/msm/dpu: add support for DSC encoder v1.2 engine

On 29/04/2023 02:45, Kuogee Hsieh wrote:
> Add support for DSC 1.2 by providing the necessary hooks to program
> the DPU DSC 1.2 encoder.
>
> Reported-by: kernel test robot <[email protected]>

What exactly was reported?

> Signed-off-by: Kuogee Hsieh <[email protected]>
> ---
> drivers/gpu/drm/msm/Makefile | 1 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 34 ++-
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 335 +++++++++++++++++++++++++
> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +-
> 5 files changed, 387 insertions(+), 4 deletions(-)
> create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>
> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
> index b814fc8..b9af5e4 100644
> --- a/drivers/gpu/drm/msm/Makefile
> +++ b/drivers/gpu/drm/msm/Makefile
> @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
> disp/dpu1/dpu_hw_catalog.o \
> disp/dpu1/dpu_hw_ctl.o \
> disp/dpu1/dpu_hw_dsc.o \
> + disp/dpu1/dpu_hw_dsc_1_2.o \
> disp/dpu1/dpu_hw_interrupts.o \
> disp/dpu1/dpu_hw_intf.o \
> disp/dpu1/dpu_hw_lm.o \
> 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 71584cd..fc87db1 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -1,6 +1,6 @@
> /* SPDX-License-Identifier: GPL-2.0-only */
> /*
> - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved.
> + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved.
> * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved.
> */
>
> @@ -241,12 +241,20 @@ enum {
> };
>
> /**
> - * DSC features
> + * DSC sub-blocks/features
> * @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets
> * the pixel output from this DSC.
> + * @DPU_DSC_HW_REV_1_1 DSC block supports dsc 1.1 only
> + * @DPU_DSC_HW_REV_1_2 DSC block supports dsc 1.1 and 1.2
> + * @DPU_DSC_NATIVE_422_EN Supports native422 and native420 encoding
> + * @DPU_DSC_MAX
> */
> enum {
> DPU_DSC_OUTPUT_CTRL = 0x1,
> + DPU_DSC_HW_REV_1_1,
> + DPU_DSC_HW_REV_1_2,
> + DPU_DSC_NATIVE_422_EN,
> + DPU_DSC_MAX
> };
>
> /**
> @@ -311,6 +319,14 @@ struct dpu_pp_blk {
> };
>
> /**
> + * struct dpu_dsc_blk - DSC Encoder sub-blk information
> + * @info: HW register and features supported by this sub-blk
> + */
> +struct dpu_dsc_blk {
> + DPU_HW_SUBBLK_INFO;
> +};
> +
> +/**
> * enum dpu_qos_lut_usage - define QoS LUT use cases
> */
> enum dpu_qos_lut_usage {
> @@ -459,6 +475,17 @@ struct dpu_pingpong_sub_blks {
> };
>
> /**
> + * struct dpu_dsc_sub_blks - DSC sub-blks
> + * @enc: DSC encoder sub block
> + * @ctl: DSC controller sub block
> + *
> + */
> +struct dpu_dsc_sub_blks {
> + struct dpu_dsc_blk enc;
> + struct dpu_dsc_blk ctl;
> +};
> +
> +/**
> * dpu_clk_ctrl_type - Defines top level clock control signals
> */
> enum dpu_clk_ctrl_type {
> @@ -612,10 +639,13 @@ struct dpu_merge_3d_cfg {
> * struct dpu_dsc_cfg - information of DSC blocks
> * @id enum identifying this block
> * @base register offset of this block
> + * @len: length of hardware block
> * @features bit mask identifying sub-blocks/features
> + * @sblk sub-blocks information
> */
> struct dpu_dsc_cfg {
> DPU_HW_BLK_INFO;
> + const struct dpu_dsc_sub_blks *sblk;
> };
>
> /**
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
> index 287ec5f..e11240a 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
> @@ -1,5 +1,8 @@
> /* SPDX-License-Identifier: GPL-2.0-only */
> -/* Copyright (c) 2020-2022, Linaro Limited */
> +/*
> + * Copyright (c) 2020-2022, Linaro Limited
> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved
> + */
>
> #ifndef _DPU_HW_DSC_H
> #define _DPU_HW_DSC_H
> @@ -70,6 +73,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg,
> void __iomem *addr);
>
> /**
> + * dpu_hw_dsc_init_1_2 - initializes the v1.2 DSC hw driver block
> + * @cfg: DSC catalog entry for which driver object is required
> + * @addr: Mapped register io address of MDP
> + * Returns: Error code or allocated dpu_hw_dsc context
> + */
> +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
> + void __iomem *addr);
> +
> +/**
> * dpu_hw_dsc_destroy - destroys dsc driver context
> * @dsc: Pointer to dsc driver context returned by dpu_hw_dsc_init
> */
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
> new file mode 100644
> index 00000000..a777c7b
> --- /dev/null
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
> @@ -0,0 +1,335 @@
> +// SPDX-License-Identifier: GPL-2.0-only
> +/*
> + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved
> + */
> +
> +#include <drm/display/drm_dsc_helper.h>
> +
> +#include "dpu_kms.h"
> +#include "dpu_hw_catalog.h"
> +#include "dpu_hwio.h"
> +#include "dpu_hw_mdss.h"
> +#include "dpu_hw_dsc.h"
> +
> +

Unused empty line

> +#define DSC_CMN_MAIN_CNF 0x00
> +
> +/* DPU_DSC_ENC register offsets */
> +#define ENC_DF_CTRL 0x00
> +#define ENC_GENERAL_STATUS 0x04
> +#define ENC_HSLICE_STATUS 0x08
> +#define ENC_OUT_STATUS 0x0C
> +#define ENC_INT_STAT 0x10
> +#define ENC_INT_CLR 0x14
> +#define ENC_INT_MASK 0x18
> +#define DSC_MAIN_CONF 0x30
> +#define DSC_PICTURE_SIZE 0x34
> +#define DSC_SLICE_SIZE 0x38
> +#define DSC_MISC_SIZE 0x3C
> +#define DSC_HRD_DELAYS 0x40
> +#define DSC_RC_SCALE 0x44
> +#define DSC_RC_SCALE_INC_DEC 0x48
> +#define DSC_RC_OFFSETS_1 0x4C
> +#define DSC_RC_OFFSETS_2 0x50
> +#define DSC_RC_OFFSETS_3 0x54
> +#define DSC_RC_OFFSETS_4 0x58
> +#define DSC_FLATNESS_QP 0x5C
> +#define DSC_RC_MODEL_SIZE 0x60
> +#define DSC_RC_CONFIG 0x64
> +#define DSC_RC_BUF_THRESH_0 0x68
> +#define DSC_RC_MIN_QP_0 0x78
> +#define DSC_RC_MAX_QP_0 0x84
> +#define DSC_RC_RANGE_BPG_OFFSETS_0 0x90
> +
> +/* DPU_DSC_CTL register offsets */
> +#define DSC_CTL 0x00
> +#define DSC_CFG 0x04
> +#define DSC_DATA_IN_SWAP 0x08
> +#define DSC_CLK_CTRL 0x0C
> +
> +static inline int _dsc_calc_ob_max_addr(struct dpu_hw_dsc *hw_dsc, int num_ss, bool native_422)
> +{
> + int max_addr = 2400 / num_ss;
> +
> + if ((hw_dsc->caps->features & BIT(DPU_DSC_NATIVE_422_EN)) && native_422)
> + max_addr /= 2;
> +
> + return max_addr - 1;
> +};
> +
> +static void dpu_hw_dsc_disable_1_2(struct dpu_hw_dsc *hw_dsc)
> +{
> + struct dpu_hw_blk_reg_map *hw;
> + u32 offset;
> +
> + if (!hw_dsc)
> + return;
> +
> + hw = &hw_dsc->hw;
> + offset = hw_dsc->caps->sblk->ctl.base;
> + DPU_REG_WRITE(hw, offset + DSC_CFG, 0);
> +
> + offset = hw_dsc->caps->sblk->enc.base;
> + DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, 0);
> + DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, 0);
> +}
> +
> +static void dpu_hw_dsc_config_1_2(struct dpu_hw_dsc *hw_dsc,
> + struct drm_dsc_config *dsc,
> + u32 mode,
> + u32 initial_lines)
> +{
> + struct dpu_hw_blk_reg_map *hw;
> + u32 offset;
> + u32 data = 0;
> + u32 det_thresh_flatness;
> + u32 num_active_ss_per_enc;
> + u32 bpp;
> +
> + if (!hw_dsc || !dsc)
> + return;
> +
> + hw = &hw_dsc->hw;
> +
> + offset = hw_dsc->caps->sblk->enc.base;
> +
> + if (mode & DSC_MODE_SPLIT_PANEL)
> + data |= BIT(0);
> +
> + if (mode & DSC_MODE_MULTIPLEX)
> + data |= BIT(1);
> +
> + num_active_ss_per_enc = dsc->slice_count;
> + if (mode & DSC_MODE_MULTIPLEX)
> + num_active_ss_per_enc = dsc->slice_count >> 1;
> +
> + data |= (num_active_ss_per_enc & 0x3) << 7;
> +
> + DPU_REG_WRITE(hw, DSC_CMN_MAIN_CNF, data);
> +
> + data = (initial_lines & 0xff);
> +
> + if (mode & DSC_MODE_VIDEO)
> + data |= BIT(9);
> +
> + data |= (_dsc_calc_ob_max_addr(hw_dsc, num_active_ss_per_enc, dsc->native_422) << 18);
> +
> + DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, data);
> +
> + data = (dsc->dsc_version_minor & 0xf) << 28;
> + if (dsc->dsc_version_minor == 0x2) {
> + if (dsc->native_422)
> + data |= BIT(22);
> + if (dsc->native_420)
> + data |= BIT(21);
> + }
> +
> + bpp = dsc->bits_per_pixel;
> + /* as per hw requirement bpp should be programmed
> + * twice the actual value in case of 420 or 422 encoding
> + */
> + if (dsc->native_422 || dsc->native_420)
> + bpp = 2 * bpp;
> + data |= (dsc->block_pred_enable ? 1 : 0) << 20;
> + data |= bpp << 10;
> + data |= (dsc->line_buf_depth & 0xf) << 6;
> + data |= dsc->convert_rgb << 4;
> + data |= dsc->bits_per_component & 0xf;
> +
> + DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, data);
> +
> + data = (dsc->pic_width & 0xffff) |
> + ((dsc->pic_height & 0xffff) << 16);
> +
> + DPU_REG_WRITE(hw, offset + DSC_PICTURE_SIZE, data);
> +
> + data = (dsc->slice_width & 0xffff) |
> + ((dsc->slice_height & 0xffff) << 16);
> +
> + DPU_REG_WRITE(hw, offset + DSC_SLICE_SIZE, data);
> +
> + DPU_REG_WRITE(hw, offset + DSC_MISC_SIZE,
> + (dsc->slice_chunk_size) & 0xffff);
> +
> + data = (dsc->initial_xmit_delay & 0xffff) |
> + ((dsc->initial_dec_delay & 0xffff) << 16);
> +
> + DPU_REG_WRITE(hw, offset + DSC_HRD_DELAYS, data);
> +
> + DPU_REG_WRITE(hw, offset + DSC_RC_SCALE,
> + dsc->initial_scale_value & 0x3f);
> +
> + data = (dsc->scale_increment_interval & 0xffff) |
> + ((dsc->scale_decrement_interval & 0x7ff) << 16);
> +
> + DPU_REG_WRITE(hw, offset + DSC_RC_SCALE_INC_DEC, data);
> +
> + data = (dsc->first_line_bpg_offset & 0x1f) |
> + ((dsc->second_line_bpg_offset & 0x1f) << 5);
> +
> + DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_1, data);
> +
> + data = (dsc->nfl_bpg_offset & 0xffff) |
> + ((dsc->slice_bpg_offset & 0xffff) << 16);
> +
> + DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_2, data);
> +
> + data = (dsc->initial_offset & 0xffff) |
> + ((dsc->final_offset & 0xffff) << 16);
> +
> + DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_3, data);
> +
> + data = (dsc->nsl_bpg_offset & 0xffff) |
> + ((dsc->second_line_offset_adj & 0xffff) << 16);
> +
> + DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_4, data);
> +
> + data = (dsc->flatness_min_qp & 0x1f);
> + data |= (dsc->flatness_max_qp & 0x1f) << 5;
> +
> + det_thresh_flatness = drm_dsc_calculate_flatness_det_thresh(dsc);
> + data |= (det_thresh_flatness & 0xff) << 10;
> +
> + DPU_REG_WRITE(hw, offset + DSC_FLATNESS_QP, data);
> +
> + DPU_REG_WRITE(hw, offset + DSC_RC_MODEL_SIZE,
> + (dsc->rc_model_size) & 0xffff);
> +
> + data = dsc->rc_edge_factor & 0xf;
> + data |= (dsc->rc_quant_incr_limit0 & 0x1f) << 8;
> + data |= (dsc->rc_quant_incr_limit1 & 0x1f) << 13;
> + data |= (dsc->rc_tgt_offset_high & 0xf) << 20;
> + data |= (dsc->rc_tgt_offset_low & 0xf) << 24;
> +
> + DPU_REG_WRITE(hw, offset + DSC_RC_CONFIG, data);
> +
> + /* program the dsc wrapper */
> + offset = hw_dsc->caps->sblk->ctl.base;
> +
> + data = BIT(0); /* encoder enable */
> + if (dsc->native_422)
> + data |= BIT(8);
> + else if (dsc->native_420)
> + data |= BIT(9);
> + if (!dsc->convert_rgb)
> + data |= BIT(10);
> + if (dsc->bits_per_component == 8)
> + data |= BIT(11);
> + if (mode & DSC_MODE_SPLIT_PANEL)
> + data |= BIT(12);
> + if (mode & DSC_MODE_MULTIPLEX)
> + data |= BIT(13);
> + if (!(mode & DSC_MODE_VIDEO))
> + data |= BIT(17);
> +
> + DPU_REG_WRITE(hw, offset + DSC_CFG, data);
> +}
> +
> +static void dpu_hw_dsc_config_thresh_1_2(struct dpu_hw_dsc *hw_dsc,
> + struct drm_dsc_config *dsc)
> +{
> + struct dpu_hw_blk_reg_map *hw;
> + u32 offset, off;
> + int i, j = 0;
> + struct drm_dsc_rc_range_parameters *rc;
> + u32 data = 0, min_qp = 0, max_qp = 0, bpg_off = 0;
> +
> + if (!hw_dsc || !dsc)
> + return;
> +
> + offset = hw_dsc->caps->sblk->enc.base;
> +
> + hw = &hw_dsc->hw;
> +
> + rc = dsc->rc_range_params;
> +
> + /*
> + * With BUF_THRESH -- 14 in total
> + * each register contains 4 thresh values with the last register
> + * containing only 2 thresh values
> + */
> + off = 0;
> + for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) {
> + data |= dsc->rc_buf_thresh[i] << (8 * j);
> + j++;
> + if ((j == 4) || (i == DSC_NUM_BUF_RANGES - 2)) {
> + DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0 + off, data);
> + off += 4;
> + j = 0;
> + data = 0;
> + }
> + }

This is barely understandable code. The following line is much better:

DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0,
(dsc->rc_buf_thresh[0] << 0) |
(dsc->rc_buf_thresh[1] << 8) |
(dsc->rc_buf_thresh[2] << 16) |
(dsc->rc_buf_thresh[3] << 24));

etc.

Please unroll both loops.

> +
> +
> + /*
> + * with min/max_QP -- 5 bits each
> + * each register contains 5 min_qp or max_qp for total of 15
> + *
> + * With BPG_OFFSET -- 6 bits each
> + * each register contains 5 BPG_offset for total of 15
> + */
> + off = 0;
> + for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
> + min_qp |= rc[i].range_min_qp << (5 * j);
> + max_qp |= rc[i].range_max_qp << (5 * j);
> + bpg_off |= rc[i].range_bpg_offset << (6 * j);
> + j++;
> + if (j == 5) {
> + DPU_REG_WRITE(hw, offset + DSC_RC_MIN_QP_0 + off, min_qp);
> + DPU_REG_WRITE(hw, offset + DSC_RC_MAX_QP_0 + off, max_qp);
> + DPU_REG_WRITE(hw, offset + DSC_RC_RANGE_BPG_OFFSETS_0 + off, bpg_off);
> + off += 4;
> + j = 0;
> + min_qp = 0;
> + max_qp = 0;
> + bpg_off = 0;
> + }
> + }
> +}
> +
> +static void dpu_hw_dsc_bind_pingpong_blk_1_2(
> + struct dpu_hw_dsc *hw_dsc,
> + bool enable,
> + const enum dpu_pingpong pp)
> +{
> + struct dpu_hw_blk_reg_map *hw;
> + int offset;
> + int mux_cfg = 0xf; /* Disabled */
> +
> + offset = hw_dsc->caps->sblk->ctl.base;
> +
> + hw = &hw_dsc->hw;
> + if (enable)
> + mux_cfg = (pp - PINGPONG_0) & 0x7;
> +
> + DPU_REG_WRITE(hw, offset + DSC_CTL, mux_cfg);
> +}

Please refactor the existing bind_pingpong_blk() semantics to accept
either a valid PINGPONG_n, or PINGPONG_NONE to disable the binding.

> +
> +static void _setup_dcs_ops_1_2(struct dpu_hw_dsc_ops *ops,
> + const unsigned long features)
> +{
> + ops->dsc_disable = dpu_hw_dsc_disable_1_2;
> + ops->dsc_config = dpu_hw_dsc_config_1_2;
> + ops->dsc_config_thresh = dpu_hw_dsc_config_thresh_1_2;
> + ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2;
> +}

Please inline the function.

> +
> +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
> + void __iomem *addr)
> +{
> + struct dpu_hw_dsc *c;
> +
> + c = kzalloc(sizeof(*c), GFP_KERNEL);
> + if (!c)
> + return ERR_PTR(-ENOMEM);
> +
> + c->hw.blk_addr = addr + cfg->base;
> + c->hw.log_mask = DPU_DBG_MASK_DSC;
> +
> + c->idx = cfg->id;
> + c->caps = cfg;
> + _setup_dcs_ops_1_2(&c->ops, c->caps->features);
> +
> + return c;
> +}
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> index 3452f88..b2f618f6 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
> @@ -1,6 +1,7 @@
> // SPDX-License-Identifier: GPL-2.0-only
> /*
> * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
> */
>
> #define pr_fmt(fmt) "[drm:%s] " fmt, __func__
> @@ -250,7 +251,11 @@ int dpu_rm_init(struct dpu_rm *rm,
> struct dpu_hw_dsc *hw;
> const struct dpu_dsc_cfg *dsc = &cat->dsc[i];
>
> - hw = dpu_hw_dsc_init(dsc, mmio);
> + if (test_bit(DPU_DSC_HW_REV_1_2, &dsc->features))
> + hw = dpu_hw_dsc_init_1_2(dsc, mmio);
> + else
> + hw = dpu_hw_dsc_init(dsc, mmio);
> +
> if (IS_ERR_OR_NULL(hw)) {
> rc = PTR_ERR(hw);
> DPU_ERROR("failed dsc object creation: err %d\n", rc);

--
With best wishes
Dmitry

2023-04-29 00:59:54

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 7/7] drm/msm/dpu: calculate DSC encoder parameters dynamically

On 29/04/2023 02:45, Kuogee Hsieh wrote:
> During DSC preparation, add run time calculation to figure out what
> usage modes, split mode and merge mode, is going to be setup.

This patch doesn't determine the mode. It changes programming of DSC
bits according to the mode being selected.

>
> Signed-off-by: Kuogee Hsieh <[email protected]>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 56 ++++++++++++++++-------------
> 1 file changed, 31 insertions(+), 25 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index 2fdacf1..3d18642 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -529,17 +529,9 @@ void dpu_encoder_helper_split_config(
> bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
> {
> struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
> - int i, intf_count = 0, num_dsc = 0;
> + struct msm_display_topology *topology = &dpu_enc->topology;
>
> - for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
> - if (dpu_enc->phys_encs[i])
> - intf_count++;
> -
> - /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
> - if (dpu_enc->dsc)
> - num_dsc = 2;
> -
> - return (num_dsc > 0) && (num_dsc > intf_count);
> + return (topology->num_dsc > topology->num_intf);
> }
>
> static void dpu_encoder_get_topology(
> @@ -1861,41 +1853,55 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc,
> struct dpu_encoder_phys *enc_master = dpu_enc->cur_master;
> struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
> struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
> - int this_frame_slices;
> + struct msm_display_topology *topology = &dpu_enc->topology;
> int intf_ip_w, enc_ip_w;
> - int dsc_common_mode;
> - int pic_width;
> + int dsc_common_mode = 0;

Please don't top-init variables unless required (or unless they are
constant).

> u32 initial_lines;
> + int num_dsc = topology->num_dsc;
> + int num_intf = topology->num_intf;
> int i;
>
> - for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
> + for (i = 0; i < num_dsc; i++) {
> hw_pp[i] = dpu_enc->hw_pp[i];
> hw_dsc[i] = dpu_enc->hw_dsc[i];
>
> if (!hw_pp[i] || !hw_dsc[i]) {
> DPU_ERROR_ENC(dpu_enc, "invalid params for DSC\n");
> return;
> - }
> + }

What is the difference here?

> }
>
> - dsc_common_mode = 0;
> - pic_width = dsc->pic_width;
> + intf_ip_w = dsc->pic_width;
>
> - dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL;
> if (enc_master->intf_mode == INTF_MODE_VIDEO)
> dsc_common_mode |= DSC_MODE_VIDEO;
>
> - this_frame_slices = pic_width / dsc->slice_width;
> - intf_ip_w = this_frame_slices * dsc->slice_width;
> -
> /*
> - * dsc merge case: when using 2 encoders for the same stream,
> - * no. of slices need to be same on both the encoders.
> + * If this encoder is driving more than one DSC encoder, they
> + * operate in tandem, same pic dimension needs to be used by
> + * each of them.(pp-split is assumed to be not supported)
> + *

Extra empty line. Also the comment doesn't make sense here anymore. We
already have comment for the division by two below.

> */
> - enc_ip_w = intf_ip_w / 2;
> + enc_ip_w = intf_ip_w;
> +
> + intf_ip_w /= num_intf;
> +
> + if (num_dsc > 1)
> + dsc_common_mode |= DSC_MODE_SPLIT_PANEL;
> +
> + if (dpu_encoder_use_dsc_merge(&dpu_enc->base)) {
> + dsc_common_mode |= DSC_MODE_MULTIPLEX;
> + /*
> + * in dsc merge case: when using 2 encoders for the same
> + * stream, no. of slices need to be same on both the
> + * encoders.
> + */
> + enc_ip_w = intf_ip_w / 2;
> + }
> +
> initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
>
> - for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
> + for (i = 0; i < num_dsc; i++)
> dpu_encoder_dsc_pipe_cfg(dpu_enc, hw_dsc[i], hw_pp[i], dsc,
> dsc_common_mode, initial_lines);
> }

--
With best wishes
Dmitry

2023-04-29 01:01:06

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 5/7] drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE

On 29/04/2023 02:45, Kuogee Hsieh wrote:
> Legacy DPU requires PP hardware block involved into setting up DSC

Nit: to be envolved

> data path. This patch add DDPU_PINGPONG_DSC feature bit to both

adds

> PP_BLK and PP_BLK_TE so that both dpu_hw_pp_setup_dsc() and
> dpu_hw_pp_dsc_enable() will be executed during DSC path setup.

Would it be easier to add PP_BLK_NO_DSC instead and make DSC enabled by
default for PP_BLK / PP_BLK_TE?

>
> Reported-by : Marijn Suijten <[email protected]>
> Signed-off-by: Kuogee Hsieh <[email protected]>
> ---
> .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 12 +++++-----
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 +++----
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26 ++++++++++------------
> .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 24 ++++++++++----------
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26 ++++++++++------------
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 ++--
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +-
> .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 8 +++----
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 +++++---
> 11 files changed, 62 insertions(+), 61 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> index 17f821c..b7cd746 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> @@ -112,16 +112,16 @@ static const struct dpu_lm_cfg msm8998_lm[] = {
> };
>
> static const struct dpu_pingpong_cfg msm8998_pp[] = {
> - PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> + PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC), 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,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> + PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC), 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, 0, 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, 0, 0, sdm845_pp_sblk,
> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
> };
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
> index ceca741..8888bd9 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
> @@ -110,16 +110,16 @@ static const struct dpu_lm_cfg sdm845_lm[] = {
> };
>
> 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, BIT(DPU_PINGPONG_DSC), 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, BIT(DPU_PINGPONG_DSC), 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, BIT(DPU_PINGPONG_DSC), 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, BIT(DPU_PINGPONG_DSC), 0, sdm845_pp_sblk,
> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
> };
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> index 42b0e58..3a7dffa 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> @@ -128,24 +128,22 @@ static const struct dpu_dspp_cfg sm8150_dspp[] = {
> };
>
> static const struct dpu_pingpong_cfg sm8150_pp[] = {
> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> + sdm845_pp_sblk, 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,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000, BIT(DPU_PINGPONG_DSC), 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,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800, BIT(DPU_PINGPONG_DSC), 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,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
> - -1),
> - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> - -1),
> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000, BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800, BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
> };
>
> static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> index 5bb9882..e766a2d 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> @@ -116,23 +116,23 @@ static const struct dpu_lm_cfg sc8180x_lm[] = {
> };
>
> static const struct dpu_pingpong_cfg sc8180x_pp[] = {
> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> + sdm845_pp_sblk, 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,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000, BIT(DPU_PINGPONG_DSC), 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,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800, BIT(DPU_PINGPONG_DSC), 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,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000, BIT(DPU_PINGPONG_DSC), 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,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800, BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> -1),
> };
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
> index ed130582..137b151 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
> @@ -129,24 +129,22 @@ static const struct dpu_dspp_cfg sm8250_dspp[] = {
> };
>
> static const struct dpu_pingpong_cfg sm8250_pp[] = {
> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0, sdm845_pp_sblk,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0, sdm845_pp_sblk,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> + sdm845_pp_sblk, 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,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000, BIT(DPU_PINGPONG_DSC), 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,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800, BIT(DPU_PINGPONG_DSC), 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,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
> - -1),
> - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2, sdm845_pp_sblk,
> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> - -1),
> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000, BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800, BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
> };
>
> static const struct dpu_merge_3d_cfg sm8250_merge_3d[] = {
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
> index a46b117..e5631a2 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
> @@ -80,8 +80,8 @@ static const struct dpu_dspp_cfg sc7180_dspp[] = {
> };
>
> static const struct dpu_pingpong_cfg sc7180_pp[] = {
> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk, -1, -1),
> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk, -1, -1),
> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 0, sdm845_pp_sblk, -1, -1),
> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, 0, sdm845_pp_sblk, -1, -1),
> };
>
> static const struct dpu_intf_cfg sc7180_intf[] = {
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
> index 988d820..7b4ad0f 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
> @@ -60,7 +60,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[] = {
> };
>
> static const struct dpu_pingpong_cfg sm6115_pp[] = {
> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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/catalog/dpu_6_5_qcm2290.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
> index c9003dc..20d4d14 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
> @@ -57,7 +57,7 @@ static const struct dpu_dspp_cfg qcm2290_dspp[] = {
> };
>
> static const struct dpu_pingpong_cfg qcm2290_pp[] = {
> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> index 91bfc8a..83c0cd9 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> @@ -501,21 +501,21 @@ static const struct dpu_pingpong_sub_blks sc7280_pp_sblk = {
> .intr_done = _done, \
> .intr_rdptr = _rdptr, \
> }
> -#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 = PINGPONG_SDM845_SPLIT_MASK | _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 = PINGPONG_SDM845_MASK | _features, \
> .merge_3d = _merge_3d, \
> .sblk = &_sblk, \
> .intr_done = _done, \
> 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 fc87db1..6b49171 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> @@ -144,6 +144,7 @@ enum {
> * @DPU_PINGPONG_SPLIT PP block supports split fifo
> * @DPU_PINGPONG_SLAVE PP block is a suitable slave for split fifo
> * @DPU_PINGPONG_DITHER, Dither blocks
> + * @DPU_PINGPONG_DSC, PP block binding to DSC
> * @DPU_PINGPONG_MAX
> */
> enum {
> @@ -152,6 +153,7 @@ enum {
> DPU_PINGPONG_SPLIT,
> DPU_PINGPONG_SLAVE,
> DPU_PINGPONG_DITHER,
> + DPU_PINGPONG_DSC,
> DPU_PINGPONG_MAX
> };
>
> 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 3822e06..f255a04 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
> @@ -264,9 +264,12 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong *c,
> 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;
> +
> + if (features & BIT(DPU_PINGPONG_DSC)) {
> + 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;
> + }
>
> if (test_bit(DPU_PINGPONG_DITHER, &features))
> c->ops.setup_dither = dpu_hw_pp_setup_dither;

--
With best wishes
Dmitry

2023-04-29 01:05:00

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 6/7] drm/msm/dpu: save dpu topology configuration

On 29/04/2023 02:45, Kuogee Hsieh wrote:
> At current implementation, topology configuration is thrown away after
> dpu_rm_reserve(). This patch save the topology so that it can be used
> for DSC related calculation later.

Even if we delay the virtual wide planes patchset, please don't save the
topology in the encoder. If we get cloned encoders support (e.g. for
CWB), the end topology will contain both WB and INTF entries and as such
it will not be useable by a single encoder. Thus this change is not
future-proof.

>
> Signed-off-by: Kuogee Hsieh <[email protected]>
> ---
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 32 ++++++++++++++---------------
> 1 file changed, 16 insertions(+), 16 deletions(-)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> index ecb87bc..2fdacf1 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
> @@ -542,13 +542,13 @@ bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
> return (num_dsc > 0) && (num_dsc > intf_count);
> }
>
> -static struct msm_display_topology dpu_encoder_get_topology(
> +static void dpu_encoder_get_topology(
> struct dpu_encoder_virt *dpu_enc,
> struct dpu_kms *dpu_kms,
> struct drm_display_mode *mode,
> - struct drm_crtc_state *crtc_state)
> + struct drm_crtc_state *crtc_state,
> + struct msm_display_topology *topology)
> {
> - struct msm_display_topology topology = {0};
> int i, intf_count = 0;
>
> for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
> @@ -567,16 +567,16 @@ static struct msm_display_topology dpu_encoder_get_topology(
> * Add dspps to the reservation requirements if ctm is requested
> */
> if (intf_count == 2)
> - topology.num_lm = 2;
> + topology->num_lm = 2;
> else if (!dpu_kms->catalog->caps->has_3d_merge)
> - topology.num_lm = 1;
> + topology->num_lm = 1;
> else
> - topology.num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
> + topology->num_lm = (mode->hdisplay > MAX_HDISPLAY_SPLIT) ? 2 : 1;
>
> if (crtc_state->ctm)
> - topology.num_dspp = topology.num_lm;
> + topology->num_dspp = topology->num_lm;
>
> - topology.num_intf = intf_count;
> + topology->num_intf = intf_count;
>
> if (dpu_enc->dsc) {
> /*
> @@ -585,12 +585,10 @@ static struct msm_display_topology dpu_encoder_get_topology(
> * this is power optimal and can drive up to (including) 4k
> * screens
> */
> - topology.num_dsc = 2;
> - topology.num_lm = 2;
> - topology.num_intf = 1;
> + topology->num_dsc = 2;
> + topology->num_lm = 2;
> + topology->num_intf = 1;
> }
> -
> - return topology;
> }
>
> static int dpu_encoder_virt_atomic_check(
> @@ -602,7 +600,7 @@ static int dpu_encoder_virt_atomic_check(
> struct msm_drm_private *priv;
> struct dpu_kms *dpu_kms;
> struct drm_display_mode *adj_mode;
> - struct msm_display_topology topology;
> + struct msm_display_topology *topology;
> struct dpu_global_state *global_state;
> int i = 0;
> int ret = 0;
> @@ -639,7 +637,9 @@ static int dpu_encoder_virt_atomic_check(
> }
> }
>
> - topology = dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state);
> + topology = &dpu_enc->topology;
> + memset(topology, 0, sizeof (*topology));
> + dpu_encoder_get_topology(dpu_enc, dpu_kms, adj_mode, crtc_state, topology);
>
> /*
> * Release and Allocate resources on every modeset
> @@ -650,7 +650,7 @@ static int dpu_encoder_virt_atomic_check(
>
> if (!crtc_state->active_changed || crtc_state->enable)
> ret = dpu_rm_reserve(&dpu_kms->rm, global_state,
> - drm_enc, crtc_state, topology);
> + drm_enc, crtc_state, *topology);
> }
>
> trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags);

--
With best wishes
Dmitry

2023-04-29 01:05:00

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 4/7] drm/msm/dpu: add dsc blocks for remaining chipsets in catalog

On 29/04/2023 02:45, Kuogee Hsieh wrote:
> From: Abhinav Kumar <[email protected]>
>
> In preparation of calling ping-pong DSC related functions only
> for chipsets which have such a design add the dsc blocks for the
> chipsets for which DSC is present but was not added in the catalog.

Why/how is it prearing us for such calling?

The change itself LGTM.

>
> Signed-off-by: Abhinav Kumar <[email protected]>
> ---
> drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 7 +++++++
> drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 11 +++++++++++
> 2 files changed, 18 insertions(+)
>
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> index 2b3ae84..17f821c 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> @@ -126,6 +126,11 @@ static const struct dpu_pingpong_cfg msm8998_pp[] = {
> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
> };
>
> +static const struct dpu_dsc_cfg msm8998_dsc[] = {
> + DSC_BLK("dsc_0", DSC_0, 0x80000, 0),
> + DSC_BLK("dsc_1", DSC_1, 0x80400, 0),
> +};
> +
> static const struct dpu_dspp_cfg msm8998_dspp[] = {
> DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_MSM8998_MASK,
> &msm8998_dspp_sblk),
> @@ -191,6 +196,8 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = {
> .dspp = msm8998_dspp,
> .pingpong_count = ARRAY_SIZE(msm8998_pp),
> .pingpong = msm8998_pp,
> + .dsc_count = ARRAY_SIZE(msm8998_dsc),
> + .dsc = msm8998_dsc,
> .intf_count = ARRAY_SIZE(msm8998_intf),
> .intf = msm8998_intf,
> .vbif_count = ARRAY_SIZE(msm8998_vbif),
> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> index e3bdfe7..5bb9882 100644
> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> @@ -142,6 +142,15 @@ static const struct dpu_merge_3d_cfg sc8180x_merge_3d[] = {
> MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x83200),
> };
>
> +static const struct dpu_dsc_cfg sc8180x_dsc[] = {
> + DSC_BLK("dsc_0", DSC_0, 0x80000, BIT(DPU_DSC_OUTPUT_CTRL)),
> + DSC_BLK("dsc_1", DSC_1, 0x80400, BIT(DPU_DSC_OUTPUT_CTRL)),
> + DSC_BLK("dsc_2", DSC_2, 0x80800, BIT(DPU_DSC_OUTPUT_CTRL)),
> + DSC_BLK("dsc_3", DSC_3, 0x80c00, BIT(DPU_DSC_OUTPUT_CTRL)),
> + DSC_BLK("dsc_4", DSC_4, 0x81000, BIT(DPU_DSC_OUTPUT_CTRL)),
> + DSC_BLK("dsc_5", DSC_5, 0x81400, BIT(DPU_DSC_OUTPUT_CTRL)),
> +};
> +
> static const struct dpu_intf_cfg sc8180x_intf[] = {
> INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
> INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
> @@ -192,6 +201,8 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = {
> .mixer = sc8180x_lm,
> .pingpong_count = ARRAY_SIZE(sc8180x_pp),
> .pingpong = sc8180x_pp,
> + .dsc_count = ARRAY_SIZE(sc8180x_dsc),
> + .dsc = sc8180x_dsc,
> .merge_3d_count = ARRAY_SIZE(sc8180x_merge_3d),
> .merge_3d = sc8180x_merge_3d,
> .intf_count = ARRAY_SIZE(sc8180x_intf),

--
With best wishes
Dmitry

2023-04-29 01:20:52

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [PATCH v2 5/7] drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE



On 4/28/2023 5:45 PM, Dmitry Baryshkov wrote:
> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>> Legacy DPU requires PP hardware block involved into setting up DSC
>
> Nit: to be envolved
>
>> data path. This patch add DDPU_PINGPONG_DSC feature bit to both
>
> adds
>
>> PP_BLK and PP_BLK_TE so that both dpu_hw_pp_setup_dsc() and
>> dpu_hw_pp_dsc_enable() will be executed during DSC path setup.
>
> Would it be easier to add PP_BLK_NO_DSC instead and make DSC enabled by
> default for PP_BLK / PP_BLK_TE?
>

No because for some chipsets like qcm2290, it has a ping pong block but
no DSC.

>>
>> Reported-by : Marijn Suijten <[email protected]>
>> Signed-off-by: Kuogee Hsieh <[email protected]>
>> ---
>>   .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h    | 12 +++++-----
>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h |  8 +++----
>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26
>> ++++++++++------------
>>   .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h    | 24
>> ++++++++++----------
>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26
>> ++++++++++------------
>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h |  4 ++--
>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h |  2 +-
>>   .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h    |  2 +-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c     |  8 +++----
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h     |  2 ++
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c    |  9 +++++---
>>   11 files changed, 62 insertions(+), 61 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>> index 17f821c..b7cd746 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>> @@ -112,16 +112,16 @@ static const struct dpu_lm_cfg msm8998_lm[] = {
>>   };
>>   static const struct dpu_pingpong_cfg msm8998_pp[] = {
>> -    PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>> +    PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000,
>> BIT(DPU_PINGPONG_DSC), 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,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>> +    PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800,
>> BIT(DPU_PINGPONG_DSC), 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, 0, 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, 0, 0, sdm845_pp_sblk,
>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>   };
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>> index ceca741..8888bd9 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>> @@ -110,16 +110,16 @@ static const struct dpu_lm_cfg sdm845_lm[] = {
>>   };
>>   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,
>> BIT(DPU_PINGPONG_DSC), 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,
>> BIT(DPU_PINGPONG_DSC), 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, BIT(DPU_PINGPONG_DSC),
>> 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, BIT(DPU_PINGPONG_DSC),
>> 0, sdm845_pp_sblk,
>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>   };
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>> index 42b0e58..3a7dffa 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>> @@ -128,24 +128,22 @@ static const struct dpu_dspp_cfg sm8150_dspp[] = {
>>   };
>>   static const struct dpu_pingpong_cfg sm8150_pp[] = {
>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>> sdm845_pp_sblk,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC),
>> MERGE_3D_0,
>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>> sdm845_pp_sblk,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC),
>> MERGE_3D_0,
>> +            sdm845_pp_sblk, 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,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000, BIT(DPU_PINGPONG_DSC),
>> 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,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800, BIT(DPU_PINGPONG_DSC),
>> 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,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>> -            -1),
>> -    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>> sdm845_pp_sblk,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>> -            -1),
>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000, BIT(DPU_PINGPONG_DSC),
>> MERGE_3D_2,
>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, BIT(DPU_PINGPONG_DSC),
>> MERGE_3D_2,
>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
>>   };
>>   static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>> index 5bb9882..e766a2d 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>> @@ -116,23 +116,23 @@ static const struct dpu_lm_cfg sc8180x_lm[] = {
>>   };
>>   static const struct dpu_pingpong_cfg sc8180x_pp[] = {
>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>> sdm845_pp_sblk,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC),
>> MERGE_3D_0,
>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>> sdm845_pp_sblk,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC),
>> MERGE_3D_0,
>> +            sdm845_pp_sblk, 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,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000, BIT(DPU_PINGPONG_DSC),
>> 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,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800, BIT(DPU_PINGPONG_DSC),
>> 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,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000, BIT(DPU_PINGPONG_DSC),
>> 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,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, BIT(DPU_PINGPONG_DSC),
>> MERGE_3D_2,
>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>               -1),
>>   };
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>> index ed130582..137b151 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>> @@ -129,24 +129,22 @@ static const struct dpu_dspp_cfg sm8250_dspp[] = {
>>   };
>>   static const struct dpu_pingpong_cfg sm8250_pp[] = {
>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>> sdm845_pp_sblk,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC),
>> MERGE_3D_0,
>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>> sdm845_pp_sblk,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC),
>> MERGE_3D_0,
>> +            sdm845_pp_sblk, 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,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000, BIT(DPU_PINGPONG_DSC),
>> 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,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800, BIT(DPU_PINGPONG_DSC),
>> 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,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>> -            -1),
>> -    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>> sdm845_pp_sblk,
>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>> -            -1),
>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000, BIT(DPU_PINGPONG_DSC),
>> MERGE_3D_2,
>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, BIT(DPU_PINGPONG_DSC),
>> MERGE_3D_2,
>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
>>   };
>>   static const struct dpu_merge_3d_cfg sm8250_merge_3d[] = {
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>> index a46b117..e5631a2 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>> @@ -80,8 +80,8 @@ static const struct dpu_dspp_cfg sc7180_dspp[] = {
>>   };
>>   static const struct dpu_pingpong_cfg sc7180_pp[] = {
>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk, -1,
>> -1),
>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk, -1,
>> -1),
>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 0, sdm845_pp_sblk,
>> -1, -1),
>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, 0, sdm845_pp_sblk,
>> -1, -1),
>>   };
>>   static const struct dpu_intf_cfg sc7180_intf[] = {
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>> index 988d820..7b4ad0f 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>> @@ -60,7 +60,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[] = {
>>   };
>>   static const struct dpu_pingpong_cfg sm6115_pp[] = {
>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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/catalog/dpu_6_5_qcm2290.h
>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>> index c9003dc..20d4d14 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>> @@ -57,7 +57,7 @@ static const struct dpu_dspp_cfg qcm2290_dspp[] = {
>>   };
>>   static const struct dpu_pingpong_cfg qcm2290_pp[] = {
>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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_catalog.c
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>> index 91bfc8a..83c0cd9 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>> @@ -501,21 +501,21 @@ static const struct dpu_pingpong_sub_blks
>> sc7280_pp_sblk = {
>>       .intr_done = _done, \
>>       .intr_rdptr = _rdptr, \
>>       }
>> -#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 = PINGPONG_SDM845_SPLIT_MASK | _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 = PINGPONG_SDM845_MASK | _features, \
>>       .merge_3d = _merge_3d, \
>>       .sblk = &_sblk, \
>>       .intr_done = _done, \
>> 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 fc87db1..6b49171 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>> @@ -144,6 +144,7 @@ enum {
>>    * @DPU_PINGPONG_SPLIT      PP block supports split fifo
>>    * @DPU_PINGPONG_SLAVE      PP block is a suitable slave for split fifo
>>    * @DPU_PINGPONG_DITHER,    Dither blocks
>> + * @DPU_PINGPONG_DSC,        PP block binding to DSC
>>    * @DPU_PINGPONG_MAX
>>    */
>>   enum {
>> @@ -152,6 +153,7 @@ enum {
>>       DPU_PINGPONG_SPLIT,
>>       DPU_PINGPONG_SLAVE,
>>       DPU_PINGPONG_DITHER,
>> +    DPU_PINGPONG_DSC,
>>       DPU_PINGPONG_MAX
>>   };
>> 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 3822e06..f255a04 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>> @@ -264,9 +264,12 @@ static void _setup_pingpong_ops(struct
>> dpu_hw_pingpong *c,
>>       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;
>> +
>> +    if (features & BIT(DPU_PINGPONG_DSC)) {
>> +        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;
>> +    }
>>       if (test_bit(DPU_PINGPONG_DITHER, &features))
>>           c->ops.setup_dither = dpu_hw_pp_setup_dither;
>

2023-04-29 01:20:56

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 1/7] drm/msm/dpu: add support for DSC encoder v1.2 engine

On 29/04/2023 04:10, Abhinav Kumar wrote:
>
>
> On 4/28/2023 5:30 PM, Dmitry Baryshkov wrote:
>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>>> Add support for DSC 1.2 by providing the necessary hooks to program
>>> the DPU DSC 1.2 encoder.
>>>
>>> Reported-by: kernel test robot <[email protected]>
>>
>> What exactly was reported?
>
> https://patchwork.freedesktop.org/patch/533188/?series=116789&rev=1#comment_967016
>
> I think we should update the commit text with the change log to mention
> what was fixed and how.

Yes, that would be nice.

>
>>
>>> Signed-off-by: Kuogee Hsieh <[email protected]>
>>> ---
>>>   drivers/gpu/drm/msm/Makefile                   |   1 +
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  34 ++-
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h     |  14 +-
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 335
>>> +++++++++++++++++++++++++
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c         |   7 +-
>>>   5 files changed, 387 insertions(+), 4 deletions(-)
>>>   create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>>
>>> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
>>> index b814fc8..b9af5e4 100644
>>> --- a/drivers/gpu/drm/msm/Makefile
>>> +++ b/drivers/gpu/drm/msm/Makefile
>>> @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
>>>       disp/dpu1/dpu_hw_catalog.o \
>>>       disp/dpu1/dpu_hw_ctl.o \
>>>       disp/dpu1/dpu_hw_dsc.o \
>>> +    disp/dpu1/dpu_hw_dsc_1_2.o \
>>>       disp/dpu1/dpu_hw_interrupts.o \
>>>       disp/dpu1/dpu_hw_intf.o \
>>>       disp/dpu1/dpu_hw_lm.o \
>>> 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 71584cd..fc87db1 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>> @@ -1,6 +1,6 @@
>>>   /* SPDX-License-Identifier: GPL-2.0-only */
>>>   /*
>>> - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights
>>> reserved.
>>> + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All
>>> rights reserved.
>>>    * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights
>>> reserved.
>>>    */
>>> @@ -241,12 +241,20 @@ enum {
>>>   };
>>>   /**
>>> - * DSC features
>>> + * DSC sub-blocks/features
>>>    * @DPU_DSC_OUTPUT_CTRL       Configure which PINGPONG block gets
>>>    *                            the pixel output from this DSC.
>>> + * @DPU_DSC_HW_REV_1_1        DSC block supports dsc 1.1 only
>>> + * @DPU_DSC_HW_REV_1_2        DSC block supports dsc 1.1 and 1.2
>>> + * @DPU_DSC_NATIVE_422_EN     Supports native422 and native420 encoding
>>> + * @DPU_DSC_MAX
>>>    */
>>>   enum {
>>>       DPU_DSC_OUTPUT_CTRL = 0x1,
>>> +    DPU_DSC_HW_REV_1_1,
>>> +    DPU_DSC_HW_REV_1_2,
>>> +    DPU_DSC_NATIVE_422_EN,
>>> +    DPU_DSC_MAX
>>>   };
>>>   /**
>>> @@ -311,6 +319,14 @@ struct dpu_pp_blk {
>>>   };
>>>   /**
>>> + * struct dpu_dsc_blk - DSC Encoder sub-blk information
>>> + * @info:   HW register and features supported by this sub-blk
>>> + */
>>> +struct dpu_dsc_blk {
>>> +    DPU_HW_SUBBLK_INFO;
>>> +};
>>> +
>>> +/**
>>>    * enum dpu_qos_lut_usage - define QoS LUT use cases
>>>    */
>>>   enum dpu_qos_lut_usage {
>>> @@ -459,6 +475,17 @@ struct dpu_pingpong_sub_blks {
>>>   };
>>>   /**
>>> + * struct dpu_dsc_sub_blks - DSC sub-blks
>>> + * @enc: DSC encoder sub block
>>> + * @ctl: DSC controller sub block
>>> + *
>>> + */
>>> +struct dpu_dsc_sub_blks {
>>> +    struct dpu_dsc_blk enc;
>>> +    struct dpu_dsc_blk ctl;
>>> +};
>>> +
>>> +/**
>>>    * dpu_clk_ctrl_type - Defines top level clock control signals
>>>    */
>>>   enum dpu_clk_ctrl_type {
>>> @@ -612,10 +639,13 @@ struct dpu_merge_3d_cfg  {
>>>    * struct dpu_dsc_cfg - information of DSC blocks
>>>    * @id                 enum identifying this block
>>>    * @base               register offset of this block
>>> + * @len:               length of hardware block
>>>    * @features           bit mask identifying sub-blocks/features
>>> + * @sblk               sub-blocks information
>>>    */
>>>   struct dpu_dsc_cfg {
>>>       DPU_HW_BLK_INFO;
>>> +    const struct dpu_dsc_sub_blks *sblk;
>>>   };
>>>   /**
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>>> index 287ec5f..e11240a 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>>> @@ -1,5 +1,8 @@
>>>   /* SPDX-License-Identifier: GPL-2.0-only */
>>> -/* Copyright (c) 2020-2022, Linaro Limited */
>>> +/*
>>> + * Copyright (c) 2020-2022, Linaro Limited
>>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>>> reserved
>>> + */
>>>   #ifndef _DPU_HW_DSC_H
>>>   #define _DPU_HW_DSC_H
>>> @@ -70,6 +73,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct
>>> dpu_dsc_cfg *cfg,
>>>           void __iomem *addr);
>>>   /**
>>> + * dpu_hw_dsc_init_1_2 - initializes the v1.2 DSC hw driver block
>>> + * @cfg:  DSC catalog entry for which driver object is required
>>> + * @addr: Mapped register io address of MDP
>>> + * Returns: Error code or allocated dpu_hw_dsc context
>>> + */
>>> +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
>>> +        void __iomem *addr);
>>> +
>>> +/**
>>>    * dpu_hw_dsc_destroy - destroys dsc driver context
>>>    * @dsc:   Pointer to dsc driver context returned by dpu_hw_dsc_init
>>>    */
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>> new file mode 100644
>>> index 00000000..a777c7b
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>> @@ -0,0 +1,335 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +/*
>>> + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
>>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>>> reserved
>>> + */
>>> +
>>> +#include <drm/display/drm_dsc_helper.h>
>>> +
>>> +#include "dpu_kms.h"
>>> +#include "dpu_hw_catalog.h"
>>> +#include "dpu_hwio.h"
>>> +#include "dpu_hw_mdss.h"
>>> +#include "dpu_hw_dsc.h"
>>> +
>>> +
>>
>> Unused empty line
>>
>>> +#define DSC_CMN_MAIN_CNF           0x00
>>> +
>>> +/* DPU_DSC_ENC register offsets */
>>> +#define ENC_DF_CTRL                0x00
>>> +#define ENC_GENERAL_STATUS         0x04
>>> +#define ENC_HSLICE_STATUS          0x08
>>> +#define ENC_OUT_STATUS             0x0C
>>> +#define ENC_INT_STAT               0x10
>>> +#define ENC_INT_CLR                0x14
>>> +#define ENC_INT_MASK               0x18
>>> +#define DSC_MAIN_CONF              0x30
>>> +#define DSC_PICTURE_SIZE           0x34
>>> +#define DSC_SLICE_SIZE             0x38
>>> +#define DSC_MISC_SIZE              0x3C
>>> +#define DSC_HRD_DELAYS             0x40
>>> +#define DSC_RC_SCALE               0x44
>>> +#define DSC_RC_SCALE_INC_DEC       0x48
>>> +#define DSC_RC_OFFSETS_1           0x4C
>>> +#define DSC_RC_OFFSETS_2           0x50
>>> +#define DSC_RC_OFFSETS_3           0x54
>>> +#define DSC_RC_OFFSETS_4           0x58
>>> +#define DSC_FLATNESS_QP            0x5C
>>> +#define DSC_RC_MODEL_SIZE          0x60
>>> +#define DSC_RC_CONFIG              0x64
>>> +#define DSC_RC_BUF_THRESH_0        0x68
>>> +#define DSC_RC_MIN_QP_0            0x78
>>> +#define DSC_RC_MAX_QP_0            0x84
>>> +#define DSC_RC_RANGE_BPG_OFFSETS_0 0x90
>>> +
>>> +/* DPU_DSC_CTL register offsets */
>>> +#define DSC_CTL                    0x00
>>> +#define DSC_CFG                    0x04
>>> +#define DSC_DATA_IN_SWAP           0x08
>>> +#define DSC_CLK_CTRL               0x0C
>>> +
>>> +static inline int _dsc_calc_ob_max_addr(struct dpu_hw_dsc *hw_dsc,
>>> int num_ss, bool native_422)
>>> +{
>>> +    int max_addr = 2400 / num_ss;
>>> +
>>> +    if ((hw_dsc->caps->features & BIT(DPU_DSC_NATIVE_422_EN)) &&
>>> native_422)
>>> +        max_addr /= 2;
>>> +
>>> +    return max_addr - 1;
>>> +};
>>> +
>>> +static void dpu_hw_dsc_disable_1_2(struct dpu_hw_dsc *hw_dsc)
>>> +{
>>> +    struct dpu_hw_blk_reg_map *hw;
>>> +    u32 offset;
>>> +
>>> +    if (!hw_dsc)
>>> +        return;
>>> +
>>> +    hw = &hw_dsc->hw;
>>> +    offset = hw_dsc->caps->sblk->ctl.base;
>>> +    DPU_REG_WRITE(hw, offset + DSC_CFG, 0);
>>> +
>>> +    offset = hw_dsc->caps->sblk->enc.base;
>>> +    DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, 0);
>>> +    DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, 0);
>>> +}
>>> +
>>> +static void dpu_hw_dsc_config_1_2(struct dpu_hw_dsc *hw_dsc,
>>> +                  struct drm_dsc_config *dsc,
>>> +                  u32 mode,
>>> +                  u32 initial_lines)
>>> +{
>>> +    struct dpu_hw_blk_reg_map *hw;
>>> +    u32 offset;
>>> +    u32 data = 0;
>>> +    u32 det_thresh_flatness;
>>> +    u32 num_active_ss_per_enc;
>>> +    u32 bpp;
>>> +
>>> +    if (!hw_dsc || !dsc)
>>> +        return;
>>> +
>>> +    hw = &hw_dsc->hw;
>>> +
>>> +    offset = hw_dsc->caps->sblk->enc.base;
>>> +
>>> +    if (mode & DSC_MODE_SPLIT_PANEL)
>>> +        data |= BIT(0);
>>> +
>>> +    if (mode & DSC_MODE_MULTIPLEX)
>>> +        data |= BIT(1);
>>> +
>>> +    num_active_ss_per_enc = dsc->slice_count;
>>> +    if (mode & DSC_MODE_MULTIPLEX)
>>> +        num_active_ss_per_enc = dsc->slice_count >> 1;
>>> +
>>> +    data |= (num_active_ss_per_enc & 0x3) << 7;
>>> +
>>> +    DPU_REG_WRITE(hw, DSC_CMN_MAIN_CNF, data);
>>> +
>>> +    data = (initial_lines & 0xff);
>>> +
>>> +    if (mode & DSC_MODE_VIDEO)
>>> +        data |= BIT(9);
>>> +
>>> +    data |= (_dsc_calc_ob_max_addr(hw_dsc, num_active_ss_per_enc,
>>> dsc->native_422) << 18);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, data);
>>> +
>>> +    data = (dsc->dsc_version_minor & 0xf) << 28;
>>> +    if (dsc->dsc_version_minor == 0x2) {
>>> +        if (dsc->native_422)
>>> +            data |= BIT(22);
>>> +        if (dsc->native_420)
>>> +            data |= BIT(21);
>>> +    }
>>> +
>>> +    bpp = dsc->bits_per_pixel;
>>> +    /* as per hw requirement bpp should be programmed
>>> +     * twice the actual value in case of 420 or 422 encoding
>>> +     */
>>> +    if (dsc->native_422 || dsc->native_420)
>>> +        bpp = 2 * bpp;
>>> +    data |= (dsc->block_pred_enable ? 1 : 0) << 20;
>>> +    data |= bpp << 10;
>>> +    data |= (dsc->line_buf_depth & 0xf) << 6;
>>> +    data |= dsc->convert_rgb << 4;
>>> +    data |= dsc->bits_per_component & 0xf;
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, data);
>>> +
>>> +    data = (dsc->pic_width & 0xffff) |
>>> +        ((dsc->pic_height & 0xffff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_PICTURE_SIZE, data);
>>> +
>>> +    data = (dsc->slice_width & 0xffff) |
>>> +        ((dsc->slice_height & 0xffff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_SLICE_SIZE, data);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_MISC_SIZE,
>>> +            (dsc->slice_chunk_size) & 0xffff);
>>> +
>>> +    data = (dsc->initial_xmit_delay & 0xffff) |
>>> +        ((dsc->initial_dec_delay & 0xffff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_HRD_DELAYS, data);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_SCALE,
>>> +            dsc->initial_scale_value & 0x3f);
>>> +
>>> +    data = (dsc->scale_increment_interval & 0xffff) |
>>> +        ((dsc->scale_decrement_interval & 0x7ff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_SCALE_INC_DEC, data);
>>> +
>>> +    data = (dsc->first_line_bpg_offset & 0x1f) |
>>> +        ((dsc->second_line_bpg_offset & 0x1f) << 5);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_1, data);
>>> +
>>> +    data = (dsc->nfl_bpg_offset & 0xffff) |
>>> +        ((dsc->slice_bpg_offset & 0xffff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_2, data);
>>> +
>>> +    data = (dsc->initial_offset & 0xffff) |
>>> +        ((dsc->final_offset & 0xffff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_3, data);
>>> +
>>> +    data = (dsc->nsl_bpg_offset & 0xffff) |
>>> +        ((dsc->second_line_offset_adj & 0xffff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_4, data);
>>> +
>>> +    data = (dsc->flatness_min_qp & 0x1f);
>>> +    data |= (dsc->flatness_max_qp & 0x1f) << 5;
>>> +
>>> +    det_thresh_flatness = drm_dsc_calculate_flatness_det_thresh(dsc);
>>> +    data |= (det_thresh_flatness & 0xff) << 10;
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_FLATNESS_QP, data);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_MODEL_SIZE,
>>> +            (dsc->rc_model_size) & 0xffff);
>>> +
>>> +    data = dsc->rc_edge_factor & 0xf;
>>> +    data |= (dsc->rc_quant_incr_limit0 & 0x1f) << 8;
>>> +    data |= (dsc->rc_quant_incr_limit1 & 0x1f) << 13;
>>> +    data |= (dsc->rc_tgt_offset_high & 0xf) << 20;
>>> +    data |= (dsc->rc_tgt_offset_low & 0xf) << 24;
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_CONFIG, data);
>>> +
>>> +    /* program the dsc wrapper */
>>> +    offset = hw_dsc->caps->sblk->ctl.base;
>>> +
>>> +    data = BIT(0); /* encoder enable */
>>> +    if (dsc->native_422)
>>> +        data |= BIT(8);
>>> +    else if (dsc->native_420)
>>> +        data |= BIT(9);
>>> +    if (!dsc->convert_rgb)
>>> +        data |= BIT(10);
>>> +    if (dsc->bits_per_component == 8)
>>> +        data |= BIT(11);
>>> +    if (mode & DSC_MODE_SPLIT_PANEL)
>>> +        data |= BIT(12);
>>> +    if (mode & DSC_MODE_MULTIPLEX)
>>> +        data |= BIT(13);
>>> +    if (!(mode & DSC_MODE_VIDEO))
>>> +        data |= BIT(17);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_CFG, data);
>>> +}
>>> +
>>> +static void dpu_hw_dsc_config_thresh_1_2(struct dpu_hw_dsc *hw_dsc,
>>> +                    struct drm_dsc_config *dsc)
>>> +{
>>> +    struct dpu_hw_blk_reg_map *hw;
>>> +    u32 offset, off;
>>> +    int i, j = 0;
>>> +    struct drm_dsc_rc_range_parameters *rc;
>>> +    u32 data = 0, min_qp = 0, max_qp = 0, bpg_off = 0;
>>> +
>>> +    if (!hw_dsc || !dsc)
>>> +        return;
>>> +
>>> +    offset = hw_dsc->caps->sblk->enc.base;
>>> +
>>> +    hw = &hw_dsc->hw;
>>> +
>>> +    rc = dsc->rc_range_params;
>>> +
>>> +    /*
>>> +     * With BUF_THRESH -- 14 in total
>>> +     * each register contains 4 thresh values with the last register
>>> +     * containing only 2 thresh values
>>> +     */
>>> +    off = 0;
>>> +    for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) {
>>> +        data |= dsc->rc_buf_thresh[i] << (8 * j);
>>> +        j++;
>>> +        if ((j == 4) || (i == DSC_NUM_BUF_RANGES - 2)) {
>>> +            DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0 + off,
>>> data);
>>> +            off += 4;
>>> +            j = 0;
>>> +            data = 0;
>>> +        }
>>> +    }
>>
>> This is barely understandable code. The following line is much better:
>>
>> DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0,
>>      (dsc->rc_buf_thresh[0] << 0) |
>>      (dsc->rc_buf_thresh[1] << 8) |
>>      (dsc->rc_buf_thresh[2] << 16) |
>>      (dsc->rc_buf_thresh[3] << 24));
>>
>> etc.
>>
>> Please unroll both loops.
>>
>>> +
>>> +
>>> +    /*
>>> +     * with min/max_QP -- 5 bits each
>>> +     * each register contains 5 min_qp or max_qp for total of 15
>>> +     *
>>> +     * With BPG_OFFSET -- 6 bits each
>>> +     * each register contains 5 BPG_offset for total of 15
>>> +     */
>>> +    off = 0;
>>> +    for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
>>> +        min_qp |= rc[i].range_min_qp << (5 * j);
>>> +        max_qp |= rc[i].range_max_qp << (5 * j);
>>> +        bpg_off |= rc[i].range_bpg_offset << (6 * j);
>>> +        j++;
>>> +        if (j == 5) {
>>> +            DPU_REG_WRITE(hw, offset + DSC_RC_MIN_QP_0 + off, min_qp);
>>> +            DPU_REG_WRITE(hw, offset + DSC_RC_MAX_QP_0 + off, max_qp);
>>> +            DPU_REG_WRITE(hw, offset + DSC_RC_RANGE_BPG_OFFSETS_0 +
>>> off, bpg_off);
>>> +            off += 4;
>>> +            j = 0;
>>> +            min_qp = 0;
>>> +            max_qp = 0;
>>> +            bpg_off = 0;
>>> +        }
>>> +    }
>>> +}
>>> +
>>> +static void dpu_hw_dsc_bind_pingpong_blk_1_2(
>>> +        struct dpu_hw_dsc *hw_dsc,
>>> +        bool enable,
>>> +        const enum dpu_pingpong pp)
>>> +{
>>> +    struct dpu_hw_blk_reg_map *hw;
>>> +    int offset;
>>> +    int mux_cfg = 0xf; /* Disabled */
>>> +
>>> +    offset = hw_dsc->caps->sblk->ctl.base;
>>> +
>>> +    hw = &hw_dsc->hw;
>>> +    if (enable)
>>> +        mux_cfg = (pp - PINGPONG_0) & 0x7;
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_CTL, mux_cfg);
>>> +}
>>
>> Please refactor the existing bind_pingpong_blk() semantics to accept
>> either a valid PINGPONG_n, or PINGPONG_NONE to disable the binding.
>>
>>> +
>>> +static void _setup_dcs_ops_1_2(struct dpu_hw_dsc_ops *ops,
>>> +        const unsigned long features)
>>> +{
>>> +    ops->dsc_disable = dpu_hw_dsc_disable_1_2;
>>> +    ops->dsc_config = dpu_hw_dsc_config_1_2;
>>> +    ops->dsc_config_thresh = dpu_hw_dsc_config_thresh_1_2;
>>> +    ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2;
>>> +}
>>
>> Please inline the function.
>>
>>> +
>>> +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
>>> +                   void __iomem *addr)
>>> +{
>>> +    struct dpu_hw_dsc *c;
>>> +
>>> +    c = kzalloc(sizeof(*c), GFP_KERNEL);
>>> +    if (!c)
>>> +        return ERR_PTR(-ENOMEM);
>>> +
>>> +    c->hw.blk_addr = addr + cfg->base;
>>> +    c->hw.log_mask = DPU_DBG_MASK_DSC;
>>> +
>>> +    c->idx = cfg->id;
>>> +    c->caps = cfg;
>>> +    _setup_dcs_ops_1_2(&c->ops, c->caps->features);
>>> +
>>> +    return c;
>>> +}
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>>> index 3452f88..b2f618f6 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>>> @@ -1,6 +1,7 @@
>>>   // SPDX-License-Identifier: GPL-2.0-only
>>>   /*
>>>    * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
>>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>>> reserved.
>>>    */
>>>   #define pr_fmt(fmt)    "[drm:%s] " fmt, __func__
>>> @@ -250,7 +251,11 @@ int dpu_rm_init(struct dpu_rm *rm,
>>>           struct dpu_hw_dsc *hw;
>>>           const struct dpu_dsc_cfg *dsc = &cat->dsc[i];
>>> -        hw = dpu_hw_dsc_init(dsc, mmio);
>>> +        if (test_bit(DPU_DSC_HW_REV_1_2, &dsc->features))
>>> +            hw = dpu_hw_dsc_init_1_2(dsc, mmio);
>>> +        else
>>> +            hw = dpu_hw_dsc_init(dsc, mmio);
>>> +
>>>           if (IS_ERR_OR_NULL(hw)) {
>>>               rc = PTR_ERR(hw);
>>>               DPU_ERROR("failed dsc object creation: err %d\n", rc);
>>

--
With best wishes
Dmitry

2023-04-29 01:23:53

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [PATCH v2 1/7] drm/msm/dpu: add support for DSC encoder v1.2 engine



On 4/28/2023 5:30 PM, Dmitry Baryshkov wrote:
> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>> Add support for DSC 1.2 by providing the necessary hooks to program
>> the DPU DSC 1.2 encoder.
>>
>> Reported-by: kernel test robot <[email protected]>
>
> What exactly was reported?

https://patchwork.freedesktop.org/patch/533188/?series=116789&rev=1#comment_967016

I think we should update the commit text with the change log to mention
what was fixed and how.

>
>> Signed-off-by: Kuogee Hsieh <[email protected]>
>> ---
>>   drivers/gpu/drm/msm/Makefile                   |   1 +
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  34 ++-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h     |  14 +-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 335
>> +++++++++++++++++++++++++
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c         |   7 +-
>>   5 files changed, 387 insertions(+), 4 deletions(-)
>>   create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>
>> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
>> index b814fc8..b9af5e4 100644
>> --- a/drivers/gpu/drm/msm/Makefile
>> +++ b/drivers/gpu/drm/msm/Makefile
>> @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
>>       disp/dpu1/dpu_hw_catalog.o \
>>       disp/dpu1/dpu_hw_ctl.o \
>>       disp/dpu1/dpu_hw_dsc.o \
>> +    disp/dpu1/dpu_hw_dsc_1_2.o \
>>       disp/dpu1/dpu_hw_interrupts.o \
>>       disp/dpu1/dpu_hw_intf.o \
>>       disp/dpu1/dpu_hw_lm.o \
>> 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 71584cd..fc87db1 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>> @@ -1,6 +1,6 @@
>>   /* SPDX-License-Identifier: GPL-2.0-only */
>>   /*
>> - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights
>> reserved.
>> + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All
>> rights reserved.
>>    * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights
>> reserved.
>>    */
>> @@ -241,12 +241,20 @@ enum {
>>   };
>>   /**
>> - * DSC features
>> + * DSC sub-blocks/features
>>    * @DPU_DSC_OUTPUT_CTRL       Configure which PINGPONG block gets
>>    *                            the pixel output from this DSC.
>> + * @DPU_DSC_HW_REV_1_1        DSC block supports dsc 1.1 only
>> + * @DPU_DSC_HW_REV_1_2        DSC block supports dsc 1.1 and 1.2
>> + * @DPU_DSC_NATIVE_422_EN     Supports native422 and native420 encoding
>> + * @DPU_DSC_MAX
>>    */
>>   enum {
>>       DPU_DSC_OUTPUT_CTRL = 0x1,
>> +    DPU_DSC_HW_REV_1_1,
>> +    DPU_DSC_HW_REV_1_2,
>> +    DPU_DSC_NATIVE_422_EN,
>> +    DPU_DSC_MAX
>>   };
>>   /**
>> @@ -311,6 +319,14 @@ struct dpu_pp_blk {
>>   };
>>   /**
>> + * struct dpu_dsc_blk - DSC Encoder sub-blk information
>> + * @info:   HW register and features supported by this sub-blk
>> + */
>> +struct dpu_dsc_blk {
>> +    DPU_HW_SUBBLK_INFO;
>> +};
>> +
>> +/**
>>    * enum dpu_qos_lut_usage - define QoS LUT use cases
>>    */
>>   enum dpu_qos_lut_usage {
>> @@ -459,6 +475,17 @@ struct dpu_pingpong_sub_blks {
>>   };
>>   /**
>> + * struct dpu_dsc_sub_blks - DSC sub-blks
>> + * @enc: DSC encoder sub block
>> + * @ctl: DSC controller sub block
>> + *
>> + */
>> +struct dpu_dsc_sub_blks {
>> +    struct dpu_dsc_blk enc;
>> +    struct dpu_dsc_blk ctl;
>> +};
>> +
>> +/**
>>    * dpu_clk_ctrl_type - Defines top level clock control signals
>>    */
>>   enum dpu_clk_ctrl_type {
>> @@ -612,10 +639,13 @@ struct dpu_merge_3d_cfg  {
>>    * struct dpu_dsc_cfg - information of DSC blocks
>>    * @id                 enum identifying this block
>>    * @base               register offset of this block
>> + * @len:               length of hardware block
>>    * @features           bit mask identifying sub-blocks/features
>> + * @sblk               sub-blocks information
>>    */
>>   struct dpu_dsc_cfg {
>>       DPU_HW_BLK_INFO;
>> +    const struct dpu_dsc_sub_blks *sblk;
>>   };
>>   /**
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>> index 287ec5f..e11240a 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>> @@ -1,5 +1,8 @@
>>   /* SPDX-License-Identifier: GPL-2.0-only */
>> -/* Copyright (c) 2020-2022, Linaro Limited */
>> +/*
>> + * Copyright (c) 2020-2022, Linaro Limited
>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>> reserved
>> + */
>>   #ifndef _DPU_HW_DSC_H
>>   #define _DPU_HW_DSC_H
>> @@ -70,6 +73,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct
>> dpu_dsc_cfg *cfg,
>>           void __iomem *addr);
>>   /**
>> + * dpu_hw_dsc_init_1_2 - initializes the v1.2 DSC hw driver block
>> + * @cfg:  DSC catalog entry for which driver object is required
>> + * @addr: Mapped register io address of MDP
>> + * Returns: Error code or allocated dpu_hw_dsc context
>> + */
>> +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
>> +        void __iomem *addr);
>> +
>> +/**
>>    * dpu_hw_dsc_destroy - destroys dsc driver context
>>    * @dsc:   Pointer to dsc driver context returned by dpu_hw_dsc_init
>>    */
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>> new file mode 100644
>> index 00000000..a777c7b
>> --- /dev/null
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>> @@ -0,0 +1,335 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>> reserved
>> + */
>> +
>> +#include <drm/display/drm_dsc_helper.h>
>> +
>> +#include "dpu_kms.h"
>> +#include "dpu_hw_catalog.h"
>> +#include "dpu_hwio.h"
>> +#include "dpu_hw_mdss.h"
>> +#include "dpu_hw_dsc.h"
>> +
>> +
>
> Unused empty line
>
>> +#define DSC_CMN_MAIN_CNF           0x00
>> +
>> +/* DPU_DSC_ENC register offsets */
>> +#define ENC_DF_CTRL                0x00
>> +#define ENC_GENERAL_STATUS         0x04
>> +#define ENC_HSLICE_STATUS          0x08
>> +#define ENC_OUT_STATUS             0x0C
>> +#define ENC_INT_STAT               0x10
>> +#define ENC_INT_CLR                0x14
>> +#define ENC_INT_MASK               0x18
>> +#define DSC_MAIN_CONF              0x30
>> +#define DSC_PICTURE_SIZE           0x34
>> +#define DSC_SLICE_SIZE             0x38
>> +#define DSC_MISC_SIZE              0x3C
>> +#define DSC_HRD_DELAYS             0x40
>> +#define DSC_RC_SCALE               0x44
>> +#define DSC_RC_SCALE_INC_DEC       0x48
>> +#define DSC_RC_OFFSETS_1           0x4C
>> +#define DSC_RC_OFFSETS_2           0x50
>> +#define DSC_RC_OFFSETS_3           0x54
>> +#define DSC_RC_OFFSETS_4           0x58
>> +#define DSC_FLATNESS_QP            0x5C
>> +#define DSC_RC_MODEL_SIZE          0x60
>> +#define DSC_RC_CONFIG              0x64
>> +#define DSC_RC_BUF_THRESH_0        0x68
>> +#define DSC_RC_MIN_QP_0            0x78
>> +#define DSC_RC_MAX_QP_0            0x84
>> +#define DSC_RC_RANGE_BPG_OFFSETS_0 0x90
>> +
>> +/* DPU_DSC_CTL register offsets */
>> +#define DSC_CTL                    0x00
>> +#define DSC_CFG                    0x04
>> +#define DSC_DATA_IN_SWAP           0x08
>> +#define DSC_CLK_CTRL               0x0C
>> +
>> +static inline int _dsc_calc_ob_max_addr(struct dpu_hw_dsc *hw_dsc,
>> int num_ss, bool native_422)
>> +{
>> +    int max_addr = 2400 / num_ss;
>> +
>> +    if ((hw_dsc->caps->features & BIT(DPU_DSC_NATIVE_422_EN)) &&
>> native_422)
>> +        max_addr /= 2;
>> +
>> +    return max_addr - 1;
>> +};
>> +
>> +static void dpu_hw_dsc_disable_1_2(struct dpu_hw_dsc *hw_dsc)
>> +{
>> +    struct dpu_hw_blk_reg_map *hw;
>> +    u32 offset;
>> +
>> +    if (!hw_dsc)
>> +        return;
>> +
>> +    hw = &hw_dsc->hw;
>> +    offset = hw_dsc->caps->sblk->ctl.base;
>> +    DPU_REG_WRITE(hw, offset + DSC_CFG, 0);
>> +
>> +    offset = hw_dsc->caps->sblk->enc.base;
>> +    DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, 0);
>> +    DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, 0);
>> +}
>> +
>> +static void dpu_hw_dsc_config_1_2(struct dpu_hw_dsc *hw_dsc,
>> +                  struct drm_dsc_config *dsc,
>> +                  u32 mode,
>> +                  u32 initial_lines)
>> +{
>> +    struct dpu_hw_blk_reg_map *hw;
>> +    u32 offset;
>> +    u32 data = 0;
>> +    u32 det_thresh_flatness;
>> +    u32 num_active_ss_per_enc;
>> +    u32 bpp;
>> +
>> +    if (!hw_dsc || !dsc)
>> +        return;
>> +
>> +    hw = &hw_dsc->hw;
>> +
>> +    offset = hw_dsc->caps->sblk->enc.base;
>> +
>> +    if (mode & DSC_MODE_SPLIT_PANEL)
>> +        data |= BIT(0);
>> +
>> +    if (mode & DSC_MODE_MULTIPLEX)
>> +        data |= BIT(1);
>> +
>> +    num_active_ss_per_enc = dsc->slice_count;
>> +    if (mode & DSC_MODE_MULTIPLEX)
>> +        num_active_ss_per_enc = dsc->slice_count >> 1;
>> +
>> +    data |= (num_active_ss_per_enc & 0x3) << 7;
>> +
>> +    DPU_REG_WRITE(hw, DSC_CMN_MAIN_CNF, data);
>> +
>> +    data = (initial_lines & 0xff);
>> +
>> +    if (mode & DSC_MODE_VIDEO)
>> +        data |= BIT(9);
>> +
>> +    data |= (_dsc_calc_ob_max_addr(hw_dsc, num_active_ss_per_enc,
>> dsc->native_422) << 18);
>> +
>> +    DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, data);
>> +
>> +    data = (dsc->dsc_version_minor & 0xf) << 28;
>> +    if (dsc->dsc_version_minor == 0x2) {
>> +        if (dsc->native_422)
>> +            data |= BIT(22);
>> +        if (dsc->native_420)
>> +            data |= BIT(21);
>> +    }
>> +
>> +    bpp = dsc->bits_per_pixel;
>> +    /* as per hw requirement bpp should be programmed
>> +     * twice the actual value in case of 420 or 422 encoding
>> +     */
>> +    if (dsc->native_422 || dsc->native_420)
>> +        bpp = 2 * bpp;
>> +    data |= (dsc->block_pred_enable ? 1 : 0) << 20;
>> +    data |= bpp << 10;
>> +    data |= (dsc->line_buf_depth & 0xf) << 6;
>> +    data |= dsc->convert_rgb << 4;
>> +    data |= dsc->bits_per_component & 0xf;
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, data);
>> +
>> +    data = (dsc->pic_width & 0xffff) |
>> +        ((dsc->pic_height & 0xffff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_PICTURE_SIZE, data);
>> +
>> +    data = (dsc->slice_width & 0xffff) |
>> +        ((dsc->slice_height & 0xffff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_SLICE_SIZE, data);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_MISC_SIZE,
>> +            (dsc->slice_chunk_size) & 0xffff);
>> +
>> +    data = (dsc->initial_xmit_delay & 0xffff) |
>> +        ((dsc->initial_dec_delay & 0xffff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_HRD_DELAYS, data);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_SCALE,
>> +            dsc->initial_scale_value & 0x3f);
>> +
>> +    data = (dsc->scale_increment_interval & 0xffff) |
>> +        ((dsc->scale_decrement_interval & 0x7ff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_SCALE_INC_DEC, data);
>> +
>> +    data = (dsc->first_line_bpg_offset & 0x1f) |
>> +        ((dsc->second_line_bpg_offset & 0x1f) << 5);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_1, data);
>> +
>> +    data = (dsc->nfl_bpg_offset & 0xffff) |
>> +        ((dsc->slice_bpg_offset & 0xffff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_2, data);
>> +
>> +    data = (dsc->initial_offset & 0xffff) |
>> +        ((dsc->final_offset & 0xffff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_3, data);
>> +
>> +    data = (dsc->nsl_bpg_offset & 0xffff) |
>> +        ((dsc->second_line_offset_adj & 0xffff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_4, data);
>> +
>> +    data = (dsc->flatness_min_qp & 0x1f);
>> +    data |= (dsc->flatness_max_qp & 0x1f) << 5;
>> +
>> +    det_thresh_flatness = drm_dsc_calculate_flatness_det_thresh(dsc);
>> +    data |= (det_thresh_flatness & 0xff) << 10;
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_FLATNESS_QP, data);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_MODEL_SIZE,
>> +            (dsc->rc_model_size) & 0xffff);
>> +
>> +    data = dsc->rc_edge_factor & 0xf;
>> +    data |= (dsc->rc_quant_incr_limit0 & 0x1f) << 8;
>> +    data |= (dsc->rc_quant_incr_limit1 & 0x1f) << 13;
>> +    data |= (dsc->rc_tgt_offset_high & 0xf) << 20;
>> +    data |= (dsc->rc_tgt_offset_low & 0xf) << 24;
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_CONFIG, data);
>> +
>> +    /* program the dsc wrapper */
>> +    offset = hw_dsc->caps->sblk->ctl.base;
>> +
>> +    data = BIT(0); /* encoder enable */
>> +    if (dsc->native_422)
>> +        data |= BIT(8);
>> +    else if (dsc->native_420)
>> +        data |= BIT(9);
>> +    if (!dsc->convert_rgb)
>> +        data |= BIT(10);
>> +    if (dsc->bits_per_component == 8)
>> +        data |= BIT(11);
>> +    if (mode & DSC_MODE_SPLIT_PANEL)
>> +        data |= BIT(12);
>> +    if (mode & DSC_MODE_MULTIPLEX)
>> +        data |= BIT(13);
>> +    if (!(mode & DSC_MODE_VIDEO))
>> +        data |= BIT(17);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_CFG, data);
>> +}
>> +
>> +static void dpu_hw_dsc_config_thresh_1_2(struct dpu_hw_dsc *hw_dsc,
>> +                    struct drm_dsc_config *dsc)
>> +{
>> +    struct dpu_hw_blk_reg_map *hw;
>> +    u32 offset, off;
>> +    int i, j = 0;
>> +    struct drm_dsc_rc_range_parameters *rc;
>> +    u32 data = 0, min_qp = 0, max_qp = 0, bpg_off = 0;
>> +
>> +    if (!hw_dsc || !dsc)
>> +        return;
>> +
>> +    offset = hw_dsc->caps->sblk->enc.base;
>> +
>> +    hw = &hw_dsc->hw;
>> +
>> +    rc = dsc->rc_range_params;
>> +
>> +    /*
>> +     * With BUF_THRESH -- 14 in total
>> +     * each register contains 4 thresh values with the last register
>> +     * containing only 2 thresh values
>> +     */
>> +    off = 0;
>> +    for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) {
>> +        data |= dsc->rc_buf_thresh[i] << (8 * j);
>> +        j++;
>> +        if ((j == 4) || (i == DSC_NUM_BUF_RANGES - 2)) {
>> +            DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0 + off, data);
>> +            off += 4;
>> +            j = 0;
>> +            data = 0;
>> +        }
>> +    }
>
> This is barely understandable code. The following line is much better:
>
> DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0,
>     (dsc->rc_buf_thresh[0] << 0) |
>     (dsc->rc_buf_thresh[1] << 8) |
>     (dsc->rc_buf_thresh[2] << 16) |
>     (dsc->rc_buf_thresh[3] << 24));
>
> etc.
>
> Please unroll both loops.
>
>> +
>> +
>> +    /*
>> +     * with min/max_QP -- 5 bits each
>> +     * each register contains 5 min_qp or max_qp for total of 15
>> +     *
>> +     * With BPG_OFFSET -- 6 bits each
>> +     * each register contains 5 BPG_offset for total of 15
>> +     */
>> +    off = 0;
>> +    for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
>> +        min_qp |= rc[i].range_min_qp << (5 * j);
>> +        max_qp |= rc[i].range_max_qp << (5 * j);
>> +        bpg_off |= rc[i].range_bpg_offset << (6 * j);
>> +        j++;
>> +        if (j == 5) {
>> +            DPU_REG_WRITE(hw, offset + DSC_RC_MIN_QP_0 + off, min_qp);
>> +            DPU_REG_WRITE(hw, offset + DSC_RC_MAX_QP_0 + off, max_qp);
>> +            DPU_REG_WRITE(hw, offset + DSC_RC_RANGE_BPG_OFFSETS_0 +
>> off, bpg_off);
>> +            off += 4;
>> +            j = 0;
>> +            min_qp = 0;
>> +            max_qp = 0;
>> +            bpg_off = 0;
>> +        }
>> +    }
>> +}
>> +
>> +static void dpu_hw_dsc_bind_pingpong_blk_1_2(
>> +        struct dpu_hw_dsc *hw_dsc,
>> +        bool enable,
>> +        const enum dpu_pingpong pp)
>> +{
>> +    struct dpu_hw_blk_reg_map *hw;
>> +    int offset;
>> +    int mux_cfg = 0xf; /* Disabled */
>> +
>> +    offset = hw_dsc->caps->sblk->ctl.base;
>> +
>> +    hw = &hw_dsc->hw;
>> +    if (enable)
>> +        mux_cfg = (pp - PINGPONG_0) & 0x7;
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_CTL, mux_cfg);
>> +}
>
> Please refactor the existing bind_pingpong_blk() semantics to accept
> either a valid PINGPONG_n, or PINGPONG_NONE to disable the binding.
>
>> +
>> +static void _setup_dcs_ops_1_2(struct dpu_hw_dsc_ops *ops,
>> +        const unsigned long features)
>> +{
>> +    ops->dsc_disable = dpu_hw_dsc_disable_1_2;
>> +    ops->dsc_config = dpu_hw_dsc_config_1_2;
>> +    ops->dsc_config_thresh = dpu_hw_dsc_config_thresh_1_2;
>> +    ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2;
>> +}
>
> Please inline the function.
>
>> +
>> +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
>> +                   void __iomem *addr)
>> +{
>> +    struct dpu_hw_dsc *c;
>> +
>> +    c = kzalloc(sizeof(*c), GFP_KERNEL);
>> +    if (!c)
>> +        return ERR_PTR(-ENOMEM);
>> +
>> +    c->hw.blk_addr = addr + cfg->base;
>> +    c->hw.log_mask = DPU_DBG_MASK_DSC;
>> +
>> +    c->idx = cfg->id;
>> +    c->caps = cfg;
>> +    _setup_dcs_ops_1_2(&c->ops, c->caps->features);
>> +
>> +    return c;
>> +}
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>> index 3452f88..b2f618f6 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>> @@ -1,6 +1,7 @@
>>   // SPDX-License-Identifier: GPL-2.0-only
>>   /*
>>    * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>> reserved.
>>    */
>>   #define pr_fmt(fmt)    "[drm:%s] " fmt, __func__
>> @@ -250,7 +251,11 @@ int dpu_rm_init(struct dpu_rm *rm,
>>           struct dpu_hw_dsc *hw;
>>           const struct dpu_dsc_cfg *dsc = &cat->dsc[i];
>> -        hw = dpu_hw_dsc_init(dsc, mmio);
>> +        if (test_bit(DPU_DSC_HW_REV_1_2, &dsc->features))
>> +            hw = dpu_hw_dsc_init_1_2(dsc, mmio);
>> +        else
>> +            hw = dpu_hw_dsc_init(dsc, mmio);
>> +
>>           if (IS_ERR_OR_NULL(hw)) {
>>               rc = PTR_ERR(hw);
>>               DPU_ERROR("failed dsc object creation: err %d\n", rc);
>

2023-04-29 01:26:16

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [Freedreno] [PATCH v2 4/7] drm/msm/dpu: add dsc blocks for remaining chipsets in catalog



On 4/28/2023 5:35 PM, Dmitry Baryshkov wrote:
> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>> From: Abhinav Kumar <[email protected]>
>>
>> In preparation of calling ping-pong DSC related functions only
>> for chipsets which have such a design add the dsc blocks for the
>> chipsets for which DSC is present but was not added in the catalog.
>
> Why/how is it prearing us for such calling?
>
> The change itself LGTM.

The next change adds DPU_PINGPONG_DSC feature flag to chipsets where it
is supported. But when I checked there were many chipsets where DSC is
present but were not added in catalog.

Without doing that, the next change was originally adding 0 to the
feature flags of those chipsets which didnt seem right to me.

This seemed like the right way to do it to first add the DSC blocks for
those chipsets and add the feature flag to them in the next change.

>
>>
>> Signed-off-by: Abhinav Kumar <[email protected]>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h |  7 +++++++
>>   drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 11
>> +++++++++++
>>   2 files changed, 18 insertions(+)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>> index 2b3ae84..17f821c 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>> @@ -126,6 +126,11 @@ static const struct dpu_pingpong_cfg msm8998_pp[]
>> = {
>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>   };
>> +static const struct dpu_dsc_cfg msm8998_dsc[] = {
>> +    DSC_BLK("dsc_0", DSC_0, 0x80000, 0),
>> +    DSC_BLK("dsc_1", DSC_1, 0x80400, 0),
>> +};
>> +
>>   static const struct dpu_dspp_cfg msm8998_dspp[] = {
>>       DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_MSM8998_MASK,
>>            &msm8998_dspp_sblk),
>> @@ -191,6 +196,8 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = {
>>       .dspp = msm8998_dspp,
>>       .pingpong_count = ARRAY_SIZE(msm8998_pp),
>>       .pingpong = msm8998_pp,
>> +    .dsc_count = ARRAY_SIZE(msm8998_dsc),
>> +    .dsc = msm8998_dsc,
>>       .intf_count = ARRAY_SIZE(msm8998_intf),
>>       .intf = msm8998_intf,
>>       .vbif_count = ARRAY_SIZE(msm8998_vbif),
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>> index e3bdfe7..5bb9882 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>> @@ -142,6 +142,15 @@ static const struct dpu_merge_3d_cfg
>> sc8180x_merge_3d[] = {
>>       MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x83200),
>>   };
>> +static const struct dpu_dsc_cfg sc8180x_dsc[] = {
>> +    DSC_BLK("dsc_0", DSC_0, 0x80000, BIT(DPU_DSC_OUTPUT_CTRL)),
>> +    DSC_BLK("dsc_1", DSC_1, 0x80400, BIT(DPU_DSC_OUTPUT_CTRL)),
>> +    DSC_BLK("dsc_2", DSC_2, 0x80800, BIT(DPU_DSC_OUTPUT_CTRL)),
>> +    DSC_BLK("dsc_3", DSC_3, 0x80c00, BIT(DPU_DSC_OUTPUT_CTRL)),
>> +    DSC_BLK("dsc_4", DSC_4, 0x81000, BIT(DPU_DSC_OUTPUT_CTRL)),
>> +    DSC_BLK("dsc_5", DSC_5, 0x81400, BIT(DPU_DSC_OUTPUT_CTRL)),
>> +};
>> +
>>   static const struct dpu_intf_cfg sc8180x_intf[] = {
>>       INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP,
>> MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 24, 25),
>>       INTF_BLK("intf_1", INTF_1, 0x6a800, 0x2bc, INTF_DSI, 0, 24,
>> INTF_SC7180_MASK, MDP_SSPP_TOP0_INTR, 26, 27),
>> @@ -192,6 +201,8 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = {
>>       .mixer = sc8180x_lm,
>>       .pingpong_count = ARRAY_SIZE(sc8180x_pp),
>>       .pingpong = sc8180x_pp,
>> +    .dsc_count = ARRAY_SIZE(sc8180x_dsc),
>> +    .dsc = sc8180x_dsc,
>>       .merge_3d_count = ARRAY_SIZE(sc8180x_merge_3d),
>>       .merge_3d = sc8180x_merge_3d,
>>       .intf_count = ARRAY_SIZE(sc8180x_intf),
>

2023-04-29 01:30:18

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [PATCH v2 7/7] drm/msm/dpu: calculate DSC encoder parameters dynamically



On 4/28/2023 5:52 PM, Dmitry Baryshkov wrote:
> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>> During DSC preparation, add run time calculation to figure out what
>> usage modes, split mode and merge mode, is going to be setup.
>
> This patch doesn't determine the mode. It changes programming of DSC
> bits according to the mode being selected.
>

The term mode is a bit confusing here but he is referring to
dsc_common_mode.

>>
>> Signed-off-by: Kuogee Hsieh <[email protected]>
>> ---
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 56
>> ++++++++++++++++-------------
>>   1 file changed, 31 insertions(+), 25 deletions(-)
>>
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> index 2fdacf1..3d18642 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>> @@ -529,17 +529,9 @@ void dpu_encoder_helper_split_config(
>>   bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
>>   {
>>       struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
>> -    int i, intf_count = 0, num_dsc = 0;
>> +    struct msm_display_topology *topology = &dpu_enc->topology;
>> -    for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
>> -        if (dpu_enc->phys_encs[i])
>> -            intf_count++;
>> -
>> -    /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
>> -    if (dpu_enc->dsc)
>> -        num_dsc = 2;
>> -
>> -    return (num_dsc > 0) && (num_dsc > intf_count);
>> +    return (topology->num_dsc > topology->num_intf);
>>   }
>>   static void dpu_encoder_get_topology(
>> @@ -1861,41 +1853,55 @@ static void dpu_encoder_prep_dsc(struct
>> dpu_encoder_virt *dpu_enc,
>>       struct dpu_encoder_phys *enc_master = dpu_enc->cur_master;
>>       struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
>>       struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
>> -    int this_frame_slices;
>> +    struct msm_display_topology *topology = &dpu_enc->topology;
>>       int intf_ip_w, enc_ip_w;
>> -    int dsc_common_mode;
>> -    int pic_width;
>> +    int dsc_common_mode = 0;
>
> Please don't top-init variables unless required (or unless they are
> constant).
>
>>       u32 initial_lines;
>> +    int num_dsc = topology->num_dsc;
>> +    int num_intf = topology->num_intf;
>>       int i;
>> -    for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
>> +    for (i = 0; i < num_dsc; i++) {
>>           hw_pp[i] = dpu_enc->hw_pp[i];
>>           hw_dsc[i] = dpu_enc->hw_dsc[i];
>>           if (!hw_pp[i] || !hw_dsc[i]) {
>>               DPU_ERROR_ENC(dpu_enc, "invalid params for DSC\n");
>>               return;
>> -        }
>> +        }
>
> What is the difference here?
>
>>       }
>> -    dsc_common_mode = 0;
>> -    pic_width = dsc->pic_width;
>> +    intf_ip_w = dsc->pic_width;
>> -    dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL;
>>       if (enc_master->intf_mode == INTF_MODE_VIDEO)
>>           dsc_common_mode |= DSC_MODE_VIDEO;
>> -    this_frame_slices = pic_width / dsc->slice_width;
>> -    intf_ip_w = this_frame_slices * dsc->slice_width;
>> -
>>       /*
>> -     * dsc merge case: when using 2 encoders for the same stream,
>> -     * no. of slices need to be same on both the encoders.
>> +     * If this encoder is driving more than one DSC encoder, they
>> +     * operate in tandem, same pic dimension needs to be used by
>> +     * each of them.(pp-split is assumed to be not supported)
>> +     *
>
> Extra empty line. Also the comment doesn't make sense here anymore. We
> already have comment for the division by two below.
>
>>        */
>> -    enc_ip_w = intf_ip_w / 2;
>> +    enc_ip_w = intf_ip_w;
>> +
>> +    intf_ip_w /= num_intf;
>> +
>> +    if (num_dsc > 1)
>> +        dsc_common_mode |= DSC_MODE_SPLIT_PANEL;
>> +
>> +    if (dpu_encoder_use_dsc_merge(&dpu_enc->base)) {
>> +        dsc_common_mode |= DSC_MODE_MULTIPLEX;
>> +        /*
>> +         * in dsc merge case: when using 2 encoders for the same
>> +         * stream, no. of slices need to be same on both the
>> +         * encoders.
>> +         */
>> +        enc_ip_w = intf_ip_w / 2;
>> +    }
>> +
>>       initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
>> -    for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
>> +    for (i = 0; i < num_dsc; i++)
>>           dpu_encoder_dsc_pipe_cfg(dpu_enc, hw_dsc[i], hw_pp[i], dsc,
>>                       dsc_common_mode, initial_lines);
>>   }
>

2023-04-29 01:41:52

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 7/7] drm/msm/dpu: calculate DSC encoder parameters dynamically

On 29/04/2023 04:22, Abhinav Kumar wrote:
>
>
> On 4/28/2023 5:52 PM, Dmitry Baryshkov wrote:
>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>>> During DSC preparation, add run time calculation to figure out what
>>> usage modes, split mode and merge mode, is going to be setup.
>>
>> This patch doesn't determine the mode. It changes programming of DSC
>> bits according to the mode being selected.
>>
>
> The term mode is a bit confusing here but he is referring to
> dsc_common_mode.

Yes, that's clear. The patch description is not correct.

>
>>>
>>> Signed-off-by: Kuogee Hsieh <[email protected]>
>>> ---
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 56
>>> ++++++++++++++++-------------
>>>   1 file changed, 31 insertions(+), 25 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>> index 2fdacf1..3d18642 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c
>>> @@ -529,17 +529,9 @@ void dpu_encoder_helper_split_config(
>>>   bool dpu_encoder_use_dsc_merge(struct drm_encoder *drm_enc)
>>>   {
>>>       struct dpu_encoder_virt *dpu_enc = to_dpu_encoder_virt(drm_enc);
>>> -    int i, intf_count = 0, num_dsc = 0;
>>> +    struct msm_display_topology *topology = &dpu_enc->topology;
>>> -    for (i = 0; i < MAX_PHYS_ENCODERS_PER_VIRTUAL; i++)
>>> -        if (dpu_enc->phys_encs[i])
>>> -            intf_count++;
>>> -
>>> -    /* See dpu_encoder_get_topology, we only support 2:2:1 topology */
>>> -    if (dpu_enc->dsc)
>>> -        num_dsc = 2;
>>> -
>>> -    return (num_dsc > 0) && (num_dsc > intf_count);
>>> +    return (topology->num_dsc > topology->num_intf);
>>>   }
>>>   static void dpu_encoder_get_topology(
>>> @@ -1861,41 +1853,55 @@ static void dpu_encoder_prep_dsc(struct
>>> dpu_encoder_virt *dpu_enc,
>>>       struct dpu_encoder_phys *enc_master = dpu_enc->cur_master;
>>>       struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC];
>>>       struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC];
>>> -    int this_frame_slices;
>>> +    struct msm_display_topology *topology = &dpu_enc->topology;
>>>       int intf_ip_w, enc_ip_w;
>>> -    int dsc_common_mode;
>>> -    int pic_width;
>>> +    int dsc_common_mode = 0;
>>
>> Please don't top-init variables unless required (or unless they are
>> constant).
>>
>>>       u32 initial_lines;
>>> +    int num_dsc = topology->num_dsc;
>>> +    int num_intf = topology->num_intf;
>>>       int i;
>>> -    for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) {
>>> +    for (i = 0; i < num_dsc; i++) {
>>>           hw_pp[i] = dpu_enc->hw_pp[i];
>>>           hw_dsc[i] = dpu_enc->hw_dsc[i];
>>>           if (!hw_pp[i] || !hw_dsc[i]) {
>>>               DPU_ERROR_ENC(dpu_enc, "invalid params for DSC\n");
>>>               return;
>>> -        }
>>> +        }
>>
>> What is the difference here?
>>
>>>       }
>>> -    dsc_common_mode = 0;
>>> -    pic_width = dsc->pic_width;
>>> +    intf_ip_w = dsc->pic_width;
>>> -    dsc_common_mode = DSC_MODE_MULTIPLEX | DSC_MODE_SPLIT_PANEL;
>>>       if (enc_master->intf_mode == INTF_MODE_VIDEO)
>>>           dsc_common_mode |= DSC_MODE_VIDEO;
>>> -    this_frame_slices = pic_width / dsc->slice_width;
>>> -    intf_ip_w = this_frame_slices * dsc->slice_width;
>>> -
>>>       /*
>>> -     * dsc merge case: when using 2 encoders for the same stream,
>>> -     * no. of slices need to be same on both the encoders.
>>> +     * If this encoder is driving more than one DSC encoder, they
>>> +     * operate in tandem, same pic dimension needs to be used by
>>> +     * each of them.(pp-split is assumed to be not supported)
>>> +     *
>>
>> Extra empty line. Also the comment doesn't make sense here anymore. We
>> already have comment for the division by two below.
>>
>>>        */
>>> -    enc_ip_w = intf_ip_w / 2;
>>> +    enc_ip_w = intf_ip_w;
>>> +
>>> +    intf_ip_w /= num_intf;
>>> +
>>> +    if (num_dsc > 1)
>>> +        dsc_common_mode |= DSC_MODE_SPLIT_PANEL;
>>> +
>>> +    if (dpu_encoder_use_dsc_merge(&dpu_enc->base)) {
>>> +        dsc_common_mode |= DSC_MODE_MULTIPLEX;
>>> +        /*
>>> +         * in dsc merge case: when using 2 encoders for the same
>>> +         * stream, no. of slices need to be same on both the
>>> +         * encoders.
>>> +         */
>>> +        enc_ip_w = intf_ip_w / 2;
>>> +    }
>>> +
>>>       initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w);
>>> -    for (i = 0; i < MAX_CHANNELS_PER_ENC; i++)
>>> +    for (i = 0; i < num_dsc; i++)
>>>           dpu_encoder_dsc_pipe_cfg(dpu_enc, hw_dsc[i], hw_pp[i], dsc,
>>>                       dsc_common_mode, initial_lines);
>>>   }
>>

--
With best wishes
Dmitry

2023-04-29 01:59:39

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 5/7] drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE

On 29/04/2023 04:08, Abhinav Kumar wrote:
>
>
> On 4/28/2023 5:45 PM, Dmitry Baryshkov wrote:
>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>>> Legacy DPU requires PP hardware block involved into setting up DSC
>>
>> Nit: to be envolved
>>
>>> data path. This patch add DDPU_PINGPONG_DSC feature bit to both
>>
>> adds
>>
>>> PP_BLK and PP_BLK_TE so that both dpu_hw_pp_setup_dsc() and
>>> dpu_hw_pp_dsc_enable() will be executed during DSC path setup.
>>
>> Would it be easier to add PP_BLK_NO_DSC instead and make DSC enabled
>> by default for PP_BLK / PP_BLK_TE?
>>
>
> No because for some chipsets like qcm2290, it has a ping pong block but
> no DSC.

And so it will use PP_BLK_NO_DSC (like msm8998 for PP_2/_3). But this
might be not the optimal solution. Let's check all possible cases:

- PP (or PP_TE?) with no DSC support,
- PP/PP_TE tightly bound to the particular DSC instance, should be
allocated together,
- PP/PP_TE which can use any DSC block.
- all PP_DITHER probably support any DSC?

Is this list correct? If so, we'd need to be able to specify the DSC id
in the PP block description.

>
>>>
>>> Reported-by : Marijn Suijten <[email protected]>
>>> Signed-off-by: Kuogee Hsieh <[email protected]>
>>> ---
>>>   .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h    | 12 +++++-----
>>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h |  8 +++----
>>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26
>>> ++++++++++------------
>>>   .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h    | 24
>>> ++++++++++----------
>>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26
>>> ++++++++++------------
>>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h |  4 ++--
>>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h |  2 +-
>>>   .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h    |  2 +-
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c     |  8 +++----
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h     |  2 ++
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c    |  9 +++++---
>>>   11 files changed, 62 insertions(+), 61 deletions(-)
>>>
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>> index 17f821c..b7cd746 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>> @@ -112,16 +112,16 @@ static const struct dpu_lm_cfg msm8998_lm[] = {
>>>   };
>>>   static const struct dpu_pingpong_cfg msm8998_pp[] = {
>>> -    PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>> +    PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000,
>>> BIT(DPU_PINGPONG_DSC), 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,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>> +    PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800,
>>> BIT(DPU_PINGPONG_DSC), 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, 0, 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, 0, 0, sdm845_pp_sblk,
>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>   };
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>> index ceca741..8888bd9 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>> @@ -110,16 +110,16 @@ static const struct dpu_lm_cfg sdm845_lm[] = {
>>>   };
>>>   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,
>>> BIT(DPU_PINGPONG_DSC), 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,
>>> BIT(DPU_PINGPONG_DSC), 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, BIT(DPU_PINGPONG_DSC),
>>> 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, BIT(DPU_PINGPONG_DSC),
>>> 0, sdm845_pp_sblk,
>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>   };
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>> index 42b0e58..3a7dffa 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>> @@ -128,24 +128,22 @@ static const struct dpu_dspp_cfg sm8150_dspp[] = {
>>>   };
>>>   static const struct dpu_pingpong_cfg sm8150_pp[] = {
>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>> sdm845_pp_sblk,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC),
>>> MERGE_3D_0,
>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>> sdm845_pp_sblk,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC),
>>> MERGE_3D_0,
>>> +            sdm845_pp_sblk, 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,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000, BIT(DPU_PINGPONG_DSC),
>>> 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,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800, BIT(DPU_PINGPONG_DSC),
>>> 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,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>> -            -1),
>>> -    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>>> sdm845_pp_sblk,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>> -            -1),
>>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000, BIT(DPU_PINGPONG_DSC),
>>> MERGE_3D_2,
>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
>>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, BIT(DPU_PINGPONG_DSC),
>>> MERGE_3D_2,
>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
>>>   };
>>>   static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>> index 5bb9882..e766a2d 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>> @@ -116,23 +116,23 @@ static const struct dpu_lm_cfg sc8180x_lm[] = {
>>>   };
>>>   static const struct dpu_pingpong_cfg sc8180x_pp[] = {
>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>> sdm845_pp_sblk,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC),
>>> MERGE_3D_0,
>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>> sdm845_pp_sblk,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC),
>>> MERGE_3D_0,
>>> +            sdm845_pp_sblk, 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,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000, BIT(DPU_PINGPONG_DSC),
>>> 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,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800, BIT(DPU_PINGPONG_DSC),
>>> 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,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000, BIT(DPU_PINGPONG_DSC),
>>> 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,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, BIT(DPU_PINGPONG_DSC),
>>> MERGE_3D_2,
>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>               -1),
>>>   };
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>> index ed130582..137b151 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>> @@ -129,24 +129,22 @@ static const struct dpu_dspp_cfg sm8250_dspp[] = {
>>>   };
>>>   static const struct dpu_pingpong_cfg sm8250_pp[] = {
>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>> sdm845_pp_sblk,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, BIT(DPU_PINGPONG_DSC),
>>> MERGE_3D_0,
>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>> sdm845_pp_sblk,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, BIT(DPU_PINGPONG_DSC),
>>> MERGE_3D_0,
>>> +            sdm845_pp_sblk, 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,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000, BIT(DPU_PINGPONG_DSC),
>>> 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,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800, BIT(DPU_PINGPONG_DSC),
>>> 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,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>> -            -1),
>>> -    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>>> sdm845_pp_sblk,
>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>> -            -1),
>>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000, BIT(DPU_PINGPONG_DSC),
>>> MERGE_3D_2,
>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
>>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, BIT(DPU_PINGPONG_DSC),
>>> MERGE_3D_2,
>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
>>>   };
>>>   static const struct dpu_merge_3d_cfg sm8250_merge_3d[] = {
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>> index a46b117..e5631a2 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>> @@ -80,8 +80,8 @@ static const struct dpu_dspp_cfg sc7180_dspp[] = {
>>>   };
>>>   static const struct dpu_pingpong_cfg sc7180_pp[] = {
>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk, -1,
>>> -1),
>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk, -1,
>>> -1),
>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 0, sdm845_pp_sblk,
>>> -1, -1),
>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, 0, sdm845_pp_sblk,
>>> -1, -1),
>>>   };
>>>   static const struct dpu_intf_cfg sc7180_intf[] = {
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>> index 988d820..7b4ad0f 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>> @@ -60,7 +60,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[] = {
>>>   };
>>>   static const struct dpu_pingpong_cfg sm6115_pp[] = {
>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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/catalog/dpu_6_5_qcm2290.h
>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>> index c9003dc..20d4d14 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>> @@ -57,7 +57,7 @@ static const struct dpu_dspp_cfg qcm2290_dspp[] = {
>>>   };
>>>   static const struct dpu_pingpong_cfg qcm2290_pp[] = {
>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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_catalog.c
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>> index 91bfc8a..83c0cd9 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>> @@ -501,21 +501,21 @@ static const struct dpu_pingpong_sub_blks
>>> sc7280_pp_sblk = {
>>>       .intr_done = _done, \
>>>       .intr_rdptr = _rdptr, \
>>>       }
>>> -#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 = PINGPONG_SDM845_SPLIT_MASK | _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 = PINGPONG_SDM845_MASK | _features, \
>>>       .merge_3d = _merge_3d, \
>>>       .sblk = &_sblk, \
>>>       .intr_done = _done, \
>>> 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 fc87db1..6b49171 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>> @@ -144,6 +144,7 @@ enum {
>>>    * @DPU_PINGPONG_SPLIT      PP block supports split fifo
>>>    * @DPU_PINGPONG_SLAVE      PP block is a suitable slave for split
>>> fifo
>>>    * @DPU_PINGPONG_DITHER,    Dither blocks
>>> + * @DPU_PINGPONG_DSC,        PP block binding to DSC
>>>    * @DPU_PINGPONG_MAX
>>>    */
>>>   enum {
>>> @@ -152,6 +153,7 @@ enum {
>>>       DPU_PINGPONG_SPLIT,
>>>       DPU_PINGPONG_SLAVE,
>>>       DPU_PINGPONG_DITHER,
>>> +    DPU_PINGPONG_DSC,
>>>       DPU_PINGPONG_MAX
>>>   };
>>> 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 3822e06..f255a04 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>> @@ -264,9 +264,12 @@ static void _setup_pingpong_ops(struct
>>> dpu_hw_pingpong *c,
>>>       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;
>>> +
>>> +    if (features & BIT(DPU_PINGPONG_DSC)) {
>>> +        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;
>>> +    }
>>>       if (test_bit(DPU_PINGPONG_DITHER, &features))
>>>           c->ops.setup_dither = dpu_hw_pp_setup_dither;
>>

--
With best wishes
Dmitry

2023-04-29 02:51:27

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [PATCH v2 5/7] drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE



On 4/28/2023 6:41 PM, Dmitry Baryshkov wrote:
> On 29/04/2023 04:08, Abhinav Kumar wrote:
>>
>>
>> On 4/28/2023 5:45 PM, Dmitry Baryshkov wrote:
>>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>>>> Legacy DPU requires PP hardware block involved into setting up DSC
>>>
>>> Nit: to be envolved
>>>
>>>> data path. This patch add DDPU_PINGPONG_DSC feature bit to both
>>>
>>> adds
>>>
>>>> PP_BLK and PP_BLK_TE so that both dpu_hw_pp_setup_dsc() and
>>>> dpu_hw_pp_dsc_enable() will be executed during DSC path setup.
>>>
>>> Would it be easier to add PP_BLK_NO_DSC instead and make DSC enabled
>>> by default for PP_BLK / PP_BLK_TE?
>>>
>>
>> No because for some chipsets like qcm2290, it has a ping pong block
>> but no DSC.
>
> And so it will use PP_BLK_NO_DSC (like msm8998 for PP_2/_3). But this

Ok so you meant adding another PP_BLK_* macro. I mistook it for a
feature flag.

This is getting a bit confusing with many PP_BLK_* variations.

> might be not the optimal solution. Let's check all possible cases:
>
> - PP (or PP_TE?) with no DSC support,

Yes correct for chipsets like qcm2290.

> - PP/PP_TE tightly bound to the particular DSC instance, should be
> allocated together,

I need to check which exact chipset does this (I recall one does) but
perhaps msm8998 fits here.

> - PP/PP_TE which can use any DSC block.

This is what DPU_PINGPONG_DSC feature flag should mean today and should
cover most of the DSC 1.1 chipsets present in upstream today.

> - all PP_DITHER probably support any DSC?
>

No, PP_DITHER means that there is no DSC in ping-pong block. Its
actually DSC 1.2. From our standpoint, this is same as PP_BLK_NO_DSC
then as the PP blk has no DSC. This is where the confusion will come.

> Is this list correct? If so, we'd need to be able to specify the DSC id
> in the PP block description.
>

Is this for the PP bound to a particular DSC case? If so, the goal of
this is then you want to not allocate DSCs from RM for this case or what
would be the purpose of specifying the DSC id in the ping-pong?

From this classification, it looks like this case shall fit
PP_BLK_NO_DSC but we have to then migrate PP_BLK_DITHER to this as well
and add dither to that.

Seems like this can be a separate effort to cleanup the PP_BLK_* macros
first and go with this feature flag first instead of undertaking a
PP_BLK_* macro cleanup in this series.

>>
>>>>
>>>> Reported-by : Marijn Suijten <[email protected]>
>>>> Signed-off-by: Kuogee Hsieh <[email protected]>
>>>> ---
>>>>   .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h    | 12 +++++-----
>>>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h |  8 +++----
>>>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26
>>>> ++++++++++------------
>>>>   .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h    | 24
>>>> ++++++++++----------
>>>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26
>>>> ++++++++++------------
>>>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h |  4 ++--
>>>>   .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h |  2 +-
>>>>   .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h    |  2 +-
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c     |  8 +++----
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h     |  2 ++
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c    |  9 +++++---
>>>>   11 files changed, 62 insertions(+), 61 deletions(-)
>>>>
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>> index 17f821c..b7cd746 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>> @@ -112,16 +112,16 @@ static const struct dpu_lm_cfg msm8998_lm[] = {
>>>>   };
>>>>   static const struct dpu_pingpong_cfg msm8998_pp[] = {
>>>> -    PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>> +    PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000,
>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>> +    PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800,
>>>> BIT(DPU_PINGPONG_DSC), 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, 0, 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, 0, 0, sdm845_pp_sblk,
>>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>>   };
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>> index ceca741..8888bd9 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>> @@ -110,16 +110,16 @@ static const struct dpu_lm_cfg sdm845_lm[] = {
>>>>   };
>>>>   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,
>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>> BIT(DPU_PINGPONG_DSC), 0, sdm845_pp_sblk,
>>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>>   };
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>> index 42b0e58..3a7dffa 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>> @@ -128,24 +128,22 @@ static const struct dpu_dspp_cfg sm8150_dspp[]
>>>> = {
>>>>   };
>>>>   static const struct dpu_pingpong_cfg sm8150_pp[] = {
>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>> sdm845_pp_sblk,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>> sdm845_pp_sblk,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>> +            sdm845_pp_sblk, 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,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>> -            -1),
>>>> -    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>>>> sdm845_pp_sblk,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>> -            -1),
>>>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
>>>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
>>>>   };
>>>>   static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>> index 5bb9882..e766a2d 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>> @@ -116,23 +116,23 @@ static const struct dpu_lm_cfg sc8180x_lm[] = {
>>>>   };
>>>>   static const struct dpu_pingpong_cfg sc8180x_pp[] = {
>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>> sdm845_pp_sblk,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>> sdm845_pp_sblk,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>> +            sdm845_pp_sblk, 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,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>               -1),
>>>>   };
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>> index ed130582..137b151 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>> @@ -129,24 +129,22 @@ static const struct dpu_dspp_cfg sm8250_dspp[]
>>>> = {
>>>>   };
>>>>   static const struct dpu_pingpong_cfg sm8250_pp[] = {
>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>> sdm845_pp_sblk,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>               DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>> sdm845_pp_sblk,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>> +            sdm845_pp_sblk, 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,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>> -            -1),
>>>> -    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>>>> sdm845_pp_sblk,
>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>> -            -1),
>>>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
>>>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
>>>>   };
>>>>   static const struct dpu_merge_3d_cfg sm8250_merge_3d[] = {
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>> index a46b117..e5631a2 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>> @@ -80,8 +80,8 @@ static const struct dpu_dspp_cfg sc7180_dspp[] = {
>>>>   };
>>>>   static const struct dpu_pingpong_cfg sc7180_pp[] = {
>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>> -1, -1),
>>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk,
>>>> -1, -1),
>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 0, sdm845_pp_sblk,
>>>> -1, -1),
>>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, 0, sdm845_pp_sblk,
>>>> -1, -1),
>>>>   };
>>>>   static const struct dpu_intf_cfg sc7180_intf[] = {
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>> index 988d820..7b4ad0f 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>> @@ -60,7 +60,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[] = {
>>>>   };
>>>>   static const struct dpu_pingpong_cfg sm6115_pp[] = {
>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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/catalog/dpu_6_5_qcm2290.h
>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>> index c9003dc..20d4d14 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>> @@ -57,7 +57,7 @@ static const struct dpu_dspp_cfg qcm2290_dspp[] = {
>>>>   };
>>>>   static const struct dpu_pingpong_cfg qcm2290_pp[] = {
>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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_catalog.c
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>> index 91bfc8a..83c0cd9 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>> @@ -501,21 +501,21 @@ static const struct dpu_pingpong_sub_blks
>>>> sc7280_pp_sblk = {
>>>>       .intr_done = _done, \
>>>>       .intr_rdptr = _rdptr, \
>>>>       }
>>>> -#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 = PINGPONG_SDM845_SPLIT_MASK | _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 = PINGPONG_SDM845_MASK | _features, \
>>>>       .merge_3d = _merge_3d, \
>>>>       .sblk = &_sblk, \
>>>>       .intr_done = _done, \
>>>> 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 fc87db1..6b49171 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>>> @@ -144,6 +144,7 @@ enum {
>>>>    * @DPU_PINGPONG_SPLIT      PP block supports split fifo
>>>>    * @DPU_PINGPONG_SLAVE      PP block is a suitable slave for split
>>>> fifo
>>>>    * @DPU_PINGPONG_DITHER,    Dither blocks
>>>> + * @DPU_PINGPONG_DSC,        PP block binding to DSC
>>>>    * @DPU_PINGPONG_MAX
>>>>    */
>>>>   enum {
>>>> @@ -152,6 +153,7 @@ enum {
>>>>       DPU_PINGPONG_SPLIT,
>>>>       DPU_PINGPONG_SLAVE,
>>>>       DPU_PINGPONG_DITHER,
>>>> +    DPU_PINGPONG_DSC,
>>>>       DPU_PINGPONG_MAX
>>>>   };
>>>> 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 3822e06..f255a04 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>>> @@ -264,9 +264,12 @@ static void _setup_pingpong_ops(struct
>>>> dpu_hw_pingpong *c,
>>>>       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;
>>>> +
>>>> +    if (features & BIT(DPU_PINGPONG_DSC)) {
>>>> +        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;
>>>> +    }
>>>>       if (test_bit(DPU_PINGPONG_DITHER, &features))
>>>>           c->ops.setup_dither = dpu_hw_pp_setup_dither;
>>>
>

2023-04-29 02:54:12

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 0/7] add DSC 1.2 dpu supports

On Sat, 29 Apr 2023 at 02:45, Kuogee Hsieh <[email protected]> wrote:
>
> This series adds the DPU side changes to support DSC 1.2 encoder. This
> was validated with both DSI DSC 1.2 panel and DP DSC 1.2 monitor.
> The DSI and DP parts will be pushed later on top of this change.
> This seriel is rebase on [1], [2] and catalog fixes from [3].
>
> [1]: https://patchwork.freedesktop.org/series/116851/
> [2]: https://patchwork.freedesktop.org/series/116615/
> [3]: https://patchwork.freedesktop.org/series/112332/
>
> Abhinav Kumar (2):
> drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
> drm/msm/dpu: add dsc blocks for remaining chipsets in catalog
>
> Kuogee Hsieh (5):
> drm/msm/dpu: add support for DSC encoder v1.2 engine
> drm/msm/dpu: separate DSC flush update out of interface
> drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE
> drm/msm/dpu: save dpu topology configuration
> drm/msm/dpu: calculate DSC encoder parameters dynamically

Another generic comment: this patchset doesn't have discussed RM
changes to allocate DSC blocks in proper pairs as required by DCE.

>
> drivers/gpu/drm/msm/Makefile | 1 +
> .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 19 +-
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 +-
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26 +-
> .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 35 ++-
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26 +-
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 +-
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +-
> .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +-
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 +
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 +
> .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 +
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 +
> .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 102 ++++---
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 35 ++-
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 36 ++-
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 22 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 10 +
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 335 +++++++++++++++++++++
> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 +-
> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +-
> 23 files changed, 642 insertions(+), 116 deletions(-)
> create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>
> --
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> a Linux Foundation Collaborative Project
>


--
With best wishes
Dmitry

2023-04-29 03:17:17

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [PATCH v2 0/7] add DSC 1.2 dpu supports



On 4/28/2023 7:46 PM, Dmitry Baryshkov wrote:
> On Sat, 29 Apr 2023 at 02:45, Kuogee Hsieh <[email protected]> wrote:
>>
>> This series adds the DPU side changes to support DSC 1.2 encoder. This
>> was validated with both DSI DSC 1.2 panel and DP DSC 1.2 monitor.
>> The DSI and DP parts will be pushed later on top of this change.
>> This seriel is rebase on [1], [2] and catalog fixes from [3].
>>
>> [1]: https://patchwork.freedesktop.org/series/116851/
>> [2]: https://patchwork.freedesktop.org/series/116615/
>> [3]: https://patchwork.freedesktop.org/series/112332/
>>
>> Abhinav Kumar (2):
>> drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
>> drm/msm/dpu: add dsc blocks for remaining chipsets in catalog
>>
>> Kuogee Hsieh (5):
>> drm/msm/dpu: add support for DSC encoder v1.2 engine
>> drm/msm/dpu: separate DSC flush update out of interface
>> drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE
>> drm/msm/dpu: save dpu topology configuration
>> drm/msm/dpu: calculate DSC encoder parameters dynamically
>
> Another generic comment: this patchset doesn't have discussed RM
> changes to allocate DSC blocks in proper pairs as required by DCE.
>

We have already made that change. It will be pushed with the DP series
because today DSC only support 2-2-1 so they will always be allocated in
pairs.

>>
>> drivers/gpu/drm/msm/Makefile | 1 +
>> .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 19 +-
>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 +-
>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26 +-
>> .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 35 ++-
>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26 +-
>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 +-
>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +-
>> .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +-
>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 +
>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 +
>> .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 +
>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 +
>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 +
>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 102 ++++---
>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 35 ++-
>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 36 ++-
>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 22 +-
>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 10 +
>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +-
>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 335 +++++++++++++++++++++
>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 +-
>> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +-
>> 23 files changed, 642 insertions(+), 116 deletions(-)
>> create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>
>> --
>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
>> a Linux Foundation Collaborative Project
>>
>
>

2023-04-29 03:28:40

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 0/7] add DSC 1.2 dpu supports

On Sat, 29 Apr 2023 at 05:51, Abhinav Kumar <[email protected]> wrote:
>
>
>
> On 4/28/2023 7:46 PM, Dmitry Baryshkov wrote:
> > On Sat, 29 Apr 2023 at 02:45, Kuogee Hsieh <[email protected]> wrote:
> >>
> >> This series adds the DPU side changes to support DSC 1.2 encoder. This
> >> was validated with both DSI DSC 1.2 panel and DP DSC 1.2 monitor.
> >> The DSI and DP parts will be pushed later on top of this change.
> >> This seriel is rebase on [1], [2] and catalog fixes from [3].
> >>
> >> [1]: https://patchwork.freedesktop.org/series/116851/
> >> [2]: https://patchwork.freedesktop.org/series/116615/
> >> [3]: https://patchwork.freedesktop.org/series/112332/
> >>
> >> Abhinav Kumar (2):
> >> drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
> >> drm/msm/dpu: add dsc blocks for remaining chipsets in catalog
> >>
> >> Kuogee Hsieh (5):
> >> drm/msm/dpu: add support for DSC encoder v1.2 engine
> >> drm/msm/dpu: separate DSC flush update out of interface
> >> drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE
> >> drm/msm/dpu: save dpu topology configuration
> >> drm/msm/dpu: calculate DSC encoder parameters dynamically
> >
> > Another generic comment: this patchset doesn't have discussed RM
> > changes to allocate DSC blocks in proper pairs as required by DCE.
> >
>
> We have already made that change. It will be pushed with the DP series
> because today DSC only support 2-2-1 so they will always be allocated in
> pairs.

Then there is no reason to touch the dpu_encoder in this series as the
topology is also known to be 2:2:1.

>
> >>
> >> drivers/gpu/drm/msm/Makefile | 1 +
> >> .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 19 +-
> >> .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 +-
> >> .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26 +-
> >> .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 35 ++-
> >> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26 +-
> >> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 +-
> >> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +-
> >> .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +-
> >> .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 +
> >> .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 +
> >> .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 +
> >> .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 +
> >> .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 +
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 102 ++++---
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 35 ++-
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 36 ++-
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 22 +-
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 10 +
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +-
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 335 +++++++++++++++++++++
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 +-
> >> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +-
> >> 23 files changed, 642 insertions(+), 116 deletions(-)
> >> create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
> >>
> >> --
> >> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> >> a Linux Foundation Collaborative Project
> >>
> >
> >



--
With best wishes
Dmitry

2023-04-29 03:31:48

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 5/7] drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE

On Sat, 29 Apr 2023 at 05:50, Abhinav Kumar <[email protected]> wrote:
>
>
>
> On 4/28/2023 6:41 PM, Dmitry Baryshkov wrote:
> > On 29/04/2023 04:08, Abhinav Kumar wrote:
> >>
> >>
> >> On 4/28/2023 5:45 PM, Dmitry Baryshkov wrote:
> >>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
> >>>> Legacy DPU requires PP hardware block involved into setting up DSC
> >>>
> >>> Nit: to be envolved
> >>>
> >>>> data path. This patch add DDPU_PINGPONG_DSC feature bit to both
> >>>
> >>> adds
> >>>
> >>>> PP_BLK and PP_BLK_TE so that both dpu_hw_pp_setup_dsc() and
> >>>> dpu_hw_pp_dsc_enable() will be executed during DSC path setup.
> >>>
> >>> Would it be easier to add PP_BLK_NO_DSC instead and make DSC enabled
> >>> by default for PP_BLK / PP_BLK_TE?
> >>>
> >>
> >> No because for some chipsets like qcm2290, it has a ping pong block
> >> but no DSC.
> >
> > And so it will use PP_BLK_NO_DSC (like msm8998 for PP_2/_3). But this
>
> Ok so you meant adding another PP_BLK_* macro. I mistook it for a
> feature flag.
>
> This is getting a bit confusing with many PP_BLK_* variations.

Yes. As I wrote it might be not the optimal solution.

>
> > might be not the optimal solution. Let's check all possible cases:
> >
> > - PP (or PP_TE?) with no DSC support,
>
> Yes correct for chipsets like qcm2290.
>
> > - PP/PP_TE tightly bound to the particular DSC instance, should be
> > allocated together,
>
> I need to check which exact chipset does this (I recall one does) but
> perhaps msm8998 fits here.

All targets earlier than sm8150. SDE driver sets SDE_DSC_OUTPUT_CTRL
if for v1 CTL blocks (sm8150+).

>
> > - PP/PP_TE which can use any DSC block.
>
> This is what DPU_PINGPONG_DSC feature flag should mean today and should
> cover most of the DSC 1.1 chipsets present in upstream today.

Then it should probably be renamed to DPU_PINGPONG_ANY_DSC

> > - all PP_DITHER probably support any DSC?
> >
>
> No, PP_DITHER means that there is no DSC in ping-pong block. Its
> actually DSC 1.2. From our standpoint, this is same as PP_BLK_NO_DSC
> then as the PP blk has no DSC. This is where the confusion will come.

But we should still bind the DSC to the PP block, shouldn't we? So
from the software point of view it is the same situation: PP_DITHER
supports any DSC (1.2) and should be bound to it.

> > Is this list correct? If so, we'd need to be able to specify the DSC id
> > in the PP block description.
> >
>
> Is this for the PP bound to a particular DSC case? If so, the goal of
> this is then you want to not allocate DSCs from RM for this case or what
> would be the purpose of specifying the DSC id in the ping-pong?

I think it would be better to still return PP from the RM. It's that
the RM will have to return PP/DSC in pairs.

>
> From this classification, it looks like this case shall fit
> PP_BLK_NO_DSC but we have to then migrate PP_BLK_DITHER to this as well
> and add dither to that.
>
> Seems like this can be a separate effort to cleanup the PP_BLK_* macros
> first and go with this feature flag first instead of undertaking a
> PP_BLK_* macro cleanup in this series.
>
> >>
> >>>>
> >>>> Reported-by : Marijn Suijten <[email protected]>
> >>>> Signed-off-by: Kuogee Hsieh <[email protected]>
> >>>> ---
> >>>> .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 12 +++++-----
> >>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 +++----
> >>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26
> >>>> ++++++++++------------
> >>>> .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 24
> >>>> ++++++++++----------
> >>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26
> >>>> ++++++++++------------
> >>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 ++--
> >>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +-
> >>>> .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +-
> >>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 8 +++----
> >>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++
> >>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 +++++---
> >>>> 11 files changed, 62 insertions(+), 61 deletions(-)
> >>>>
> >>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> >>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> >>>> index 17f821c..b7cd746 100644
> >>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> >>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> >>>> @@ -112,16 +112,16 @@ static const struct dpu_lm_cfg msm8998_lm[] = {
> >>>> };
> >>>> static const struct dpu_pingpong_cfg msm8998_pp[] = {
> >>>> - PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>> + PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000,
> >>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> >>>> + PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800,
> >>>> BIT(DPU_PINGPONG_DSC), 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, 0, 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, 0, 0, sdm845_pp_sblk,
> >>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> >>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
> >>>> };
> >>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
> >>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
> >>>> index ceca741..8888bd9 100644
> >>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
> >>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
> >>>> @@ -110,16 +110,16 @@ static const struct dpu_lm_cfg sdm845_lm[] = {
> >>>> };
> >>>> 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,
> >>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>> BIT(DPU_PINGPONG_DSC), 0, sdm845_pp_sblk,
> >>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> >>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
> >>>> };
> >>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> >>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> >>>> index 42b0e58..3a7dffa 100644
> >>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> >>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> >>>> @@ -128,24 +128,22 @@ static const struct dpu_dspp_cfg sm8150_dspp[]
> >>>> = {
> >>>> };
> >>>> static const struct dpu_pingpong_cfg sm8150_pp[] = {
> >>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
> >>>> sdm845_pp_sblk,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
> >>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> >>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> >>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
> >>>> sdm845_pp_sblk,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> >>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
> >>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> >>>> + sdm845_pp_sblk, 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,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
> >>>> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
> >>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> >>>> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
> >>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
> >>>> - -1),
> >>>> - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
> >>>> sdm845_pp_sblk,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> >>>> - -1),
> >>>> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
> >>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> >>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
> >>>> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
> >>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> >>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
> >>>> };
> >>>> static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
> >>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> >>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> >>>> index 5bb9882..e766a2d 100644
> >>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> >>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> >>>> @@ -116,23 +116,23 @@ static const struct dpu_lm_cfg sc8180x_lm[] = {
> >>>> };
> >>>> static const struct dpu_pingpong_cfg sc8180x_pp[] = {
> >>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
> >>>> sdm845_pp_sblk,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
> >>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> >>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> >>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
> >>>> sdm845_pp_sblk,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> >>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
> >>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> >>>> + sdm845_pp_sblk, 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,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
> >>>> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
> >>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> >>>> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
> >>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
> >>>> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
> >>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> >>>> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
> >>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> >>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> >>>> -1),
> >>>> };
> >>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
> >>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
> >>>> index ed130582..137b151 100644
> >>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
> >>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
> >>>> @@ -129,24 +129,22 @@ static const struct dpu_dspp_cfg sm8250_dspp[]
> >>>> = {
> >>>> };
> >>>> static const struct dpu_pingpong_cfg sm8250_pp[] = {
> >>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
> >>>> sdm845_pp_sblk,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
> >>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> >>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> >>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
> >>>> sdm845_pp_sblk,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> >>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
> >>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> >>>> + sdm845_pp_sblk, 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,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
> >>>> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
> >>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> >>>> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
> >>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
> >>>> - -1),
> >>>> - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
> >>>> sdm845_pp_sblk,
> >>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> >>>> - -1),
> >>>> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
> >>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> >>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
> >>>> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
> >>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> >>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
> >>>> };
> >>>> static const struct dpu_merge_3d_cfg sm8250_merge_3d[] = {
> >>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
> >>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
> >>>> index a46b117..e5631a2 100644
> >>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
> >>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
> >>>> @@ -80,8 +80,8 @@ static const struct dpu_dspp_cfg sc7180_dspp[] = {
> >>>> };
> >>>> static const struct dpu_pingpong_cfg sc7180_pp[] = {
> >>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
> >>>> -1, -1),
> >>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk,
> >>>> -1, -1),
> >>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 0, sdm845_pp_sblk,
> >>>> -1, -1),
> >>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, 0, sdm845_pp_sblk,
> >>>> -1, -1),
> >>>> };
> >>>> static const struct dpu_intf_cfg sc7180_intf[] = {
> >>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
> >>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
> >>>> index 988d820..7b4ad0f 100644
> >>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
> >>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
> >>>> @@ -60,7 +60,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[] = {
> >>>> };
> >>>> static const struct dpu_pingpong_cfg sm6115_pp[] = {
> >>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
> >>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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/catalog/dpu_6_5_qcm2290.h
> >>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
> >>>> index c9003dc..20d4d14 100644
> >>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
> >>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
> >>>> @@ -57,7 +57,7 @@ static const struct dpu_dspp_cfg qcm2290_dspp[] = {
> >>>> };
> >>>> static const struct dpu_pingpong_cfg qcm2290_pp[] = {
> >>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
> >>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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_catalog.c
> >>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >>>> index 91bfc8a..83c0cd9 100644
> >>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >>>> @@ -501,21 +501,21 @@ static const struct dpu_pingpong_sub_blks
> >>>> sc7280_pp_sblk = {
> >>>> .intr_done = _done, \
> >>>> .intr_rdptr = _rdptr, \
> >>>> }
> >>>> -#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 = PINGPONG_SDM845_SPLIT_MASK | _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 = PINGPONG_SDM845_MASK | _features, \
> >>>> .merge_3d = _merge_3d, \
> >>>> .sblk = &_sblk, \
> >>>> .intr_done = _done, \
> >>>> 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 fc87db1..6b49171 100644
> >>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> >>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> >>>> @@ -144,6 +144,7 @@ enum {
> >>>> * @DPU_PINGPONG_SPLIT PP block supports split fifo
> >>>> * @DPU_PINGPONG_SLAVE PP block is a suitable slave for split
> >>>> fifo
> >>>> * @DPU_PINGPONG_DITHER, Dither blocks
> >>>> + * @DPU_PINGPONG_DSC, PP block binding to DSC
> >>>> * @DPU_PINGPONG_MAX
> >>>> */
> >>>> enum {
> >>>> @@ -152,6 +153,7 @@ enum {
> >>>> DPU_PINGPONG_SPLIT,
> >>>> DPU_PINGPONG_SLAVE,
> >>>> DPU_PINGPONG_DITHER,
> >>>> + DPU_PINGPONG_DSC,
> >>>> DPU_PINGPONG_MAX
> >>>> };
> >>>> 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 3822e06..f255a04 100644
> >>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
> >>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
> >>>> @@ -264,9 +264,12 @@ static void _setup_pingpong_ops(struct
> >>>> dpu_hw_pingpong *c,
> >>>> 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;
> >>>> +
> >>>> + if (features & BIT(DPU_PINGPONG_DSC)) {
> >>>> + 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;
> >>>> + }
> >>>> if (test_bit(DPU_PINGPONG_DITHER, &features))
> >>>> c->ops.setup_dither = dpu_hw_pp_setup_dither;
> >>>
> >



--
With best wishes
Dmitry

2023-04-29 03:41:54

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [PATCH v2 0/7] add DSC 1.2 dpu supports



On 4/28/2023 8:12 PM, Dmitry Baryshkov wrote:
> On Sat, 29 Apr 2023 at 05:51, Abhinav Kumar <[email protected]> wrote:
>>
>>
>>
>> On 4/28/2023 7:46 PM, Dmitry Baryshkov wrote:
>>> On Sat, 29 Apr 2023 at 02:45, Kuogee Hsieh <[email protected]> wrote:
>>>>
>>>> This series adds the DPU side changes to support DSC 1.2 encoder. This
>>>> was validated with both DSI DSC 1.2 panel and DP DSC 1.2 monitor.
>>>> The DSI and DP parts will be pushed later on top of this change.
>>>> This seriel is rebase on [1], [2] and catalog fixes from [3].
>>>>
>>>> [1]: https://patchwork.freedesktop.org/series/116851/
>>>> [2]: https://patchwork.freedesktop.org/series/116615/
>>>> [3]: https://patchwork.freedesktop.org/series/112332/
>>>>
>>>> Abhinav Kumar (2):
>>>> drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
>>>> drm/msm/dpu: add dsc blocks for remaining chipsets in catalog
>>>>
>>>> Kuogee Hsieh (5):
>>>> drm/msm/dpu: add support for DSC encoder v1.2 engine
>>>> drm/msm/dpu: separate DSC flush update out of interface
>>>> drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE
>>>> drm/msm/dpu: save dpu topology configuration
>>>> drm/msm/dpu: calculate DSC encoder parameters dynamically
>>>
>>> Another generic comment: this patchset doesn't have discussed RM
>>> changes to allocate DSC blocks in proper pairs as required by DCE.
>>>
>>
>> We have already made that change. It will be pushed with the DP series
>> because today DSC only support 2-2-1 so they will always be allocated in
>> pairs.
>
> Then there is no reason to touch the dpu_encoder in this series as the
> topology is also known to be 2:2:1.
>

Agreed, no concerns with that.

>>
>>>>
>>>> drivers/gpu/drm/msm/Makefile | 1 +
>>>> .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 19 +-
>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 +-
>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26 +-
>>>> .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 35 ++-
>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26 +-
>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 +-
>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +-
>>>> .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +-
>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 +
>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 +
>>>> .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 +
>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 +
>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 +
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 102 ++++---
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 35 ++-
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 36 ++-
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 22 +-
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 10 +
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +-
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 335 +++++++++++++++++++++
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 +-
>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +-
>>>> 23 files changed, 642 insertions(+), 116 deletions(-)
>>>> create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>>>
>>>> --
>>>> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
>>>> a Linux Foundation Collaborative Project
>>>>
>>>
>>>
>
>
>

2023-04-29 04:09:55

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [Freedreno] [PATCH v2 5/7] drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE



On 4/28/2023 8:21 PM, Dmitry Baryshkov wrote:
> On Sat, 29 Apr 2023 at 05:50, Abhinav Kumar <[email protected]> wrote:
>>
>>
>>
>> On 4/28/2023 6:41 PM, Dmitry Baryshkov wrote:
>>> On 29/04/2023 04:08, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 4/28/2023 5:45 PM, Dmitry Baryshkov wrote:
>>>>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>>>>>> Legacy DPU requires PP hardware block involved into setting up DSC
>>>>>
>>>>> Nit: to be envolved
>>>>>
>>>>>> data path. This patch add DDPU_PINGPONG_DSC feature bit to both
>>>>>
>>>>> adds
>>>>>
>>>>>> PP_BLK and PP_BLK_TE so that both dpu_hw_pp_setup_dsc() and
>>>>>> dpu_hw_pp_dsc_enable() will be executed during DSC path setup.
>>>>>
>>>>> Would it be easier to add PP_BLK_NO_DSC instead and make DSC enabled
>>>>> by default for PP_BLK / PP_BLK_TE?
>>>>>
>>>>
>>>> No because for some chipsets like qcm2290, it has a ping pong block
>>>> but no DSC.
>>>
>>> And so it will use PP_BLK_NO_DSC (like msm8998 for PP_2/_3). But this
>>
>> Ok so you meant adding another PP_BLK_* macro. I mistook it for a
>> feature flag.
>>
>> This is getting a bit confusing with many PP_BLK_* variations.
>
> Yes. As I wrote it might be not the optimal solution.
>
>>
>>> might be not the optimal solution. Let's check all possible cases:
>>>
>>> - PP (or PP_TE?) with no DSC support,
>>
>> Yes correct for chipsets like qcm2290.
>>
>>> - PP/PP_TE tightly bound to the particular DSC instance, should be
>>> allocated together,
>>
>> I need to check which exact chipset does this (I recall one does) but
>> perhaps msm8998 fits here.
>
> All targets earlier than sm8150. SDE driver sets SDE_DSC_OUTPUT_CTRL
> if for v1 CTL blocks (sm8150+).
>
>>
>>> - PP/PP_TE which can use any DSC block.
>>
>> This is what DPU_PINGPONG_DSC feature flag should mean today and should
>> cover most of the DSC 1.1 chipsets present in upstream today.
>
> Then it should probably be renamed to DPU_PINGPONG_ANY_DSC
>

Actually that "any" is incorrect. As part of the DSC pairing logic
change it will become clear but not all ping-pongs can pair with all
DSCs. So any is not right.

This is why I think we should go with this feature flag first. Lets
identify a pattern and then work on unifying or cleaning up the PP_BLK_*
masks.

>>> - all PP_DITHER probably support any DSC?
>>>
>>
>> No, PP_DITHER means that there is no DSC in ping-pong block. Its
>> actually DSC 1.2. From our standpoint, this is same as PP_BLK_NO_DSC
>> then as the PP blk has no DSC. This is where the confusion will come.
>
> But we should still bind the DSC to the PP block, shouldn't we? So
> from the software point of view it is the same situation: PP_DITHER
> supports any DSC (1.2) and should be bound to it.
>

Yes, the DSC ctl will need to be programmed correctly to tell which
ping-pong but like I said, any is not right. There are some conditions.

Please refer to _sde_rm_reserve_dsc() in downstream.

>>> Is this list correct? If so, we'd need to be able to specify the DSC id
>>> in the PP block description.
>>>
>>
>> Is this for the PP bound to a particular DSC case? If so, the goal of
>> this is then you want to not allocate DSCs from RM for this case or what
>> would be the purpose of specifying the DSC id in the ping-pong?
>
> I think it would be better to still return PP from the RM. It's that
> the RM will have to return PP/DSC in pairs.
>

Yes, I was trying to understand what would be the purpose of this DSC id
in the ping-pong block then.

>>
>> From this classification, it looks like this case shall fit
>> PP_BLK_NO_DSC but we have to then migrate PP_BLK_DITHER to this as well
>> and add dither to that.
>>
>> Seems like this can be a separate effort to cleanup the PP_BLK_* macros
>> first and go with this feature flag first instead of undertaking a
>> PP_BLK_* macro cleanup in this series.
>>
>>>>
>>>>>>
>>>>>> Reported-by : Marijn Suijten <[email protected]>
>>>>>> Signed-off-by: Kuogee Hsieh <[email protected]>
>>>>>> ---
>>>>>> .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 12 +++++-----
>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 +++----
>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26
>>>>>> ++++++++++------------
>>>>>> .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 24
>>>>>> ++++++++++----------
>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26
>>>>>> ++++++++++------------
>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 ++--
>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +-
>>>>>> .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +-
>>>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 8 +++----
>>>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++
>>>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 +++++---
>>>>>> 11 files changed, 62 insertions(+), 61 deletions(-)
>>>>>>
>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>> index 17f821c..b7cd746 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>> @@ -112,16 +112,16 @@ static const struct dpu_lm_cfg msm8998_lm[] = {
>>>>>> };
>>>>>> static const struct dpu_pingpong_cfg msm8998_pp[] = {
>>>>>> - PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk_te,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>> + PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000,
>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>> + PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800,
>>>>>> BIT(DPU_PINGPONG_DSC), 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, 0, 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, 0, 0, sdm845_pp_sblk,
>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>>>> };
>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>> index ceca741..8888bd9 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>> @@ -110,16 +110,16 @@ static const struct dpu_lm_cfg sdm845_lm[] = {
>>>>>> };
>>>>>> 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,
>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>> BIT(DPU_PINGPONG_DSC), 0, sdm845_pp_sblk,
>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>>>> };
>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>> index 42b0e58..3a7dffa 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>> @@ -128,24 +128,22 @@ static const struct dpu_dspp_cfg sm8150_dspp[]
>>>>>> = {
>>>>>> };
>>>>>> static const struct dpu_pingpong_cfg sm8150_pp[] = {
>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>>>> sdm845_pp_sblk,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>>>> sdm845_pp_sblk,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>> + sdm845_pp_sblk, 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,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>>>> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>>>> - -1),
>>>>>> - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>>>>>> sdm845_pp_sblk,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>> - -1),
>>>>>> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
>>>>>> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
>>>>>> };
>>>>>> static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>> index 5bb9882..e766a2d 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>> @@ -116,23 +116,23 @@ static const struct dpu_lm_cfg sc8180x_lm[] = {
>>>>>> };
>>>>>> static const struct dpu_pingpong_cfg sc8180x_pp[] = {
>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>>>> sdm845_pp_sblk,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>>>> sdm845_pp_sblk,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>> + sdm845_pp_sblk, 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,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>>>> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>>>> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>> -1),
>>>>>> };
>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>> index ed130582..137b151 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>> @@ -129,24 +129,22 @@ static const struct dpu_dspp_cfg sm8250_dspp[]
>>>>>> = {
>>>>>> };
>>>>>> static const struct dpu_pingpong_cfg sm8250_pp[] = {
>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>>>> sdm845_pp_sblk,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>>>> sdm845_pp_sblk,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>> + sdm845_pp_sblk, 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,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>>>> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>>>> - -1),
>>>>>> - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>>>>>> sdm845_pp_sblk,
>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>> - -1),
>>>>>> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30), -1),
>>>>>> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31), -1),
>>>>>> };
>>>>>> static const struct dpu_merge_3d_cfg sm8250_merge_3d[] = {
>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>> index a46b117..e5631a2 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>> @@ -80,8 +80,8 @@ static const struct dpu_dspp_cfg sc7180_dspp[] = {
>>>>>> };
>>>>>> static const struct dpu_pingpong_cfg sc7180_pp[] = {
>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>>>> -1, -1),
>>>>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk,
>>>>>> -1, -1),
>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 0, sdm845_pp_sblk,
>>>>>> -1, -1),
>>>>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, 0, sdm845_pp_sblk,
>>>>>> -1, -1),
>>>>>> };
>>>>>> static const struct dpu_intf_cfg sc7180_intf[] = {
>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>> index 988d820..7b4ad0f 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>> @@ -60,7 +60,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[] = {
>>>>>> };
>>>>>> static const struct dpu_pingpong_cfg sm6115_pp[] = {
>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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/catalog/dpu_6_5_qcm2290.h
>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>>>> index c9003dc..20d4d14 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>>>> @@ -57,7 +57,7 @@ static const struct dpu_dspp_cfg qcm2290_dspp[] = {
>>>>>> };
>>>>>> static const struct dpu_pingpong_cfg qcm2290_pp[] = {
>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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_catalog.c
>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>> index 91bfc8a..83c0cd9 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>> @@ -501,21 +501,21 @@ static const struct dpu_pingpong_sub_blks
>>>>>> sc7280_pp_sblk = {
>>>>>> .intr_done = _done, \
>>>>>> .intr_rdptr = _rdptr, \
>>>>>> }
>>>>>> -#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 = PINGPONG_SDM845_SPLIT_MASK | _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 = PINGPONG_SDM845_MASK | _features, \
>>>>>> .merge_3d = _merge_3d, \
>>>>>> .sblk = &_sblk, \
>>>>>> .intr_done = _done, \
>>>>>> 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 fc87db1..6b49171 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>>>>> @@ -144,6 +144,7 @@ enum {
>>>>>> * @DPU_PINGPONG_SPLIT PP block supports split fifo
>>>>>> * @DPU_PINGPONG_SLAVE PP block is a suitable slave for split
>>>>>> fifo
>>>>>> * @DPU_PINGPONG_DITHER, Dither blocks
>>>>>> + * @DPU_PINGPONG_DSC, PP block binding to DSC
>>>>>> * @DPU_PINGPONG_MAX
>>>>>> */
>>>>>> enum {
>>>>>> @@ -152,6 +153,7 @@ enum {
>>>>>> DPU_PINGPONG_SPLIT,
>>>>>> DPU_PINGPONG_SLAVE,
>>>>>> DPU_PINGPONG_DITHER,
>>>>>> + DPU_PINGPONG_DSC,
>>>>>> DPU_PINGPONG_MAX
>>>>>> };
>>>>>> 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 3822e06..f255a04 100644
>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>>>>> @@ -264,9 +264,12 @@ static void _setup_pingpong_ops(struct
>>>>>> dpu_hw_pingpong *c,
>>>>>> 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;
>>>>>> +
>>>>>> + if (features & BIT(DPU_PINGPONG_DSC)) {
>>>>>> + 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;
>>>>>> + }
>>>>>> if (test_bit(DPU_PINGPONG_DITHER, &features))
>>>>>> c->ops.setup_dither = dpu_hw_pp_setup_dither;
>>>>>
>>>
>
>
>

2023-04-29 04:47:04

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [Freedreno] [PATCH v2 5/7] drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE

On 29/04/2023 07:04, Abhinav Kumar wrote:
>
>
> On 4/28/2023 8:21 PM, Dmitry Baryshkov wrote:
>> On Sat, 29 Apr 2023 at 05:50, Abhinav Kumar
>> <[email protected]> wrote:
>>>
>>>
>>>
>>> On 4/28/2023 6:41 PM, Dmitry Baryshkov wrote:
>>>> On 29/04/2023 04:08, Abhinav Kumar wrote:
>>>>>
>>>>>
>>>>> On 4/28/2023 5:45 PM, Dmitry Baryshkov wrote:
>>>>>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>>>>>>> Legacy DPU requires PP hardware block involved into setting up DSC
>>>>>>
>>>>>> Nit: to be envolved
>>>>>>
>>>>>>> data path. This patch add DDPU_PINGPONG_DSC feature bit to both
>>>>>>
>>>>>> adds
>>>>>>
>>>>>>> PP_BLK and PP_BLK_TE so that both dpu_hw_pp_setup_dsc() and
>>>>>>> dpu_hw_pp_dsc_enable() will be executed during DSC path setup.
>>>>>>
>>>>>> Would it be easier to add PP_BLK_NO_DSC instead and make DSC enabled
>>>>>> by default for PP_BLK / PP_BLK_TE?
>>>>>>
>>>>>
>>>>> No because for some chipsets like qcm2290, it has a ping pong block
>>>>> but no DSC.
>>>>
>>>> And so it will use PP_BLK_NO_DSC (like msm8998 for PP_2/_3). But this
>>>
>>> Ok so you meant adding another PP_BLK_* macro. I mistook it for a
>>> feature flag.
>>>
>>> This is getting a bit confusing with many PP_BLK_* variations.
>>
>> Yes. As I wrote it might be not the optimal solution.
>>
>>>
>>>> might be not the optimal solution. Let's check all possible cases:
>>>>
>>>> - PP (or PP_TE?) with no DSC support,
>>>
>>> Yes correct for chipsets like qcm2290.
>>>
>>>> - PP/PP_TE tightly bound to the particular DSC instance, should be
>>>> allocated together,
>>>
>>> I need to check which exact chipset does this (I recall one does) but
>>> perhaps msm8998 fits here.
>>
>> All targets earlier than sm8150. SDE driver sets SDE_DSC_OUTPUT_CTRL
>> if for v1 CTL blocks (sm8150+).
>>
>>>
>>>> - PP/PP_TE which can use any DSC block.
>>>
>>> This is what DPU_PINGPONG_DSC feature flag should mean today and should
>>> cover most of the DSC 1.1 chipsets present in upstream today.
>>
>> Then it should probably be renamed to DPU_PINGPONG_ANY_DSC
>>
>
> Actually that "any" is incorrect. As part of the DSC pairing logic
> change it will become clear but not all ping-pongs can pair with all
> DSCs. So any is not right.
>
> This is why I think we should go with this feature flag first. Lets
> identify a pattern and then work on unifying or cleaning up the PP_BLK_*
> masks.

Then I'd like to see the series sent together so that we don't have to
be wondering in the myst. At least the RM changes might better go into
this series (together with the topology changes. I think RM will depend
on 1 DSC topology support).

I went on and checked the SDE. It has condition that pp % 2 == dsc % 2.
Does this condition apply only to "newest" DSC/PP combo (DITHER + 1.2)
or to the older ones too? Are there any other conditionals?

>
>>>> - all PP_DITHER probably support any DSC?
>>>>
>>>
>>> No, PP_DITHER means that there is no DSC in ping-pong block. Its
>>> actually DSC 1.2. From our standpoint, this is same as PP_BLK_NO_DSC
>>> then as the PP blk has no DSC. This is where the confusion will come.
>>
>> But we should still bind the DSC to the PP block, shouldn't we? So
>> from the software point of view it is the same situation: PP_DITHER
>> supports any DSC (1.2) and should be bound to it.
>>
>
> Yes, the DSC ctl will need to be programmed correctly to tell which
> ping-pong but like I said, any is not right. There are some conditions.
>
> Please refer to _sde_rm_reserve_dsc() in downstream.
>
>>>> Is this list correct? If so, we'd need to be able to specify the DSC id
>>>> in the PP block description.
>>>>
>>>
>>> Is this for the PP bound to a particular DSC case? If so, the goal of
>>> this is then you want to not allocate DSCs from RM for this case or what
>>> would be the purpose of specifying the DSC id in the ping-pong?
>>
>> I think it would be better to still return PP from the RM. It's that
>> the RM will have to return PP/DSC in pairs.
>>
>
> Yes, I was trying to understand what would be the purpose of this DSC id
> in the ping-pong block then.
>
>>>
>>>   From this classification, it looks like this case shall fit
>>> PP_BLK_NO_DSC but we have to then migrate PP_BLK_DITHER to this as well
>>> and add dither to that.
>>>
>>> Seems like this can be a separate effort to cleanup the PP_BLK_* macros
>>> first and go with this feature flag first instead of undertaking a
>>> PP_BLK_* macro cleanup in this series.
>>>
>>>>>
>>>>>>>
>>>>>>> Reported-by : Marijn Suijten <[email protected]>
>>>>>>> Signed-off-by: Kuogee Hsieh <[email protected]>
>>>>>>> ---
>>>>>>>    .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h    | 12
>>>>>>> +++++-----
>>>>>>>    .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h |  8 +++----
>>>>>>>    .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26
>>>>>>> ++++++++++------------
>>>>>>>    .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h    | 24
>>>>>>> ++++++++++----------
>>>>>>>    .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26
>>>>>>> ++++++++++------------
>>>>>>>    .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h |  4 ++--
>>>>>>>    .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h |  2 +-
>>>>>>>    .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h    |  2 +-
>>>>>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c     |  8 +++----
>>>>>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h     |  2 ++
>>>>>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c    |  9 +++++---
>>>>>>>    11 files changed, 62 insertions(+), 61 deletions(-)
>>>>>>>
>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>>> index 17f821c..b7cd746 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>>> @@ -112,16 +112,16 @@ static const struct dpu_lm_cfg msm8998_lm[]
>>>>>>> = {
>>>>>>>    };
>>>>>>>    static const struct dpu_pingpong_cfg msm8998_pp[] = {
>>>>>>> -    PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0,
>>>>>>> sdm845_pp_sblk_te,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>> +    PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000,
>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>>> +    PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800,
>>>>>>> BIT(DPU_PINGPONG_DSC), 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, 0, 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, 0, 0, sdm845_pp_sblk,
>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>>>>>    };
>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>>> index ceca741..8888bd9 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>>> @@ -110,16 +110,16 @@ static const struct dpu_lm_cfg sdm845_lm[] = {
>>>>>>>    };
>>>>>>>    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,
>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>> BIT(DPU_PINGPONG_DSC), 0, sdm845_pp_sblk,
>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>>>>>    };
>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>>> index 42b0e58..3a7dffa 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>>> @@ -128,24 +128,22 @@ static const struct dpu_dspp_cfg sm8150_dspp[]
>>>>>>> = {
>>>>>>>    };
>>>>>>>    static const struct dpu_pingpong_cfg sm8150_pp[] = {
>>>>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>>>>> sdm845_pp_sblk,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>>>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>>>>> sdm845_pp_sblk,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>> +            sdm845_pp_sblk, 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,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>>>>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>>>>> -            -1),
>>>>>>> -    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>>>>>>> sdm845_pp_sblk,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>>> -            -1),
>>>>>>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
>>>>>>> 30), -1),
>>>>>>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
>>>>>>> 31), -1),
>>>>>>>    };
>>>>>>>    static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>>> index 5bb9882..e766a2d 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>>> @@ -116,23 +116,23 @@ static const struct dpu_lm_cfg sc8180x_lm[]
>>>>>>> = {
>>>>>>>    };
>>>>>>>    static const struct dpu_pingpong_cfg sc8180x_pp[] = {
>>>>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>>>>> sdm845_pp_sblk,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>>>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>>>>> sdm845_pp_sblk,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>> +            sdm845_pp_sblk, 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,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>>>>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>>>>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>>>                -1),
>>>>>>>    };
>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>>> index ed130582..137b151 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>>> @@ -129,24 +129,22 @@ static const struct dpu_dspp_cfg sm8250_dspp[]
>>>>>>> = {
>>>>>>>    };
>>>>>>>    static const struct dpu_pingpong_cfg sm8250_pp[] = {
>>>>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>>>>> sdm845_pp_sblk,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>>>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>>>>> sdm845_pp_sblk,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>> +            sdm845_pp_sblk, 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,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>>>>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>>>>> -            -1),
>>>>>>> -    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>>>>>>> sdm845_pp_sblk,
>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>>> -            -1),
>>>>>>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
>>>>>>> 30), -1),
>>>>>>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
>>>>>>> 31), -1),
>>>>>>>    };
>>>>>>>    static const struct dpu_merge_3d_cfg sm8250_merge_3d[] = {
>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>>> index a46b117..e5631a2 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>>> @@ -80,8 +80,8 @@ static const struct dpu_dspp_cfg sc7180_dspp[] = {
>>>>>>>    };
>>>>>>>    static const struct dpu_pingpong_cfg sc7180_pp[] = {
>>>>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>>>>> -1, -1),
>>>>>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk,
>>>>>>> -1, -1),
>>>>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 0, sdm845_pp_sblk,
>>>>>>> -1, -1),
>>>>>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, 0, sdm845_pp_sblk,
>>>>>>> -1, -1),
>>>>>>>    };
>>>>>>>    static const struct dpu_intf_cfg sc7180_intf[] = {
>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>>> index 988d820..7b4ad0f 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>>> @@ -60,7 +60,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[] = {
>>>>>>>    };
>>>>>>>    static const struct dpu_pingpong_cfg sm6115_pp[] = {
>>>>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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/catalog/dpu_6_5_qcm2290.h
>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>>>>> index c9003dc..20d4d14 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>>>>> @@ -57,7 +57,7 @@ static const struct dpu_dspp_cfg qcm2290_dspp[]
>>>>>>> = {
>>>>>>>    };
>>>>>>>    static const struct dpu_pingpong_cfg qcm2290_pp[] = {
>>>>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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_catalog.c
>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>> index 91bfc8a..83c0cd9 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>> @@ -501,21 +501,21 @@ static const struct dpu_pingpong_sub_blks
>>>>>>> sc7280_pp_sblk = {
>>>>>>>        .intr_done = _done, \
>>>>>>>        .intr_rdptr = _rdptr, \
>>>>>>>        }
>>>>>>> -#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 = PINGPONG_SDM845_SPLIT_MASK | _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 = PINGPONG_SDM845_MASK | _features, \
>>>>>>>        .merge_3d = _merge_3d, \
>>>>>>>        .sblk = &_sblk, \
>>>>>>>        .intr_done = _done, \
>>>>>>> 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 fc87db1..6b49171 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>>>>>> @@ -144,6 +144,7 @@ enum {
>>>>>>>     * @DPU_PINGPONG_SPLIT      PP block supports split fifo
>>>>>>>     * @DPU_PINGPONG_SLAVE      PP block is a suitable slave for
>>>>>>> split
>>>>>>> fifo
>>>>>>>     * @DPU_PINGPONG_DITHER,    Dither blocks
>>>>>>> + * @DPU_PINGPONG_DSC,        PP block binding to DSC
>>>>>>>     * @DPU_PINGPONG_MAX
>>>>>>>     */
>>>>>>>    enum {
>>>>>>> @@ -152,6 +153,7 @@ enum {
>>>>>>>        DPU_PINGPONG_SPLIT,
>>>>>>>        DPU_PINGPONG_SLAVE,
>>>>>>>        DPU_PINGPONG_DITHER,
>>>>>>> +    DPU_PINGPONG_DSC,
>>>>>>>        DPU_PINGPONG_MAX
>>>>>>>    };
>>>>>>> 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 3822e06..f255a04 100644
>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>>>>>> @@ -264,9 +264,12 @@ static void _setup_pingpong_ops(struct
>>>>>>> dpu_hw_pingpong *c,
>>>>>>>        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;
>>>>>>> +
>>>>>>> +    if (features & BIT(DPU_PINGPONG_DSC)) {
>>>>>>> +        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;
>>>>>>> +    }
>>>>>>>        if (test_bit(DPU_PINGPONG_DITHER, &features))
>>>>>>>            c->ops.setup_dither = dpu_hw_pp_setup_dither;
>>>>>>
>>>>
>>
>>
>>

--
With best wishes
Dmitry

2023-04-29 08:46:29

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [Freedreno] [PATCH v2 5/7] drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE



On 4/28/2023 9:35 PM, Dmitry Baryshkov wrote:
> On 29/04/2023 07:04, Abhinav Kumar wrote:
>>
>>
>> On 4/28/2023 8:21 PM, Dmitry Baryshkov wrote:
>>> On Sat, 29 Apr 2023 at 05:50, Abhinav Kumar
>>> <[email protected]> wrote:
>>>>
>>>>
>>>>
>>>> On 4/28/2023 6:41 PM, Dmitry Baryshkov wrote:
>>>>> On 29/04/2023 04:08, Abhinav Kumar wrote:
>>>>>>
>>>>>>
>>>>>> On 4/28/2023 5:45 PM, Dmitry Baryshkov wrote:
>>>>>>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>>>>>>>> Legacy DPU requires PP hardware block involved into setting up DSC
>>>>>>>
>>>>>>> Nit: to be envolved
>>>>>>>
>>>>>>>> data path. This patch add DDPU_PINGPONG_DSC feature bit to both
>>>>>>>
>>>>>>> adds
>>>>>>>
>>>>>>>> PP_BLK and PP_BLK_TE so that both dpu_hw_pp_setup_dsc() and
>>>>>>>> dpu_hw_pp_dsc_enable() will be executed during DSC path setup.
>>>>>>>
>>>>>>> Would it be easier to add PP_BLK_NO_DSC instead and make DSC enabled
>>>>>>> by default for PP_BLK / PP_BLK_TE?
>>>>>>>
>>>>>>
>>>>>> No because for some chipsets like qcm2290, it has a ping pong block
>>>>>> but no DSC.
>>>>>
>>>>> And so it will use PP_BLK_NO_DSC (like msm8998 for PP_2/_3). But this
>>>>
>>>> Ok so you meant adding another PP_BLK_* macro. I mistook it for a
>>>> feature flag.
>>>>
>>>> This is getting a bit confusing with many PP_BLK_* variations.
>>>
>>> Yes. As I wrote it might be not the optimal solution.
>>>
>>>>
>>>>> might be not the optimal solution. Let's check all possible cases:
>>>>>
>>>>> - PP (or PP_TE?) with no DSC support,
>>>>
>>>> Yes correct for chipsets like qcm2290.
>>>>
>>>>> - PP/PP_TE tightly bound to the particular DSC instance, should be
>>>>> allocated together,
>>>>
>>>> I need to check which exact chipset does this (I recall one does) but
>>>> perhaps msm8998 fits here.
>>>
>>> All targets earlier than sm8150. SDE driver sets SDE_DSC_OUTPUT_CTRL
>>> if for v1 CTL blocks (sm8150+).
>>>
>>>>
>>>>> - PP/PP_TE which can use any DSC block.
>>>>
>>>> This is what DPU_PINGPONG_DSC feature flag should mean today and should
>>>> cover most of the DSC 1.1 chipsets present in upstream today.
>>>
>>> Then it should probably be renamed to DPU_PINGPONG_ANY_DSC
>>>
>>
>> Actually that "any" is incorrect. As part of the DSC pairing logic
>> change it will become clear but not all ping-pongs can pair with all
>> DSCs. So any is not right.
>>
>> This is why I think we should go with this feature flag first. Lets
>> identify a pattern and then work on unifying or cleaning up the
>> PP_BLK_* masks.
>
> Then I'd like to see the series sent together so that we don't have to
> be wondering in the myst. At least the RM changes might better go into
> this series (together with the topology changes. I think RM will depend
> on 1 DSC topology support).

Topology changes depend on which way the virtual planes series is going
to do and since we are going with fixed topology you preferred it to be
dropped right?

Now that you have seen the DSC to PP mapping code downstream you know
that every DSC cannot goto every ping-pong. So which way do you want to
go with this patch. If we are going to post a next revision, need some
conclusion here and I do not think PP_BLK_* was agreed as a clean
solution anyway.

Thats why I suggested:

1) Lets go with feature flag
2) When DP lands, thats the one which uses 1-1-1 topology so we can hit
some corner cases of lets say DP uses one DSC and then DSI uses merge we
should go with the right DSC pair. With only DSI, this will not arise.
3) With (1) and (2) done, we can take up PP_BLK_* cleanup if we feel its
necessary.

I dont see any conclusion or plan suggested by you so far on which way
you want to go.

>
> I went on and checked the SDE. It has condition that pp % 2 == dsc % 2.
> Does this condition apply only to "newest" DSC/PP combo (DITHER + 1.2)
> or to the older ones too? Are there any other conditionals?
>

It was there even for older DSCs and looks like wasnt implemented in the
current upstream code.


>>
>>>>> - all PP_DITHER probably support any DSC?
>>>>>
>>>>
>>>> No, PP_DITHER means that there is no DSC in ping-pong block. Its
>>>> actually DSC 1.2. From our standpoint, this is same as PP_BLK_NO_DSC
>>>> then as the PP blk has no DSC. This is where the confusion will come.
>>>
>>> But we should still bind the DSC to the PP block, shouldn't we? So
>>> from the software point of view it is the same situation: PP_DITHER
>>> supports any DSC (1.2) and should be bound to it.
>>>
>>
>> Yes, the DSC ctl will need to be programmed correctly to tell which
>> ping-pong but like I said, any is not right. There are some conditions.
>>
>> Please refer to _sde_rm_reserve_dsc() in downstream.
>>
>>>>> Is this list correct? If so, we'd need to be able to specify the
>>>>> DSC id
>>>>> in the PP block description.
>>>>>
>>>>
>>>> Is this for the PP bound to a particular DSC case? If so, the goal of
>>>> this is then you want to not allocate DSCs from RM for this case or
>>>> what
>>>> would be the purpose of specifying the DSC id in the ping-pong?
>>>
>>> I think it would be better to still return PP from the RM. It's that
>>> the RM will have to return PP/DSC in pairs.
>>>
>>
>> Yes, I was trying to understand what would be the purpose of this DSC
>> id in the ping-pong block then.
>>
>>>>
>>>>   From this classification, it looks like this case shall fit
>>>> PP_BLK_NO_DSC but we have to then migrate PP_BLK_DITHER to this as well
>>>> and add dither to that.
>>>>
>>>> Seems like this can be a separate effort to cleanup the PP_BLK_* macros
>>>> first and go with this feature flag first instead of undertaking a
>>>> PP_BLK_* macro cleanup in this series.
>>>>
>>>>>>
>>>>>>>>
>>>>>>>> Reported-by : Marijn Suijten <[email protected]>
>>>>>>>> Signed-off-by: Kuogee Hsieh <[email protected]>
>>>>>>>> ---
>>>>>>>>    .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h    | 12
>>>>>>>> +++++-----
>>>>>>>>    .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h |  8 +++----
>>>>>>>>    .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26
>>>>>>>> ++++++++++------------
>>>>>>>>    .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h    | 24
>>>>>>>> ++++++++++----------
>>>>>>>>    .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26
>>>>>>>> ++++++++++------------
>>>>>>>>    .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h |  4 ++--
>>>>>>>>    .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h |  2 +-
>>>>>>>>    .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h    |  2 +-
>>>>>>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c     |  8 +++----
>>>>>>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h     |  2 ++
>>>>>>>>    drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c    |  9 +++++---
>>>>>>>>    11 files changed, 62 insertions(+), 61 deletions(-)
>>>>>>>>
>>>>>>>> diff --git
>>>>>>>> a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>>>> index 17f821c..b7cd746 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>>>> @@ -112,16 +112,16 @@ static const struct dpu_lm_cfg
>>>>>>>> msm8998_lm[] = {
>>>>>>>>    };
>>>>>>>>    static const struct dpu_pingpong_cfg msm8998_pp[] = {
>>>>>>>> -    PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0,
>>>>>>>> sdm845_pp_sblk_te,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>> +    PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>>>> +    PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 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, 0, 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, 0, 0,
>>>>>>>> sdm845_pp_sblk,
>>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>>>>>>    };
>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>>>> index ceca741..8888bd9 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>>>> @@ -110,16 +110,16 @@ static const struct dpu_lm_cfg sdm845_lm[]
>>>>>>>> = {
>>>>>>>>    };
>>>>>>>>    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,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 0, sdm845_pp_sblk,
>>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>>>>>>    };
>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>>>> index 42b0e58..3a7dffa 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>>>> @@ -128,24 +128,22 @@ static const struct dpu_dspp_cfg
>>>>>>>> sm8150_dspp[]
>>>>>>>> = {
>>>>>>>>    };
>>>>>>>>    static const struct dpu_pingpong_cfg sm8150_pp[] = {
>>>>>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>>>>>> sdm845_pp_sblk,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>>>>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>>>>>> sdm845_pp_sblk,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>>> +            sdm845_pp_sblk, 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,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>>>>>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>>>>>> -            -1),
>>>>>>>> -    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>>>>>>>> sdm845_pp_sblk,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>>>> -            -1),
>>>>>>>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
>>>>>>>> 30), -1),
>>>>>>>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
>>>>>>>> 31), -1),
>>>>>>>>    };
>>>>>>>>    static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
>>>>>>>> diff --git
>>>>>>>> a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>>>> index 5bb9882..e766a2d 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>>>> @@ -116,23 +116,23 @@ static const struct dpu_lm_cfg
>>>>>>>> sc8180x_lm[] = {
>>>>>>>>    };
>>>>>>>>    static const struct dpu_pingpong_cfg sc8180x_pp[] = {
>>>>>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>>>>>> sdm845_pp_sblk,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>>>>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>>>>>> sdm845_pp_sblk,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>>> +            sdm845_pp_sblk, 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,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>>>>>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>>>>>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>>>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>>>>                -1),
>>>>>>>>    };
>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>>>> index ed130582..137b151 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>>>> @@ -129,24 +129,22 @@ static const struct dpu_dspp_cfg
>>>>>>>> sm8250_dspp[]
>>>>>>>> = {
>>>>>>>>    };
>>>>>>>>    static const struct dpu_pingpong_cfg sm8250_pp[] = {
>>>>>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>>>>>> sdm845_pp_sblk,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>>                DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>>>>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>>>>>> sdm845_pp_sblk,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>>> +            sdm845_pp_sblk, 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,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>>>>>> +    PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>>> +    PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>>>>>> -            -1),
>>>>>>>> -    PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>>>>>>>> sdm845_pp_sblk,
>>>>>>>> -            DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>>>> -            -1),
>>>>>>>> +    PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
>>>>>>>> 30), -1),
>>>>>>>> +    PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>>> +            sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
>>>>>>>> 31), -1),
>>>>>>>>    };
>>>>>>>>    static const struct dpu_merge_3d_cfg sm8250_merge_3d[] = {
>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>>>> index a46b117..e5631a2 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>>>> @@ -80,8 +80,8 @@ static const struct dpu_dspp_cfg sc7180_dspp[]
>>>>>>>> = {
>>>>>>>>    };
>>>>>>>>    static const struct dpu_pingpong_cfg sc7180_pp[] = {
>>>>>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>>>>>> -1, -1),
>>>>>>>> -    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk,
>>>>>>>> -1, -1),
>>>>>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 0,
>>>>>>>> sdm845_pp_sblk,
>>>>>>>> -1, -1),
>>>>>>>> +    PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, 0,
>>>>>>>> sdm845_pp_sblk,
>>>>>>>> -1, -1),
>>>>>>>>    };
>>>>>>>>    static const struct dpu_intf_cfg sc7180_intf[] = {
>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>>>> index 988d820..7b4ad0f 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>>>> @@ -60,7 +60,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[]
>>>>>>>> = {
>>>>>>>>    };
>>>>>>>>    static const struct dpu_pingpong_cfg sm6115_pp[] = {
>>>>>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>>>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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/catalog/dpu_6_5_qcm2290.h
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>>>>>> index c9003dc..20d4d14 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>>>>>> @@ -57,7 +57,7 @@ static const struct dpu_dspp_cfg
>>>>>>>> qcm2290_dspp[] = {
>>>>>>>>    };
>>>>>>>>    static const struct dpu_pingpong_cfg qcm2290_pp[] = {
>>>>>>>> -    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>>>>>> +    PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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_catalog.c
>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>> index 91bfc8a..83c0cd9 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>> @@ -501,21 +501,21 @@ static const struct dpu_pingpong_sub_blks
>>>>>>>> sc7280_pp_sblk = {
>>>>>>>>        .intr_done = _done, \
>>>>>>>>        .intr_rdptr = _rdptr, \
>>>>>>>>        }
>>>>>>>> -#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 = PINGPONG_SDM845_SPLIT_MASK | _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 = PINGPONG_SDM845_MASK | _features, \
>>>>>>>>        .merge_3d = _merge_3d, \
>>>>>>>>        .sblk = &_sblk, \
>>>>>>>>        .intr_done = _done, \
>>>>>>>> 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 fc87db1..6b49171 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>>>>>>> @@ -144,6 +144,7 @@ enum {
>>>>>>>>     * @DPU_PINGPONG_SPLIT      PP block supports split fifo
>>>>>>>>     * @DPU_PINGPONG_SLAVE      PP block is a suitable slave for
>>>>>>>> split
>>>>>>>> fifo
>>>>>>>>     * @DPU_PINGPONG_DITHER,    Dither blocks
>>>>>>>> + * @DPU_PINGPONG_DSC,        PP block binding to DSC
>>>>>>>>     * @DPU_PINGPONG_MAX
>>>>>>>>     */
>>>>>>>>    enum {
>>>>>>>> @@ -152,6 +153,7 @@ enum {
>>>>>>>>        DPU_PINGPONG_SPLIT,
>>>>>>>>        DPU_PINGPONG_SLAVE,
>>>>>>>>        DPU_PINGPONG_DITHER,
>>>>>>>> +    DPU_PINGPONG_DSC,
>>>>>>>>        DPU_PINGPONG_MAX
>>>>>>>>    };
>>>>>>>> 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 3822e06..f255a04 100644
>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>>>>>>> @@ -264,9 +264,12 @@ static void _setup_pingpong_ops(struct
>>>>>>>> dpu_hw_pingpong *c,
>>>>>>>>        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;
>>>>>>>> +
>>>>>>>> +    if (features & BIT(DPU_PINGPONG_DSC)) {
>>>>>>>> +        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;
>>>>>>>> +    }
>>>>>>>>        if (test_bit(DPU_PINGPONG_DITHER, &features))
>>>>>>>>            c->ops.setup_dither = dpu_hw_pp_setup_dither;
>>>>>>>
>>>>>
>>>
>>>
>>>
>

2023-04-29 19:51:23

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [Freedreno] [PATCH v2 5/7] drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE

On Sat, 29 Apr 2023 at 11:43, Abhinav Kumar <[email protected]> wrote:
>
>
>
> On 4/28/2023 9:35 PM, Dmitry Baryshkov wrote:
> > On 29/04/2023 07:04, Abhinav Kumar wrote:
> >>
> >>
> >> On 4/28/2023 8:21 PM, Dmitry Baryshkov wrote:
> >>> On Sat, 29 Apr 2023 at 05:50, Abhinav Kumar
> >>> <[email protected]> wrote:
> >>>>
> >>>>
> >>>>
> >>>> On 4/28/2023 6:41 PM, Dmitry Baryshkov wrote:
> >>>>> On 29/04/2023 04:08, Abhinav Kumar wrote:
> >>>>>>
> >>>>>>
> >>>>>> On 4/28/2023 5:45 PM, Dmitry Baryshkov wrote:
> >>>>>>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
> >>>>>>>> Legacy DPU requires PP hardware block involved into setting up DSC
> >>>>>>>
> >>>>>>> Nit: to be envolved
> >>>>>>>
> >>>>>>>> data path. This patch add DDPU_PINGPONG_DSC feature bit to both
> >>>>>>>
> >>>>>>> adds
> >>>>>>>
> >>>>>>>> PP_BLK and PP_BLK_TE so that both dpu_hw_pp_setup_dsc() and
> >>>>>>>> dpu_hw_pp_dsc_enable() will be executed during DSC path setup.
> >>>>>>>
> >>>>>>> Would it be easier to add PP_BLK_NO_DSC instead and make DSC enabled
> >>>>>>> by default for PP_BLK / PP_BLK_TE?
> >>>>>>>
> >>>>>>
> >>>>>> No because for some chipsets like qcm2290, it has a ping pong block
> >>>>>> but no DSC.
> >>>>>
> >>>>> And so it will use PP_BLK_NO_DSC (like msm8998 for PP_2/_3). But this
> >>>>
> >>>> Ok so you meant adding another PP_BLK_* macro. I mistook it for a
> >>>> feature flag.
> >>>>
> >>>> This is getting a bit confusing with many PP_BLK_* variations.
> >>>
> >>> Yes. As I wrote it might be not the optimal solution.
> >>>
> >>>>
> >>>>> might be not the optimal solution. Let's check all possible cases:
> >>>>>
> >>>>> - PP (or PP_TE?) with no DSC support,
> >>>>
> >>>> Yes correct for chipsets like qcm2290.
> >>>>
> >>>>> - PP/PP_TE tightly bound to the particular DSC instance, should be
> >>>>> allocated together,
> >>>>
> >>>> I need to check which exact chipset does this (I recall one does) but
> >>>> perhaps msm8998 fits here.
> >>>
> >>> All targets earlier than sm8150. SDE driver sets SDE_DSC_OUTPUT_CTRL
> >>> if for v1 CTL blocks (sm8150+).
> >>>
> >>>>
> >>>>> - PP/PP_TE which can use any DSC block.
> >>>>
> >>>> This is what DPU_PINGPONG_DSC feature flag should mean today and should
> >>>> cover most of the DSC 1.1 chipsets present in upstream today.
> >>>
> >>> Then it should probably be renamed to DPU_PINGPONG_ANY_DSC
> >>>
> >>
> >> Actually that "any" is incorrect. As part of the DSC pairing logic
> >> change it will become clear but not all ping-pongs can pair with all
> >> DSCs. So any is not right.
> >>
> >> This is why I think we should go with this feature flag first. Lets
> >> identify a pattern and then work on unifying or cleaning up the
> >> PP_BLK_* masks.
> >
> > Then I'd like to see the series sent together so that we don't have to
> > be wondering in the myst. At least the RM changes might better go into
> > this series (together with the topology changes. I think RM will depend
> > on 1 DSC topology support).
>
> Topology changes depend on which way the virtual planes series is going
> to do and since we are going with fixed topology you preferred it to be
> dropped right?

It was not about the topology changes (e.g. supporting 1:1:1), but
about storying the topology in the encoder.

>
> Now that you have seen the DSC to PP mapping code downstream you know
> that every DSC cannot goto every ping-pong. So which way do you want to
> go with this patch. If we are going to post a next revision, need some
> conclusion here and I do not think PP_BLK_* was agreed as a clean
> solution anyway.

No, it was not agreed. That's why I tried listing all possible cases
(in an attempt to understand the limitations and/or possible
usecases).

>
> Thats why I suggested:
>
> 1) Lets go with feature flag
> 2) When DP lands, thats the one which uses 1-1-1 topology so we can hit
> some corner cases of lets say DP uses one DSC and then DSI uses merge we
> should go with the right DSC pair. With only DSI, this will not arise.
> 3) With (1) and (2) done, we can take up PP_BLK_* cleanup if we feel its
> necessary.
>
> I dont see any conclusion or plan suggested by you so far on which way
> you want to go.

I'd propose the following plan:
- Drop all the topology and PP changes from this series. Make it add
just DSC 1.2 support.

Then for the DSI DSC 1.2 we should be able to continue using existing
RM/PP code with known limitations.

Next:
- Split DPU_PINGPONG_DSC feature flag to a separate patch series. It
looks like it should have some Fixes tag, as it prevents one from
calling *dsc functions for PPs which do not support them
- Extend the series with the RM fix which skips non-DSC-enabled PPs
when DSC is required.
- As this series is touching RM, it is a good place to handle DSC
allocation issues, which includes:
* tight coupling of PP/DSC blocks on sdm845 and msm8998
* limitations for 1:1:1 or co-allocation of DSC blocks for both DSI
and DP DSC (might be split to a separate patchset, up to you)

DP DSC depends either on this series or on a separate patchset

>
> >
> > I went on and checked the SDE. It has condition that pp % 2 == dsc % 2.
> > Does this condition apply only to "newest" DSC/PP combo (DITHER + 1.2)
> > or to the older ones too? Are there any other conditionals?
> >
>
> It was there even for older DSCs and looks like wasnt implemented in the
> current upstream code.

Thanks for the info.


>
>
> >>
> >>>>> - all PP_DITHER probably support any DSC?
> >>>>>
> >>>>
> >>>> No, PP_DITHER means that there is no DSC in ping-pong block. Its
> >>>> actually DSC 1.2. From our standpoint, this is same as PP_BLK_NO_DSC
> >>>> then as the PP blk has no DSC. This is where the confusion will come.
> >>>
> >>> But we should still bind the DSC to the PP block, shouldn't we? So
> >>> from the software point of view it is the same situation: PP_DITHER
> >>> supports any DSC (1.2) and should be bound to it.
> >>>
> >>
> >> Yes, the DSC ctl will need to be programmed correctly to tell which
> >> ping-pong but like I said, any is not right. There are some conditions.
> >>
> >> Please refer to _sde_rm_reserve_dsc() in downstream.
> >>
> >>>>> Is this list correct? If so, we'd need to be able to specify the
> >>>>> DSC id
> >>>>> in the PP block description.
> >>>>>
> >>>>
> >>>> Is this for the PP bound to a particular DSC case? If so, the goal of
> >>>> this is then you want to not allocate DSCs from RM for this case or
> >>>> what
> >>>> would be the purpose of specifying the DSC id in the ping-pong?
> >>>
> >>> I think it would be better to still return PP from the RM. It's that
> >>> the RM will have to return PP/DSC in pairs.
> >>>
> >>
> >> Yes, I was trying to understand what would be the purpose of this DSC
> >> id in the ping-pong block then.
> >>
> >>>>
> >>>> From this classification, it looks like this case shall fit
> >>>> PP_BLK_NO_DSC but we have to then migrate PP_BLK_DITHER to this as well
> >>>> and add dither to that.
> >>>>
> >>>> Seems like this can be a separate effort to cleanup the PP_BLK_* macros
> >>>> first and go with this feature flag first instead of undertaking a
> >>>> PP_BLK_* macro cleanup in this series.
> >>>>
> >>>>>>
> >>>>>>>>
> >>>>>>>> Reported-by : Marijn Suijten <[email protected]>
> >>>>>>>> Signed-off-by: Kuogee Hsieh <[email protected]>
> >>>>>>>> ---
> >>>>>>>> .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 12
> >>>>>>>> +++++-----
> >>>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 +++----
> >>>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26
> >>>>>>>> ++++++++++------------
> >>>>>>>> .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 24
> >>>>>>>> ++++++++++----------
> >>>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26
> >>>>>>>> ++++++++++------------
> >>>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 ++--
> >>>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +-
> >>>>>>>> .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +-
> >>>>>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 8 +++----
> >>>>>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++
> >>>>>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 +++++---
> >>>>>>>> 11 files changed, 62 insertions(+), 61 deletions(-)
> >>>>>>>>
> >>>>>>>> diff --git
> >>>>>>>> a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> >>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> >>>>>>>> index 17f821c..b7cd746 100644
> >>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> >>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
> >>>>>>>> @@ -112,16 +112,16 @@ static const struct dpu_lm_cfg
> >>>>>>>> msm8998_lm[] = {
> >>>>>>>> };
> >>>>>>>> static const struct dpu_pingpong_cfg msm8998_pp[] = {
> >>>>>>>> - PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0,
> >>>>>>>> sdm845_pp_sblk_te,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>>>>>> + PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> >>>>>>>> + PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 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, 0, 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, 0, 0,
> >>>>>>>> sdm845_pp_sblk,
> >>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> >>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
> >>>>>>>> };
> >>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
> >>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
> >>>>>>>> index ceca741..8888bd9 100644
> >>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
> >>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
> >>>>>>>> @@ -110,16 +110,16 @@ static const struct dpu_lm_cfg sdm845_lm[]
> >>>>>>>> = {
> >>>>>>>> };
> >>>>>>>> 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,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 0, sdm845_pp_sblk,
> >>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> >>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
> >>>>>>>> };
> >>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> >>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> >>>>>>>> index 42b0e58..3a7dffa 100644
> >>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> >>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
> >>>>>>>> @@ -128,24 +128,22 @@ static const struct dpu_dspp_cfg
> >>>>>>>> sm8150_dspp[]
> >>>>>>>> = {
> >>>>>>>> };
> >>>>>>>> static const struct dpu_pingpong_cfg sm8150_pp[] = {
> >>>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
> >>>>>>>> sdm845_pp_sblk,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> >>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> >>>>>>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
> >>>>>>>> sdm845_pp_sblk,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> >>>>>>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> >>>>>>>> + sdm845_pp_sblk, 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,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
> >>>>>>>> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> >>>>>>>> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
> >>>>>>>> - -1),
> >>>>>>>> - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
> >>>>>>>> sdm845_pp_sblk,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> >>>>>>>> - -1),
> >>>>>>>> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> >>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
> >>>>>>>> 30), -1),
> >>>>>>>> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> >>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
> >>>>>>>> 31), -1),
> >>>>>>>> };
> >>>>>>>> static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
> >>>>>>>> diff --git
> >>>>>>>> a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> >>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> >>>>>>>> index 5bb9882..e766a2d 100644
> >>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> >>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
> >>>>>>>> @@ -116,23 +116,23 @@ static const struct dpu_lm_cfg
> >>>>>>>> sc8180x_lm[] = {
> >>>>>>>> };
> >>>>>>>> static const struct dpu_pingpong_cfg sc8180x_pp[] = {
> >>>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
> >>>>>>>> sdm845_pp_sblk,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> >>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> >>>>>>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
> >>>>>>>> sdm845_pp_sblk,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> >>>>>>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> >>>>>>>> + sdm845_pp_sblk, 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,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
> >>>>>>>> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> >>>>>>>> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
> >>>>>>>> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> >>>>>>>> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> >>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> >>>>>>>> -1),
> >>>>>>>> };
> >>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
> >>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
> >>>>>>>> index ed130582..137b151 100644
> >>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
> >>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
> >>>>>>>> @@ -129,24 +129,22 @@ static const struct dpu_dspp_cfg
> >>>>>>>> sm8250_dspp[]
> >>>>>>>> = {
> >>>>>>>> };
> >>>>>>>> static const struct dpu_pingpong_cfg sm8250_pp[] = {
> >>>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
> >>>>>>>> sdm845_pp_sblk,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> >>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
> >>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
> >>>>>>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
> >>>>>>>> sdm845_pp_sblk,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
> >>>>>>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
> >>>>>>>> + sdm845_pp_sblk, 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,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
> >>>>>>>> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
> >>>>>>>> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
> >>>>>>>> - -1),
> >>>>>>>> - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
> >>>>>>>> sdm845_pp_sblk,
> >>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
> >>>>>>>> - -1),
> >>>>>>>> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> >>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
> >>>>>>>> 30), -1),
> >>>>>>>> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
> >>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
> >>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
> >>>>>>>> 31), -1),
> >>>>>>>> };
> >>>>>>>> static const struct dpu_merge_3d_cfg sm8250_merge_3d[] = {
> >>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
> >>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
> >>>>>>>> index a46b117..e5631a2 100644
> >>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
> >>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
> >>>>>>>> @@ -80,8 +80,8 @@ static const struct dpu_dspp_cfg sc7180_dspp[]
> >>>>>>>> = {
> >>>>>>>> };
> >>>>>>>> static const struct dpu_pingpong_cfg sc7180_pp[] = {
> >>>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
> >>>>>>>> -1, -1),
> >>>>>>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk,
> >>>>>>>> -1, -1),
> >>>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 0,
> >>>>>>>> sdm845_pp_sblk,
> >>>>>>>> -1, -1),
> >>>>>>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, 0,
> >>>>>>>> sdm845_pp_sblk,
> >>>>>>>> -1, -1),
> >>>>>>>> };
> >>>>>>>> static const struct dpu_intf_cfg sc7180_intf[] = {
> >>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
> >>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
> >>>>>>>> index 988d820..7b4ad0f 100644
> >>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
> >>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
> >>>>>>>> @@ -60,7 +60,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[]
> >>>>>>>> = {
> >>>>>>>> };
> >>>>>>>> static const struct dpu_pingpong_cfg sm6115_pp[] = {
> >>>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
> >>>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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/catalog/dpu_6_5_qcm2290.h
> >>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
> >>>>>>>> index c9003dc..20d4d14 100644
> >>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
> >>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
> >>>>>>>> @@ -57,7 +57,7 @@ static const struct dpu_dspp_cfg
> >>>>>>>> qcm2290_dspp[] = {
> >>>>>>>> };
> >>>>>>>> static const struct dpu_pingpong_cfg qcm2290_pp[] = {
> >>>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
> >>>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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_catalog.c
> >>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >>>>>>>> index 91bfc8a..83c0cd9 100644
> >>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
> >>>>>>>> @@ -501,21 +501,21 @@ static const struct dpu_pingpong_sub_blks
> >>>>>>>> sc7280_pp_sblk = {
> >>>>>>>> .intr_done = _done, \
> >>>>>>>> .intr_rdptr = _rdptr, \
> >>>>>>>> }
> >>>>>>>> -#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 = PINGPONG_SDM845_SPLIT_MASK | _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 = PINGPONG_SDM845_MASK | _features, \
> >>>>>>>> .merge_3d = _merge_3d, \
> >>>>>>>> .sblk = &_sblk, \
> >>>>>>>> .intr_done = _done, \
> >>>>>>>> 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 fc87db1..6b49171 100644
> >>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> >>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
> >>>>>>>> @@ -144,6 +144,7 @@ enum {
> >>>>>>>> * @DPU_PINGPONG_SPLIT PP block supports split fifo
> >>>>>>>> * @DPU_PINGPONG_SLAVE PP block is a suitable slave for
> >>>>>>>> split
> >>>>>>>> fifo
> >>>>>>>> * @DPU_PINGPONG_DITHER, Dither blocks
> >>>>>>>> + * @DPU_PINGPONG_DSC, PP block binding to DSC
> >>>>>>>> * @DPU_PINGPONG_MAX
> >>>>>>>> */
> >>>>>>>> enum {
> >>>>>>>> @@ -152,6 +153,7 @@ enum {
> >>>>>>>> DPU_PINGPONG_SPLIT,
> >>>>>>>> DPU_PINGPONG_SLAVE,
> >>>>>>>> DPU_PINGPONG_DITHER,
> >>>>>>>> + DPU_PINGPONG_DSC,
> >>>>>>>> DPU_PINGPONG_MAX
> >>>>>>>> };
> >>>>>>>> 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 3822e06..f255a04 100644
> >>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
> >>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
> >>>>>>>> @@ -264,9 +264,12 @@ static void _setup_pingpong_ops(struct
> >>>>>>>> dpu_hw_pingpong *c,
> >>>>>>>> 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;
> >>>>>>>> +
> >>>>>>>> + if (features & BIT(DPU_PINGPONG_DSC)) {
> >>>>>>>> + 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;
> >>>>>>>> + }
> >>>>>>>> if (test_bit(DPU_PINGPONG_DITHER, &features))
> >>>>>>>> c->ops.setup_dither = dpu_hw_pp_setup_dither;
> >>>>>>>
> >>>>>
> >>>
> >>>
> >>>
> >



--
With best wishes
Dmitry

2023-04-29 20:27:23

by Abhinav Kumar

[permalink] [raw]
Subject: Re: [Freedreno] [PATCH v2 5/7] drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE



On 4/29/2023 12:45 PM, Dmitry Baryshkov wrote:
> On Sat, 29 Apr 2023 at 11:43, Abhinav Kumar <[email protected]> wrote:
>>
>>
>>
>> On 4/28/2023 9:35 PM, Dmitry Baryshkov wrote:
>>> On 29/04/2023 07:04, Abhinav Kumar wrote:
>>>>
>>>>
>>>> On 4/28/2023 8:21 PM, Dmitry Baryshkov wrote:
>>>>> On Sat, 29 Apr 2023 at 05:50, Abhinav Kumar
>>>>> <[email protected]> wrote:
>>>>>>
>>>>>>
>>>>>>
>>>>>> On 4/28/2023 6:41 PM, Dmitry Baryshkov wrote:
>>>>>>> On 29/04/2023 04:08, Abhinav Kumar wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>> On 4/28/2023 5:45 PM, Dmitry Baryshkov wrote:
>>>>>>>>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>>>>>>>>>> Legacy DPU requires PP hardware block involved into setting up DSC
>>>>>>>>>
>>>>>>>>> Nit: to be envolved
>>>>>>>>>
>>>>>>>>>> data path. This patch add DDPU_PINGPONG_DSC feature bit to both
>>>>>>>>>
>>>>>>>>> adds
>>>>>>>>>
>>>>>>>>>> PP_BLK and PP_BLK_TE so that both dpu_hw_pp_setup_dsc() and
>>>>>>>>>> dpu_hw_pp_dsc_enable() will be executed during DSC path setup.
>>>>>>>>>
>>>>>>>>> Would it be easier to add PP_BLK_NO_DSC instead and make DSC enabled
>>>>>>>>> by default for PP_BLK / PP_BLK_TE?
>>>>>>>>>
>>>>>>>>
>>>>>>>> No because for some chipsets like qcm2290, it has a ping pong block
>>>>>>>> but no DSC.
>>>>>>>
>>>>>>> And so it will use PP_BLK_NO_DSC (like msm8998 for PP_2/_3). But this
>>>>>>
>>>>>> Ok so you meant adding another PP_BLK_* macro. I mistook it for a
>>>>>> feature flag.
>>>>>>
>>>>>> This is getting a bit confusing with many PP_BLK_* variations.
>>>>>
>>>>> Yes. As I wrote it might be not the optimal solution.
>>>>>
>>>>>>
>>>>>>> might be not the optimal solution. Let's check all possible cases:
>>>>>>>
>>>>>>> - PP (or PP_TE?) with no DSC support,
>>>>>>
>>>>>> Yes correct for chipsets like qcm2290.
>>>>>>
>>>>>>> - PP/PP_TE tightly bound to the particular DSC instance, should be
>>>>>>> allocated together,
>>>>>>
>>>>>> I need to check which exact chipset does this (I recall one does) but
>>>>>> perhaps msm8998 fits here.
>>>>>
>>>>> All targets earlier than sm8150. SDE driver sets SDE_DSC_OUTPUT_CTRL
>>>>> if for v1 CTL blocks (sm8150+).
>>>>>
>>>>>>
>>>>>>> - PP/PP_TE which can use any DSC block.
>>>>>>
>>>>>> This is what DPU_PINGPONG_DSC feature flag should mean today and should
>>>>>> cover most of the DSC 1.1 chipsets present in upstream today.
>>>>>
>>>>> Then it should probably be renamed to DPU_PINGPONG_ANY_DSC
>>>>>
>>>>
>>>> Actually that "any" is incorrect. As part of the DSC pairing logic
>>>> change it will become clear but not all ping-pongs can pair with all
>>>> DSCs. So any is not right.
>>>>
>>>> This is why I think we should go with this feature flag first. Lets
>>>> identify a pattern and then work on unifying or cleaning up the
>>>> PP_BLK_* masks.
>>>
>>> Then I'd like to see the series sent together so that we don't have to
>>> be wondering in the myst. At least the RM changes might better go into
>>> this series (together with the topology changes. I think RM will depend
>>> on 1 DSC topology support).
>>
>> Topology changes depend on which way the virtual planes series is going
>> to do and since we are going with fixed topology you preferred it to be
>> dropped right?
>
> It was not about the topology changes (e.g. supporting 1:1:1), but
> about storying the topology in the encoder.
>

So you are suggesting drop patch 6 of this series and keep 7 OR drop 6
and 7 both?

It looks like if 6 is dropped, then 7 has to be as well because we need
to store topology somewhere cannot keep passing locally.

Thats why I was okay to drop 6 and 7 together.

>>
>> Now that you have seen the DSC to PP mapping code downstream you know
>> that every DSC cannot goto every ping-pong. So which way do you want to
>> go with this patch. If we are going to post a next revision, need some
>> conclusion here and I do not think PP_BLK_* was agreed as a clean
>> solution anyway.
>
> No, it was not agreed. That's why I tried listing all possible cases
> (in an attempt to understand the limitations and/or possible
> usecases).
>
>>
>> Thats why I suggested:
>>
>> 1) Lets go with feature flag
>> 2) When DP lands, thats the one which uses 1-1-1 topology so we can hit
>> some corner cases of lets say DP uses one DSC and then DSI uses merge we
>> should go with the right DSC pair. With only DSI, this will not arise.
>> 3) With (1) and (2) done, we can take up PP_BLK_* cleanup if we feel its
>> necessary.
>>
>> I dont see any conclusion or plan suggested by you so far on which way
>> you want to go.
>
> I'd propose the following plan:

Thanks for summarizing what you had in mind, that makes it clear.

> - Drop all the topology and PP changes from this series. Make it add
> just DSC 1.2 support.
>
> Then for the DSI DSC 1.2 we should be able to continue using existing
> RM/PP code with known limitations.
>


So just keep patches 1-3 right? The issue with that is
_setup_pingpong_ops will still get called even for DSC 1.2 with those
changes. This was actually noted by Marijn during the catalog cleanup we
recently merged to -fixes. Thats why we included that in this so that we
dont call DSC 1.1 related functions for 1.2

Any specific reason why you dont want to go with patches 1-5 now and
drop 6,7 as that depends on storing topology.

> Next:
> - Split DPU_PINGPONG_DSC feature flag to a separate patch series. It
> looks like it should have some Fixes tag, as it prevents one from
> calling *dsc functions for PPs which do not support them

We can still add the fixes tag and keep it here and move it to the front?

> - Extend the series with the RM fix which skips non-DSC-enabled PPs
> when DSC is required.
> - As this series is touching RM, it is a good place to handle DSC
> allocation issues, which includes:
> * tight coupling of PP/DSC blocks on sdm845 and msm8998
> * limitations for 1:1:1 or co-allocation of DSC blocks for both DSI
> and DP DSC (might be split to a separate patchset, up to you)

I am a bit confused about this. This patch is not touching RM at all
from what I can see. So the issue of DSC pair allocation is there even
today with or without DSC 1.2 about which DSCs pair with which ones and
which DSCs go with which PP.

I feel that once DSC 1.2, that is just patches 1-5 land, I agree this
can be and should be a series on its own to prepare for DP DSC.

What use-case gets broken for DSI if we land 1-5?

We are trying to expand this series for a condition which wont hit till
DP DSC lands due to the fixed topology and only one client for DSC which
is DSI.

>
> DP DSC depends either on this series or on a separate patchset
>
>>
>>>
>>> I went on and checked the SDE. It has condition that pp % 2 == dsc % 2.
>>> Does this condition apply only to "newest" DSC/PP combo (DITHER + 1.2)
>>> or to the older ones too? Are there any other conditionals?
>>>
>>
>> It was there even for older DSCs and looks like wasnt implemented in the
>> current upstream code.
>
> Thanks for the info.
>
>
>>
>>
>>>>
>>>>>>> - all PP_DITHER probably support any DSC?
>>>>>>>
>>>>>>
>>>>>> No, PP_DITHER means that there is no DSC in ping-pong block. Its
>>>>>> actually DSC 1.2. From our standpoint, this is same as PP_BLK_NO_DSC
>>>>>> then as the PP blk has no DSC. This is where the confusion will come.
>>>>>
>>>>> But we should still bind the DSC to the PP block, shouldn't we? So
>>>>> from the software point of view it is the same situation: PP_DITHER
>>>>> supports any DSC (1.2) and should be bound to it.
>>>>>
>>>>
>>>> Yes, the DSC ctl will need to be programmed correctly to tell which
>>>> ping-pong but like I said, any is not right. There are some conditions.
>>>>
>>>> Please refer to _sde_rm_reserve_dsc() in downstream.
>>>>
>>>>>>> Is this list correct? If so, we'd need to be able to specify the
>>>>>>> DSC id
>>>>>>> in the PP block description.
>>>>>>>
>>>>>>
>>>>>> Is this for the PP bound to a particular DSC case? If so, the goal of
>>>>>> this is then you want to not allocate DSCs from RM for this case or
>>>>>> what
>>>>>> would be the purpose of specifying the DSC id in the ping-pong?
>>>>>
>>>>> I think it would be better to still return PP from the RM. It's that
>>>>> the RM will have to return PP/DSC in pairs.
>>>>>
>>>>
>>>> Yes, I was trying to understand what would be the purpose of this DSC
>>>> id in the ping-pong block then.
>>>>
>>>>>>
>>>>>> From this classification, it looks like this case shall fit
>>>>>> PP_BLK_NO_DSC but we have to then migrate PP_BLK_DITHER to this as well
>>>>>> and add dither to that.
>>>>>>
>>>>>> Seems like this can be a separate effort to cleanup the PP_BLK_* macros
>>>>>> first and go with this feature flag first instead of undertaking a
>>>>>> PP_BLK_* macro cleanup in this series.
>>>>>>
>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Reported-by : Marijn Suijten <[email protected]>
>>>>>>>>>> Signed-off-by: Kuogee Hsieh <[email protected]>
>>>>>>>>>> ---
>>>>>>>>>> .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 12
>>>>>>>>>> +++++-----
>>>>>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h | 8 +++----
>>>>>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h | 26
>>>>>>>>>> ++++++++++------------
>>>>>>>>>> .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 24
>>>>>>>>>> ++++++++++----------
>>>>>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h | 26
>>>>>>>>>> ++++++++++------------
>>>>>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h | 4 ++--
>>>>>>>>>> .../gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h | 2 +-
>>>>>>>>>> .../drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h | 2 +-
>>>>>>>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 8 +++----
>>>>>>>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 2 ++
>>>>>>>>>> drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 +++++---
>>>>>>>>>> 11 files changed, 62 insertions(+), 61 deletions(-)
>>>>>>>>>>
>>>>>>>>>> diff --git
>>>>>>>>>> a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>>>>>> index 17f821c..b7cd746 100644
>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h
>>>>>>>>>> @@ -112,16 +112,16 @@ static const struct dpu_lm_cfg
>>>>>>>>>> msm8998_lm[] = {
>>>>>>>>>> };
>>>>>>>>>> static const struct dpu_pingpong_cfg msm8998_pp[] = {
>>>>>>>>>> - PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000, 0,
>>>>>>>>>> sdm845_pp_sblk_te,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>>>> + PP_BLK_TE("pingpong_0", PINGPONG_0, 0x70000,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>>>>>> + PP_BLK_TE("pingpong_1", PINGPONG_1, 0x70800,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 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, 0, 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, 0, 0,
>>>>>>>>>> sdm845_pp_sblk,
>>>>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>>>>>>>> };
>>>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>>>>>> index ceca741..8888bd9 100644
>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_4_0_sdm845.h
>>>>>>>>>> @@ -110,16 +110,16 @@ static const struct dpu_lm_cfg sdm845_lm[]
>>>>>>>>>> = {
>>>>>>>>>> };
>>>>>>>>>> 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,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 0, sdm845_pp_sblk,
>>>>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)),
>>>>>>>>>> };
>>>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>>>>>> index 42b0e58..3a7dffa 100644
>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_0_sm8150.h
>>>>>>>>>> @@ -128,24 +128,22 @@ static const struct dpu_dspp_cfg
>>>>>>>>>> sm8150_dspp[]
>>>>>>>>>> = {
>>>>>>>>>> };
>>>>>>>>>> static const struct dpu_pingpong_cfg sm8150_pp[] = {
>>>>>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>>>>>>>> sdm845_pp_sblk,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>>>>>>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>>>>>>>> sdm845_pp_sblk,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>>>>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>>>>> + sdm845_pp_sblk, 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,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>>>>>>>> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>>>>> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>>>>>>>> - -1),
>>>>>>>>>> - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>>>>>>>>>> sdm845_pp_sblk,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>>>>>> - -1),
>>>>>>>>>> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
>>>>>>>>>> 30), -1),
>>>>>>>>>> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
>>>>>>>>>> 31), -1),
>>>>>>>>>> };
>>>>>>>>>> static const struct dpu_merge_3d_cfg sm8150_merge_3d[] = {
>>>>>>>>>> diff --git
>>>>>>>>>> a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>>>>>> index 5bb9882..e766a2d 100644
>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h
>>>>>>>>>> @@ -116,23 +116,23 @@ static const struct dpu_lm_cfg
>>>>>>>>>> sc8180x_lm[] = {
>>>>>>>>>> };
>>>>>>>>>> static const struct dpu_pingpong_cfg sc8180x_pp[] = {
>>>>>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>>>>>>>> sdm845_pp_sblk,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>>>>>>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>>>>>>>> sdm845_pp_sblk,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>>>>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>>>>> + sdm845_pp_sblk, 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,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>>>>>>>> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>>>>> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>>>>>>>> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>>>>>> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>>>>>> -1),
>>>>>>>>>> };
>>>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>>>>>> index ed130582..137b151 100644
>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_0_sm8250.h
>>>>>>>>>> @@ -129,24 +129,22 @@ static const struct dpu_dspp_cfg
>>>>>>>>>> sm8250_dspp[]
>>>>>>>>>> = {
>>>>>>>>>> };
>>>>>>>>>> static const struct dpu_pingpong_cfg sm8250_pp[] = {
>>>>>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, MERGE_3D_0,
>>>>>>>>>> sdm845_pp_sblk,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 8),
>>>>>>>>>> DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 12)),
>>>>>>>>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, MERGE_3D_0,
>>>>>>>>>> sdm845_pp_sblk,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 9),
>>>>>>>>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_0,
>>>>>>>>>> + sdm845_pp_sblk, 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,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 10),
>>>>>>>>>> + PP_BLK("pingpong_2", PINGPONG_2, 0x71000,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 11),
>>>>>>>>>> + PP_BLK("pingpong_3", PINGPONG_3, 0x71800,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), 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,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 30),
>>>>>>>>>> - -1),
>>>>>>>>>> - PP_BLK("pingpong_5", PINGPONG_5, 0x72800, MERGE_3D_2,
>>>>>>>>>> sdm845_pp_sblk,
>>>>>>>>>> - DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2, 31),
>>>>>>>>>> - -1),
>>>>>>>>>> + PP_BLK("pingpong_4", PINGPONG_4, 0x72000,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
>>>>>>>>>> 30), -1),
>>>>>>>>>> + PP_BLK("pingpong_5", PINGPONG_5, 0x72800,
>>>>>>>>>> BIT(DPU_PINGPONG_DSC), MERGE_3D_2,
>>>>>>>>>> + sdm845_pp_sblk, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR2,
>>>>>>>>>> 31), -1),
>>>>>>>>>> };
>>>>>>>>>> static const struct dpu_merge_3d_cfg sm8250_merge_3d[] = {
>>>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>>>>>> index a46b117..e5631a2 100644
>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_2_sc7180.h
>>>>>>>>>> @@ -80,8 +80,8 @@ static const struct dpu_dspp_cfg sc7180_dspp[]
>>>>>>>>>> = {
>>>>>>>>>> };
>>>>>>>>>> static const struct dpu_pingpong_cfg sc7180_pp[] = {
>>>>>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>>>>>>>> -1, -1),
>>>>>>>>>> - PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, sdm845_pp_sblk,
>>>>>>>>>> -1, -1),
>>>>>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 0,
>>>>>>>>>> sdm845_pp_sblk,
>>>>>>>>>> -1, -1),
>>>>>>>>>> + PP_BLK("pingpong_1", PINGPONG_1, 0x70800, 0, 0,
>>>>>>>>>> sdm845_pp_sblk,
>>>>>>>>>> -1, -1),
>>>>>>>>>> };
>>>>>>>>>> static const struct dpu_intf_cfg sc7180_intf[] = {
>>>>>>>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>>>>>> index 988d820..7b4ad0f 100644
>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_3_sm6115.h
>>>>>>>>>> @@ -60,7 +60,7 @@ static const struct dpu_dspp_cfg sm6115_dspp[]
>>>>>>>>>> = {
>>>>>>>>>> };
>>>>>>>>>> static const struct dpu_pingpong_cfg sm6115_pp[] = {
>>>>>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>>>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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/catalog/dpu_6_5_qcm2290.h
>>>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>>>>>>>> index c9003dc..20d4d14 100644
>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_6_5_qcm2290.h
>>>>>>>>>> @@ -57,7 +57,7 @@ static const struct dpu_dspp_cfg
>>>>>>>>>> qcm2290_dspp[] = {
>>>>>>>>>> };
>>>>>>>>>> static const struct dpu_pingpong_cfg qcm2290_pp[] = {
>>>>>>>>>> - PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, sdm845_pp_sblk,
>>>>>>>>>> + PP_BLK("pingpong_0", PINGPONG_0, 0x70000, 0, 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_catalog.c
>>>>>>>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>>> index 91bfc8a..83c0cd9 100644
>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c
>>>>>>>>>> @@ -501,21 +501,21 @@ static const struct dpu_pingpong_sub_blks
>>>>>>>>>> sc7280_pp_sblk = {
>>>>>>>>>> .intr_done = _done, \
>>>>>>>>>> .intr_rdptr = _rdptr, \
>>>>>>>>>> }
>>>>>>>>>> -#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 = PINGPONG_SDM845_SPLIT_MASK | _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 = PINGPONG_SDM845_MASK | _features, \
>>>>>>>>>> .merge_3d = _merge_3d, \
>>>>>>>>>> .sblk = &_sblk, \
>>>>>>>>>> .intr_done = _done, \
>>>>>>>>>> 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 fc87db1..6b49171 100644
>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>>>>>>>>> @@ -144,6 +144,7 @@ enum {
>>>>>>>>>> * @DPU_PINGPONG_SPLIT PP block supports split fifo
>>>>>>>>>> * @DPU_PINGPONG_SLAVE PP block is a suitable slave for
>>>>>>>>>> split
>>>>>>>>>> fifo
>>>>>>>>>> * @DPU_PINGPONG_DITHER, Dither blocks
>>>>>>>>>> + * @DPU_PINGPONG_DSC, PP block binding to DSC
>>>>>>>>>> * @DPU_PINGPONG_MAX
>>>>>>>>>> */
>>>>>>>>>> enum {
>>>>>>>>>> @@ -152,6 +153,7 @@ enum {
>>>>>>>>>> DPU_PINGPONG_SPLIT,
>>>>>>>>>> DPU_PINGPONG_SLAVE,
>>>>>>>>>> DPU_PINGPONG_DITHER,
>>>>>>>>>> + DPU_PINGPONG_DSC,
>>>>>>>>>> DPU_PINGPONG_MAX
>>>>>>>>>> };
>>>>>>>>>> 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 3822e06..f255a04 100644
>>>>>>>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>>>>>>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c
>>>>>>>>>> @@ -264,9 +264,12 @@ static void _setup_pingpong_ops(struct
>>>>>>>>>> dpu_hw_pingpong *c,
>>>>>>>>>> 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;
>>>>>>>>>> +
>>>>>>>>>> + if (features & BIT(DPU_PINGPONG_DSC)) {
>>>>>>>>>> + 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;
>>>>>>>>>> + }
>>>>>>>>>> if (test_bit(DPU_PINGPONG_DITHER, &features))
>>>>>>>>>> c->ops.setup_dither = dpu_hw_pp_setup_dither;
>>>>>>>>>
>>>>>>>
>>>>>
>>>>>
>>>>>
>>>
>
>
>
> --
> With best wishes
> Dmitry

2023-04-29 21:28:18

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [Freedreno] [PATCH v2 5/7] drm/msm/dpu: add DPU_PINGPONG_DSC feature PP_BLK and PP_BLK_TE

On 29/04/2023 23:23, Abhinav Kumar wrote:
>
>
> On 4/29/2023 12:45 PM, Dmitry Baryshkov wrote:
>> On Sat, 29 Apr 2023 at 11:43, Abhinav Kumar
>> <[email protected]> wrote:
>>>
>>>
>>>
>>> On 4/28/2023 9:35 PM, Dmitry Baryshkov wrote:
>>>> On 29/04/2023 07:04, Abhinav Kumar wrote:
>>>>>
>>>>>
>>>>> On 4/28/2023 8:21 PM, Dmitry Baryshkov wrote:
>>>>>> On Sat, 29 Apr 2023 at 05:50, Abhinav Kumar
>>>>>> <[email protected]> wrote:
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> On 4/28/2023 6:41 PM, Dmitry Baryshkov wrote:
>>>>>>>> On 29/04/2023 04:08, Abhinav Kumar wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> On 4/28/2023 5:45 PM, Dmitry Baryshkov wrote:
>>>>>>>>>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>>>>>>>>>>> Legacy DPU requires PP hardware block involved into setting
>>>>>>>>>>> up DSC
>>>>>>>>>>
>>>>>>>>>> Nit: to be envolved
>>>>>>>>>>
>>>>>>>>>>> data path. This patch add DDPU_PINGPONG_DSC feature bit to both
>>>>>>>>>>
>>>>>>>>>> adds
>>>>>>>>>>
>>>>>>>>>>> PP_BLK and PP_BLK_TE so that both dpu_hw_pp_setup_dsc() and
>>>>>>>>>>> dpu_hw_pp_dsc_enable() will be executed during DSC path setup.
>>>>>>>>>>
>>>>>>>>>> Would it be easier to add PP_BLK_NO_DSC instead and make DSC
>>>>>>>>>> enabled
>>>>>>>>>> by default for PP_BLK / PP_BLK_TE?
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>> No because for some chipsets like qcm2290, it has a ping pong
>>>>>>>>> block
>>>>>>>>> but no DSC.
>>>>>>>>
>>>>>>>> And so it will use PP_BLK_NO_DSC (like msm8998 for PP_2/_3). But
>>>>>>>> this
>>>>>>>
>>>>>>> Ok so you meant adding another PP_BLK_* macro. I mistook it for a
>>>>>>> feature flag.
>>>>>>>
>>>>>>> This is getting a bit confusing with many PP_BLK_* variations.
>>>>>>
>>>>>> Yes. As I wrote it might be not the optimal solution.
>>>>>>
>>>>>>>
>>>>>>>> might be not the optimal solution. Let's check all possible cases:
>>>>>>>>
>>>>>>>> - PP (or PP_TE?) with no DSC support,
>>>>>>>
>>>>>>> Yes correct for chipsets like qcm2290.
>>>>>>>
>>>>>>>> - PP/PP_TE tightly bound to the particular DSC instance, should be
>>>>>>>> allocated together,
>>>>>>>
>>>>>>> I need to check which exact chipset does this (I recall one does)
>>>>>>> but
>>>>>>> perhaps msm8998 fits here.
>>>>>>
>>>>>> All targets earlier than sm8150. SDE driver sets SDE_DSC_OUTPUT_CTRL
>>>>>> if for v1 CTL blocks (sm8150+).
>>>>>>
>>>>>>>
>>>>>>>> - PP/PP_TE which can use any DSC block.
>>>>>>>
>>>>>>> This is what DPU_PINGPONG_DSC feature flag should mean today and
>>>>>>> should
>>>>>>> cover most of the DSC 1.1 chipsets present in upstream today.
>>>>>>
>>>>>> Then it should probably be renamed to DPU_PINGPONG_ANY_DSC
>>>>>>
>>>>>
>>>>> Actually that "any" is incorrect. As part of the DSC pairing logic
>>>>> change it will become clear but not all ping-pongs can pair with all
>>>>> DSCs. So any is not right.
>>>>>
>>>>> This is why I think we should go with this feature flag first. Lets
>>>>> identify a pattern and then work on unifying or cleaning up the
>>>>> PP_BLK_* masks.
>>>>
>>>> Then I'd like to see the series sent together so that we don't have to
>>>> be wondering in the myst. At least the RM changes might better go into
>>>> this series (together with the topology changes. I think RM will depend
>>>> on 1 DSC topology support).
>>>
>>> Topology changes depend on which way the virtual planes series is going
>>> to do and since we are going with fixed topology you preferred it to be
>>> dropped right?
>>
>> It was not about the topology changes (e.g. supporting 1:1:1), but
>> about storying the topology in the encoder.
>>
>
> So you are suggesting drop patch 6 of this series and keep 7 OR drop 6
> and 7 both?
>
> It looks like if 6 is dropped, then 7 has to be as well because we need
> to store topology somewhere cannot keep passing locally.

Yes, 6/7 should be split from this series. For #7 we have all the
information necessary (num_dsc and num_intf), so it is not strictly
dependent on #6, but is anyway a separate change, not related to DSC 1.2.

Are there any actual changes in #7 for 2:1:1 case? If not, it should go
together with 1:1:1 topology support.

>
> Thats why I was okay to drop 6 and 7 together.
>
>>>
>>> Now that you have seen the DSC to PP mapping code downstream you know
>>> that every DSC cannot goto every ping-pong. So which way do you want to
>>> go with this patch. If we are going to post a next revision, need some
>>> conclusion here and I do not think PP_BLK_* was agreed as a clean
>>> solution anyway.
>>
>> No, it was not agreed. That's why I tried listing all possible cases
>> (in an attempt to understand the limitations and/or possible
>> usecases).
>>
>>>
>>> Thats why I suggested:
>>>
>>> 1) Lets go with feature flag
>>> 2) When DP lands, thats the one which uses 1-1-1 topology so we can hit
>>> some corner cases of lets say DP uses one DSC and then DSI uses merge we
>>> should go with the right DSC pair. With only DSI, this will not arise.
>>> 3) With (1) and (2) done, we can take up PP_BLK_* cleanup if we feel its
>>> necessary.
>>>
>>> I dont see any conclusion or plan suggested by you so far on which way
>>> you want to go.
>>
>> I'd propose the following plan:
>
> Thanks for summarizing what you had in mind, that makes it clear.
>
>> - Drop all the topology and PP changes from this series. Make it add
>> just DSC 1.2 support.
>>
>> Then for the DSI DSC 1.2 we should be able to continue using existing
>> RM/PP code with known limitations.
>>
>
>
> So just keep patches 1-3 right? The issue with that is
> _setup_pingpong_ops will still get called even for DSC 1.2 with those
> changes. This was actually noted by Marijn during the catalog cleanup we
> recently merged to -fixes. Thats why we included that in this so that we
> dont call DSC 1.1 related functions for 1.2

I thought about 1-4 initially. I didn't notice that this flag was not
set for newer PP blocks.

Please split patch #5 into two: generic code + definition and catalog
changes actually enabling this feature.

Also please note that 'PP block binding to DSC' isn't probably a good
enough description of this feature bit. It doesn't control PP/DSC
binding, it shows if DCE is controlled from PP block or not.

>
> Any specific reason why you dont want to go with patches 1-5 now and
> drop 6,7 as that depends on storing topology.
>
>> Next:
>> - Split DPU_PINGPONG_DSC feature flag to a separate patch series. It
>> looks like it should have some Fixes tag, as it prevents one from
>> calling *dsc functions for PPs which do not support them
>
> We can still add the fixes tag and keep it here and move it to the front?

Yes! Even w/o DSC 1.2 we should not be calling dsc functions for PP
which have no DCE support.

>> - Extend the series with the RM fix which skips non-DSC-enabled PPs
>> when DSC is required.
>> - As this series is touching RM, it is a good place to handle DSC
>> allocation issues, which includes:
>>    * tight coupling of PP/DSC blocks on sdm845 and msm8998
>>    * limitations for 1:1:1 or co-allocation of DSC blocks for both DSI
>> and DP DSC (might be split to a separate patchset, up to you)
>
> I am a bit confused about this. This patch is not touching RM at all
> from what I can see. So the issue of DSC pair allocation is there even
> today with or without DSC 1.2 about which DSCs pair with which ones and
> which DSCs go with which PP.

I was also confused here, as you see. What I meant here was to add a new
patch touching RM code to the new, separate series.

> I feel that once DSC 1.2, that is just patches 1-5 land, I agree this
> can be and should be a series on its own to prepare for DP DSC.

Yes, please.

> What use-case gets broken for DSI if we land 1-5?

None. As I wrote, "Then for the DSI DSC 1.2 we should be able to
continue using existing RM/PP code with known limitations."

>
> We are trying to expand this series for a condition which wont hit till
> DP DSC lands due to the fixed topology and only one client for DSC which
> is DSI.

Please don't. Let it be just DSC 1.2 (e.g. as required for DSI DSC 1.2).
The 1:1:1 and multi-client can be a separate series fixing RM/dpu_encoder.

>
>>
>> DP DSC depends either on this series or on a separate patchset
>>
>>>
>>>>
>>>> I went on and checked the SDE. It has condition that pp % 2 == dsc % 2.
>>>> Does this condition apply only to "newest" DSC/PP combo (DITHER + 1.2)
>>>> or to the older ones too? Are there any other conditionals?
>>>>
>>>
>>> It was there even for older DSCs and looks like wasnt implemented in the
>>> current upstream code.
>>
>> Thanks for the info.


--
With best wishes
Dmitry

2023-05-01 20:51:18

by Kuogee Hsieh

[permalink] [raw]
Subject: Re: [PATCH v2 1/7] drm/msm/dpu: add support for DSC encoder v1.2 engine


On 4/28/2023 5:30 PM, Dmitry Baryshkov wrote:
> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>> Add support for DSC 1.2 by providing the necessary hooks to program
>> the DPU DSC 1.2 encoder.
>>
>> Reported-by: kernel test robot <[email protected]>
>
> What exactly was reported?
>
>> Signed-off-by: Kuogee Hsieh <[email protected]>
>> ---
>>   drivers/gpu/drm/msm/Makefile                   |   1 +
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  34 ++-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h     |  14 +-
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 335
>> +++++++++++++++++++++++++
>>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c         |   7 +-
>>   5 files changed, 387 insertions(+), 4 deletions(-)
>>   create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>
>> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
>> index b814fc8..b9af5e4 100644
>> --- a/drivers/gpu/drm/msm/Makefile
>> +++ b/drivers/gpu/drm/msm/Makefile
>> @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
>>       disp/dpu1/dpu_hw_catalog.o \
>>       disp/dpu1/dpu_hw_ctl.o \
>>       disp/dpu1/dpu_hw_dsc.o \
>> +    disp/dpu1/dpu_hw_dsc_1_2.o \
>>       disp/dpu1/dpu_hw_interrupts.o \
>>       disp/dpu1/dpu_hw_intf.o \
>>       disp/dpu1/dpu_hw_lm.o \
>> 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 71584cd..fc87db1 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>> @@ -1,6 +1,6 @@
>>   /* SPDX-License-Identifier: GPL-2.0-only */
>>   /*
>> - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights
>> reserved.
>> + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All
>> rights reserved.
>>    * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights
>> reserved.
>>    */
>>   @@ -241,12 +241,20 @@ enum {
>>   };
>>     /**
>> - * DSC features
>> + * DSC sub-blocks/features
>>    * @DPU_DSC_OUTPUT_CTRL       Configure which PINGPONG block gets
>>    *                            the pixel output from this DSC.
>> + * @DPU_DSC_HW_REV_1_1        DSC block supports dsc 1.1 only
>> + * @DPU_DSC_HW_REV_1_2        DSC block supports dsc 1.1 and 1.2
>> + * @DPU_DSC_NATIVE_422_EN     Supports native422 and native420 encoding
>> + * @DPU_DSC_MAX
>>    */
>>   enum {
>>       DPU_DSC_OUTPUT_CTRL = 0x1,
>> +    DPU_DSC_HW_REV_1_1,
>> +    DPU_DSC_HW_REV_1_2,
>> +    DPU_DSC_NATIVE_422_EN,
>> +    DPU_DSC_MAX
>>   };
>>     /**
>> @@ -311,6 +319,14 @@ struct dpu_pp_blk {
>>   };
>>     /**
>> + * struct dpu_dsc_blk - DSC Encoder sub-blk information
>> + * @info:   HW register and features supported by this sub-blk
>> + */
>> +struct dpu_dsc_blk {
>> +    DPU_HW_SUBBLK_INFO;
>> +};
>> +
>> +/**
>>    * enum dpu_qos_lut_usage - define QoS LUT use cases
>>    */
>>   enum dpu_qos_lut_usage {
>> @@ -459,6 +475,17 @@ struct dpu_pingpong_sub_blks {
>>   };
>>     /**
>> + * struct dpu_dsc_sub_blks - DSC sub-blks
>> + * @enc: DSC encoder sub block
>> + * @ctl: DSC controller sub block
>> + *
>> + */
>> +struct dpu_dsc_sub_blks {
>> +    struct dpu_dsc_blk enc;
>> +    struct dpu_dsc_blk ctl;
>> +};
>> +
>> +/**
>>    * dpu_clk_ctrl_type - Defines top level clock control signals
>>    */
>>   enum dpu_clk_ctrl_type {
>> @@ -612,10 +639,13 @@ struct dpu_merge_3d_cfg  {
>>    * struct dpu_dsc_cfg - information of DSC blocks
>>    * @id                 enum identifying this block
>>    * @base               register offset of this block
>> + * @len:               length of hardware block
>>    * @features           bit mask identifying sub-blocks/features
>> + * @sblk               sub-blocks information
>>    */
>>   struct dpu_dsc_cfg {
>>       DPU_HW_BLK_INFO;
>> +    const struct dpu_dsc_sub_blks *sblk;
>>   };
>>     /**
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>> index 287ec5f..e11240a 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>> @@ -1,5 +1,8 @@
>>   /* SPDX-License-Identifier: GPL-2.0-only */
>> -/* Copyright (c) 2020-2022, Linaro Limited */
>> +/*
>> + * Copyright (c) 2020-2022, Linaro Limited
>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>> reserved
>> + */
>>     #ifndef _DPU_HW_DSC_H
>>   #define _DPU_HW_DSC_H
>> @@ -70,6 +73,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct
>> dpu_dsc_cfg *cfg,
>>           void __iomem *addr);
>>     /**
>> + * dpu_hw_dsc_init_1_2 - initializes the v1.2 DSC hw driver block
>> + * @cfg:  DSC catalog entry for which driver object is required
>> + * @addr: Mapped register io address of MDP
>> + * Returns: Error code or allocated dpu_hw_dsc context
>> + */
>> +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
>> +        void __iomem *addr);
>> +
>> +/**
>>    * dpu_hw_dsc_destroy - destroys dsc driver context
>>    * @dsc:   Pointer to dsc driver context returned by dpu_hw_dsc_init
>>    */
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>> new file mode 100644
>> index 00000000..a777c7b
>> --- /dev/null
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>> @@ -0,0 +1,335 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>> reserved
>> + */
>> +
>> +#include <drm/display/drm_dsc_helper.h>
>> +
>> +#include "dpu_kms.h"
>> +#include "dpu_hw_catalog.h"
>> +#include "dpu_hwio.h"
>> +#include "dpu_hw_mdss.h"
>> +#include "dpu_hw_dsc.h"
>> +
>> +
>
> Unused empty line
>
>> +#define DSC_CMN_MAIN_CNF           0x00
>> +
>> +/* DPU_DSC_ENC register offsets */
>> +#define ENC_DF_CTRL                0x00
>> +#define ENC_GENERAL_STATUS         0x04
>> +#define ENC_HSLICE_STATUS          0x08
>> +#define ENC_OUT_STATUS             0x0C
>> +#define ENC_INT_STAT               0x10
>> +#define ENC_INT_CLR                0x14
>> +#define ENC_INT_MASK               0x18
>> +#define DSC_MAIN_CONF              0x30
>> +#define DSC_PICTURE_SIZE           0x34
>> +#define DSC_SLICE_SIZE             0x38
>> +#define DSC_MISC_SIZE              0x3C
>> +#define DSC_HRD_DELAYS             0x40
>> +#define DSC_RC_SCALE               0x44
>> +#define DSC_RC_SCALE_INC_DEC       0x48
>> +#define DSC_RC_OFFSETS_1           0x4C
>> +#define DSC_RC_OFFSETS_2           0x50
>> +#define DSC_RC_OFFSETS_3           0x54
>> +#define DSC_RC_OFFSETS_4           0x58
>> +#define DSC_FLATNESS_QP            0x5C
>> +#define DSC_RC_MODEL_SIZE          0x60
>> +#define DSC_RC_CONFIG              0x64
>> +#define DSC_RC_BUF_THRESH_0        0x68
>> +#define DSC_RC_MIN_QP_0            0x78
>> +#define DSC_RC_MAX_QP_0            0x84
>> +#define DSC_RC_RANGE_BPG_OFFSETS_0 0x90
>> +
>> +/* DPU_DSC_CTL register offsets */
>> +#define DSC_CTL                    0x00
>> +#define DSC_CFG                    0x04
>> +#define DSC_DATA_IN_SWAP           0x08
>> +#define DSC_CLK_CTRL               0x0C
>> +
>> +static inline int _dsc_calc_ob_max_addr(struct dpu_hw_dsc *hw_dsc,
>> int num_ss, bool native_422)
>> +{
>> +    int max_addr = 2400 / num_ss;
>> +
>> +    if ((hw_dsc->caps->features & BIT(DPU_DSC_NATIVE_422_EN)) &&
>> native_422)
>> +        max_addr /= 2;
>> +
>> +    return max_addr - 1;
>> +};
>> +
>> +static void dpu_hw_dsc_disable_1_2(struct dpu_hw_dsc *hw_dsc)
>> +{
>> +    struct dpu_hw_blk_reg_map *hw;
>> +    u32 offset;
>> +
>> +    if (!hw_dsc)
>> +        return;
>> +
>> +    hw = &hw_dsc->hw;
>> +    offset = hw_dsc->caps->sblk->ctl.base;
>> +    DPU_REG_WRITE(hw, offset + DSC_CFG, 0);
>> +
>> +    offset = hw_dsc->caps->sblk->enc.base;
>> +    DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, 0);
>> +    DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, 0);
>> +}
>> +
>> +static void dpu_hw_dsc_config_1_2(struct dpu_hw_dsc *hw_dsc,
>> +                  struct drm_dsc_config *dsc,
>> +                  u32 mode,
>> +                  u32 initial_lines)
>> +{
>> +    struct dpu_hw_blk_reg_map *hw;
>> +    u32 offset;
>> +    u32 data = 0;
>> +    u32 det_thresh_flatness;
>> +    u32 num_active_ss_per_enc;
>> +    u32 bpp;
>> +
>> +    if (!hw_dsc || !dsc)
>> +        return;
>> +
>> +    hw = &hw_dsc->hw;
>> +
>> +    offset = hw_dsc->caps->sblk->enc.base;
>> +
>> +    if (mode & DSC_MODE_SPLIT_PANEL)
>> +        data |= BIT(0);
>> +
>> +    if (mode & DSC_MODE_MULTIPLEX)
>> +        data |= BIT(1);
>> +
>> +    num_active_ss_per_enc = dsc->slice_count;
>> +    if (mode & DSC_MODE_MULTIPLEX)
>> +        num_active_ss_per_enc = dsc->slice_count >> 1;
>> +
>> +    data |= (num_active_ss_per_enc & 0x3) << 7;
>> +
>> +    DPU_REG_WRITE(hw, DSC_CMN_MAIN_CNF, data);
>> +
>> +    data = (initial_lines & 0xff);
>> +
>> +    if (mode & DSC_MODE_VIDEO)
>> +        data |= BIT(9);
>> +
>> +    data |= (_dsc_calc_ob_max_addr(hw_dsc, num_active_ss_per_enc,
>> dsc->native_422) << 18);
>> +
>> +    DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, data);
>> +
>> +    data = (dsc->dsc_version_minor & 0xf) << 28;
>> +    if (dsc->dsc_version_minor == 0x2) {
>> +        if (dsc->native_422)
>> +            data |= BIT(22);
>> +        if (dsc->native_420)
>> +            data |= BIT(21);
>> +    }
>> +
>> +    bpp = dsc->bits_per_pixel;
>> +    /* as per hw requirement bpp should be programmed
>> +     * twice the actual value in case of 420 or 422 encoding
>> +     */
>> +    if (dsc->native_422 || dsc->native_420)
>> +        bpp = 2 * bpp;
>> +    data |= (dsc->block_pred_enable ? 1 : 0) << 20;
>> +    data |= bpp << 10;
>> +    data |= (dsc->line_buf_depth & 0xf) << 6;
>> +    data |= dsc->convert_rgb << 4;
>> +    data |= dsc->bits_per_component & 0xf;
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, data);
>> +
>> +    data = (dsc->pic_width & 0xffff) |
>> +        ((dsc->pic_height & 0xffff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_PICTURE_SIZE, data);
>> +
>> +    data = (dsc->slice_width & 0xffff) |
>> +        ((dsc->slice_height & 0xffff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_SLICE_SIZE, data);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_MISC_SIZE,
>> +            (dsc->slice_chunk_size) & 0xffff);
>> +
>> +    data = (dsc->initial_xmit_delay & 0xffff) |
>> +        ((dsc->initial_dec_delay & 0xffff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_HRD_DELAYS, data);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_SCALE,
>> +            dsc->initial_scale_value & 0x3f);
>> +
>> +    data = (dsc->scale_increment_interval & 0xffff) |
>> +        ((dsc->scale_decrement_interval & 0x7ff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_SCALE_INC_DEC, data);
>> +
>> +    data = (dsc->first_line_bpg_offset & 0x1f) |
>> +        ((dsc->second_line_bpg_offset & 0x1f) << 5);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_1, data);
>> +
>> +    data = (dsc->nfl_bpg_offset & 0xffff) |
>> +        ((dsc->slice_bpg_offset & 0xffff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_2, data);
>> +
>> +    data = (dsc->initial_offset & 0xffff) |
>> +        ((dsc->final_offset & 0xffff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_3, data);
>> +
>> +    data = (dsc->nsl_bpg_offset & 0xffff) |
>> +        ((dsc->second_line_offset_adj & 0xffff) << 16);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_4, data);
>> +
>> +    data = (dsc->flatness_min_qp & 0x1f);
>> +    data |= (dsc->flatness_max_qp & 0x1f) << 5;
>> +
>> +    det_thresh_flatness = drm_dsc_calculate_flatness_det_thresh(dsc);
>> +    data |= (det_thresh_flatness & 0xff) << 10;
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_FLATNESS_QP, data);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_MODEL_SIZE,
>> +            (dsc->rc_model_size) & 0xffff);
>> +
>> +    data = dsc->rc_edge_factor & 0xf;
>> +    data |= (dsc->rc_quant_incr_limit0 & 0x1f) << 8;
>> +    data |= (dsc->rc_quant_incr_limit1 & 0x1f) << 13;
>> +    data |= (dsc->rc_tgt_offset_high & 0xf) << 20;
>> +    data |= (dsc->rc_tgt_offset_low & 0xf) << 24;
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_RC_CONFIG, data);
>> +
>> +    /* program the dsc wrapper */
>> +    offset = hw_dsc->caps->sblk->ctl.base;
>> +
>> +    data = BIT(0); /* encoder enable */
>> +    if (dsc->native_422)
>> +        data |= BIT(8);
>> +    else if (dsc->native_420)
>> +        data |= BIT(9);
>> +    if (!dsc->convert_rgb)
>> +        data |= BIT(10);
>> +    if (dsc->bits_per_component == 8)
>> +        data |= BIT(11);
>> +    if (mode & DSC_MODE_SPLIT_PANEL)
>> +        data |= BIT(12);
>> +    if (mode & DSC_MODE_MULTIPLEX)
>> +        data |= BIT(13);
>> +    if (!(mode & DSC_MODE_VIDEO))
>> +        data |= BIT(17);
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_CFG, data);
>> +}
>> +
>> +static void dpu_hw_dsc_config_thresh_1_2(struct dpu_hw_dsc *hw_dsc,
>> +                    struct drm_dsc_config *dsc)
>> +{
>> +    struct dpu_hw_blk_reg_map *hw;
>> +    u32 offset, off;
>> +    int i, j = 0;
>> +    struct drm_dsc_rc_range_parameters *rc;
>> +    u32 data = 0, min_qp = 0, max_qp = 0, bpg_off = 0;
>> +
>> +    if (!hw_dsc || !dsc)
>> +        return;
>> +
>> +    offset = hw_dsc->caps->sblk->enc.base;
>> +
>> +    hw = &hw_dsc->hw;
>> +
>> +    rc = dsc->rc_range_params;
>> +
>> +    /*
>> +     * With BUF_THRESH -- 14 in total
>> +     * each register contains 4 thresh values with the last register
>> +     * containing only 2 thresh values
>> +     */
>> +    off = 0;
>> +    for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) {
>> +        data |= dsc->rc_buf_thresh[i] << (8 * j);
>> +        j++;
>> +        if ((j == 4) || (i == DSC_NUM_BUF_RANGES - 2)) {
>> +            DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0 + off,
>> data);
>> +            off += 4;
>> +            j = 0;
>> +            data = 0;
>> +        }
>> +    }
>
> This is barely understandable code. The following line is much better:
>
> DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0,
>     (dsc->rc_buf_thresh[0] << 0) |
>     (dsc->rc_buf_thresh[1] << 8) |
>     (dsc->rc_buf_thresh[2] << 16) |
>     (dsc->rc_buf_thresh[3] << 24));
>
> etc.
>
> Please unroll both loops.
>
>> +
>> +
>> +    /*
>> +     * with min/max_QP -- 5 bits each
>> +     * each register contains 5 min_qp or max_qp for total of 15
>> +     *
>> +     * With BPG_OFFSET -- 6 bits each
>> +     * each register contains 5 BPG_offset for total of 15
>> +     */
>> +    off = 0;
>> +    for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
>> +        min_qp |= rc[i].range_min_qp << (5 * j);
>> +        max_qp |= rc[i].range_max_qp << (5 * j);
>> +        bpg_off |= rc[i].range_bpg_offset << (6 * j);
>> +        j++;
>> +        if (j == 5) {
>> +            DPU_REG_WRITE(hw, offset + DSC_RC_MIN_QP_0 + off, min_qp);
>> +            DPU_REG_WRITE(hw, offset + DSC_RC_MAX_QP_0 + off, max_qp);
>> +            DPU_REG_WRITE(hw, offset + DSC_RC_RANGE_BPG_OFFSETS_0 +
>> off, bpg_off);
>> +            off += 4;
>> +            j = 0;
>> +            min_qp = 0;
>> +            max_qp = 0;
>> +            bpg_off = 0;
>> +        }
>> +    }
>> +}
>> +
>> +static void dpu_hw_dsc_bind_pingpong_blk_1_2(
>> +        struct dpu_hw_dsc *hw_dsc,
>> +        bool enable,
>> +        const enum dpu_pingpong pp)
>> +{
>> +    struct dpu_hw_blk_reg_map *hw;
>> +    int offset;
>> +    int mux_cfg = 0xf; /* Disabled */
>> +
>> +    offset = hw_dsc->caps->sblk->ctl.base;
>> +
>> +    hw = &hw_dsc->hw;
>> +    if (enable)
>> +        mux_cfg = (pp - PINGPONG_0) & 0x7;
>> +
>> +    DPU_REG_WRITE(hw, offset + DSC_CTL, mux_cfg);
>> +}
>
> Please refactor the existing bind_pingpong_blk() semantics to accept
> either a valid PINGPONG_n, or PINGPONG_NONE to disable the binding.

Could you please give me more details for this comment.

both dsc_1_1 and dsc_1_2 are required to select and set mux bits of
mux_cfg to binding dsc and  pingpong together.

>
>> +
>> +static void _setup_dcs_ops_1_2(struct dpu_hw_dsc_ops *ops,
>> +        const unsigned long features)
>> +{
>> +    ops->dsc_disable = dpu_hw_dsc_disable_1_2;
>> +    ops->dsc_config = dpu_hw_dsc_config_1_2;
>> +    ops->dsc_config_thresh = dpu_hw_dsc_config_thresh_1_2;
>> +    ops->dsc_bind_pingpong_blk = dpu_hw_dsc_bind_pingpong_blk_1_2;
>> +}
>
> Please inline the function.
>
>> +
>> +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
>> +                   void __iomem *addr)
>> +{
>> +    struct dpu_hw_dsc *c;
>> +
>> +    c = kzalloc(sizeof(*c), GFP_KERNEL);
>> +    if (!c)
>> +        return ERR_PTR(-ENOMEM);
>> +
>> +    c->hw.blk_addr = addr + cfg->base;
>> +    c->hw.log_mask = DPU_DBG_MASK_DSC;
>> +
>> +    c->idx = cfg->id;
>> +    c->caps = cfg;
>> +    _setup_dcs_ops_1_2(&c->ops, c->caps->features);
>> +
>> +    return c;
>> +}
>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>> index 3452f88..b2f618f6 100644
>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c
>> @@ -1,6 +1,7 @@
>>   // SPDX-License-Identifier: GPL-2.0-only
>>   /*
>>    * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>> reserved.
>>    */
>>     #define pr_fmt(fmt)    "[drm:%s] " fmt, __func__
>> @@ -250,7 +251,11 @@ int dpu_rm_init(struct dpu_rm *rm,
>>           struct dpu_hw_dsc *hw;
>>           const struct dpu_dsc_cfg *dsc = &cat->dsc[i];
>>   -        hw = dpu_hw_dsc_init(dsc, mmio);
>> +        if (test_bit(DPU_DSC_HW_REV_1_2, &dsc->features))
>> +            hw = dpu_hw_dsc_init_1_2(dsc, mmio);
>> +        else
>> +            hw = dpu_hw_dsc_init(dsc, mmio);
>> +
>>           if (IS_ERR_OR_NULL(hw)) {
>>               rc = PTR_ERR(hw);
>>               DPU_ERROR("failed dsc object creation: err %d\n", rc);
>

2023-05-01 20:52:25

by Dmitry Baryshkov

[permalink] [raw]
Subject: Re: [PATCH v2 1/7] drm/msm/dpu: add support for DSC encoder v1.2 engine

On 01/05/2023 23:40, Kuogee Hsieh wrote:
>
> On 4/28/2023 5:30 PM, Dmitry Baryshkov wrote:
>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>>> Add support for DSC 1.2 by providing the necessary hooks to program
>>> the DPU DSC 1.2 encoder.
>>>
>>> Reported-by: kernel test robot <[email protected]>
>>
>> What exactly was reported?
>>
>>> Signed-off-by: Kuogee Hsieh <[email protected]>
>>> ---
>>>   drivers/gpu/drm/msm/Makefile                   |   1 +
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  34 ++-
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h     |  14 +-
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 335
>>> +++++++++++++++++++++++++
>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c         |   7 +-
>>>   5 files changed, 387 insertions(+), 4 deletions(-)
>>>   create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>>
>>> diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile
>>> index b814fc8..b9af5e4 100644
>>> --- a/drivers/gpu/drm/msm/Makefile
>>> +++ b/drivers/gpu/drm/msm/Makefile
>>> @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
>>>       disp/dpu1/dpu_hw_catalog.o \
>>>       disp/dpu1/dpu_hw_ctl.o \
>>>       disp/dpu1/dpu_hw_dsc.o \
>>> +    disp/dpu1/dpu_hw_dsc_1_2.o \
>>>       disp/dpu1/dpu_hw_interrupts.o \
>>>       disp/dpu1/dpu_hw_intf.o \
>>>       disp/dpu1/dpu_hw_lm.o \
>>> 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 71584cd..fc87db1 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>> @@ -1,6 +1,6 @@
>>>   /* SPDX-License-Identifier: GPL-2.0-only */
>>>   /*
>>> - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights
>>> reserved.
>>> + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All
>>> rights reserved.
>>>    * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights
>>> reserved.
>>>    */
>>>   @@ -241,12 +241,20 @@ enum {
>>>   };
>>>     /**
>>> - * DSC features
>>> + * DSC sub-blocks/features
>>>    * @DPU_DSC_OUTPUT_CTRL       Configure which PINGPONG block gets
>>>    *                            the pixel output from this DSC.
>>> + * @DPU_DSC_HW_REV_1_1        DSC block supports dsc 1.1 only
>>> + * @DPU_DSC_HW_REV_1_2        DSC block supports dsc 1.1 and 1.2
>>> + * @DPU_DSC_NATIVE_422_EN     Supports native422 and native420 encoding
>>> + * @DPU_DSC_MAX
>>>    */
>>>   enum {
>>>       DPU_DSC_OUTPUT_CTRL = 0x1,
>>> +    DPU_DSC_HW_REV_1_1,
>>> +    DPU_DSC_HW_REV_1_2,
>>> +    DPU_DSC_NATIVE_422_EN,
>>> +    DPU_DSC_MAX
>>>   };
>>>     /**
>>> @@ -311,6 +319,14 @@ struct dpu_pp_blk {
>>>   };
>>>     /**
>>> + * struct dpu_dsc_blk - DSC Encoder sub-blk information
>>> + * @info:   HW register and features supported by this sub-blk
>>> + */
>>> +struct dpu_dsc_blk {
>>> +    DPU_HW_SUBBLK_INFO;
>>> +};
>>> +
>>> +/**
>>>    * enum dpu_qos_lut_usage - define QoS LUT use cases
>>>    */
>>>   enum dpu_qos_lut_usage {
>>> @@ -459,6 +475,17 @@ struct dpu_pingpong_sub_blks {
>>>   };
>>>     /**
>>> + * struct dpu_dsc_sub_blks - DSC sub-blks
>>> + * @enc: DSC encoder sub block
>>> + * @ctl: DSC controller sub block
>>> + *
>>> + */
>>> +struct dpu_dsc_sub_blks {
>>> +    struct dpu_dsc_blk enc;
>>> +    struct dpu_dsc_blk ctl;
>>> +};
>>> +
>>> +/**
>>>    * dpu_clk_ctrl_type - Defines top level clock control signals
>>>    */
>>>   enum dpu_clk_ctrl_type {
>>> @@ -612,10 +639,13 @@ struct dpu_merge_3d_cfg  {
>>>    * struct dpu_dsc_cfg - information of DSC blocks
>>>    * @id                 enum identifying this block
>>>    * @base               register offset of this block
>>> + * @len:               length of hardware block
>>>    * @features           bit mask identifying sub-blocks/features
>>> + * @sblk               sub-blocks information
>>>    */
>>>   struct dpu_dsc_cfg {
>>>       DPU_HW_BLK_INFO;
>>> +    const struct dpu_dsc_sub_blks *sblk;
>>>   };
>>>     /**
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>>> index 287ec5f..e11240a 100644
>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>>> @@ -1,5 +1,8 @@
>>>   /* SPDX-License-Identifier: GPL-2.0-only */
>>> -/* Copyright (c) 2020-2022, Linaro Limited */
>>> +/*
>>> + * Copyright (c) 2020-2022, Linaro Limited
>>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>>> reserved
>>> + */
>>>     #ifndef _DPU_HW_DSC_H
>>>   #define _DPU_HW_DSC_H
>>> @@ -70,6 +73,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct
>>> dpu_dsc_cfg *cfg,
>>>           void __iomem *addr);
>>>     /**
>>> + * dpu_hw_dsc_init_1_2 - initializes the v1.2 DSC hw driver block
>>> + * @cfg:  DSC catalog entry for which driver object is required
>>> + * @addr: Mapped register io address of MDP
>>> + * Returns: Error code or allocated dpu_hw_dsc context
>>> + */
>>> +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
>>> +        void __iomem *addr);
>>> +
>>> +/**
>>>    * dpu_hw_dsc_destroy - destroys dsc driver context
>>>    * @dsc:   Pointer to dsc driver context returned by dpu_hw_dsc_init
>>>    */
>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>> new file mode 100644
>>> index 00000000..a777c7b
>>> --- /dev/null
>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>> @@ -0,0 +1,335 @@
>>> +// SPDX-License-Identifier: GPL-2.0-only
>>> +/*
>>> + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved.
>>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>>> reserved
>>> + */
>>> +
>>> +#include <drm/display/drm_dsc_helper.h>
>>> +
>>> +#include "dpu_kms.h"
>>> +#include "dpu_hw_catalog.h"
>>> +#include "dpu_hwio.h"
>>> +#include "dpu_hw_mdss.h"
>>> +#include "dpu_hw_dsc.h"
>>> +
>>> +
>>
>> Unused empty line
>>
>>> +#define DSC_CMN_MAIN_CNF           0x00
>>> +
>>> +/* DPU_DSC_ENC register offsets */
>>> +#define ENC_DF_CTRL                0x00
>>> +#define ENC_GENERAL_STATUS         0x04
>>> +#define ENC_HSLICE_STATUS          0x08
>>> +#define ENC_OUT_STATUS             0x0C
>>> +#define ENC_INT_STAT               0x10
>>> +#define ENC_INT_CLR                0x14
>>> +#define ENC_INT_MASK               0x18
>>> +#define DSC_MAIN_CONF              0x30
>>> +#define DSC_PICTURE_SIZE           0x34
>>> +#define DSC_SLICE_SIZE             0x38
>>> +#define DSC_MISC_SIZE              0x3C
>>> +#define DSC_HRD_DELAYS             0x40
>>> +#define DSC_RC_SCALE               0x44
>>> +#define DSC_RC_SCALE_INC_DEC       0x48
>>> +#define DSC_RC_OFFSETS_1           0x4C
>>> +#define DSC_RC_OFFSETS_2           0x50
>>> +#define DSC_RC_OFFSETS_3           0x54
>>> +#define DSC_RC_OFFSETS_4           0x58
>>> +#define DSC_FLATNESS_QP            0x5C
>>> +#define DSC_RC_MODEL_SIZE          0x60
>>> +#define DSC_RC_CONFIG              0x64
>>> +#define DSC_RC_BUF_THRESH_0        0x68
>>> +#define DSC_RC_MIN_QP_0            0x78
>>> +#define DSC_RC_MAX_QP_0            0x84
>>> +#define DSC_RC_RANGE_BPG_OFFSETS_0 0x90
>>> +
>>> +/* DPU_DSC_CTL register offsets */
>>> +#define DSC_CTL                    0x00
>>> +#define DSC_CFG                    0x04
>>> +#define DSC_DATA_IN_SWAP           0x08
>>> +#define DSC_CLK_CTRL               0x0C
>>> +
>>> +static inline int _dsc_calc_ob_max_addr(struct dpu_hw_dsc *hw_dsc,
>>> int num_ss, bool native_422)
>>> +{
>>> +    int max_addr = 2400 / num_ss;
>>> +
>>> +    if ((hw_dsc->caps->features & BIT(DPU_DSC_NATIVE_422_EN)) &&
>>> native_422)
>>> +        max_addr /= 2;
>>> +
>>> +    return max_addr - 1;
>>> +};
>>> +
>>> +static void dpu_hw_dsc_disable_1_2(struct dpu_hw_dsc *hw_dsc)
>>> +{
>>> +    struct dpu_hw_blk_reg_map *hw;
>>> +    u32 offset;
>>> +
>>> +    if (!hw_dsc)
>>> +        return;
>>> +
>>> +    hw = &hw_dsc->hw;
>>> +    offset = hw_dsc->caps->sblk->ctl.base;
>>> +    DPU_REG_WRITE(hw, offset + DSC_CFG, 0);
>>> +
>>> +    offset = hw_dsc->caps->sblk->enc.base;
>>> +    DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, 0);
>>> +    DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, 0);
>>> +}
>>> +
>>> +static void dpu_hw_dsc_config_1_2(struct dpu_hw_dsc *hw_dsc,
>>> +                  struct drm_dsc_config *dsc,
>>> +                  u32 mode,
>>> +                  u32 initial_lines)
>>> +{
>>> +    struct dpu_hw_blk_reg_map *hw;
>>> +    u32 offset;
>>> +    u32 data = 0;
>>> +    u32 det_thresh_flatness;
>>> +    u32 num_active_ss_per_enc;
>>> +    u32 bpp;
>>> +
>>> +    if (!hw_dsc || !dsc)
>>> +        return;
>>> +
>>> +    hw = &hw_dsc->hw;
>>> +
>>> +    offset = hw_dsc->caps->sblk->enc.base;
>>> +
>>> +    if (mode & DSC_MODE_SPLIT_PANEL)
>>> +        data |= BIT(0);
>>> +
>>> +    if (mode & DSC_MODE_MULTIPLEX)
>>> +        data |= BIT(1);
>>> +
>>> +    num_active_ss_per_enc = dsc->slice_count;
>>> +    if (mode & DSC_MODE_MULTIPLEX)
>>> +        num_active_ss_per_enc = dsc->slice_count >> 1;
>>> +
>>> +    data |= (num_active_ss_per_enc & 0x3) << 7;
>>> +
>>> +    DPU_REG_WRITE(hw, DSC_CMN_MAIN_CNF, data);
>>> +
>>> +    data = (initial_lines & 0xff);
>>> +
>>> +    if (mode & DSC_MODE_VIDEO)
>>> +        data |= BIT(9);
>>> +
>>> +    data |= (_dsc_calc_ob_max_addr(hw_dsc, num_active_ss_per_enc,
>>> dsc->native_422) << 18);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, data);
>>> +
>>> +    data = (dsc->dsc_version_minor & 0xf) << 28;
>>> +    if (dsc->dsc_version_minor == 0x2) {
>>> +        if (dsc->native_422)
>>> +            data |= BIT(22);
>>> +        if (dsc->native_420)
>>> +            data |= BIT(21);
>>> +    }
>>> +
>>> +    bpp = dsc->bits_per_pixel;
>>> +    /* as per hw requirement bpp should be programmed
>>> +     * twice the actual value in case of 420 or 422 encoding
>>> +     */
>>> +    if (dsc->native_422 || dsc->native_420)
>>> +        bpp = 2 * bpp;
>>> +    data |= (dsc->block_pred_enable ? 1 : 0) << 20;
>>> +    data |= bpp << 10;
>>> +    data |= (dsc->line_buf_depth & 0xf) << 6;
>>> +    data |= dsc->convert_rgb << 4;
>>> +    data |= dsc->bits_per_component & 0xf;
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, data);
>>> +
>>> +    data = (dsc->pic_width & 0xffff) |
>>> +        ((dsc->pic_height & 0xffff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_PICTURE_SIZE, data);
>>> +
>>> +    data = (dsc->slice_width & 0xffff) |
>>> +        ((dsc->slice_height & 0xffff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_SLICE_SIZE, data);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_MISC_SIZE,
>>> +            (dsc->slice_chunk_size) & 0xffff);
>>> +
>>> +    data = (dsc->initial_xmit_delay & 0xffff) |
>>> +        ((dsc->initial_dec_delay & 0xffff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_HRD_DELAYS, data);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_SCALE,
>>> +            dsc->initial_scale_value & 0x3f);
>>> +
>>> +    data = (dsc->scale_increment_interval & 0xffff) |
>>> +        ((dsc->scale_decrement_interval & 0x7ff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_SCALE_INC_DEC, data);
>>> +
>>> +    data = (dsc->first_line_bpg_offset & 0x1f) |
>>> +        ((dsc->second_line_bpg_offset & 0x1f) << 5);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_1, data);
>>> +
>>> +    data = (dsc->nfl_bpg_offset & 0xffff) |
>>> +        ((dsc->slice_bpg_offset & 0xffff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_2, data);
>>> +
>>> +    data = (dsc->initial_offset & 0xffff) |
>>> +        ((dsc->final_offset & 0xffff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_3, data);
>>> +
>>> +    data = (dsc->nsl_bpg_offset & 0xffff) |
>>> +        ((dsc->second_line_offset_adj & 0xffff) << 16);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_4, data);
>>> +
>>> +    data = (dsc->flatness_min_qp & 0x1f);
>>> +    data |= (dsc->flatness_max_qp & 0x1f) << 5;
>>> +
>>> +    det_thresh_flatness = drm_dsc_calculate_flatness_det_thresh(dsc);
>>> +    data |= (det_thresh_flatness & 0xff) << 10;
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_FLATNESS_QP, data);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_MODEL_SIZE,
>>> +            (dsc->rc_model_size) & 0xffff);
>>> +
>>> +    data = dsc->rc_edge_factor & 0xf;
>>> +    data |= (dsc->rc_quant_incr_limit0 & 0x1f) << 8;
>>> +    data |= (dsc->rc_quant_incr_limit1 & 0x1f) << 13;
>>> +    data |= (dsc->rc_tgt_offset_high & 0xf) << 20;
>>> +    data |= (dsc->rc_tgt_offset_low & 0xf) << 24;
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_CONFIG, data);
>>> +
>>> +    /* program the dsc wrapper */
>>> +    offset = hw_dsc->caps->sblk->ctl.base;
>>> +
>>> +    data = BIT(0); /* encoder enable */
>>> +    if (dsc->native_422)
>>> +        data |= BIT(8);
>>> +    else if (dsc->native_420)
>>> +        data |= BIT(9);
>>> +    if (!dsc->convert_rgb)
>>> +        data |= BIT(10);
>>> +    if (dsc->bits_per_component == 8)
>>> +        data |= BIT(11);
>>> +    if (mode & DSC_MODE_SPLIT_PANEL)
>>> +        data |= BIT(12);
>>> +    if (mode & DSC_MODE_MULTIPLEX)
>>> +        data |= BIT(13);
>>> +    if (!(mode & DSC_MODE_VIDEO))
>>> +        data |= BIT(17);
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_CFG, data);
>>> +}
>>> +
>>> +static void dpu_hw_dsc_config_thresh_1_2(struct dpu_hw_dsc *hw_dsc,
>>> +                    struct drm_dsc_config *dsc)
>>> +{
>>> +    struct dpu_hw_blk_reg_map *hw;
>>> +    u32 offset, off;
>>> +    int i, j = 0;
>>> +    struct drm_dsc_rc_range_parameters *rc;
>>> +    u32 data = 0, min_qp = 0, max_qp = 0, bpg_off = 0;
>>> +
>>> +    if (!hw_dsc || !dsc)
>>> +        return;
>>> +
>>> +    offset = hw_dsc->caps->sblk->enc.base;
>>> +
>>> +    hw = &hw_dsc->hw;
>>> +
>>> +    rc = dsc->rc_range_params;
>>> +
>>> +    /*
>>> +     * With BUF_THRESH -- 14 in total
>>> +     * each register contains 4 thresh values with the last register
>>> +     * containing only 2 thresh values
>>> +     */
>>> +    off = 0;
>>> +    for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) {
>>> +        data |= dsc->rc_buf_thresh[i] << (8 * j);
>>> +        j++;
>>> +        if ((j == 4) || (i == DSC_NUM_BUF_RANGES - 2)) {
>>> +            DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0 + off,
>>> data);
>>> +            off += 4;
>>> +            j = 0;
>>> +            data = 0;
>>> +        }
>>> +    }
>>
>> This is barely understandable code. The following line is much better:
>>
>> DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0,
>>     (dsc->rc_buf_thresh[0] << 0) |
>>     (dsc->rc_buf_thresh[1] << 8) |
>>     (dsc->rc_buf_thresh[2] << 16) |
>>     (dsc->rc_buf_thresh[3] << 24));
>>
>> etc.
>>
>> Please unroll both loops.
>>
>>> +
>>> +
>>> +    /*
>>> +     * with min/max_QP -- 5 bits each
>>> +     * each register contains 5 min_qp or max_qp for total of 15
>>> +     *
>>> +     * With BPG_OFFSET -- 6 bits each
>>> +     * each register contains 5 BPG_offset for total of 15
>>> +     */
>>> +    off = 0;
>>> +    for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
>>> +        min_qp |= rc[i].range_min_qp << (5 * j);
>>> +        max_qp |= rc[i].range_max_qp << (5 * j);
>>> +        bpg_off |= rc[i].range_bpg_offset << (6 * j);
>>> +        j++;
>>> +        if (j == 5) {
>>> +            DPU_REG_WRITE(hw, offset + DSC_RC_MIN_QP_0 + off, min_qp);
>>> +            DPU_REG_WRITE(hw, offset + DSC_RC_MAX_QP_0 + off, max_qp);
>>> +            DPU_REG_WRITE(hw, offset + DSC_RC_RANGE_BPG_OFFSETS_0 +
>>> off, bpg_off);
>>> +            off += 4;
>>> +            j = 0;
>>> +            min_qp = 0;
>>> +            max_qp = 0;
>>> +            bpg_off = 0;
>>> +        }
>>> +    }
>>> +}
>>> +
>>> +static void dpu_hw_dsc_bind_pingpong_blk_1_2(
>>> +        struct dpu_hw_dsc *hw_dsc,
>>> +        bool enable,
>>> +        const enum dpu_pingpong pp)
>>> +{
>>> +    struct dpu_hw_blk_reg_map *hw;
>>> +    int offset;
>>> +    int mux_cfg = 0xf; /* Disabled */
>>> +
>>> +    offset = hw_dsc->caps->sblk->ctl.base;
>>> +
>>> +    hw = &hw_dsc->hw;
>>> +    if (enable)
>>> +        mux_cfg = (pp - PINGPONG_0) & 0x7;
>>> +
>>> +    DPU_REG_WRITE(hw, offset + DSC_CTL, mux_cfg);
>>> +}
>>
>> Please refactor the existing bind_pingpong_blk() semantics to accept
>> either a valid PINGPONG_n, or PINGPONG_NONE to disable the binding.
>
> Could you please give me more details for this comment.
>
> both dsc_1_1 and dsc_1_2 are required to select and set mux bits of
> mux_cfg to binding dsc and  pingpong together.

Yes. I was refererring to the function interface. You pass both `bool
enable` and PP index. The index doesn't make sense for 'disable' case.
So we can use a single argument of `enum dpu_pingpong` type. Pass
PINGPONG_n for binding it. Pass PINGPONG_NONE for removing the binding.

>

--
With best wishes
Dmitry

2023-05-01 23:14:24

by Kuogee Hsieh

[permalink] [raw]
Subject: Re: [PATCH v2 1/7] drm/msm/dpu: add support for DSC encoder v1.2 engine


On 5/1/2023 1:50 PM, Dmitry Baryshkov wrote:
> On 01/05/2023 23:40, Kuogee Hsieh wrote:
>>
>> On 4/28/2023 5:30 PM, Dmitry Baryshkov wrote:
>>> On 29/04/2023 02:45, Kuogee Hsieh wrote:
>>>> Add support for DSC 1.2 by providing the necessary hooks to program
>>>> the DPU DSC 1.2 encoder.
>>>>
>>>> Reported-by: kernel test robot <[email protected]>
>>>
>>> What exactly was reported?
>>>
>>>> Signed-off-by: Kuogee Hsieh <[email protected]>
>>>> ---
>>>>   drivers/gpu/drm/msm/Makefile                   |   1 +
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h |  34 ++-
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h     |  14 +-
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 335
>>>> +++++++++++++++++++++++++
>>>>   drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c         |   7 +-
>>>>   5 files changed, 387 insertions(+), 4 deletions(-)
>>>>   create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>>>
>>>> diff --git a/drivers/gpu/drm/msm/Makefile
>>>> b/drivers/gpu/drm/msm/Makefile
>>>> index b814fc8..b9af5e4 100644
>>>> --- a/drivers/gpu/drm/msm/Makefile
>>>> +++ b/drivers/gpu/drm/msm/Makefile
>>>> @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \
>>>>       disp/dpu1/dpu_hw_catalog.o \
>>>>       disp/dpu1/dpu_hw_ctl.o \
>>>>       disp/dpu1/dpu_hw_dsc.o \
>>>> +    disp/dpu1/dpu_hw_dsc_1_2.o \
>>>>       disp/dpu1/dpu_hw_interrupts.o \
>>>>       disp/dpu1/dpu_hw_intf.o \
>>>>       disp/dpu1/dpu_hw_lm.o \
>>>> 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 71584cd..fc87db1 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h
>>>> @@ -1,6 +1,6 @@
>>>>   /* SPDX-License-Identifier: GPL-2.0-only */
>>>>   /*
>>>> - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights
>>>> reserved.
>>>> + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All
>>>> rights reserved.
>>>>    * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights
>>>> reserved.
>>>>    */
>>>>   @@ -241,12 +241,20 @@ enum {
>>>>   };
>>>>     /**
>>>> - * DSC features
>>>> + * DSC sub-blocks/features
>>>>    * @DPU_DSC_OUTPUT_CTRL       Configure which PINGPONG block gets
>>>>    *                            the pixel output from this DSC.
>>>> + * @DPU_DSC_HW_REV_1_1        DSC block supports dsc 1.1 only
>>>> + * @DPU_DSC_HW_REV_1_2        DSC block supports dsc 1.1 and 1.2
>>>> + * @DPU_DSC_NATIVE_422_EN     Supports native422 and native420
>>>> encoding
>>>> + * @DPU_DSC_MAX
>>>>    */
>>>>   enum {
>>>>       DPU_DSC_OUTPUT_CTRL = 0x1,
>>>> +    DPU_DSC_HW_REV_1_1,
>>>> +    DPU_DSC_HW_REV_1_2,
>>>> +    DPU_DSC_NATIVE_422_EN,
>>>> +    DPU_DSC_MAX
>>>>   };
>>>>     /**
>>>> @@ -311,6 +319,14 @@ struct dpu_pp_blk {
>>>>   };
>>>>     /**
>>>> + * struct dpu_dsc_blk - DSC Encoder sub-blk information
>>>> + * @info:   HW register and features supported by this sub-blk
>>>> + */
>>>> +struct dpu_dsc_blk {
>>>> +    DPU_HW_SUBBLK_INFO;
>>>> +};
>>>> +
>>>> +/**
>>>>    * enum dpu_qos_lut_usage - define QoS LUT use cases
>>>>    */
>>>>   enum dpu_qos_lut_usage {
>>>> @@ -459,6 +475,17 @@ struct dpu_pingpong_sub_blks {
>>>>   };
>>>>     /**
>>>> + * struct dpu_dsc_sub_blks - DSC sub-blks
>>>> + * @enc: DSC encoder sub block
>>>> + * @ctl: DSC controller sub block
>>>> + *
>>>> + */
>>>> +struct dpu_dsc_sub_blks {
>>>> +    struct dpu_dsc_blk enc;
>>>> +    struct dpu_dsc_blk ctl;
>>>> +};
>>>> +
>>>> +/**
>>>>    * dpu_clk_ctrl_type - Defines top level clock control signals
>>>>    */
>>>>   enum dpu_clk_ctrl_type {
>>>> @@ -612,10 +639,13 @@ struct dpu_merge_3d_cfg  {
>>>>    * struct dpu_dsc_cfg - information of DSC blocks
>>>>    * @id                 enum identifying this block
>>>>    * @base               register offset of this block
>>>> + * @len:               length of hardware block
>>>>    * @features           bit mask identifying sub-blocks/features
>>>> + * @sblk               sub-blocks information
>>>>    */
>>>>   struct dpu_dsc_cfg {
>>>>       DPU_HW_BLK_INFO;
>>>> +    const struct dpu_dsc_sub_blks *sblk;
>>>>   };
>>>>     /**
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>>>> index 287ec5f..e11240a 100644
>>>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h
>>>> @@ -1,5 +1,8 @@
>>>>   /* SPDX-License-Identifier: GPL-2.0-only */
>>>> -/* Copyright (c) 2020-2022, Linaro Limited */
>>>> +/*
>>>> + * Copyright (c) 2020-2022, Linaro Limited
>>>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>>>> reserved
>>>> + */
>>>>     #ifndef _DPU_HW_DSC_H
>>>>   #define _DPU_HW_DSC_H
>>>> @@ -70,6 +73,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct
>>>> dpu_dsc_cfg *cfg,
>>>>           void __iomem *addr);
>>>>     /**
>>>> + * dpu_hw_dsc_init_1_2 - initializes the v1.2 DSC hw driver block
>>>> + * @cfg:  DSC catalog entry for which driver object is required
>>>> + * @addr: Mapped register io address of MDP
>>>> + * Returns: Error code or allocated dpu_hw_dsc context
>>>> + */
>>>> +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg,
>>>> +        void __iomem *addr);
>>>> +
>>>> +/**
>>>>    * dpu_hw_dsc_destroy - destroys dsc driver context
>>>>    * @dsc:   Pointer to dsc driver context returned by dpu_hw_dsc_init
>>>>    */
>>>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>>> new file mode 100644
>>>> index 00000000..a777c7b
>>>> --- /dev/null
>>>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c
>>>> @@ -0,0 +1,335 @@
>>>> +// SPDX-License-Identifier: GPL-2.0-only
>>>> +/*
>>>> + * Copyright (c) 2020-2021, The Linux Foundation. All rights
>>>> reserved.
>>>> + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights
>>>> reserved
>>>> + */
>>>> +
>>>> +#include <drm/display/drm_dsc_helper.h>
>>>> +
>>>> +#include "dpu_kms.h"
>>>> +#include "dpu_hw_catalog.h"
>>>> +#include "dpu_hwio.h"
>>>> +#include "dpu_hw_mdss.h"
>>>> +#include "dpu_hw_dsc.h"
>>>> +
>>>> +
>>>
>>> Unused empty line
>>>
>>>> +#define DSC_CMN_MAIN_CNF 0x00
>>>> +
>>>> +/* DPU_DSC_ENC register offsets */
>>>> +#define ENC_DF_CTRL                0x00
>>>> +#define ENC_GENERAL_STATUS         0x04
>>>> +#define ENC_HSLICE_STATUS          0x08
>>>> +#define ENC_OUT_STATUS             0x0C
>>>> +#define ENC_INT_STAT               0x10
>>>> +#define ENC_INT_CLR                0x14
>>>> +#define ENC_INT_MASK               0x18
>>>> +#define DSC_MAIN_CONF              0x30
>>>> +#define DSC_PICTURE_SIZE           0x34
>>>> +#define DSC_SLICE_SIZE             0x38
>>>> +#define DSC_MISC_SIZE              0x3C
>>>> +#define DSC_HRD_DELAYS             0x40
>>>> +#define DSC_RC_SCALE               0x44
>>>> +#define DSC_RC_SCALE_INC_DEC       0x48
>>>> +#define DSC_RC_OFFSETS_1           0x4C
>>>> +#define DSC_RC_OFFSETS_2           0x50
>>>> +#define DSC_RC_OFFSETS_3           0x54
>>>> +#define DSC_RC_OFFSETS_4           0x58
>>>> +#define DSC_FLATNESS_QP            0x5C
>>>> +#define DSC_RC_MODEL_SIZE          0x60
>>>> +#define DSC_RC_CONFIG              0x64
>>>> +#define DSC_RC_BUF_THRESH_0        0x68
>>>> +#define DSC_RC_MIN_QP_0            0x78
>>>> +#define DSC_RC_MAX_QP_0            0x84
>>>> +#define DSC_RC_RANGE_BPG_OFFSETS_0 0x90
>>>> +
>>>> +/* DPU_DSC_CTL register offsets */
>>>> +#define DSC_CTL                    0x00
>>>> +#define DSC_CFG                    0x04
>>>> +#define DSC_DATA_IN_SWAP           0x08
>>>> +#define DSC_CLK_CTRL               0x0C
>>>> +
>>>> +static inline int _dsc_calc_ob_max_addr(struct dpu_hw_dsc *hw_dsc,
>>>> int num_ss, bool native_422)
>>>> +{
>>>> +    int max_addr = 2400 / num_ss;
>>>> +
>>>> +    if ((hw_dsc->caps->features & BIT(DPU_DSC_NATIVE_422_EN)) &&
>>>> native_422)
>>>> +        max_addr /= 2;
>>>> +
>>>> +    return max_addr - 1;
>>>> +};
>>>> +
>>>> +static void dpu_hw_dsc_disable_1_2(struct dpu_hw_dsc *hw_dsc)
>>>> +{
>>>> +    struct dpu_hw_blk_reg_map *hw;
>>>> +    u32 offset;
>>>> +
>>>> +    if (!hw_dsc)
>>>> +        return;
>>>> +
>>>> +    hw = &hw_dsc->hw;
>>>> +    offset = hw_dsc->caps->sblk->ctl.base;
>>>> +    DPU_REG_WRITE(hw, offset + DSC_CFG, 0);
>>>> +
>>>> +    offset = hw_dsc->caps->sblk->enc.base;
>>>> +    DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, 0);
>>>> +    DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, 0);
>>>> +}
>>>> +
>>>> +static void dpu_hw_dsc_config_1_2(struct dpu_hw_dsc *hw_dsc,
>>>> +                  struct drm_dsc_config *dsc,
>>>> +                  u32 mode,
>>>> +                  u32 initial_lines)
>>>> +{
>>>> +    struct dpu_hw_blk_reg_map *hw;
>>>> +    u32 offset;
>>>> +    u32 data = 0;
>>>> +    u32 det_thresh_flatness;
>>>> +    u32 num_active_ss_per_enc;
>>>> +    u32 bpp;
>>>> +
>>>> +    if (!hw_dsc || !dsc)
>>>> +        return;
>>>> +
>>>> +    hw = &hw_dsc->hw;
>>>> +
>>>> +    offset = hw_dsc->caps->sblk->enc.base;
>>>> +
>>>> +    if (mode & DSC_MODE_SPLIT_PANEL)
>>>> +        data |= BIT(0);
>>>> +
>>>> +    if (mode & DSC_MODE_MULTIPLEX)
>>>> +        data |= BIT(1);
>>>> +
>>>> +    num_active_ss_per_enc = dsc->slice_count;
>>>> +    if (mode & DSC_MODE_MULTIPLEX)
>>>> +        num_active_ss_per_enc = dsc->slice_count >> 1;
>>>> +
>>>> +    data |= (num_active_ss_per_enc & 0x3) << 7;
>>>> +
>>>> +    DPU_REG_WRITE(hw, DSC_CMN_MAIN_CNF, data);
>>>> +
>>>> +    data = (initial_lines & 0xff);
>>>> +
>>>> +    if (mode & DSC_MODE_VIDEO)
>>>> +        data |= BIT(9);
>>>> +
>>>> +    data |= (_dsc_calc_ob_max_addr(hw_dsc, num_active_ss_per_enc,
>>>> dsc->native_422) << 18);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + ENC_DF_CTRL, data);
>>>> +
>>>> +    data = (dsc->dsc_version_minor & 0xf) << 28;
>>>> +    if (dsc->dsc_version_minor == 0x2) {
>>>> +        if (dsc->native_422)
>>>> +            data |= BIT(22);
>>>> +        if (dsc->native_420)
>>>> +            data |= BIT(21);
>>>> +    }
>>>> +
>>>> +    bpp = dsc->bits_per_pixel;
>>>> +    /* as per hw requirement bpp should be programmed
>>>> +     * twice the actual value in case of 420 or 422 encoding
>>>> +     */
>>>> +    if (dsc->native_422 || dsc->native_420)
>>>> +        bpp = 2 * bpp;
>>>> +    data |= (dsc->block_pred_enable ? 1 : 0) << 20;
>>>> +    data |= bpp << 10;
>>>> +    data |= (dsc->line_buf_depth & 0xf) << 6;
>>>> +    data |= dsc->convert_rgb << 4;
>>>> +    data |= dsc->bits_per_component & 0xf;
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_MAIN_CONF, data);
>>>> +
>>>> +    data = (dsc->pic_width & 0xffff) |
>>>> +        ((dsc->pic_height & 0xffff) << 16);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_PICTURE_SIZE, data);
>>>> +
>>>> +    data = (dsc->slice_width & 0xffff) |
>>>> +        ((dsc->slice_height & 0xffff) << 16);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_SLICE_SIZE, data);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_MISC_SIZE,
>>>> +            (dsc->slice_chunk_size) & 0xffff);
>>>> +
>>>> +    data = (dsc->initial_xmit_delay & 0xffff) |
>>>> +        ((dsc->initial_dec_delay & 0xffff) << 16);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_HRD_DELAYS, data);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_SCALE,
>>>> +            dsc->initial_scale_value & 0x3f);
>>>> +
>>>> +    data = (dsc->scale_increment_interval & 0xffff) |
>>>> +        ((dsc->scale_decrement_interval & 0x7ff) << 16);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_SCALE_INC_DEC, data);
>>>> +
>>>> +    data = (dsc->first_line_bpg_offset & 0x1f) |
>>>> +        ((dsc->second_line_bpg_offset & 0x1f) << 5);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_1, data);
>>>> +
>>>> +    data = (dsc->nfl_bpg_offset & 0xffff) |
>>>> +        ((dsc->slice_bpg_offset & 0xffff) << 16);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_2, data);
>>>> +
>>>> +    data = (dsc->initial_offset & 0xffff) |
>>>> +        ((dsc->final_offset & 0xffff) << 16);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_3, data);
>>>> +
>>>> +    data = (dsc->nsl_bpg_offset & 0xffff) |
>>>> +        ((dsc->second_line_offset_adj & 0xffff) << 16);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_OFFSETS_4, data);
>>>> +
>>>> +    data = (dsc->flatness_min_qp & 0x1f);
>>>> +    data |= (dsc->flatness_max_qp & 0x1f) << 5;
>>>> +
>>>> +    det_thresh_flatness = drm_dsc_calculate_flatness_det_thresh(dsc);
>>>> +    data |= (det_thresh_flatness & 0xff) << 10;
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_FLATNESS_QP, data);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_MODEL_SIZE,
>>>> +            (dsc->rc_model_size) & 0xffff);
>>>> +
>>>> +    data = dsc->rc_edge_factor & 0xf;
>>>> +    data |= (dsc->rc_quant_incr_limit0 & 0x1f) << 8;
>>>> +    data |= (dsc->rc_quant_incr_limit1 & 0x1f) << 13;
>>>> +    data |= (dsc->rc_tgt_offset_high & 0xf) << 20;
>>>> +    data |= (dsc->rc_tgt_offset_low & 0xf) << 24;
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_RC_CONFIG, data);
>>>> +
>>>> +    /* program the dsc wrapper */
>>>> +    offset = hw_dsc->caps->sblk->ctl.base;
>>>> +
>>>> +    data = BIT(0); /* encoder enable */
>>>> +    if (dsc->native_422)
>>>> +        data |= BIT(8);
>>>> +    else if (dsc->native_420)
>>>> +        data |= BIT(9);
>>>> +    if (!dsc->convert_rgb)
>>>> +        data |= BIT(10);
>>>> +    if (dsc->bits_per_component == 8)
>>>> +        data |= BIT(11);
>>>> +    if (mode & DSC_MODE_SPLIT_PANEL)
>>>> +        data |= BIT(12);
>>>> +    if (mode & DSC_MODE_MULTIPLEX)
>>>> +        data |= BIT(13);
>>>> +    if (!(mode & DSC_MODE_VIDEO))
>>>> +        data |= BIT(17);
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_CFG, data);
>>>> +}
>>>> +
>>>> +static void dpu_hw_dsc_config_thresh_1_2(struct dpu_hw_dsc *hw_dsc,
>>>> +                    struct drm_dsc_config *dsc)
>>>> +{
>>>> +    struct dpu_hw_blk_reg_map *hw;
>>>> +    u32 offset, off;
>>>> +    int i, j = 0;
>>>> +    struct drm_dsc_rc_range_parameters *rc;
>>>> +    u32 data = 0, min_qp = 0, max_qp = 0, bpg_off = 0;
>>>> +
>>>> +    if (!hw_dsc || !dsc)
>>>> +        return;
>>>> +
>>>> +    offset = hw_dsc->caps->sblk->enc.base;
>>>> +
>>>> +    hw = &hw_dsc->hw;
>>>> +
>>>> +    rc = dsc->rc_range_params;
>>>> +
>>>> +    /*
>>>> +     * With BUF_THRESH -- 14 in total
>>>> +     * each register contains 4 thresh values with the last register
>>>> +     * containing only 2 thresh values
>>>> +     */
>>>> +    off = 0;
>>>> +    for (i = 0; i < DSC_NUM_BUF_RANGES - 1; i++) {
>>>> +        data |= dsc->rc_buf_thresh[i] << (8 * j);
>>>> +        j++;
>>>> +        if ((j == 4) || (i == DSC_NUM_BUF_RANGES - 2)) {
>>>> +            DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0 + off,
>>>> data);
>>>> +            off += 4;
>>>> +            j = 0;
>>>> +            data = 0;
>>>> +        }
>>>> +    }
>>>
>>> This is barely understandable code. The following line is much better:
>>>
>>> DPU_REG_WRITE(hw, offset + DSC_RC_BUF_THRESH_0,
>>>     (dsc->rc_buf_thresh[0] << 0) |
>>>     (dsc->rc_buf_thresh[1] << 8) |
>>>     (dsc->rc_buf_thresh[2] << 16) |
>>>     (dsc->rc_buf_thresh[3] << 24));
>>>
>>> etc.
>>>
>>> Please unroll both loops.
>>>
>>>> +
>>>> +
>>>> +    /*
>>>> +     * with min/max_QP -- 5 bits each
>>>> +     * each register contains 5 min_qp or max_qp for total of 15
>>>> +     *
>>>> +     * With BPG_OFFSET -- 6 bits each
>>>> +     * each register contains 5 BPG_offset for total of 15
>>>> +     */
>>>> +    off = 0;
>>>> +    for (i = 0; i < DSC_NUM_BUF_RANGES; i++) {
>>>> +        min_qp |= rc[i].range_min_qp << (5 * j);
>>>> +        max_qp |= rc[i].range_max_qp << (5 * j);
>>>> +        bpg_off |= rc[i].range_bpg_offset << (6 * j);
>>>> +        j++;
>>>> +        if (j == 5) {
>>>> +            DPU_REG_WRITE(hw, offset + DSC_RC_MIN_QP_0 + off,
>>>> min_qp);
>>>> +            DPU_REG_WRITE(hw, offset + DSC_RC_MAX_QP_0 + off,
>>>> max_qp);
>>>> +            DPU_REG_WRITE(hw, offset + DSC_RC_RANGE_BPG_OFFSETS_0
>>>> + off, bpg_off);
>>>> +            off += 4;
>>>> +            j = 0;
>>>> +            min_qp = 0;
>>>> +            max_qp = 0;
>>>> +            bpg_off = 0;
>>>> +        }
>>>> +    }
>>>> +}
>>>> +
>>>> +static void dpu_hw_dsc_bind_pingpong_blk_1_2(
>>>> +        struct dpu_hw_dsc *hw_dsc,
>>>> +        bool enable,
>>>> +        const enum dpu_pingpong pp)
>>>> +{
>>>> +    struct dpu_hw_blk_reg_map *hw;
>>>> +    int offset;
>>>> +    int mux_cfg = 0xf; /* Disabled */
>>>> +
>>>> +    offset = hw_dsc->caps->sblk->ctl.base;
>>>> +
>>>> +    hw = &hw_dsc->hw;
>>>> +    if (enable)
>>>> +        mux_cfg = (pp - PINGPONG_0) & 0x7;
>>>> +
>>>> +    DPU_REG_WRITE(hw, offset + DSC_CTL, mux_cfg);
>>>> +}
>>>
>>> Please refactor the existing bind_pingpong_blk() semantics to accept
>>> either a valid PINGPONG_n, or PINGPONG_NONE to disable the binding.
>>
>> Could you please give me more details for this comment.
>>
>> both dsc_1_1 and dsc_1_2 are required to select and set mux bits of
>> mux_cfg to binding dsc and  pingpong together.
>
> Yes. I was refererring to the function interface. You pass both `bool
> enable` and PP index. The index doesn't make sense for 'disable' case.
> So we can use a single argument of `enum dpu_pingpong` type. Pass
> PINGPONG_n for binding it. Pass PINGPONG_NONE for removing the binding.
ok, i will add an patch for this since it will touch dpu_encoder.c and
dpu_hw_dsc.c
>
>>
>