浏览代码

disp: msm: sde: enable mdp vsync frame count

Currently, the driver uses the panel frame count along with
mdp vsync timestamp which can be unreliable if there are any
latencies. This change adds support to use mdp vsync frame
count, if the hardware supports it.

Change-Id: I784d4f4e525212269371a40071bcb912181cba9f
Signed-off-by: Nilaan Gunabalachandran <[email protected]>
Nilaan Gunabalachandran 3 年之前
父节点
当前提交
00369e3266
共有 3 个文件被更改,包括 26 次插入2 次删除
  1. 3 0
      msm/sde/sde_hw_catalog.c
  2. 2 0
      msm/sde/sde_hw_catalog.h
  3. 21 2
      msm/sde/sde_hw_intf.c

+ 3 - 0
msm/sde/sde_hw_catalog.c

@@ -2380,6 +2380,9 @@ static int sde_intf_parse_dt(struct device_node *np,
 			set_bit(SDE_INTF_MDP_VSYNC_TS, &intf->features);
 			set_bit(SDE_INTF_WD_JITTER, &intf->features);
 		}
+
+		if (SDE_HW_MAJOR(sde_cfg->hw_rev) >= SDE_HW_MAJOR(SDE_HW_VER_A00))
+			set_bit(SDE_INTF_MDP_VSYNC_FC, &intf->features);
 	}
 
 end:

+ 2 - 0
msm/sde/sde_hw_catalog.h

@@ -584,6 +584,7 @@ enum {
  * @SDE_INTF_RESET_COUNTER      INTF block has frame/line counter reset support
  * @SDE_INTF_PANEL_VSYNC_TS     INTF block has panel vsync timestamp logged
  * @SDE_INTF_MDP_VSYNC_TS       INTF block has mdp vsync timestamp logged
+ * @SDE_INTF_MDP_VSYNC_FC       INTF block has mdp vsync frame counter
  * @SDE_INTF_AVR_STATUS         INTF block has AVR_STATUS field in AVR_CONTROL register
  * @SDE_INTF_WD_JITTER          INTF block has WD timer jitter support
  * @SDE_INTF_MAX
@@ -597,6 +598,7 @@ enum {
 	SDE_INTF_RESET_COUNTER,
 	SDE_INTF_PANEL_VSYNC_TS,
 	SDE_INTF_MDP_VSYNC_TS,
+	SDE_INTF_MDP_VSYNC_FC,
 	SDE_INTF_AVR_STATUS,
 	SDE_INTF_WD_JITTER,
 	SDE_INTF_MAX

+ 21 - 2
msm/sde/sde_hw_intf.c

@@ -40,6 +40,7 @@
 #define INTF_DISPLAY_DATA_HCTL          0x064
 #define INTF_ACTIVE_DATA_HCTL           0x068
 #define INTF_FRAME_LINE_COUNT_EN        0x0A8
+#define INTF_MDP_FRAME_COUNT            0x0A4
 #define INTF_FRAME_COUNT                0x0AC
 #define INTF_LINE_COUNT                 0x0B0
 
@@ -541,6 +542,24 @@ static void sde_hw_intf_bind_pingpong_blk(
 	SDE_REG_WRITE(c, INTF_MUX, mux_cfg);
 }
 
+static u32 sde_hw_intf_get_frame_count(struct sde_hw_intf *intf)
+{
+	struct sde_hw_blk_reg_map *c = &intf->hw;
+	bool en;
+
+	/*
+	 * MDP VSync Frame Count is enabled with programmable fetch
+	 * or with auto-refresh enabled.
+	 */
+	en  = (SDE_REG_READ(c, INTF_TEAR_AUTOREFRESH_CONFIG) & BIT(31)) |
+			(SDE_REG_READ(c, INTF_CONFIG) & BIT(31));
+
+	if (en && (intf->cap->features & BIT(SDE_INTF_MDP_VSYNC_FC)))
+		return SDE_REG_READ(c, INTF_MDP_FRAME_COUNT);
+	else
+		return SDE_REG_READ(c, INTF_FRAME_COUNT);
+}
+
 static void sde_hw_intf_get_status(
 		struct sde_hw_intf *intf,
 		struct intf_status *s)
@@ -566,7 +585,7 @@ static void sde_hw_intf_v1_get_status(
 	s->is_en = SDE_REG_READ(c, INTF_STATUS) & BIT(0);
 	s->is_prog_fetch_en = (SDE_REG_READ(c, INTF_CONFIG) & BIT(31));
 	if (s->is_en) {
-		s->frame_count = SDE_REG_READ(c, INTF_FRAME_COUNT);
+		s->frame_count = sde_hw_intf_get_frame_count(intf);
 		s->line_count = SDE_REG_READ(c, INTF_LINE_COUNT) & 0xffff;
 	} else {
 		s->line_count = 0;
@@ -826,7 +845,7 @@ static int sde_hw_intf_get_vsync_info(struct sde_hw_intf *intf,
 	val = SDE_REG_READ(c, INTF_TEAR_LINE_COUNT);
 	info->wr_ptr_line_count = val & 0xffff;
 
-	val = SDE_REG_READ(c, INTF_FRAME_COUNT);
+	val = sde_hw_intf_get_frame_count(intf);
 	info->intf_frame_count = val;
 
 	return 0;