Browse Source

disp: msm: sde: fix reg dump from accessing unavailable registers

On Waipio target, periph top0 block has been removed from mdp top
register block. This creates a hole in the accessible register space
and can lead to NOC errors. In addition, accessing register offset
for invalid dedicated concurrent write back can lead to NOC errors.

This change adds support for indicating if the periph block has been
removed and splitting the mdp top register block into two for reg dump.
In addition, it only registers valid dcwb to be reg dumped by
adding a dcwb count.

Change-Id: I23931cdf5ce4d858a3837f3946b54d9231e0db27
Signed-off-by: Nilaan Gunabalachandran <[email protected]>
Nilaan Gunabalachandran 4 years ago
parent
commit
f9ff8af5b6
4 changed files with 27 additions and 3 deletions
  1. 5 1
      msm/sde/sde_hw_catalog.c
  2. 5 0
      msm/sde/sde_hw_catalog.h
  3. 16 1
      msm/sde/sde_hw_top.c
  4. 1 1
      msm/sde/sde_hw_wb.c

+ 5 - 1
msm/sde/sde_hw_catalog.c

@@ -3880,8 +3880,11 @@ static int sde_pp_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
 		if (PROP_VALUE_ACCESS(prop_value, PP_SLAVE, i))
 			set_bit(SDE_PINGPONG_SLAVE, &pp->features);
 
-		if (PROP_VALUE_ACCESS(prop_value, PP_CWB, i))
+		if (PROP_VALUE_ACCESS(prop_value, PP_CWB, i)) {
 			set_bit(SDE_PINGPONG_CWB, &pp->features);
+			if (sde_cfg->has_dedicated_cwb_support)
+				sde_cfg->dcwb_count++;
+		}
 
 		if (major_version < SDE_HW_MAJOR(SDE_HW_VER_700)) {
 			sblk->dsc.base = PROP_VALUE_ACCESS(prop_value,
@@ -5115,6 +5118,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
 		sde_cfg->syscache_supported = true;
 		sde_cfg->sspp_multirect_error = true;
 		sde_cfg->has_fp16 = true;
+		set_bit(SDE_MDP_PERIPH_TOP_0_REMOVED, &sde_cfg->mdp[0].features);
 	} else {
 		SDE_ERROR("unsupported chipset id:%X\n", hw_rev);
 		sde_cfg->perf.min_prefill_lines = 0xffff;

+ 5 - 0
msm/sde/sde_hw_catalog.h

@@ -214,6 +214,7 @@ struct sde_intr_irq_offsets {
  * @SDE_MDP_WD_TIMER      WD timer support
  * @SDE_MDP_DHDR_MEMPOOL   Dynamic HDR Metadata mempool present
  * @SDE_MDP_DHDR_MEMPOOL_4K Dynamic HDR mempool is 4k aligned
+ * @SDE_MDP_PERIPH_TOP_REMOVED Indicates if periph top0 block is removed
  * @SDE_MDP_MAX            Maximum value
 
  */
@@ -227,6 +228,7 @@ enum {
 	SDE_MDP_WD_TIMER,
 	SDE_MDP_DHDR_MEMPOOL,
 	SDE_MDP_DHDR_MEMPOOL_4K,
+	SDE_MDP_PERIPH_TOP_0_REMOVED,
 	SDE_MDP_MAX
 };
 
@@ -1510,6 +1512,7 @@ struct sde_perf_cfg {
  * @irq_offset_list     list of sde_intr_irq_offsets to initialize irq table
  * @rc_count	number of rounded corner hardware instances
  * @demura_count number of demura hardware instances
+ * @dcwb_count          number of dcwb hardware instances
  */
 struct sde_mdss_cfg {
 	u32 hwversion;
@@ -1648,6 +1651,8 @@ struct sde_mdss_cfg {
 	u32 qdss_count;
 	struct sde_qdss_cfg qdss[MAX_BLOCKS];
 
+	u32 dcwb_count;
+
 	/* Add additional block data structures here */
 
 	struct sde_perf_cfg perf;

+ 16 - 1
msm/sde/sde_hw_top.c

@@ -50,6 +50,9 @@
 #define MDP_WD_TIMER_4_CTL2               0x444
 #define MDP_WD_TIMER_4_LOAD_VALUE         0x448
 
+#define MDP_PERIPH_TOP0                   0x380
+#define MDP_SSPP_TOP2                     0x3A8
+
 #define AUTOREFRESH_TEST_POINT	0x2
 #define TEST_MASK(id, tp)	((id << 4) | (tp << 1) | BIT(0))
 
@@ -695,9 +698,21 @@ struct sde_hw_mdp *sde_hw_mdptop_init(enum sde_mdp idx,
 	sde_dbg_reg_register_dump_range(SDE_DBG_NAME, "mdss_hw", 0,
 			m->mdss_hw_block_size, 0);
 
-	sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name,
+	if (test_bit(SDE_MDP_PERIPH_TOP_0_REMOVED, &m->mdp[0].features)) {
+		char name[SDE_HW_BLK_NAME_LEN];
+
+		snprintf(name, sizeof(name), "%s_1", cfg->name);
+
+		sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name, mdp->hw.blk_off,
+				mdp->hw.blk_off + MDP_PERIPH_TOP0, mdp->hw.xin_id);
+
+		sde_dbg_reg_register_dump_range(SDE_DBG_NAME, name, mdp->hw.blk_off + MDP_SSPP_TOP2,
+				mdp->hw.blk_off +  mdp->hw.length, mdp->hw.xin_id);
+	} else {
+		sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name,
 			mdp->hw.blk_off, mdp->hw.blk_off + mdp->hw.length,
 			mdp->hw.xin_id);
+	}
 	sde_dbg_set_sde_top_offset(mdp->hw.blk_off);
 
 	return mdp;

+ 1 - 1
msm/sde/sde_hw_wb.c

@@ -117,7 +117,7 @@ static void _sde_hw_dcwb_ctrl_init(struct sde_mdss_cfg *m,
 	b->hwversion = m->hwversion;
 	b->log_mask = SDE_DBG_MASK_WB;
 
-	for (i = 0; i < m->pingpong_count; i++) {
+	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);