소스 검색

disp: msm: sde: hw_fence update autorefresh disable sequence

This change updates the autorefresh disable sequence to manually
trigger output hw_fence during the transition. This is required
since on the last autorefresh frame HW will not trigger the output fence.

Change-Id: I6789fc6b51421524f88dcbdd1a063ae947646ae4
Signed-off-by: Christina Oliveira <[email protected]>
Christina Oliveira 3 년 전
부모
커밋
9a33a2a1fd
4개의 변경된 파일31개의 추가작업 그리고 2개의 파일을 삭제
  1. 2 0
      msm/sde/sde_encoder_phys.h
  2. 16 2
      msm/sde/sde_encoder_phys_cmd.c
  3. 7 0
      msm/sde/sde_hw_ctl.c
  4. 6 0
      msm/sde/sde_hw_ctl.h

+ 2 - 0
msm/sde/sde_encoder_phys.h

@@ -311,6 +311,7 @@ struct sde_encoder_irq {
  * @frame_trigger_mode:		frame trigger mode indication for command
  *				mode display
  * @recovered:			flag set to true when recovered from pp timeout
+ * @autorefresh_disable_trans:   flag set to true during autorefresh disable transition
  */
 struct sde_encoder_phys {
 	struct drm_encoder *parent;
@@ -358,6 +359,7 @@ struct sde_encoder_phys {
 	int vfp_cached;
 	enum frame_trigger_mode_type frame_trigger_mode;
 	bool recovered;
+	bool autorefresh_disable_trans;
 };
 
 static inline int sde_encoder_phys_inc_pending(struct sde_encoder_phys *phys)

+ 16 - 2
msm/sde/sde_encoder_phys_cmd.c

@@ -196,11 +196,23 @@ static void _sde_encoder_phys_signal_frame_done(struct sde_encoder_phys *phys_en
 		spin_unlock(phys_enc->enc_spinlock);
 	}
 
-	if (ctl && ctl->ops.get_scheduler_status)
+	if (ctl->ops.get_scheduler_status)
 		scheduler_status = ctl->ops.get_scheduler_status(ctl);
 
 	SDE_EVT32_IRQ(DRMID(phys_enc->parent), ctl->idx - CTL_0,
-		phys_enc->hw_pp->idx - PINGPONG_0, event, scheduler_status);
+		phys_enc->hw_pp->idx - PINGPONG_0, event, scheduler_status,
+		phys_enc->autorefresh_disable_trans);
+
+	/*
+	 * For hw-fences, in the last frame during the autorefresh disable transition
+	 * hw won't trigger the output-fence signal once the frame is done, therefore
+	 * sw must trigger the override to force the signal here
+	 */
+	if (phys_enc->autorefresh_disable_trans) {
+		if (ctl->ops.trigger_output_fence_override)
+			ctl->ops.trigger_output_fence_override(ctl);
+		phys_enc->autorefresh_disable_trans = false;
+	}
 
 	/* Signal any waiting atomic commit thread */
 	wake_up_all(&phys_enc->pending_kickoff_wq);
@@ -1881,6 +1893,8 @@ static void _sde_encoder_phys_disable_autorefresh(struct sde_encoder_phys *phys_
 
 	sde_encoder_phys_cmd_connect_te(phys_enc, false);
 	_sde_encoder_phys_cmd_config_autorefresh(phys_enc, 0);
+	phys_enc->autorefresh_disable_trans = true;
+
 	if (sde_kms && sde_kms->catalog &&
 			(sde_kms->catalog->autorefresh_disable_seq == AUTOREFRESH_DISABLE_SEQ1)) {
 		_sde_encoder_autorefresh_disable_seq1(phys_enc);

+ 7 - 0
msm/sde/sde_hw_ctl.c

@@ -60,6 +60,7 @@
 #define CTL_OUTPUT_FENCE_CTRL         0x25C
 #define CTL_OUTPUT_FENCE_ID           0x260
 #define CTL_HW_FENCE_STATUS           0x278
+#define CTL_OUTPUT_FENCE_SW_OVERRIDE  0x27C
 
 #define CTL_MIXER_BORDER_OUT            BIT(24)
 #define CTL_FLUSH_MASK_ROT              BIT(27)
@@ -371,6 +372,11 @@ static inline void sde_hw_ctl_trigger_sw_override(struct sde_hw_ctl *ctx)
 	SDE_REG_WRITE(&ctx->hw, CTL_FENCE_READY_SW_OVERRIDE, 0x1);
 }
 
+static inline void sde_hw_ctl_trigger_output_fence_override(struct sde_hw_ctl *ctx)
+{
+	SDE_REG_WRITE(&ctx->hw, CTL_OUTPUT_FENCE_SW_OVERRIDE, 0x1);
+}
+
 static inline int sde_hw_ctl_trigger_start(struct sde_hw_ctl *ctx)
 {
 	if (!ctx)
@@ -1426,6 +1432,7 @@ static void _setup_ctl_ops(struct sde_hw_ctl_ops *ops,
 		ops->hw_fence_ctrl = sde_hw_ctl_hw_fence_ctrl;
 		ops->hw_fence_trigger_sw_override = sde_hw_ctl_trigger_sw_override;
 		ops->get_hw_fence_status = sde_hw_ctl_get_hw_fence_status;
+		ops->trigger_output_fence_override = sde_hw_ctl_trigger_output_fence_override;
 	}
 
 	if (cap & BIT(SDE_CTL_UIDLE))

+ 6 - 0
msm/sde/sde_hw_ctl.h

@@ -177,6 +177,12 @@ struct sde_hw_ctl_ops {
 	 */
 	void (*hw_fence_ctrl)(struct sde_hw_ctl *ctx, bool sw_set, bool sw_clear, u32 mode);
 
+	/**
+	 * override to trigger the signal for the output hw-fence
+	 * @ctx         : ctl path ctx pointer
+	 */
+	void (*trigger_output_fence_override)(struct sde_hw_ctl *ctx);
+
 	/**
 	 * trigger hw fence fence-ready sw override
 	 * @ctx         : ctl path ctx pointer