Sfoglia il codice sorgente

disp: msm: fix vsync wait for poms and dms

SDE RSC does not need to wait for vsync during
dms. It was removed unintentionally with commit
a74d2cf7fa2f ("disp: msm: add runtime_pm ops
support in drm driver"). However, Panel mode
switch still needs vsync wait based on
recommendation. This change fixes vsync wait
for both cases.

Change-Id: Ic9119132eb15a8c33f3841ba5df2624189d93395
Signed-off-by: Dhaval Patel <[email protected]>
Dhaval Patel 6 anni fa
parent
commit
7b5c2fff43
2 ha cambiato i file con 34 aggiunte e 17 eliminazioni
  1. 32 15
      msm/sde/sde_encoder.c
  2. 2 2
      msm/sde_rsc.c

+ 32 - 15
msm/sde/sde_encoder.c

@@ -2443,8 +2443,13 @@ static int _sde_encoder_rc_pre_modeset(struct drm_encoder *drm_enc,
 
 	mutex_lock(&sde_enc->rc_lock);
 
-	/* return if the resource control is already in ON state */
-	if (sde_enc->rc_state != SDE_ENC_RC_STATE_ON) {
+	if (sde_enc->rc_state == SDE_ENC_RC_STATE_OFF) {
+		SDE_DEBUG_ENC(sde_enc, "sw_event:%d, rc in OFF state\n",
+				sw_event);
+		SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
+			SDE_EVTLOG_FUNC_CASE5);
+		goto end;
+	} else if (sde_enc->rc_state != SDE_ENC_RC_STATE_ON) {
 		/* enable all the clks and resources */
 		ret = _sde_encoder_resource_control_helper(drm_enc,
 				true);
@@ -2496,8 +2501,13 @@ static int _sde_encoder_rc_post_modeset(struct drm_encoder *drm_enc,
 
 	mutex_lock(&sde_enc->rc_lock);
 
-	/* return if the resource control is already in ON state */
-	if (sde_enc->rc_state != SDE_ENC_RC_STATE_MODESET) {
+	if (sde_enc->rc_state == SDE_ENC_RC_STATE_OFF) {
+		SDE_DEBUG_ENC(sde_enc, "sw_event:%d, rc in OFF state\n",
+				sw_event);
+		SDE_EVT32(DRMID(drm_enc), sw_event, sde_enc->rc_state,
+			SDE_EVTLOG_FUNC_CASE5);
+		goto end;
+	} else if (sde_enc->rc_state != SDE_ENC_RC_STATE_MODESET) {
 		SDE_ERROR_ENC(sde_enc,
 				"sw_event:%d, rc:%d !MODESET state\n",
 				sw_event, sde_enc->rc_state);
@@ -2711,25 +2721,29 @@ static int sde_encoder_resource_control(struct drm_encoder *drm_enc,
 	return ret;
 }
 
-static void sde_encoder_virt_mode_switch(enum sde_intf_mode intf_mode,
-					struct sde_encoder_virt *sde_enc,
-					struct drm_display_mode *adj_mode)
+static void sde_encoder_virt_mode_switch(struct drm_encoder *drm_enc,
+	enum sde_intf_mode intf_mode, struct drm_display_mode *adj_mode)
 {
 	int i = 0;
+	struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
+
+	if (intf_mode == INTF_MODE_CMD)
+		sde_enc->disp_info.curr_panel_mode = MSM_DISPLAY_VIDEO_MODE;
+	else if (intf_mode == INTF_MODE_VIDEO)
+		sde_enc->disp_info.curr_panel_mode = MSM_DISPLAY_CMD_MODE;
+
+	_sde_encoder_update_rsc_client(drm_enc, true);
 
 	if (intf_mode == INTF_MODE_CMD) {
 		for (i = 0; i < sde_enc->num_phys_encs; i++)
 			sde_enc->phys_encs[i] = sde_enc->phys_vid_encs[i];
-		sde_enc->disp_info.curr_panel_mode = MSM_DISPLAY_VIDEO_MODE;
 		SDE_DEBUG_ENC(sde_enc, "switch to video physical encoder\n");
 		SDE_EVT32(DRMID(&sde_enc->base), intf_mode,
 			msm_is_mode_seamless_poms(adj_mode),
 			SDE_EVTLOG_FUNC_CASE1);
-	}
-	if (intf_mode == INTF_MODE_VIDEO) {
+	} else if (intf_mode == INTF_MODE_VIDEO) {
 		for (i = 0; i < sde_enc->num_phys_encs; i++)
 			sde_enc->phys_encs[i] = sde_enc->phys_cmd_encs[i];
-		sde_enc->disp_info.curr_panel_mode = MSM_DISPLAY_CMD_MODE;
 		SDE_EVT32(DRMID(&sde_enc->base), intf_mode,
 			msm_is_mode_seamless_poms(adj_mode),
 			SDE_EVTLOG_FUNC_CASE2);
@@ -2810,10 +2824,6 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
 	}
 	intf_mode = sde_encoder_get_intf_mode(drm_enc);
 
-	/* Switch pysical encoder */
-	if (msm_is_mode_seamless_poms(adj_mode))
-		sde_encoder_virt_mode_switch(intf_mode, sde_enc, adj_mode);
-
 	/* release resources before seamless mode change */
 	if (msm_is_mode_seamless_dms(adj_mode)) {
 		/* restore resource state before releasing them */
@@ -2831,6 +2841,10 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
 		 * to guarantee that previous kickoff finished.
 		 */
 		_sde_encoder_dsc_disable(sde_enc);
+	} else if (msm_is_mode_seamless_poms(adj_mode)) {
+		_sde_encoder_modeset_helper_locked(drm_enc,
+					SDE_ENC_RC_EVENT_PRE_MODESET);
+		sde_encoder_virt_mode_switch(drm_enc, intf_mode, adj_mode);
 	}
 
 	/* Reserve dynamic resources now. Indicating non-AtomicTest phase */
@@ -2908,6 +2922,9 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
 	if (msm_is_mode_seamless_dms(adj_mode))
 		sde_encoder_resource_control(&sde_enc->base,
 						SDE_ENC_RC_EVENT_POST_MODESET);
+	else if (msm_is_mode_seamless_poms(adj_mode))
+		_sde_encoder_modeset_helper_locked(drm_enc,
+						SDE_ENC_RC_EVENT_POST_MODESET);
 }
 
 void sde_encoder_control_te(struct drm_encoder *drm_enc, bool enable)

+ 2 - 2
msm/sde_rsc.c

@@ -427,7 +427,7 @@ static int sde_rsc_switch_to_cmd(struct sde_rsc_priv *rsc,
 	 */
 	if (rsc->current_state == SDE_RSC_CMD_STATE) {
 		rc = 0;
-		if (config)
+		if (config && rsc->version < SDE_RSC_REV_3)
 			goto vsync_wait;
 		else
 			goto end;
@@ -565,7 +565,7 @@ static int sde_rsc_switch_to_vid(struct sde_rsc_priv *rsc,
 	 */
 	if (rsc->current_state == SDE_RSC_VID_STATE) {
 		rc = 0;
-		if (config)
+		if (config && rsc->version < SDE_RSC_REV_3)
 			goto vsync_wait;
 		else
 			goto end;