Prechádzať zdrojové kódy

disp: msm: sde: add changes to support additional dedicated-CWB

Update the hardware blocks and corresponding APIs
to configure new D-CWB data path. Add new hardware
pingpong blocks that are dedicated for second DCWB.

Change-Id: I529c24ac5aa483f30b6c9e7653eb1713c6b8fb8a
Signed-off-by: Shamika Joshi <[email protected]>
Shamika Joshi 2 rokov pred
rodič
commit
b9553cf5f3

+ 4 - 0
msm/sde/sde_connector.c

@@ -2932,6 +2932,10 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
 								       sde_kms->catalog->features));
 		sde_kms_info_add_keyint(info, "has_dedicated_cwb_support",
 				test_bit(SDE_FEATURE_DEDICATED_CWB, sde_kms->catalog->features));
+		if (test_bit(SDE_FEATURE_DUAL_DEDICATED_CWB, sde_kms->catalog->features))
+			sde_kms_info_add_keyint(info, "max_cwb", 2);
+		else
+			sde_kms_info_add_keyint(info, "max_cwb", 1);
 
 		sde_kms_info_add_keyint(info, "mdp_transfer_time_us",
 			mode_info.mdp_transfer_time_us);

+ 2 - 0
msm/sde/sde_encoder_phys.h

@@ -211,6 +211,7 @@ struct sde_encoder_phys_ops {
  * @INTR_IDX_PP4_OVFL: Pingpong overflow interrupt on PP4 for Concurrent WB
  * @INTR_IDX_PP5_OVFL: Pingpong overflow interrupt on PP5 for Concurrent WB
  * @INTR_IDX_PP_CWB_OVFL: Pingpong overflow interrupt on PP_CWB0/1 for Concurrent WB
+ * @INTR_IDX_PP_CWB2_OVFL: Pingpong overflow interrupt on PP_CWB2/3 for Concurrent WB
  * @INTR_IDX_AUTOREFRESH_DONE:  Autorefresh done for cmd mode panel meaning
  *                              autorefresh has triggered a double buffer flip
  * @INTR_IDX_WRPTR:    Writepointer start interrupt for cmd mode panel
@@ -231,6 +232,7 @@ enum sde_intr_idx {
 	INTR_IDX_PP4_OVFL,
 	INTR_IDX_PP5_OVFL,
 	INTR_IDX_PP_CWB_OVFL,
+	INTR_IDX_PP_CWB2_OVFL,
 	INTR_IDX_WRPTR,
 	INTR_IDX_WB_LINEPTR,
 	INTR_IDX_MAX,

+ 1 - 1
msm/sde/sde_encoder_phys_wb.c

@@ -1251,7 +1251,7 @@ static void _sde_encoder_phys_wb_update_cwb_flush_helper(
 		src_pp_idx = (enum sde_cwb) (src_pp_idx + i);
 
 		if (test_bit(SDE_WB_DCWB_CTRL, &hw_wb->caps->features)) {
-			dcwb_idx = (enum sde_dcwb) ((hw_pp->idx % 2) + i);
+			dcwb_idx = (enum sde_dcwb) ((hw_pp->idx - (PINGPONG_CWB_0 - 1)) + i);
 			if ((test_bit(SDE_WB_CWB_DITHER_CTRL, &hw_wb->caps->features)) &&
 				hw_wb->ops.program_cwb_dither_ctrl){
 				hw_wb->ops.program_cwb_dither_ctrl(hw_wb,

+ 16 - 6
msm/sde/sde_hw_catalog.c

@@ -2493,16 +2493,22 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
 
 		if (test_bit(SDE_FEATURE_DEDICATED_CWB, sde_cfg->features)) {
 			set_bit(SDE_WB_HAS_DCWB, &wb->features);
+			if (test_bit(SDE_FEATURE_DUAL_DEDICATED_CWB, sde_cfg->features))
+				set_bit(SDE_HW_HAS_DUAL_DCWB, &wb->features);
 			if (IS_SDE_CTL_REV_100(sde_cfg->ctl_rev))
 				set_bit(SDE_WB_DCWB_CTRL, &wb->features);
-			if (major_version >= SDE_HW_MAJOR(SDE_HW_VER_900)) {
-				sde_cfg->cwb_blk_off = 0x67200;
+			if (major_version >= SDE_HW_MAJOR(SDE_HW_VER_A00)) {
+				sde_cfg->cwb_blk_off[0] = 0x67200;
+				sde_cfg->cwb_blk_off[1] = 0x7F200;
+				sde_cfg->cwb_blk_stride = 0x400;
+			} else if (major_version >= SDE_HW_MAJOR(SDE_HW_VER_900)) {
+				sde_cfg->cwb_blk_off[0] = 0x67200;
 				sde_cfg->cwb_blk_stride = 0x400;
 			} else if (major_version >= SDE_HW_MAJOR(SDE_HW_VER_810)) {
-				sde_cfg->cwb_blk_off = 0x66A00;
+				sde_cfg->cwb_blk_off[0] = 0x66A00;
 				sde_cfg->cwb_blk_stride = 0x400;
 			} else {
-				sde_cfg->cwb_blk_off = 0x83000;
+				sde_cfg->cwb_blk_off[0] = 0x83000;
 				sde_cfg->cwb_blk_stride = 0x100;
 			}
 
@@ -2514,10 +2520,10 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
 			if (IS_SDE_CTL_REV_100(sde_cfg->ctl_rev))
 				set_bit(SDE_WB_CWB_CTRL, &wb->features);
 			if (major_version >= SDE_HW_MAJOR(SDE_HW_VER_700)) {
-				sde_cfg->cwb_blk_off = 0x6A200;
+				sde_cfg->cwb_blk_off[0] = 0x6A200;
 				sde_cfg->cwb_blk_stride = 0x1000;
 			} else {
-				sde_cfg->cwb_blk_off = 0x83000;
+				sde_cfg->cwb_blk_off[0] = 0x83000;
 				sde_cfg->cwb_blk_stride = 0x100;
 			}
 		}
@@ -5350,6 +5356,10 @@ static int _sde_hardware_post_caps(struct sde_mdss_cfg *sde_cfg,
 	sde_cfg->min_display_height = MIN_DISPLAY_HEIGHT;
 	sde_cfg->min_display_width = MIN_DISPLAY_WIDTH;
 	sde_cfg->max_cwb = min_t(u32, sde_cfg->wb_count, MAX_CWB_SESSIONS);
+	if (test_bit(SDE_FEATURE_DUAL_DEDICATED_CWB, sde_cfg->features))
+		sde_cfg->max_cwb = 2;
+	else
+		sde_cfg->max_cwb = 1;
 
 	_sde_hw_fence_caps(sde_cfg);
 

+ 8 - 2
msm/sde/sde_hw_catalog.h

@@ -21,6 +21,8 @@
  */
 #define MAX_BLOCKS    12
 #define MAX_REG_SIZE_ENTRIES 14
+#define MAX_CWB_BLOCKS    2
+#define MAX_CWB_BLOCKSIZE    2
 
 #define SDE_HW_VER(MAJOR, MINOR, STEP) ((u32)((MAJOR & 0xF) << 28)    |\
 		((MINOR & 0xFFF) << 16)  |\
@@ -628,6 +630,7 @@ enum {
  *                          data arrives.
  * @SDE_WB_HAS_CWB          Writeback block supports concurrent writeback
  * @SDE_WB_HAS_DCWB         Writeback block supports dedicated CWB
+ * @SDE_HW_HAS_DUAL_DCWB    Writeback block supports dual dedicated CWB
  * @SDE_WB_CROP             CWB supports cropping
  * @SDE_WB_SYS_CACHE        Writeback block supports system cache usage
  * @SDE_WB_CWB_CTRL         Separate CWB control is available for configuring
@@ -651,6 +654,7 @@ enum {
 	SDE_WB_INPUT_CTRL,
 	SDE_WB_HAS_CWB,
 	SDE_WB_HAS_DCWB,
+	SDE_HW_HAS_DUAL_DCWB,
 	SDE_WB_CROP,
 	SDE_WB_SYS_CACHE,
 	SDE_WB_CWB_CTRL,
@@ -703,6 +707,7 @@ enum {
  * @SDE_FEATURE_CWB_CROP       CWB Cropping supported
  * @SDE_FEATURE_CWB_DITHER     CWB dither is supported
  * @SDE_FEATURE_DEDICATED_CWB  Dedicated-CWB supported
+ * @SDE_FEATURE_DUAL_DEDICATED_CWB   Dual Dedicated-CWB supported
  * @SDE_FEATURE_IDLE_PC        Idle Power Collapse supported
  * @SDE_FEATURE_3D_MERGE_RESET 3D merge reset supported
  * @SDE_FEATURE_DECIMATION     Decimation supported
@@ -745,6 +750,7 @@ enum sde_mdss_features {
 	SDE_FEATURE_CWB_CROP,
 	SDE_FEATURE_CWB_DITHER,
 	SDE_FEATURE_DEDICATED_CWB,
+	SDE_FEATURE_DUAL_DEDICATED_CWB,
 	SDE_FEATURE_IDLE_PC,
 	SDE_FEATURE_3D_MERGE_RESET,
 	SDE_FEATURE_DECIMATION,
@@ -1841,7 +1847,7 @@ struct sde_perf_cfg {
  * @max_dsc_width       max dsc line width
  * @max_mixer_width     max layer mixer line width
  * @max_mixer_blendstages       max layer mixer blend stages (z orders)
- * @max_cwb             max number of cwb supported
+ * @max_cwb             max number of dcwb/cwb supported
  * @vbif_qos_nlvl       number of vbif QoS priority levels
  * @qos_target_time_ns  normalized qos target time for line-based qos
  * @macrotile_mode      UBWC parameter for macro tile channel distribution
@@ -1918,7 +1924,7 @@ struct sde_mdss_cfg {
 	struct sde_merge_3d_cfg merge_3d[MAX_BLOCKS];
 	u32 qdss_count;
 	struct sde_qdss_cfg qdss[MAX_BLOCKS];
-	u32 cwb_blk_off;
+	u32 cwb_blk_off[MAX_CWB_BLOCKS];
 	u32 cwb_blk_stride;
 	u32 dcwb_count;
 

+ 1 - 1
msm/sde/sde_hw_ctl.c

@@ -180,7 +180,7 @@ static const u32 cwb_flush_tbl[CWB_MAX] = {SDE_NONE, SDE_NONE, 1, 2, 3,
 /**
  * list of CWB bits in CTL_CWB_FLUSH for dedicated cwb
  */
-static const u32 dcwb_flush_tbl[CWB_MAX] = {SDE_NONE, SDE_NONE, 0, 1};
+static const u32 dcwb_flush_tbl[CWB_MAX] = {SDE_NONE, SDE_NONE, 0, 1, 2, 3};
 
 /**
  * list of DSPP sub-blk flush bits in CTL_DSPP_x_FLUSH

+ 7 - 0
msm/sde/sde_hw_mdss.h

@@ -181,6 +181,8 @@ enum sde_lm {
 	LM_5,
 	LM_DCWB_DUMMY_0,
 	LM_DCWB_DUMMY_1,
+	LM_DCWB_DUMMY_2,
+	LM_DCWB_DUMMY_3,
 	LM_6,
 	LM_MAX
 };
@@ -264,6 +266,8 @@ enum sde_pingpong {
 	PINGPONG_5,
 	PINGPONG_CWB_0,
 	PINGPONG_CWB_1,
+	PINGPONG_CWB_2,
+	PINGPONG_CWB_3,
 	PINGPONG_S0,
 	PINGPONG_MAX
 };
@@ -346,6 +350,8 @@ enum sde_cwb {
 enum sde_dcwb {
 	DCWB_0 = 0x1,
 	DCWB_1,
+	DCWB_2,
+	DCWB_3,
 	DCWB_MAX
 };
 
@@ -383,6 +389,7 @@ enum sde_merge_3d {
 	MERGE_3D_1,
 	MERGE_3D_2,
 	MERGE_3D_CWB_0,
+	MERGE_3D_CWB_1,
 	MERGE_3D_MAX
 };
 

+ 22 - 18
msm/sde/sde_hw_wb.c

@@ -84,7 +84,7 @@ static void _sde_hw_cwb_ctrl_init(struct sde_mdss_cfg *m,
 		return;
 
 	b->base_off = addr;
-	b->blk_off = m->cwb_blk_off;
+	b->blk_off = m->cwb_blk_off[0];
 	b->length = 0x20;
 	b->hw_rev = m->hw_rev;
 	b->log_mask = SDE_DBG_MASK_WB;
@@ -99,27 +99,29 @@ static void _sde_hw_cwb_ctrl_init(struct sde_mdss_cfg *m,
 }
 
 static void _sde_hw_dcwb_ctrl_init(struct sde_mdss_cfg *m,
-		void __iomem *addr, struct sde_hw_blk_reg_map *b)
+		void __iomem *addr, struct sde_hw_wb *hw_wb)
 {
-	int i;
+	int i, j;
 	u32 blk_off;
 	char name[64] = {0};
 
-	if (!b)
+	if (!hw_wb)
 		return;
 
-	b->base_off = addr;
-	b->blk_off = m->cwb_blk_off;
-	b->length = 0x20;
-	b->hw_rev = m->hw_rev;
-	b->log_mask = SDE_DBG_MASK_WB;
+	for (j = 0; j < (m->dcwb_count / MAX_CWB_BLOCKSIZE); j++) {
+		hw_wb->dcwb_hw[j].base_off = addr;
+		hw_wb->dcwb_hw[j].blk_off = m->cwb_blk_off[j];
+		hw_wb->dcwb_hw[j].length = 0x20;
+		hw_wb->dcwb_hw[j].hw_rev = m->hw_rev;
+		hw_wb->dcwb_hw[j].log_mask = SDE_DBG_MASK_WB;
 
-	for (i = 0; i < m->dcwb_count; i++) {
-		snprintf(name, sizeof(name), "dcwb%d", i);
-		blk_off = b->blk_off + (m->cwb_blk_stride * i);
+		for (i = 0; i < MAX_CWB_BLOCKSIZE; i++) {
+			snprintf(name, sizeof(name), "dcwb%d", i);
+			blk_off = hw_wb->dcwb_hw[j].blk_off + (m->cwb_blk_stride * i);
 
-		sde_dbg_reg_register_dump_range(SDE_DBG_NAME, name,
-				blk_off, blk_off + b->length, 0xff);
+			sde_dbg_reg_register_dump_range(SDE_DBG_NAME, name,
+					blk_off, blk_off + hw_wb->dcwb_hw[j].length, 0xff);
+		}
 	}
 }
 
@@ -353,7 +355,7 @@ static void sde_hw_wb_bind_dcwb_pp_blk(
 
 	c = &ctx->hw;
 	if (enable)
-		mux_cfg = 0xd;
+		mux_cfg = (pp < PINGPONG_CWB_2) ? 0xd : 0xb;
 
 	SDE_REG_WRITE(c, WB_MUX, mux_cfg);
 }
@@ -364,12 +366,14 @@ static void sde_hw_wb_program_dcwb_ctrl(struct sde_hw_wb *ctx,
 {
 	struct sde_hw_blk_reg_map *c;
 	u32 blk_base;
+	int idx;
 
 	if (!ctx)
 		return;
 
-	c = &ctx->dcwb_hw;
-	blk_base  = ctx->catalog->cwb_blk_stride * (cur_idx - DCWB_0);
+	idx = (cur_idx < DCWB_2) ? 0 : 1;
+	c = &ctx->dcwb_hw[idx];
+	blk_base  = ctx->catalog->cwb_blk_stride * ((cur_idx - DCWB_0) % MAX_CWB_BLOCKSIZE);
 
 	if (enable) {
 		SDE_REG_WRITE(c, blk_base + CWB_CTRL_SRC_SEL, data_src - CWB_0);
@@ -678,7 +682,7 @@ struct sde_hw_blk_reg_map *sde_hw_wb_init(enum sde_wb idx,
 		_sde_hw_cwb_ctrl_init(m, addr, &c->cwb_hw);
 
 	if (test_bit(SDE_WB_DCWB_CTRL, &cfg->features)) {
-		_sde_hw_dcwb_ctrl_init(m, addr, &c->dcwb_hw);
+		_sde_hw_dcwb_ctrl_init(m, addr, c);
 		_sde_hw_dcwb_pp_ctrl_init(m, addr, c);
 	}
 

+ 2 - 1
msm/sde/sde_hw_wb.h

@@ -1,5 +1,6 @@
 /* SPDX-License-Identifier: GPL-2.0-only */
 /*
+ * Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
  * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
  */
 
@@ -242,7 +243,7 @@ struct sde_hw_wb {
 
 	struct sde_hw_mdp *hw_mdp;
 	struct sde_hw_blk_reg_map cwb_hw;
-	struct sde_hw_blk_reg_map dcwb_hw;
+	struct sde_hw_blk_reg_map dcwb_hw[MAX_CWB_BLOCKS];
 	struct sde_hw_pingpong dcwb_pp_hw[DCWB_MAX - DCWB_0];
 };