Browse Source

Merge "disp: msm: sde: disable idle notification"

qctecmdr 4 years ago
parent
commit
cdd14239fd
3 changed files with 41 additions and 30 deletions
  1. 20 20
      msm/sde/sde_crtc.c
  2. 18 9
      msm/sde/sde_encoder.c
  3. 3 1
      msm/sde/sde_encoder.h

+ 20 - 20
msm/sde/sde_crtc.c

@@ -3542,7 +3542,8 @@ static void _sde_crtc_schedule_idle_notify(struct drm_crtc *crtc,
 	if (!idle_time ||
 		!sde_encoder_check_curr_mode(sde_crtc->mixers[0].encoder,
 						MSM_DISPLAY_VIDEO_MODE) ||
-			(crtc->index >= ARRAY_SIZE(priv->event_thread)))
+			(crtc->index >= ARRAY_SIZE(priv->event_thread)) ||
+			(sde_crtc->cache_state > CACHE_STATE_NORMAL))
 		return;
 
 	/* schedule the idle notify delayed work */
@@ -3654,7 +3655,7 @@ int sde_crtc_reset_hw(struct drm_crtc *crtc, struct drm_crtc_state *old_state,
 			continue;
 
 		if (sde_encoder_get_intf_mode(encoder) == INTF_MODE_VIDEO)
-			sde_encoder_kickoff(encoder, false);
+			sde_encoder_kickoff(encoder, false, true);
 	}
 
 	/* panic the device if VBIF is not in good state */
@@ -3760,7 +3761,7 @@ void sde_crtc_commit_kickoff(struct drm_crtc *crtc,
 		if (encoder->crtc != crtc)
 			continue;
 
-		sde_encoder_kickoff(encoder, false);
+		sde_encoder_kickoff(encoder, false, true);
 	}
 
 	/* store the event after frame trigger */
@@ -6398,35 +6399,34 @@ void __sde_crtc_static_cache_read_work(struct kthread_work *work)
 	struct sde_crtc *sde_crtc = container_of(work, struct sde_crtc,
 			static_cache_read_work.work);
 	struct drm_crtc *crtc;
-	struct msm_kms *kms;
-	struct msm_drm_private *priv = NULL;
-	struct sde_crtc_mixer *mixer;
-	struct sde_hw_ctl *ctl;
+	struct drm_encoder *enc, *drm_enc = NULL;
 
 	if (!sde_crtc)
 		return;
 
 	crtc = &sde_crtc->base;
-	priv = crtc->dev->dev_private;
-	kms = priv->kms;
-	mixer = sde_crtc->mixers;
-	if (!mixer)
-		return;
 
-	ctl = mixer->hw_ctl;
+	if (sde_crtc->cache_state != CACHE_STATE_FRAME_WRITE)
+		return;
 
-	SDE_EVT32(DRMID(crtc), SDE_EVTLOG_FUNC_ENTRY);
+	drm_for_each_encoder_mask(enc, crtc->dev, crtc->state->encoder_mask) {
+		drm_enc = enc;
+		if (sde_encoder_in_clone_mode(drm_enc))
+			return;
+	}
 
-	if (sde_crtc->cache_state != CACHE_STATE_FRAME_WRITE ||
-			!ctl->ops.trigger_flush)
+	if (!drm_enc) {
+		SDE_ERROR("invalid encoder\n");
 		return;
+	}
+
+	SDE_EVT32(DRMID(crtc), SDE_EVTLOG_FUNC_ENTRY);
 
 	sde_crtc_static_img_control(crtc, CACHE_STATE_FRAME_READ, false);
 
-	/* flush with previous commit flush bits & wait till frame done */
-	ctl->ops.trigger_flush(ctl);
-	if (kms->funcs->wait_for_crtc_commit_done)
-		kms->funcs->wait_for_crtc_commit_done(kms, crtc);
+	/* kickoff encoder with previous configuration and wait for VBLANK */
+	sde_encoder_kickoff(drm_enc, false, false);
+	sde_encoder_wait_for_event(drm_enc, MSM_ENC_VBLANK);
 
 	SDE_EVT32(DRMID(crtc), SDE_EVTLOG_FUNC_EXIT);
 }

+ 18 - 9
msm/sde/sde_encoder.c

@@ -3196,10 +3196,13 @@ int sde_encoder_idle_request(struct drm_encoder *drm_enc)
  * drm_enc: Pointer to drm encoder structure
  * phys: Pointer to physical encoder structure
  * extra_flush: Additional bit mask to include in flush trigger
+ * config_changed: if true new config is applied, avoid increment of retire
+ *	count if false
  */
 static inline void _sde_encoder_trigger_flush(struct drm_encoder *drm_enc,
 		struct sde_encoder_phys *phys,
-		struct sde_ctl_flush_cfg *extra_flush)
+		struct sde_ctl_flush_cfg *extra_flush,
+		bool config_changed)
 {
 	struct sde_hw_ctl *ctl;
 	unsigned long lock_flags;
@@ -3238,7 +3241,7 @@ static inline void _sde_encoder_trigger_flush(struct drm_encoder *drm_enc,
 	/* update pending counts and trigger kickoff ctl flush atomically */
 	spin_lock_irqsave(&sde_enc->enc_spinlock, lock_flags);
 
-	if (phys->ops.is_master && phys->ops.is_master(phys))
+	if (phys->ops.is_master && phys->ops.is_master(phys) && config_changed)
 		atomic_inc(&phys->pending_retire_fence_cnt);
 
 	pend_ret_fence_cnt = atomic_read(&phys->pending_retire_fence_cnt);
@@ -3402,8 +3405,11 @@ void sde_encoder_helper_hw_reset(struct sde_encoder_phys *phys_enc)
  *	use cases that require visibility into multiple physical encoders at
  *	a time.
  * sde_enc: Pointer to virtual encoder structure
+ * config_changed: if true new config is applied. Avoid regdma_flush and
+ *	incrementing the retire count if false.
  */
-static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
+static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc,
+		bool config_changed)
 {
 	struct sde_hw_ctl *ctl;
 	uint32_t i;
@@ -3445,9 +3451,10 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
 
 		if (!phys->ops.needs_single_flush ||
 				!phys->ops.needs_single_flush(phys)) {
-			if (ctl->ops.reg_dma_flush)
+			if (config_changed && ctl->ops.reg_dma_flush)
 				ctl->ops.reg_dma_flush(ctl, is_regdma_blocking);
-			_sde_encoder_trigger_flush(&sde_enc->base, phys, 0x0);
+			_sde_encoder_trigger_flush(&sde_enc->base, phys, 0x0,
+					config_changed);
 		} else if (ctl->ops.get_pending_flush) {
 			ctl->ops.get_pending_flush(ctl, &pending_flush);
 		}
@@ -3456,10 +3463,11 @@ static void _sde_encoder_kickoff_phys(struct sde_encoder_virt *sde_enc)
 	/* for split flush, combine pending flush masks and send to master */
 	if (pending_flush.pending_flush_mask && sde_enc->cur_master) {
 		ctl = sde_enc->cur_master->hw_ctl;
-		if (ctl->ops.reg_dma_flush)
+		if (config_changed && ctl->ops.reg_dma_flush)
 			ctl->ops.reg_dma_flush(ctl, is_regdma_blocking);
 		_sde_encoder_trigger_flush(&sde_enc->base, sde_enc->cur_master,
-						&pending_flush);
+						&pending_flush,
+						config_changed);
 	}
 
 	/* update pending_kickoff_cnt AFTER flush but before trigger start */
@@ -4052,7 +4060,8 @@ static int _sde_encoder_reset_ctl_hw(struct drm_encoder *drm_enc)
 	return rc;
 }
 
-void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error)
+void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error,
+		bool config_changed)
 {
 	struct sde_encoder_virt *sde_enc;
 	struct sde_encoder_phys *phys;
@@ -4072,7 +4081,7 @@ void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error)
 		_sde_encoder_reset_ctl_hw(drm_enc);
 
 	/* All phys encs are ready to go, trigger the kickoff */
-	_sde_encoder_kickoff_phys(sde_enc);
+	_sde_encoder_kickoff_phys(sde_enc, config_changed);
 
 	/* allow phys encs to handle any post-kickoff business */
 	for (i = 0; i < sde_enc->num_phys_encs; i++) {

+ 3 - 1
msm/sde/sde_encoder.h

@@ -335,8 +335,10 @@ void sde_encoder_trigger_kickoff_pending(struct drm_encoder *encoder);
  * @encoder:	encoder pointer
  * @is_error:	whether the current commit needs to be aborted and replaced
  *		with a 'safe' commit
+ * @config_changed: if true new configuration is applied on the control path
  */
-void sde_encoder_kickoff(struct drm_encoder *encoder, bool is_error);
+void sde_encoder_kickoff(struct drm_encoder *encoder, bool is_error,
+		bool config_changed);
 
 /**
  * sde_encoder_wait_for_event - Waits for encoder events