|
@@ -1,5 +1,5 @@
|
|
|
/*
|
|
|
- * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved.
|
|
|
+ * Copyright (c) 2021-2022, Qualcomm Innovation Center, Inc. All rights reserved.
|
|
|
* Copyright (c) 2014-2021, The Linux Foundation. All rights reserved.
|
|
|
* Copyright (C) 2013 Red Hat
|
|
|
* Author: Rob Clark <[email protected]>
|
|
@@ -2428,17 +2428,37 @@ static void _sde_encoder_virt_populate_hw_res(struct drm_encoder *drm_enc)
|
|
|
}
|
|
|
|
|
|
static int sde_encoder_virt_modeset_rc(struct drm_encoder *drm_enc,
|
|
|
- struct msm_display_mode *msm_mode, bool pre_modeset)
|
|
|
+ struct drm_display_mode *adj_mode, struct msm_display_mode *msm_mode, bool pre_modeset)
|
|
|
{
|
|
|
struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc);
|
|
|
enum sde_intf_mode intf_mode;
|
|
|
+ struct drm_display_mode *old_adj_mode = NULL;
|
|
|
int ret;
|
|
|
- bool is_cmd_mode = false;
|
|
|
+ bool is_cmd_mode = false, res_switch = false;
|
|
|
|
|
|
if (sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE))
|
|
|
is_cmd_mode = true;
|
|
|
|
|
|
if (pre_modeset) {
|
|
|
+ if (sde_enc->cur_master)
|
|
|
+ old_adj_mode = &sde_enc->cur_master->cached_mode;
|
|
|
+ if (old_adj_mode && is_cmd_mode)
|
|
|
+ res_switch = !drm_mode_match(old_adj_mode, adj_mode,
|
|
|
+ DRM_MODE_MATCH_TIMINGS);
|
|
|
+
|
|
|
+ if (res_switch && sde_enc->disp_info.is_te_using_watchdog_timer) {
|
|
|
+ /*
|
|
|
+ * add tx wait for sim panel to avoid wd timer getting
|
|
|
+ * updated in middle of frame to avoid early vsync
|
|
|
+ */
|
|
|
+ ret = sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE);
|
|
|
+ if (ret && ret != -EWOULDBLOCK) {
|
|
|
+ SDE_ERROR_ENC(sde_enc, "wait for idle failed %d\n", ret);
|
|
|
+ SDE_EVT32(DRMID(drm_enc), ret, SDE_EVTLOG_ERROR);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
intf_mode = sde_encoder_get_intf_mode(drm_enc);
|
|
|
if (msm_is_mode_seamless_dms(msm_mode) ||
|
|
|
(msm_is_mode_seamless_dyn_clk(msm_mode) &&
|
|
@@ -2545,7 +2565,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
|
|
|
|
|
|
/* release resources before seamless mode change */
|
|
|
msm_mode = &c_state->msm_mode;
|
|
|
- ret = sde_encoder_virt_modeset_rc(drm_enc, msm_mode, true);
|
|
|
+ ret = sde_encoder_virt_modeset_rc(drm_enc, adj_mode, msm_mode, true);
|
|
|
if (ret)
|
|
|
return;
|
|
|
|
|
@@ -2585,7 +2605,7 @@ static void sde_encoder_virt_mode_set(struct drm_encoder *drm_enc,
|
|
|
}
|
|
|
|
|
|
/* update resources after seamless mode change */
|
|
|
- sde_encoder_virt_modeset_rc(drm_enc, msm_mode, false);
|
|
|
+ sde_encoder_virt_modeset_rc(drm_enc, adj_mode, msm_mode, false);
|
|
|
}
|
|
|
|
|
|
void sde_encoder_control_te(struct drm_encoder *drm_enc, bool enable)
|