Selaa lähdekoodia

disp: msm: sde: update kickoff timeout for CMD panel

While transition from very low fps (1Hz) to higher fps (120Hz)
there will be a delay on first frame to take effect on
mode switch. In such cases if kickoff_timeout value is programmed
based on newer high fps wr_ptr_timeout can happen. To avoid this
update the kickoff timeout with respect to lower fps and reset
it back according to present fps once the mode switch commit is
done.

Change-Id: I08e1a68bb1e388a1bda8ef61d47e9eb4b2fc97fe
Signed-off-by: Mahadevan <[email protected]>
Mahadevan 1 vuosi sitten
vanhempi
sitoutus
eb84d660f1
4 muutettua tiedostoa jossa 27 lisäystä ja 1 poistoa
  1. 14 0
      msm/sde/sde_encoder.c
  2. 6 0
      msm/sde/sde_encoder.h
  3. 2 1
      msm/sde/sde_encoder_phys_cmd.c
  4. 5 0
      msm/sde/sde_kms.c

+ 14 - 0
msm/sde/sde_encoder.c

@@ -5423,6 +5423,20 @@ u32 sde_encoder_helper_get_kickoff_timeout_ms(struct drm_encoder *drm_enc)
 		return (SEC_TO_MILLI_SEC / fps) * 2;
 }
 
+void sde_encoder_reset_kickoff_timeout_ms(struct drm_encoder *drm_enc)
+{
+	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
+
+	if (!sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE))
+		return;
+
+	for (int i = 0; i < sde_enc->num_phys_encs; i++) {
+		if (sde_enc->phys_encs[i])
+			sde_enc->phys_encs[i]->kickoff_timeout_ms =
+				sde_encoder_helper_get_kickoff_timeout_ms(drm_enc);
+	}
+}
+
 int sde_encoder_get_avr_status(struct drm_encoder *drm_enc)
 {
 	struct sde_encoder_virt *sde_enc;

+ 6 - 0
msm/sde/sde_encoder.h

@@ -386,6 +386,12 @@ int sde_encoder_prepare_for_kickoff(struct drm_encoder *encoder,
  */
 void sde_encoder_trigger_kickoff_pending(struct drm_encoder *encoder);
 
+/**
+ * sde_encoder_reset_kickoff_timeout_ms - Reset the kickoff_timout after modeset
+ *        commit for command mode display.
+ * @encoder:	encoder pointer
+ */
+void sde_encoder_reset_kickoff_timeout_ms(struct drm_encoder *encoder);
 /**
  * sde_encoder_kickoff - trigger a double buffer flip of the ctl path
  *	(i.e. ctl flush and start) immediately.

+ 2 - 1
msm/sde/sde_encoder_phys_cmd.c

@@ -827,7 +827,8 @@ static void sde_encoder_phys_cmd_mode_set(
 	_sde_encoder_phys_cmd_setup_irq_hw_idx(phys_enc);
 
 	phys_enc->kickoff_timeout_ms =
-		sde_encoder_helper_get_kickoff_timeout_ms(phys_enc->parent);
+			max(phys_enc->kickoff_timeout_ms,
+			sde_encoder_helper_get_kickoff_timeout_ms(phys_enc->parent));
 }
 
 static int _sde_encoder_phys_cmd_handle_framedone_timeout(

+ 5 - 0
msm/sde/sde_kms.c

@@ -1726,6 +1726,11 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms,
 	if (cwb_disabling && cwb_enc)
 		sde_encoder_virt_reset(cwb_enc);
 
+	if (drm_atomic_crtc_needs_modeset(crtc->state)) {
+		drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask)
+			sde_encoder_reset_kickoff_timeout_ms(encoder);
+	}
+
 	/* avoid system cache update to set rd-noalloc bit when NSE feature is enabled */
 	if (!test_bit(SDE_FEATURE_SYS_CACHE_NSE, sde_kms->catalog->features))
 		sde_crtc_static_cache_read_kickoff(crtc);