Răsfoiți Sursa

disp: msm: sde: add support for INTF line/frame count reset

From MDSS 8.x INTF line/frame counters can be reset through
a register. Reset these counters during timing engine enable /
tear-check enable to keep track of meaningful counters, which
would be useful during debugging. Additionally, reset the
counters during cont-splash modeset to track the number of
auto-refresh frames while disabling it during the first frame.

Change-Id: I66b45f5b29793df1fb4635972b1c614ad8c3b5b3
Signed-off-by: Veera Sundaram Sankaran <[email protected]>
Veera Sundaram Sankaran 4 ani în urmă
părinte
comite
9ad90a834d

+ 9 - 6
msm/sde/sde_encoder_phys_cmd.c

@@ -439,6 +439,9 @@ static void sde_encoder_phys_cmd_cont_splash_mode_set(
 			hw_pp->ops.get_autorefresh(hw_pp,
 					&cmd_enc->autorefresh.cfg);
 		}
+
+		if (hw_intf->ops.reset_counter)
+			hw_intf->ops.reset_counter(hw_intf);
 	}
 
 	_sde_encoder_phys_cmd_setup_irq_hw_idx(phys_enc);
@@ -682,12 +685,9 @@ static bool _sde_encoder_phys_cmd_is_ongoing_pptx(
 		hw_pp->ops.get_vsync_info(hw_pp, &info);
 	}
 
-	SDE_EVT32(DRMID(phys_enc->parent),
-			phys_enc->hw_pp->idx - PINGPONG_0,
-			phys_enc->hw_intf->idx - INTF_0,
-			atomic_read(&phys_enc->pending_kickoff_cnt),
-			info.wr_ptr_line_count,
-			phys_enc->cached_mode.vdisplay);
+	SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0,
+		phys_enc->hw_intf->idx - INTF_0, atomic_read(&phys_enc->pending_kickoff_cnt),
+		info.wr_ptr_line_count, info.intf_frame_count, phys_enc->cached_mode.vdisplay);
 
 	if (info.wr_ptr_line_count > 0 && info.wr_ptr_line_count <
 			phys_enc->cached_mode.vdisplay)
@@ -1348,6 +1348,9 @@ static void sde_encoder_phys_cmd_disable(struct sde_encoder_phys *phys_enc)
 			phys_enc->hw_pp->ops.enable_tearcheck(phys_enc->hw_pp,
 					false);
 		sde_encoder_helper_phys_disable(phys_enc, NULL);
+
+		if (phys_enc->hw_intf->ops.reset_counter)
+			phys_enc->hw_intf->ops.reset_counter(phys_enc->hw_intf);
 	}
 
 	phys_enc->enable_state = SDE_ENC_DISABLED;

+ 3 - 0
msm/sde/sde_encoder_phys_vid.c

@@ -1085,6 +1085,9 @@ static void sde_encoder_phys_vid_disable(struct sde_encoder_phys *phys_enc)
 	sde_encoder_phys_inc_pending(phys_enc);
 	spin_unlock_irqrestore(phys_enc->enc_spinlock, lock_flags);
 
+	if (phys_enc->hw_intf->ops.reset_counter)
+		phys_enc->hw_intf->ops.reset_counter(phys_enc->hw_intf);
+
 	sde_encoder_phys_vid_single_vblank_wait(phys_enc);
 	if (phys_enc->hw_intf->ops.get_status)
 		phys_enc->hw_intf->ops.get_status(phys_enc->hw_intf,

+ 3 - 1
msm/sde/sde_hw_catalog.c

@@ -2447,8 +2447,10 @@ static int sde_intf_parse_dt(struct device_node *np,
 			set_bit(SDE_INTF_TE_ALIGN_VSYNC, &intf->features);
 
 		if (SDE_HW_MAJOR(sde_cfg->hwversion) >=
-				SDE_HW_MAJOR(SDE_HW_VER_810))
+				SDE_HW_MAJOR(SDE_HW_VER_810)) {
 			set_bit(SDE_INTF_WD_TIMER, &intf->features);
+			set_bit(SDE_INTF_RESET_COUNTER, &intf->features);
+		}
 	}
 
 end:

+ 2 - 0
msm/sde/sde_hw_catalog.h

@@ -498,6 +498,7 @@ enum {
  * @SDE_INTF_TE_ALIGN_VSYNC     INTF block has POMS Align vsync support
  * @SDE_INTF_WD_TIMER          INTF block has WD Timer support
  * @SDE_INTF_STATUS             INTF block has INTF_STATUS register
+ * @SDE_INTF_RESET_COUNTER      INTF block has frame/line counter reset support
  * @SDE_INTF_MAX
  */
 enum {
@@ -506,6 +507,7 @@ enum {
 	SDE_INTF_TE_ALIGN_VSYNC,
 	SDE_INTF_WD_TIMER,
 	SDE_INTF_STATUS,
+	SDE_INTF_RESET_COUNTER,
 	SDE_INTF_MAX
 };
 

+ 13 - 3
msm/sde/sde_hw_intf.c

@@ -192,6 +192,13 @@ static inline void _check_and_set_comp_bit(struct sde_hw_intf *ctx,
 		(*intf_cfg2) |= BIT(12);
 }
 
+static void sde_hw_intf_reset_counter(struct sde_hw_intf *ctx)
+{
+	struct sde_hw_blk_reg_map *c = &ctx->hw;
+
+	SDE_REG_WRITE(c, INTF_LINE_COUNT, BIT(31));
+}
+
 static void sde_hw_intf_setup_timing_engine(struct sde_hw_intf *ctx,
 		const struct intf_timing_params *p,
 		const struct sde_format *fmt)
@@ -458,7 +465,7 @@ static void sde_hw_intf_get_status(
 	s->is_en = SDE_REG_READ(c, INTF_TIMING_ENGINE_EN);
 	if (s->is_en) {
 		s->frame_count = SDE_REG_READ(c, INTF_FRAME_COUNT);
-		s->line_count = SDE_REG_READ(c, INTF_LINE_COUNT);
+		s->line_count = SDE_REG_READ(c, INTF_LINE_COUNT) & 0xffff;
 	} else {
 		s->line_count = 0;
 		s->frame_count = 0;
@@ -474,7 +481,7 @@ static void sde_hw_intf_v1_get_status(
 	s->is_en = SDE_REG_READ(c, INTF_STATUS) & BIT(0);
 	if (s->is_en) {
 		s->frame_count = SDE_REG_READ(c, INTF_FRAME_COUNT);
-		s->line_count = SDE_REG_READ(c, INTF_LINE_COUNT);
+		s->line_count = SDE_REG_READ(c, INTF_LINE_COUNT) & 0xffff;
 	} else {
 		s->line_count = 0;
 		s->frame_count = 0;
@@ -537,7 +544,7 @@ static u32 sde_hw_intf_get_line_count(struct sde_hw_intf *intf)
 
 	c = &intf->hw;
 
-	return SDE_REG_READ(c, INTF_LINE_COUNT);
+	return SDE_REG_READ(c, INTF_LINE_COUNT) & 0xffff;
 }
 
 static u32 sde_hw_intf_get_underrun_line_count(struct sde_hw_intf *intf)
@@ -847,6 +854,9 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
 		ops->check_and_reset_tearcheck =
 			sde_hw_intf_v1_check_and_reset_tearcheck;
 	}
+
+	if (cap & BIT(SDE_INTF_RESET_COUNTER))
+		ops->reset_counter = sde_hw_intf_reset_counter;
 }
 
 static struct sde_hw_blk_ops sde_hw_ops = {

+ 5 - 0
msm/sde/sde_hw_intf.h

@@ -205,6 +205,11 @@ struct sde_hw_intf_ops {
 	int (*check_and_reset_tearcheck)(struct sde_hw_intf *intf,
 			struct intf_tear_status *status);
 
+	/**
+	 * Reset the interface frame & line counter
+	 */
+	void (*reset_counter)(struct sde_hw_intf *intf);
+
 	/**
 	 * Enable processing of 2 pixels per clock
 	 */