浏览代码

disp: msm: sde: avoid irq enable/disable during modeset

Avoid irq enable/disable during modeset and trigger
frame as posted start frame. This saves mode_set time
and also avoids unbalanced vblank_irq in this usecase.

Change-Id: I06958da5e52bc2aca0ddc60d2783615f80a839a4
Signed-off-by: Dhaval Patel <[email protected]>
Signed-off-by: Tatenda Chipeperekwa <[email protected]>
Dhaval Patel 5 年之前
父节点
当前提交
bd234c1885
共有 3 个文件被更改,包括 18 次插入73 次删除
  1. 15 25
      msm/sde/sde_encoder.c
  2. 0 2
      msm/sde/sde_encoder_phys.h
  3. 3 46
      msm/sde/sde_encoder_phys_cmd.c

+ 15 - 25
msm/sde/sde_encoder.c

@@ -100,13 +100,12 @@
  * @SDE_ENC_RC_EVENT_PRE_MODESET:
  *	This event happens at NORMAL priority from a work item.
  *	Event signals that there is a seamless mode switch is in prgoress. A
- *	client needs to turn of only irq - leave clocks ON to reduce the mode
- *	switch latency.
+ *	client needs to leave clocks ON to reduce the mode switch latency.
  * @SDE_ENC_RC_EVENT_POST_MODESET:
  *	This event happens at NORMAL priority from a work item.
  *	Event signals that seamless mode switch is complete and resources are
- *	acquired. Clients wants to turn on the irq again and update the rsc
- *	with new vtotal.
+ *	acquired. Clients wants to update the rsc with new vtotal and update
+ *	pm_qos vote.
  * @SDE_ENC_RC_EVENT_ENTER_IDLE:
  *	This event happens at NORMAL priority from a work item.
  *	Event signals that there were no frame updates for
@@ -1898,19 +1897,6 @@ static int _sde_encoder_rc_pre_modeset(struct drm_encoder *drm_enc,
 		sde_enc->rc_state = SDE_ENC_RC_STATE_ON;
 	}
 
-	ret = sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
-	if (ret && ret != -EWOULDBLOCK) {
-		SDE_ERROR_ENC(sde_enc,
-				"wait for commit done returned %d\n",
-				ret);
-		SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
-				ret, SDE_EVTLOG_ERROR);
-		ret = -EINVAL;
-		goto end;
-	}
-
-	sde_encoder_irq_control(drm_enc, false);
-
 	SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
 		SDE_ENC_RC_STATE_MODESET, SDE_EVTLOG_FUNC_CASE5);
 
@@ -1945,8 +1931,6 @@ static int _sde_encoder_rc_post_modeset(struct drm_encoder *drm_enc,
 		goto end;
 	}
 
-	sde_encoder_irq_control(drm_enc, true);
-
 	_sde_encoder_update_rsc_client(drm_enc, true);
 
 	SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
@@ -2396,13 +2380,19 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
 	if (ret)
 		return;
 
-	/* reserve dynamic resources now, indicating non test-only */
-	ret = sde_rm_reserve(&sde_kms->rm, drm_enc, drm_enc->crtc->state,
-			conn->state, false);
-	if (ret) {
-		SDE_ERROR_ENC(sde_enc,
+	if (drm_enc->crtc->state->active_changed ||
+		!(msm_is_mode_seamless_dms(msm_mode) ||
+		(msm_is_mode_seamless_dyn_clk(msm_mode) &&
+		sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE)))) {
+
+		/* reserve dynamic resources now, indicating non test-only */
+		ret = sde_rm_reserve(&sde_kms->rm, drm_enc, drm_enc->crtc->state,
+				conn->state, false);
+		if (ret) {
+			SDE_ERROR_ENC(sde_enc,
 				"failed to reserve hw resources, %d\n", ret);
-		return;
+			return;
+		}
 	}
 
 	/* assign the reserved HW blocks to this encoder */

+ 0 - 2
msm/sde/sde_encoder_phys.h

@@ -276,7 +276,6 @@ struct sde_encoder_irq {
  * @enc_spinlock:	Virtual-Encoder-Wide Spin Lock for IRQ purposes
  * @enable_state:	Enable state tracking
  * @vblank_refcount:	Reference count of vblank request
- * @vblank_cached_refcount:	Reference count of vblank cached request
  * @wbirq_refcount:	Reference count of wb irq request
  * @vsync_cnt:		Vsync count for the physical encoder
  * @last_vsync_timestamp:	store last vsync timestamp
@@ -327,7 +326,6 @@ struct sde_encoder_phys {
 	enum sde_enc_enable_state enable_state;
 	struct mutex *vblank_ctl_lock;
 	atomic_t vblank_refcount;
-	atomic_t vblank_cached_refcount;
 	atomic_t wbirq_refcount;
 	atomic_t vsync_cnt;
 	ktime_t last_vsync_timestamp;

+ 3 - 46
msm/sde/sde_encoder_phys_cmd.c

@@ -330,8 +330,6 @@ static void _sde_encoder_phys_cmd_setup_irq_hw_idx(
 {
 	struct sde_encoder_irq *irq;
 	struct sde_kms *sde_kms;
-	int ret = 0;
-	u32 vblank_refcount;
 
 	if (!phys_enc->sde_kms || !phys_enc->hw_pp || !phys_enc->hw_ctl) {
 		SDE_ERROR("invalid args %d %d %d\n", !phys_enc->sde_kms,
@@ -346,39 +344,13 @@ static void _sde_encoder_phys_cmd_setup_irq_hw_idx(
 
 	sde_kms = phys_enc->sde_kms;
 
-	mutex_lock(phys_enc->vblank_ctl_lock);
-	vblank_refcount = atomic_read(&phys_enc->vblank_refcount);
-	if (vblank_refcount) {
-		ret = sde_encoder_helper_unregister_irq(phys_enc,
-				INTR_IDX_RDPTR);
-		if (ret)
-			SDE_ERROR(
-				"control vblank irq registration error %d\n",
-					ret);
-		if (vblank_refcount > 1)
-			SDE_ERROR(
-				"vblank_refcount mismatch detected, try to reset %d\n",
-				atomic_read(&phys_enc->vblank_refcount));
-		else
-			atomic_set(&phys_enc->vblank_cached_refcount, 1);
-
-		SDE_EVT32(DRMID(phys_enc->parent),
-			phys_enc->hw_pp->idx - PINGPONG_0, vblank_refcount,
-			atomic_read(&phys_enc->vblank_cached_refcount));
-	}
-	atomic_set(&phys_enc->vblank_refcount, 0);
-	mutex_unlock(phys_enc->vblank_ctl_lock);
-
 	irq = &phys_enc->irq[INTR_IDX_CTL_START];
 	irq->hw_idx = phys_enc->hw_ctl->idx;
-	irq->irq_idx = -EINVAL;
 
 	irq = &phys_enc->irq[INTR_IDX_PINGPONG];
 	irq->hw_idx = phys_enc->hw_pp->idx;
-	irq->irq_idx = -EINVAL;
 
 	irq = &phys_enc->irq[INTR_IDX_RDPTR];
-	irq->irq_idx = -EINVAL;
 	if (phys_enc->has_intf_te)
 		irq->hw_idx = phys_enc->hw_intf->idx;
 	else
@@ -386,17 +358,14 @@ static void _sde_encoder_phys_cmd_setup_irq_hw_idx(
 
 	irq = &phys_enc->irq[INTR_IDX_UNDERRUN];
 	irq->hw_idx = phys_enc->intf_idx;
-	irq->irq_idx = -EINVAL;
 
 	irq = &phys_enc->irq[INTR_IDX_AUTOREFRESH_DONE];
-	irq->irq_idx = -EINVAL;
 	if (phys_enc->has_intf_te)
 		irq->hw_idx = phys_enc->hw_intf->idx;
 	else
 		irq->hw_idx = phys_enc->hw_pp->idx;
 
 	irq = &phys_enc->irq[INTR_IDX_WRPTR];
-	irq->irq_idx = -EINVAL;
 	if (phys_enc->has_intf_te)
 		irq->hw_idx = phys_enc->hw_intf->idx;
 	else
@@ -821,7 +790,7 @@ static int sde_encoder_phys_cmd_control_vblank_irq(
 	struct sde_encoder_phys_cmd *cmd_enc =
 		to_sde_encoder_phys_cmd(phys_enc);
 	int ret = 0;
-	u32 refcount, cached_refcount;
+	u32 refcount;
 	struct sde_kms *sde_kms;
 
 	if (!phys_enc || !phys_enc->hw_pp) {
@@ -836,17 +805,11 @@ static int sde_encoder_phys_cmd_control_vblank_irq(
 		goto end;
 
 	refcount = atomic_read(&phys_enc->vblank_refcount);
-	cached_refcount = atomic_read(&phys_enc->vblank_cached_refcount);
 
 	/* protect against negative */
 	if (!enable && refcount == 0) {
-		if (cached_refcount == 1) {
-			atomic_set(&phys_enc->vblank_cached_refcount, 0);
-			goto end;
-		} else {
-			ret = -EINVAL;
-			goto end;
-		}
+		ret = -EINVAL;
+		goto end;
 	}
 
 	SDE_DEBUG_CMDENC(cmd_enc, "[%pS] enable=%d/%d\n",
@@ -866,11 +829,6 @@ static int sde_encoder_phys_cmd_control_vblank_irq(
 			atomic_inc_return(&phys_enc->vblank_refcount);
 	}
 
-	if (enable && cached_refcount) {
-		atomic_inc(&phys_enc->vblank_refcount);
-		atomic_set(&phys_enc->vblank_cached_refcount, 0);
-	}
-
 end:
 	mutex_unlock(phys_enc->vblank_ctl_lock);
 	if (ret) {
@@ -2108,7 +2066,6 @@ struct sde_encoder_phys *sde_encoder_phys_cmd_init(
 	irq->cb.func = sde_encoder_phys_cmd_wr_ptr_irq;
 
 	atomic_set(&phys_enc->vblank_refcount, 0);
-	atomic_set(&phys_enc->vblank_cached_refcount, 0);
 	atomic_set(&phys_enc->pending_kickoff_cnt, 0);
 	atomic_set(&phys_enc->pending_retire_fence_cnt, 0);
 	atomic_set(&cmd_enc->pending_vblank_cnt, 0);