Эх сурвалжийг харах

disp: msm: sde: avoid mixer op setup for virtual LM

This change sets a flag to true if a mixer is a virtual mixer.
Virtual mixers will skip setting up mixer ops and debug register
dumps as their range is not valid. Since mixer ops are no longer
guaranteed to be set, add null checks before using these ops.

Change-Id: Idfe7e1e2b893dadbbe6756d69d0c4ca4fa6ae4ce
Signed-off-by: Samantha Tran <[email protected]>
Samantha Tran 4 жил өмнө
parent
commit
ef2525e0cc

+ 14 - 13
msm/sde/sde_crtc.c

@@ -641,8 +641,9 @@ static void _sde_crtc_setup_blend_cfg(struct sde_crtc_mixer *mixer,
 		break;
 		break;
 	}
 	}
 
 
-	lm->ops.setup_blend_config(lm, pstate->stage, fg_alpha,
-						bg_alpha, blend_op);
+	if (lm->ops.setup_blend_config)
+		lm->ops.setup_blend_config(lm, pstate->stage, fg_alpha, bg_alpha, blend_op);
+
 	SDE_DEBUG(
 	SDE_DEBUG(
 		"format: %4.4s, alpha_enable %u fg alpha:0x%x bg alpha:0x%x blend_op:0x%x\n",
 		"format: %4.4s, alpha_enable %u fg alpha:0x%x bg alpha:0x%x blend_op:0x%x\n",
 		(char *) &format->base.pixel_format,
 		(char *) &format->base.pixel_format,
@@ -1284,7 +1285,8 @@ static void _sde_crtc_program_lm_output_roi(struct drm_crtc *crtc)
 			cfg.right_mixer = right_mixer;
 			cfg.right_mixer = right_mixer;
 			cfg.flags = 0;
 			cfg.flags = 0;
 
 
-			hw_lm->ops.setup_mixer_out(hw_lm, &cfg);
+			if (hw_lm->ops.setup_mixer_out)
+				hw_lm->ops.setup_mixer_out(hw_lm, &cfg);
 			lm_updated = true;
 			lm_updated = true;
 		}
 		}
 
 
@@ -1828,7 +1830,8 @@ static void _sde_crtc_blend_setup(struct drm_crtc *crtc,
 		if (sde_kms_rect_is_null(lm_roi))
 		if (sde_kms_rect_is_null(lm_roi))
 			sde_crtc->mixers[i].mixer_op_mode = 0;
 			sde_crtc->mixers[i].mixer_op_mode = 0;
 
 
-		lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
+		if (lm->ops.setup_alpha_out)
+			lm->ops.setup_alpha_out(lm, mixer[i].mixer_op_mode);
 
 
 		/* stage config flush mask */
 		/* stage config flush mask */
 		ctl->ops.update_bitmask_mixer(ctl, mixer[i].hw_lm->idx, 1);
 		ctl->ops.update_bitmask_mixer(ctl, mixer[i].hw_lm->idx, 1);
@@ -6457,24 +6460,22 @@ static ssize_t _sde_crtc_misr_read(struct file *file,
 
 
 		m = &sde_crtc->mixers[i];
 		m = &sde_crtc->mixers[i];
 		if (!m->hw_lm || !m->hw_lm->ops.collect_misr) {
 		if (!m->hw_lm || !m->hw_lm->ops.collect_misr) {
-			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
-					"invalid\n");
-			SDE_ERROR("crtc:%d invalid misr ops\n", DRMID(crtc));
+			if (!m->hw_lm || !m->hw_lm->cap->dummy_mixer) {
+				len += scnprintf(buf + len, MISR_BUFF_SIZE - len, "invalid\n");
+				SDE_ERROR("crtc:%d invalid misr ops\n", DRMID(crtc));
+			}
 			continue;
 			continue;
 		}
 		}
 
 
 		rc = m->hw_lm->ops.collect_misr(m->hw_lm, false, &misr_value);
 		rc = m->hw_lm->ops.collect_misr(m->hw_lm, false, &misr_value);
 		if (rc) {
 		if (rc) {
-			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
-					"invalid\n");
-			SDE_ERROR("crtc:%d failed to collect misr %d\n",
-					DRMID(crtc), rc);
+			len += scnprintf(buf + len, MISR_BUFF_SIZE - len, "invalid\n");
+			SDE_ERROR("crtc:%d failed to collect misr %d\n", DRMID(crtc), rc);
 			continue;
 			continue;
 		} else {
 		} else {
 			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
 			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
 					"lm idx:%d\n", m->hw_lm->idx - LM_0);
 					"lm idx:%d\n", m->hw_lm->idx - LM_0);
-			len += scnprintf(buf + len, MISR_BUFF_SIZE - len,
-					"0x%x\n", misr_value);
+			len += scnprintf(buf + len, MISR_BUFF_SIZE - len, "0x%x\n", misr_value);
 		}
 		}
 	}
 	}
 
 

+ 2 - 2
msm/sde/sde_hw_catalog.c

@@ -2175,8 +2175,7 @@ void sde_hw_mixer_set_preference(struct sde_mdss_cfg *sde_cfg, u32 num_lm,
 	}
 	}
 }
 }
 
 
-static int sde_mixer_parse_dt(struct device_node *np,
-						struct sde_mdss_cfg *sde_cfg)
+static int sde_mixer_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg)
 {
 {
 	int rc = 0, i, j;
 	int rc = 0, i, j;
 	u32 off_count, blend_off_count, max_blendstages, lm_pair_mask;
 	u32 off_count, blend_off_count, max_blendstages, lm_pair_mask;
@@ -2290,6 +2289,7 @@ static int sde_mixer_parse_dt(struct device_node *np,
 			if (mixer->base == dummy_mixer_base) {
 			if (mixer->base == dummy_mixer_base) {
 				mixer->base = 0x0;
 				mixer->base = 0x0;
 				mixer->len = 0;
 				mixer->len = 0;
+				mixer->dummy_mixer = true;
 			}
 			}
 		}
 		}
 
 

+ 2 - 0
msm/sde/sde_hw_catalog.h

@@ -1060,6 +1060,7 @@ struct sde_sspp_cfg {
  * @dspp:              ID of connected DSPP, DSPP_MAX if unsupported
  * @dspp:              ID of connected DSPP, DSPP_MAX if unsupported
  * @pingpong:          ID of connected PingPong, PINGPONG_MAX if unsupported
  * @pingpong:          ID of connected PingPong, PINGPONG_MAX if unsupported
  * @ds:                ID of connected DS, DS_MAX if unsupported
  * @ds:                ID of connected DS, DS_MAX if unsupported
+ * @dummy_mixer:       identifies dcwb mixer is considered dummy
  * @lm_pair_mask:      Bitmask of LMs that can be controlled by same CTL
  * @lm_pair_mask:      Bitmask of LMs that can be controlled by same CTL
  */
  */
 struct sde_lm_cfg {
 struct sde_lm_cfg {
@@ -1068,6 +1069,7 @@ struct sde_lm_cfg {
 	u32 dspp;
 	u32 dspp;
 	u32 pingpong;
 	u32 pingpong;
 	u32 ds;
 	u32 ds;
+	bool dummy_mixer;
 	unsigned long lm_pair_mask;
 	unsigned long lm_pair_mask;
 };
 };
 
 

+ 6 - 1
msm/sde/sde_hw_lm.c

@@ -422,7 +422,6 @@ struct sde_hw_mixer *sde_hw_lm_init(enum sde_lm idx,
 	/* Assign ops */
 	/* Assign ops */
 	c->idx = idx;
 	c->idx = idx;
 	c->cap = cfg;
 	c->cap = cfg;
-	_setup_mixer_ops(m, &c->ops, c->cap->features);
 
 
 	rc = sde_hw_blk_init(&c->base, SDE_HW_BLK_LM, idx, &sde_hw_ops);
 	rc = sde_hw_blk_init(&c->base, SDE_HW_BLK_LM, idx, &sde_hw_ops);
 	if (rc) {
 	if (rc) {
@@ -430,6 +429,12 @@ struct sde_hw_mixer *sde_hw_lm_init(enum sde_lm idx,
 		goto blk_init_error;
 		goto blk_init_error;
 	}
 	}
 
 
+	/* Dummy mixers should not setup ops and not be added to dump range */
+	if (cfg->dummy_mixer)
+		return c;
+
+	_setup_mixer_ops(m, &c->ops, c->cap->features);
+
 	sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name, c->hw.blk_off,
 	sde_dbg_reg_register_dump_range(SDE_DBG_NAME, cfg->name, c->hw.blk_off,
 			c->hw.blk_off + c->hw.length, c->hw.xin_id);
 			c->hw.blk_off + c->hw.length, c->hw.xin_id);