Forráskód Böngészése

disp: msm: sde: enable 32bit intf te registers

This change adds support for INTF TE using 32 bit values and
single update per TE. These features help ensure that during
QSync mode the TE does not overrun in certain late trigger uses.

Change-Id: I893d0cde81320c3f17604694a4d8ee52b29a9425
Signed-off-by: Nilaan Gunabalachandran <[email protected]>
Nilaan Gunabalachandran 3 éve
szülő
commit
f73f15ae39

+ 12 - 7
msm/sde/sde_encoder_phys_cmd.c

@@ -384,7 +384,8 @@ static void sde_encoder_phys_cmd_wr_ptr_irq(void *arg, int irq_idx)
 		info[0].pp_idx, info[0].intf_idx, info[0].wr_ptr_line_count,
 		info[1].pp_idx, info[1].intf_idx, info[1].wr_ptr_line_count, qsync_mode);
 
-	if (qsync_mode)
+	if (qsync_mode &&
+			!test_bit(SDE_INTF_TE_SINGLE_UPDATE, &phys_enc->hw_intf->cap->features))
 		sde_encoder_override_tearcheck_rd_ptr(phys_enc);
 
 	/* Signal any waiting wr_ptr start interrupt */
@@ -1904,12 +1905,16 @@ static void _sde_encoder_autorefresh_disable_seq2(
 		autorefresh_status = hw_mdp->ops.get_autorefresh_status(hw_mdp,
 					phys_enc->intf_idx);
 		hw_intf->ops.check_and_reset_tearcheck(hw_intf, &tear_status);
-		pr_err("enc:%d autofresh status:0x%x intf:%d tear_read:0x%x tear_write:0x%x\n",
-			DRMID(phys_enc->parent), autorefresh_status, phys_enc->intf_idx - INTF_0,
-			tear_status.read_count, tear_status.write_count);
-		SDE_EVT32(DRMID(phys_enc->parent), phys_enc->intf_idx - INTF_0,
-			autorefresh_status, tear_status.read_count,
-			tear_status.write_count);
+		pr_err("enc:%d autofresh status:0x%x intf:%d\n",
+				DRMID(phys_enc->parent), autorefresh_status,
+				phys_enc->intf_idx - INTF_0);
+		pr_err("tear_read_frame_count:%d tear_read_line_count:%d\n",
+				tear_status.read_frame_count, tear_status.read_line_count);
+		pr_err("tear_write_frame_count:%d tear_write_line_count:%d\n",
+				tear_status.write_frame_count, tear_status.write_line_count);
+		SDE_EVT32(DRMID(phys_enc->parent), phys_enc->intf_idx - INTF_0, autorefresh_status,
+			tear_status.read_frame_count, tear_status.read_line_count,
+			tear_status.write_frame_count, tear_status.write_line_count);
 	}
 }
 static void _sde_encoder_phys_disable_autorefresh(struct sde_encoder_phys *phys_enc)

+ 4 - 1
msm/sde/sde_hw_catalog.c

@@ -2381,8 +2381,11 @@ static int sde_intf_parse_dt(struct device_node *np,
 			set_bit(SDE_INTF_WD_JITTER, &intf->features);
 		}
 
-		if (SDE_HW_MAJOR(sde_cfg->hw_rev) >= SDE_HW_MAJOR(SDE_HW_VER_A00))
+		if (SDE_HW_MAJOR(sde_cfg->hw_rev) >= SDE_HW_MAJOR(SDE_HW_VER_A00)) {
 			set_bit(SDE_INTF_MDP_VSYNC_FC, &intf->features);
+			set_bit(SDE_INTF_TE_32BIT, &intf->features);
+			set_bit(SDE_INTF_TE_SINGLE_UPDATE, &intf->features);
+		}
 	}
 
 end:

+ 4 - 0
msm/sde/sde_hw_catalog.h

@@ -579,6 +579,8 @@ enum {
  *                              pixel data arrives to this INTF
  * @SDE_INTF_TE                 INTF block has TE configuration support
  * @SDE_INTF_TE_ALIGN_VSYNC     INTF block has POMS Align vsync support
+ * @SDE_INTF_TE_32BIT           INTF block has 32bit TE configuration support
+ * @SDE_INTF_TE_SINGLE_UPDATE   INTF block has single frame per TE 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
@@ -593,6 +595,8 @@ enum {
 	SDE_INTF_INPUT_CTRL = 0x1,
 	SDE_INTF_TE,
 	SDE_INTF_TE_ALIGN_VSYNC,
+	SDE_INTF_TE_32BIT,
+	SDE_INTF_TE_SINGLE_UPDATE,
 	SDE_INTF_WD_TIMER,
 	SDE_INTF_STATUS,
 	SDE_INTF_RESET_COUNTER,

+ 57 - 15
msm/sde/sde_hw_intf.c

@@ -98,6 +98,12 @@
 #define INTF_TEAR_LINE_COUNT            0x2B0
 #define INTF_TEAR_AUTOREFRESH_CONFIG    0x2B4
 #define INTF_TEAR_TEAR_DETECT_CTRL      0x2B8
+#define INTF_TEAR_PROG_FETCH_START      0x2C4
+#define INTF_TEAR_DSI_DMA_SCHD_CTRL0    0x2C8
+#define INTF_TEAR_DSI_DMA_SCHD_CTRL1    0x2CC
+#define INTF_TEAR_INT_COUNT_VAL_EXT     0x2DC
+#define INTF_TEAR_SYNC_THRESH_EXT       0x2E0
+#define INTF_TEAR_SYNC_WRCOUNT_EXT      0x2E4
 
 static struct sde_intf_cfg *_intf_offset(enum sde_intf intf,
 		struct sde_mdss_cfg *m,
@@ -678,7 +684,7 @@ static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf,
 		struct sde_hw_tear_check *te)
 {
 	struct sde_hw_blk_reg_map *c;
-	u32 cfg = 0;
+	u32 cfg = 0, val;
 	spinlock_t tearcheck_spinlock;
 
 	if (!intf)
@@ -698,8 +704,10 @@ static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf,
 	 * less than 2^16 vsync clk cycles.
 	 */
 	spin_lock(&tearcheck_spinlock);
-	SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT,
-			(te->start_pos + te->sync_threshold_start + 1));
+	val = te->start_pos + te->sync_threshold_start + 1;
+	if (intf->cap->features & BIT(SDE_INTF_TE_32BIT))
+		SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT_EXT, (val >> 16));
+	SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT, (val & 0xffff));
 	SDE_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg);
 	wmb(); /* disable vsync counter before updating single buffer registers */
 	SDE_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_HEIGHT, te->sync_cfg_height);
@@ -707,9 +715,13 @@ static int sde_hw_intf_setup_te_config(struct sde_hw_intf *intf,
 	SDE_REG_WRITE(c, INTF_TEAR_RD_PTR_IRQ, te->rd_ptr_irq);
 	SDE_REG_WRITE(c, INTF_TEAR_WR_PTR_IRQ, te->wr_ptr_irq);
 	SDE_REG_WRITE(c, INTF_TEAR_START_POS, te->start_pos);
+	if (intf->cap->features & BIT(SDE_INTF_TE_32BIT))
+		SDE_REG_WRITE(c,  INTF_TEAR_SYNC_THRESH_EXT,
+				((te->sync_threshold_continue & 0xffff0000) |
+				(te->sync_threshold_start >> 16)));
 	SDE_REG_WRITE(c, INTF_TEAR_SYNC_THRESH,
 			((te->sync_threshold_continue << 16) |
-			 te->sync_threshold_start));
+			(te->sync_threshold_start & 0xffff)));
 	cfg |= BIT(19); /* VSYNC_COUNTER_EN */
 	SDE_REG_WRITE(c, INTF_TEAR_SYNC_CONFIG_VSYNC, cfg);
 	spin_unlock(&tearcheck_spinlock);
@@ -760,25 +772,38 @@ static int sde_hw_intf_poll_timeout_wr_ptr(struct sde_hw_intf *intf,
 		u32 timeout_us)
 {
 	struct sde_hw_blk_reg_map *c;
-	u32 val;
+	u32 val, mask = 0;
 
 	if (!intf)
 		return -EINVAL;
 
+	if (intf->cap->features & BIT(SDE_INTF_TE_32BIT))
+		mask = 0xffffffff;
+	else
+		mask = 0xffff;
+
 	c = &intf->hw;
-	return read_poll_timeout(sde_reg_read, val, (val & 0xffff) >= 1, 10, false, timeout_us,
+	return read_poll_timeout(sde_reg_read, val, (val & mask) >= 1, 10, false, timeout_us,
 			c, INTF_TEAR_LINE_COUNT);
 }
 
 static int sde_hw_intf_enable_te(struct sde_hw_intf *intf, bool enable)
 {
 	struct sde_hw_blk_reg_map *c;
+	uint32_t val = 0;
 
 	if (!intf)
 		return -EINVAL;
 
 	c = &intf->hw;
-	SDE_REG_WRITE(c, INTF_TEAR_TEAR_CHECK_EN, enable);
+
+	if (enable)
+		val |= BIT(0);
+
+	if (intf->cap->features & BIT(SDE_INTF_TE_SINGLE_UPDATE))
+		val |= BIT(3);
+
+	SDE_REG_WRITE(c, INTF_TEAR_TEAR_CHECK_EN, val);
 
 	if (enable && (intf->cap->features & (BIT(SDE_INTF_PANEL_VSYNC_TS) | BIT(SDE_INTF_MDP_VSYNC_TS))))
 		SDE_REG_WRITE(c, INTF_VSYNC_TIMESTAMP_CTRL, BIT(0));
@@ -836,14 +861,22 @@ static int sde_hw_intf_get_vsync_info(struct sde_hw_intf *intf,
 	c = &intf->hw;
 
 	val = SDE_REG_READ(c, INTF_TEAR_VSYNC_INIT_VAL);
-	info->rd_ptr_init_val = val & 0xffff;
+	if (intf->cap->features & BIT(SDE_INTF_TE_32BIT))
+		info->rd_ptr_init_val = val;
+	else
+		info->rd_ptr_init_val = val & 0xffff;
 
 	val = SDE_REG_READ(c, INTF_TEAR_INT_COUNT_VAL);
 	info->rd_ptr_frame_count = (val & 0xffff0000) >> 16;
 	info->rd_ptr_line_count = val & 0xffff;
 
+	if (intf->cap->features & BIT(SDE_INTF_TE_32BIT)) {
+		val = SDE_REG_READ(c, INTF_TEAR_INT_COUNT_VAL_EXT);
+		info->rd_ptr_line_count |= (val << 16);
+	}
+
 	val = SDE_REG_READ(c, INTF_TEAR_LINE_COUNT);
-	info->wr_ptr_line_count = val & 0xffff;
+	info->wr_ptr_line_count = val;
 
 	val = sde_hw_intf_get_frame_count(intf);
 	info->intf_frame_count = val;
@@ -855,19 +888,28 @@ static int sde_hw_intf_v1_check_and_reset_tearcheck(struct sde_hw_intf *intf,
 		struct intf_tear_status *status)
 {
 	struct sde_hw_blk_reg_map *c = &intf->hw;
-	u32 start_pos;
+	u32 start_pos, val;
 
 	if (!intf || !status)
 		return -EINVAL;
 
 	c = &intf->hw;
 
-	status->read_count = SDE_REG_READ(c, INTF_TEAR_INT_COUNT_VAL);
+	status->read_line_count = SDE_REG_READ(c, INTF_TEAR_INT_COUNT_VAL);
+	if (intf->cap->features & BIT(SDE_INTF_TE_32BIT))
+		status->read_line_count |= (SDE_REG_READ(c, INTF_TEAR_INT_COUNT_VAL_EXT) << 16);
 	start_pos = SDE_REG_READ(c, INTF_TEAR_START_POS);
-	status->write_count = SDE_REG_READ(c, INTF_TEAR_SYNC_WRCOUNT);
-	status->write_count &= 0xffff0000;
-	status->write_count |= start_pos;
-	SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT, status->write_count);
+	val = SDE_REG_READ(c, INTF_TEAR_SYNC_WRCOUNT);
+	status->write_frame_count = val >> 16;
+	status->write_line_count = start_pos;
+
+	if (intf->cap->features & BIT(SDE_INTF_TE_32BIT)) {
+		val = (status->write_line_count & 0xffff0000) >> 16;
+		SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT_EXT, val);
+	}
+
+	val = (status->write_frame_count << 16) | (status->write_line_count & 0xffff);
+	SDE_REG_WRITE(c, INTF_TEAR_SYNC_WRCOUNT, val);
 
 	return 0;
 }

+ 4 - 2
msm/sde/sde_hw_intf.h

@@ -56,8 +56,10 @@ struct intf_status {
 };
 
 struct intf_tear_status {
-	u32 read_count;		/* frame & line count for tear init value */
-	u32 write_count;	/* frame & line count for tear write */
+	u32 read_frame_count;	/* frame count for tear init value */
+	u32 read_line_count;	/* line count for tear init value */
+	u32 write_frame_count;	/* frame count for tear write */
+	u32 write_line_count;	/* line count for tear write */
 };
 
 struct intf_avr_params {