Browse Source

Merge "disp: msm: sde: add support for TE level trigger"

qctecmdr 2 years ago
parent
commit
a0778dcd49

+ 1 - 1
msm/dsi/dsi_display.c

@@ -6779,6 +6779,7 @@ int dsi_display_get_info(struct drm_connector *connector,
 	info->has_qsync_min_fps_list = (display->panel->qsync_caps.qsync_min_fps_list_len > 0);
 	info->has_qsync_min_fps_list = (display->panel->qsync_caps.qsync_min_fps_list_len > 0);
 	info->avr_step_fps = display->panel->avr_caps.avr_step_fps;
 	info->avr_step_fps = display->panel->avr_caps.avr_step_fps;
 	info->poms_align_vsync = display->panel->poms_align_vsync;
 	info->poms_align_vsync = display->panel->poms_align_vsync;
+	info->is_te_using_watchdog_timer = is_sim_panel(display);
 
 
 	switch (display->panel->panel_mode) {
 	switch (display->panel->panel_mode) {
 	case DSI_OP_VIDEO_MODE:
 	case DSI_OP_VIDEO_MODE:
@@ -6792,7 +6793,6 @@ int dsi_display_get_info(struct drm_connector *connector,
 		info->capabilities |= MSM_DISPLAY_CAP_CMD_MODE;
 		info->capabilities |= MSM_DISPLAY_CAP_CMD_MODE;
 		if (display->panel->panel_mode_switch_enabled)
 		if (display->panel->panel_mode_switch_enabled)
 			info->capabilities |= MSM_DISPLAY_CAP_VID_MODE;
 			info->capabilities |= MSM_DISPLAY_CAP_VID_MODE;
-		info->is_te_using_watchdog_timer = is_sim_panel(display);
 		break;
 		break;
 	default:
 	default:
 		DSI_ERR("unknwown dsi panel mode %d\n",
 		DSI_ERR("unknwown dsi panel mode %d\n",

+ 23 - 3
msm/sde/sde_encoder_phys_cmd.c

@@ -1599,7 +1599,8 @@ static void sde_encoder_phys_cmd_enable_helper(
 	sde_enc = to_sde_encoder_virt(phys_enc->parent);
 	sde_enc = to_sde_encoder_virt(phys_enc->parent);
 	if (sde_enc->idle_pc_restore) {
 	if (sde_enc->idle_pc_restore) {
 		qsync_mode = sde_connector_get_qsync_mode(phys_enc->connector);
 		qsync_mode = sde_connector_get_qsync_mode(phys_enc->connector);
-		if (qsync_mode)
+		if (qsync_mode && !test_bit(SDE_INTF_TE_LEVEL_TRIGGER,
+				&phys_enc->hw_intf->cap->features))
 			sde_enc->restore_te_rd_ptr = true;
 			sde_enc->restore_te_rd_ptr = true;
 	}
 	}
 
 
@@ -1804,6 +1805,8 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff(
 	struct sde_encoder_virt *sde_enc;
 	struct sde_encoder_virt *sde_enc;
 	int ret = 0;
 	int ret = 0;
 	bool recovery_events;
 	bool recovery_events;
+	u32 qsync_mode = 0;
+	bool panel_dead = false;
 
 
 	if (!phys_enc || !phys_enc->hw_pp) {
 	if (!phys_enc || !phys_enc->hw_pp) {
 		SDE_ERROR("invalid encoder\n");
 		SDE_ERROR("invalid encoder\n");
@@ -1811,6 +1814,7 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff(
 	}
 	}
 	SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0);
 	SDE_DEBUG_CMDENC(cmd_enc, "pp %d\n", phys_enc->hw_pp->idx - PINGPONG_0);
 
 
+	sde_enc = to_sde_encoder_virt(phys_enc->parent);
 	phys_enc->frame_trigger_mode = params->frame_trigger_mode;
 	phys_enc->frame_trigger_mode = params->frame_trigger_mode;
 	SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0,
 	SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0,
 			atomic_read(&phys_enc->pending_kickoff_cnt),
 			atomic_read(&phys_enc->pending_kickoff_cnt),
@@ -1859,11 +1863,20 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff(
 		else if (phys_enc->hw_pp->ops.update_tearcheck)
 		else if (phys_enc->hw_pp->ops.update_tearcheck)
 			phys_enc->hw_pp->ops.update_tearcheck(
 			phys_enc->hw_pp->ops.update_tearcheck(
 					phys_enc->hw_pp, &tc_cfg);
 					phys_enc->hw_pp, &tc_cfg);
+
+		qsync_mode = sde_connector_get_qsync_mode(phys_enc->connector);
+		panel_dead = sde_connector_panel_dead(phys_enc->connector);
+
+		if (cmd_enc->base.hw_intf->ops.enable_te_level_trigger &&
+				!sde_enc->disp_info.is_te_using_watchdog_timer)
+			cmd_enc->base.hw_intf->ops.enable_te_level_trigger(cmd_enc->base.hw_intf,
+					qsync_mode && !panel_dead);
+
 		SDE_EVT32(DRMID(phys_enc->parent), tc_cfg.sync_threshold_start, tc_cfg.start_pos,
 		SDE_EVT32(DRMID(phys_enc->parent), tc_cfg.sync_threshold_start, tc_cfg.start_pos,
-				SDE_EVTLOG_FUNC_CASE3);
+				qsync_mode, sde_enc->disp_info.is_te_using_watchdog_timer,
+				panel_dead, SDE_EVTLOG_FUNC_CASE3);
 	}
 	}
 
 
-	sde_enc = to_sde_encoder_virt(phys_enc->parent);
 	if (sde_enc->restore_te_rd_ptr) {
 	if (sde_enc->restore_te_rd_ptr) {
 		sde_encoder_restore_tearcheck_rd_ptr(phys_enc);
 		sde_encoder_restore_tearcheck_rd_ptr(phys_enc);
 		sde_enc->restore_te_rd_ptr = false;
 		sde_enc->restore_te_rd_ptr = false;
@@ -2051,13 +2064,20 @@ static int _sde_encoder_phys_cmd_handle_wr_ptr_timeout(
 	bool switch_te;
 	bool switch_te;
 	int ret = -ETIMEDOUT;
 	int ret = -ETIMEDOUT;
 	unsigned long lock_flags;
 	unsigned long lock_flags;
+	struct sde_encoder_virt *sde_enc;
 
 
 	switch_te = _sde_encoder_phys_cmd_needs_vsync_change(
 	switch_te = _sde_encoder_phys_cmd_needs_vsync_change(
 				phys_enc, profile_timestamp);
 				phys_enc, profile_timestamp);
+	sde_enc = to_sde_encoder_virt(phys_enc->parent);
 
 
 	SDE_EVT32(DRMID(phys_enc->parent), switch_te, SDE_EVTLOG_FUNC_ENTRY);
 	SDE_EVT32(DRMID(phys_enc->parent), switch_te, SDE_EVTLOG_FUNC_ENTRY);
 
 
 	if (sde_connector_panel_dead(phys_enc->connector)) {
 	if (sde_connector_panel_dead(phys_enc->connector)) {
+		if (cmd_enc->base.hw_intf->ops.enable_te_level_trigger &&
+				!sde_enc->disp_info.is_te_using_watchdog_timer)
+			cmd_enc->base.hw_intf->ops.enable_te_level_trigger(cmd_enc->base.hw_intf,
+					false);
+
 		ret = _sde_encoder_phys_cmd_wait_for_wr_ptr(phys_enc);
 		ret = _sde_encoder_phys_cmd_wait_for_wr_ptr(phys_enc);
 	} else if (switch_te) {
 	} else if (switch_te) {
 		SDE_DEBUG_CMDENC(cmd_enc,
 		SDE_DEBUG_CMDENC(cmd_enc,

+ 7 - 1
msm/sde/sde_encoder_phys_vid.c

@@ -393,8 +393,14 @@ static void _sde_encoder_phys_vid_avr_ctrl(struct sde_encoder_phys *phys_enc)
 	if (vid_enc->base.hw_intf->ops.avr_ctrl)
 	if (vid_enc->base.hw_intf->ops.avr_ctrl)
 		vid_enc->base.hw_intf->ops.avr_ctrl(vid_enc->base.hw_intf, &avr_params);
 		vid_enc->base.hw_intf->ops.avr_ctrl(vid_enc->base.hw_intf, &avr_params);
 
 
+	if (vid_enc->base.hw_intf->ops.enable_te_level_trigger &&
+			!sde_enc->disp_info.is_te_using_watchdog_timer)
+		vid_enc->base.hw_intf->ops.enable_te_level_trigger(vid_enc->base.hw_intf,
+				(avr_step_state == AVR_STEP_ENABLE));
+
 	SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0, avr_params.avr_mode,
 	SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0, avr_params.avr_mode,
-			avr_params.avr_step_lines, info->avr_step_fps, avr_step_state);
+			avr_params.avr_step_lines, info->avr_step_fps, avr_step_state,
+			sde_enc->disp_info.is_te_using_watchdog_timer);
 }
 }
 
 
 static void sde_encoder_phys_vid_setup_timing_engine(
 static void sde_encoder_phys_vid_setup_timing_engine(

+ 1 - 0
msm/sde/sde_hw_catalog.c

@@ -2508,6 +2508,7 @@ static int sde_intf_parse_dt(struct device_node *np,
 			set_bit(SDE_INTF_WD_LTJ_CTL, &intf->features);
 			set_bit(SDE_INTF_WD_LTJ_CTL, &intf->features);
 			set_bit(SDE_INTF_TE_DEASSERT_DETECT, &intf->features);
 			set_bit(SDE_INTF_TE_DEASSERT_DETECT, &intf->features);
 			set_bit(SDE_INTF_VSYNC_TS_SRC_EN, &intf->features);
 			set_bit(SDE_INTF_VSYNC_TS_SRC_EN, &intf->features);
+			set_bit(SDE_INTF_TE_LEVEL_TRIGGER, &intf->features);
 		}
 		}
 	}
 	}
 
 

+ 2 - 0
msm/sde/sde_hw_catalog.h

@@ -636,6 +636,7 @@ enum {
  * @SDE_INTF_WD_LTJ_CTL         INTF block has WD long term jitter control support
  * @SDE_INTF_WD_LTJ_CTL         INTF block has WD long term jitter control support
  * @SDE_INTF_TE_DEASSERT_DETECT INTF block has TE Deassert detect support
  * @SDE_INTF_TE_DEASSERT_DETECT INTF block has TE Deassert detect support
  * @SDE_INTF_VSYNC_TS_SRC_EN    INTF block has VSYNC timestamp source selection support
  * @SDE_INTF_VSYNC_TS_SRC_EN    INTF block has VSYNC timestamp source selection support
+ * @SDE_INTF_TE_LEVEL_TRIGGER   INTF block has TE Level trigger gating support
  * @SDE_INTF_MAX
  * @SDE_INTF_MAX
  */
  */
 enum {
 enum {
@@ -655,6 +656,7 @@ enum {
 	SDE_INTF_WD_LTJ_CTL,
 	SDE_INTF_WD_LTJ_CTL,
 	SDE_INTF_TE_DEASSERT_DETECT,
 	SDE_INTF_TE_DEASSERT_DETECT,
 	SDE_INTF_VSYNC_TS_SRC_EN,
 	SDE_INTF_VSYNC_TS_SRC_EN,
+	SDE_INTF_TE_LEVEL_TRIGGER,
 	SDE_INTF_MAX
 	SDE_INTF_MAX
 };
 };
 
 

+ 20 - 4
msm/sde/sde_hw_intf.c

@@ -451,6 +451,21 @@ static void sde_hw_intf_enable_timing_engine(struct sde_hw_intf *intf, u8 enable
 	}
 	}
 }
 }
 
 
+static void sde_hw_intf_enable_te_level_trigger(struct sde_hw_intf *intf, bool enable)
+{
+	struct sde_hw_blk_reg_map *c = &intf->hw;
+	u32 intf_cfg = 0;
+
+	intf_cfg = SDE_REG_READ(c, INTF_CONFIG);
+
+	if (enable)
+		intf_cfg |= BIT(22);
+	else
+		intf_cfg &= ~BIT(22);
+
+	SDE_REG_WRITE(c, INTF_CONFIG, intf_cfg);
+}
+
 static void sde_hw_intf_setup_prg_fetch(
 static void sde_hw_intf_setup_prg_fetch(
 		struct sde_hw_intf *intf,
 		struct sde_hw_intf *intf,
 		const struct intf_prog_fetch *fetch)
 		const struct intf_prog_fetch *fetch)
@@ -1081,10 +1096,11 @@ static void _setup_intf_ops(struct sde_hw_intf_ops *ops,
 		ops->get_autorefresh = sde_hw_intf_get_autorefresh_config;
 		ops->get_autorefresh = sde_hw_intf_get_autorefresh_config;
 		ops->poll_timeout_wr_ptr = sde_hw_intf_poll_timeout_wr_ptr;
 		ops->poll_timeout_wr_ptr = sde_hw_intf_poll_timeout_wr_ptr;
 		ops->vsync_sel = sde_hw_intf_vsync_sel;
 		ops->vsync_sel = sde_hw_intf_vsync_sel;
-		ops->check_and_reset_tearcheck =
-			sde_hw_intf_v1_check_and_reset_tearcheck;
-		ops->override_tear_rd_ptr_val =
-			sde_hw_intf_override_tear_rd_ptr_val;
+		ops->check_and_reset_tearcheck = sde_hw_intf_v1_check_and_reset_tearcheck;
+		ops->override_tear_rd_ptr_val = sde_hw_intf_override_tear_rd_ptr_val;
+
+		if (cap & BIT(SDE_INTF_TE_LEVEL_TRIGGER))
+			ops->enable_te_level_trigger = sde_hw_intf_enable_te_level_trigger;
 	}
 	}
 
 
 	if (cap & BIT(SDE_INTF_RESET_COUNTER))
 	if (cap & BIT(SDE_INTF_RESET_COUNTER))

+ 5 - 0
msm/sde/sde_hw_intf.h

@@ -222,6 +222,11 @@ struct sde_hw_intf_ops {
 	void (*avr_ctrl)(struct sde_hw_intf *intf,
 	void (*avr_ctrl)(struct sde_hw_intf *intf,
 			const struct intf_avr_params *avr_params);
 			const struct intf_avr_params *avr_params);
 
 
+	/**
+	 * Enable trigger based on TE level
+	 */
+	void (*enable_te_level_trigger)(struct sde_hw_intf *intf, bool enable);
+
 	/**
 	/**
 	 * Indicates the AVR armed status
 	 * Indicates the AVR armed status
 	 *
 	 *