소스 검색

Merge "disp: msm: sde: move HW recovery outside ppdone wait"

qctecmdr 5 년 전
부모
커밋
e9b326e3f2
2개의 변경된 파일25개의 추가작업 그리고 19개의 파일을 삭제
  1. 2 0
      msm/sde/sde_encoder_phys.h
  2. 23 19
      msm/sde/sde_encoder_phys_cmd.c

+ 2 - 0
msm/sde/sde_encoder_phys.h

@@ -293,6 +293,7 @@ struct sde_encoder_irq {
  *				programming ROT and MDP fetch start
  * @frame_trigger_mode:		frame trigger mode indication for command
  *				mode display
+ * @recovered:			flag set to true when recovered from pp timeout
  */
 struct sde_encoder_phys {
 	struct drm_encoder *parent;
@@ -335,6 +336,7 @@ struct sde_encoder_phys {
 	bool in_clone_mode;
 	int vfp_cached;
 	enum frame_trigger_mode_type frame_trigger_mode;
+	bool recovered;
 };
 
 static inline int sde_encoder_phys_inc_pending(struct sde_encoder_phys *phys)

+ 23 - 19
msm/sde/sde_encoder_phys_cmd.c

@@ -173,11 +173,14 @@ static void _sde_encoder_phys_cmd_update_intf_cfg(
 static void sde_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
 {
 	struct sde_encoder_phys *phys_enc = arg;
+	struct sde_encoder_phys_cmd *cmd_enc;
 	u32 event = 0;
 
 	if (!phys_enc || !phys_enc->hw_pp)
 		return;
 
+	cmd_enc = to_sde_encoder_phys_cmd(phys_enc);
+
 	SDE_ATRACE_BEGIN("pp_done_irq");
 
 	/* notify all synchronous clients first, then asynchronous clients */
@@ -188,6 +191,8 @@ static void sde_encoder_phys_cmd_pp_tx_done_irq(void *arg, int irq_idx)
 		spin_lock(phys_enc->enc_spinlock);
 		phys_enc->parent_ops.handle_frame_done(phys_enc->parent,
 				phys_enc, event);
+		if (cmd_enc->pp_timeout_report_cnt)
+			phys_enc->recovered = true;
 		spin_unlock(phys_enc->enc_spinlock);
 	}
 
@@ -482,11 +487,12 @@ static void sde_encoder_phys_cmd_mode_set(
 }
 
 static int _sde_encoder_phys_cmd_handle_ppdone_timeout(
-		struct sde_encoder_phys *phys_enc,
-		bool recovery_events)
+		struct sde_encoder_phys *phys_enc)
 {
 	struct sde_encoder_phys_cmd *cmd_enc =
 			to_sde_encoder_phys_cmd(phys_enc);
+	bool recovery_events = sde_encoder_recovery_events_enabled(
+			phys_enc->parent);
 	u32 frame_event = SDE_ENCODER_FRAME_EVENT_ERROR
 				| SDE_ENCODER_FRAME_EVENT_SIGNAL_RELEASE_FENCE;
 	struct drm_connector *conn;
@@ -728,10 +734,7 @@ static bool _sde_encoder_phys_cmd_is_scheduler_idle(
 static int _sde_encoder_phys_cmd_wait_for_idle(
 		struct sde_encoder_phys *phys_enc)
 {
-	struct sde_encoder_phys_cmd *cmd_enc =
-			to_sde_encoder_phys_cmd(phys_enc);
 	struct sde_encoder_wait_info wait_info = {0};
-	bool recovery_events;
 	int ret;
 
 	if (!phys_enc) {
@@ -745,8 +748,6 @@ static int _sde_encoder_phys_cmd_wait_for_idle(
 	wait_info.wq = &phys_enc->pending_kickoff_wq;
 	wait_info.atomic_cnt = &phys_enc->pending_kickoff_cnt;
 	wait_info.timeout_ms = KICKOFF_TIMEOUT_MS;
-	recovery_events = sde_encoder_recovery_events_enabled(
-			phys_enc->parent);
 
 	/* slave encoder doesn't enable for ppsplit */
 	if (_sde_encoder_phys_is_ppsplit_slave(phys_enc))
@@ -761,18 +762,7 @@ static int _sde_encoder_phys_cmd_wait_for_idle(
 		if (_sde_encoder_phys_cmd_is_scheduler_idle(phys_enc))
 			return 0;
 
-		_sde_encoder_phys_cmd_handle_ppdone_timeout(phys_enc,
-				recovery_events);
-	} else if (!ret) {
-		if (cmd_enc->pp_timeout_report_cnt && recovery_events) {
-			struct drm_connector *conn = phys_enc->connector;
-
-			sde_connector_event_notify(conn,
-					DRM_EVENT_SDE_HW_RECOVERY,
-					sizeof(uint8_t),
-					SDE_RECOVERY_SUCCESS);
-		}
-		cmd_enc->pp_timeout_report_cnt = 0;
+		_sde_encoder_phys_cmd_handle_ppdone_timeout(phys_enc);
 	}
 
 	return ret;
@@ -1379,6 +1369,7 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff(
 			to_sde_encoder_phys_cmd(phys_enc);
 	int ret = 0;
 	u32 extra_frame_trigger_time;
+	bool recovery_events;
 
 	if (!phys_enc || !phys_enc->hw_pp) {
 		SDE_ERROR("invalid encoder\n");
@@ -1407,6 +1398,19 @@ static int sde_encoder_phys_cmd_prepare_for_kickoff(
 		}
 	}
 
+	if (phys_enc->recovered) {
+		recovery_events = sde_encoder_recovery_events_enabled(
+				phys_enc->parent);
+		if (cmd_enc->pp_timeout_report_cnt && recovery_events)
+			sde_connector_event_notify(phys_enc->connector,
+					DRM_EVENT_SDE_HW_RECOVERY,
+					sizeof(uint8_t),
+					SDE_RECOVERY_SUCCESS);
+
+		cmd_enc->pp_timeout_report_cnt = 0;
+		phys_enc->recovered = false;
+	}
+
 	if (sde_connector_is_qsync_updated(phys_enc->connector)) {
 		tc_cfg.sync_threshold_start =
 			_get_tearcheck_threshold(phys_enc,