Просмотр исходного кода

disp: msm: sde: wait for autorefresh_status to be idle in prepare kickoff

If cont splash is enabled, wait for autorefresh_status to be idle for
1 vsync in prepare kickoff. This patch also prevents entering to
rsc_solver_mode if autorefresh_status is busy.

Change-Id: Id7491361dae2482905e10a5a10e590d5f5b49e6f
Signed-off-by: Yojana Juadi <[email protected]>
Signed-off-by: Akash Gajjar <[email protected]>
Yojana Juadi 1 год назад
Родитель
Сommit
75dece4b72
3 измененных файлов с 68 добавлено и 38 удалено
  1. 35 37
      msm/sde/sde_encoder.c
  2. 2 0
      msm/sde/sde_encoder_phys.h
  3. 31 1
      msm/sde/sde_encoder_phys_cmd.c

+ 35 - 37
msm/sde/sde_encoder.c

@@ -358,6 +358,16 @@ static bool _sde_encoder_is_autorefresh_enabled(
 			CONNECTOR_PROP_AUTOREFRESH) ? true : false;
 }
 
+static bool _sde_encoder_is_autorefresh_status_busy(struct sde_encoder_virt *sde_enc)
+{
+	if (!sde_enc->cur_master || !sde_enc->cur_master->hw_intf ||
+			!sde_enc->cur_master->hw_intf->ops.get_autorefresh_status)
+		return false;
+
+	return sde_enc->cur_master->hw_intf->ops.get_autorefresh_status(
+			sde_enc->cur_master->hw_intf);
+}
+
 static void sde_configure_qdss(struct sde_encoder_virt *sde_enc,
 				struct sde_hw_qdss *hw_qdss,
 				struct sde_encoder_phys *phys, bool enable)
@@ -1619,28 +1629,6 @@ static void sde_encoder_control_te(struct sde_encoder_virt *sde_enc, bool enable
 	}
 }
 
-static void _sde_encoder_wait_for_vsync_on_autorefresh_busy(struct sde_encoder_phys *phys_enc)
-{
-	u32 autorefresh_status;
-	int ret = 0;
-
-	if (!phys_enc || !phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_autorefresh_status) {
-		SDE_ERROR("invalid params\n");
-		return;
-	}
-
-	autorefresh_status = phys_enc->hw_intf->ops.get_autorefresh_status(phys_enc->hw_intf);
-	if (autorefresh_status) {
-		ret = sde_encoder_wait_for_event(phys_enc->parent, MSM_ENC_VBLANK);
-		if (ret) {
-			autorefresh_status = phys_enc->hw_intf->ops.get_autorefresh_status(
-					phys_enc->hw_intf);
-			SDE_ERROR("wait for vblank timed out, autorefresh_status:%d\n",
-					autorefresh_status);
-		}
-	}
-}
-
 int sde_encoder_helper_switch_vsync(struct drm_encoder *drm_enc,
 	 bool watchdog_te)
 {
@@ -1836,7 +1824,8 @@ static int _sde_encoder_update_rsc_client(
 		qsync_mode = sde_connector_get_qsync_mode(
 				sde_enc->cur_master->connector);
 		sde_enc->autorefresh_solver_disable =
-			 _sde_encoder_is_autorefresh_enabled(sde_enc) ? true : false;
+			_sde_encoder_is_autorefresh_status_busy(sde_enc) ||
+			_sde_encoder_is_autorefresh_enabled(sde_enc);
 
 		if (sde_enc->cur_master->ops.is_autoref_disable_pending)
 			sde_enc->autorefresh_solver_disable =
@@ -3670,6 +3659,28 @@ static void sde_encoder_wait_for_vsync_event_complete(struct sde_encoder_virt *s
 	}
 }
 
+static void _sde_encoder_helper_virt_disable(struct drm_encoder *drm_enc)
+{
+	int i;
+	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
+
+	if (!sde_encoder_in_clone_mode(drm_enc)) {
+		/* disable autorefresh */
+		for (i = 0; i < sde_enc->num_phys_encs; i++) {
+			struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
+
+			if (phys && phys->ops.disable_autorefresh &&
+					phys->ops.wait_for_vsync_on_autorefresh_busy) {
+				phys->ops.disable_autorefresh(phys);
+				phys->ops.wait_for_vsync_on_autorefresh_busy(phys);
+			}
+		}
+
+		/* wait for idle */
+		sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
+	}
+}
+
 static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
 {
 	struct sde_encoder_virt *sde_enc = NULL;
@@ -3710,20 +3721,7 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc)
 
 	SDE_EVT32(DRMID(drm_enc));
 
-	if (!sde_encoder_in_clone_mode(drm_enc)) {
-		/* disable autorefresh */
-		for (i = 0; i < sde_enc->num_phys_encs; i++) {
-			struct sde_encoder_phys *phys = sde_enc->phys_encs[i];
-
-			if (phys && phys->ops.disable_autorefresh) {
-				phys->ops.disable_autorefresh(phys);
-				_sde_encoder_wait_for_vsync_on_autorefresh_busy(phys);
-			}
-		}
-
-		/* wait for idle */
-		sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
-	}
+	_sde_encoder_helper_virt_disable(drm_enc);
 
 	_sde_encoder_input_handler_unregister(drm_enc);
 

+ 2 - 0
msm/sde/sde_encoder_phys.h

@@ -155,6 +155,7 @@ struct sde_encoder_virt_ops {
  * @add_to_minidump:		Add this phys_enc data to minidumps
  * @disable_autorefresh:	Disable autorefresh
  * @idle_pc_cache_display_status:	caches display status at idle power collapse
+ * @wait_for_vsync_on_autorefresh_busy:	Wait for vsync if autorefresh status busy
  */
 
 struct sde_encoder_phys_ops {
@@ -213,6 +214,7 @@ struct sde_encoder_phys_ops {
 	void (*add_to_minidump)(struct sde_encoder_phys *phys);
 	void (*disable_autorefresh)(struct sde_encoder_phys *phys);
 	void (*idle_pc_cache_display_status)(struct sde_encoder_phys *phys);
+	void (*wait_for_vsync_on_autorefresh_busy)(struct sde_encoder_phys *phys_enc);
 };
 
 /**

+ 31 - 1
msm/sde/sde_encoder_phys_cmd.c

@@ -1805,6 +1805,28 @@ static void sde_encoder_phys_cmd_get_hw_resources(
 	hw_res->intfs[phys_enc->intf_idx - INTF_0] = INTF_MODE_CMD;
 }
 
+static void _sde_encoder_phys_wait_for_vsync_on_autorefresh_busy(struct sde_encoder_phys *phys_enc)
+{
+	u32 autorefresh_status;
+	int ret = 0;
+
+	if (!phys_enc || !phys_enc->hw_intf || !phys_enc->hw_intf->ops.get_autorefresh_status) {
+		SDE_ERROR("invalid params\n");
+		return;
+	}
+
+	autorefresh_status = phys_enc->hw_intf->ops.get_autorefresh_status(phys_enc->hw_intf);
+	if (autorefresh_status) {
+		ret = sde_encoder_wait_for_event(phys_enc->parent, MSM_ENC_VBLANK);
+		if (ret) {
+			autorefresh_status = phys_enc->hw_intf->ops.get_autorefresh_status(
+					phys_enc->hw_intf);
+			SDE_ERROR("wait for vblank timed out, autorefresh_status:%d\n",
+					autorefresh_status);
+		}
+	}
+}
+
 static int sde_encoder_phys_cmd_prepare_for_kickoff(
 		struct sde_encoder_phys *phys_enc,
 		struct sde_encoder_kickoff_params *params)
@@ -1829,7 +1851,9 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff(
 	SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_pp->idx - PINGPONG_0,
 			atomic_read(&phys_enc->pending_kickoff_cnt),
 			atomic_read(&cmd_enc->autorefresh.kickoff_cnt),
-			phys_enc->frame_trigger_mode, SDE_EVTLOG_FUNC_CASE1);
+			phys_enc->frame_trigger_mode,
+			phys_enc->cont_splash_enabled,
+			SDE_EVTLOG_FUNC_CASE1);
 
 	if (phys_enc->frame_trigger_mode == FRAME_DONE_WAIT_DEFAULT) {
 		/*
@@ -1846,6 +1870,9 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff(
 		}
 	}
 
+	if (phys_enc->cont_splash_enabled)
+		_sde_encoder_phys_wait_for_vsync_on_autorefresh_busy(phys_enc);
+
 	if (phys_enc->recovered) {
 		recovery_events = sde_encoder_recovery_events_enabled(
 				phys_enc->parent);
@@ -2368,6 +2395,7 @@ static void _sde_encoder_autorefresh_disable_seq2(
 			tear_status.write_frame_count, tear_status.write_line_count);
 	}
 }
+
 static void _sde_encoder_phys_disable_autorefresh(struct sde_encoder_phys *phys_enc)
 {
 	struct sde_encoder_phys_cmd *cmd_enc = to_sde_encoder_phys_cmd(phys_enc);
@@ -2559,6 +2587,8 @@ static void sde_encoder_phys_cmd_init_ops(struct sde_encoder_phys_ops *ops)
 	ops->disable_autorefresh = _sde_encoder_phys_disable_autorefresh;
 	ops->idle_pc_cache_display_status = sde_encoder_phys_cmd_store_ltj_values;
 	ops->handle_post_kickoff = sde_encoder_phys_cmd_handle_post_kickoff;
+	ops->wait_for_vsync_on_autorefresh_busy =
+			_sde_encoder_phys_wait_for_vsync_on_autorefresh_busy;
 }
 
 static inline bool sde_encoder_phys_cmd_intf_te_supported(