diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 279191a287..aaa7d363c7 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -1483,9 +1483,12 @@ static int _sde_encoder_update_rsc_client( * secondary command mode panel. * Clone mode encoder can request CLK STATE only. */ - if (sde_enc->cur_master) + if (sde_enc->cur_master) { qsync_mode = sde_connector_get_qsync_mode( sde_enc->cur_master->connector); + sde_enc->autorefresh_solver_disable = + _sde_encoder_is_autorefresh_enabled(sde_enc) ? true : false; + } /* left primary encoder keep vote */ if (sde_encoder_in_clone_mode(drm_enc)) { @@ -1494,7 +1497,8 @@ static int _sde_encoder_update_rsc_client( } if ((disp_info->display_type != SDE_CONNECTOR_PRIMARY) || - (disp_info->display_type && qsync_mode)) + (disp_info->display_type && qsync_mode) || + sde_enc->autorefresh_solver_disable) rsc_state = enable ? SDE_RSC_CLK_STATE : SDE_RSC_IDLE_STATE; else if (sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_CMD_MODE)) rsc_state = enable ? SDE_RSC_CMD_STATE : SDE_RSC_IDLE_STATE; @@ -4235,16 +4239,16 @@ int sde_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc, if (sde_enc->cur_master && sde_connector_is_qsync_updated( - sde_enc->cur_master->connector)) { + sde_enc->cur_master->connector)) _helper_flush_qsync(phys); - - if (is_cmd_mode) - _sde_encoder_update_rsc_client(drm_enc, - true); - } } } + if (is_cmd_mode && sde_enc->cur_master && + (sde_connector_is_qsync_updated(sde_enc->cur_master->connector) || + _sde_encoder_is_autorefresh_enabled(sde_enc))) + _sde_encoder_update_rsc_client(drm_enc, true); + rc = sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_KICKOFF); if (rc) { SDE_ERROR_ENC(sde_enc, "resource kickoff failed rc %d\n", rc); @@ -4373,6 +4377,10 @@ void sde_encoder_kickoff(struct drm_encoder *drm_enc, bool is_error, phys->ops.handle_post_kickoff(phys); } + if (sde_enc->autorefresh_solver_disable && + !_sde_encoder_is_autorefresh_enabled(sde_enc)) + _sde_encoder_update_rsc_client(drm_enc, true); + SDE_ATRACE_END("encoder_kickoff"); } diff --git a/msm/sde/sde_encoder.h b/msm/sde/sde_encoder.h index 54d0a6eee5..5a089454ed 100644 --- a/msm/sde/sde_encoder.h +++ b/msm/sde/sde_encoder.h @@ -194,6 +194,8 @@ struct sde_encoder_ops { * of esd attack to ensure esd workqueue detects * the previous frame transfer completion before * next update is triggered. + * @autorefresh_solver_disable It tracks if solver state is disabled from this + * encoder due to autorefresh concurrency. */ struct sde_encoder_virt { struct drm_encoder base; @@ -262,6 +264,7 @@ struct sde_encoder_virt { struct cpumask valid_cpu_mask; struct msm_mode_info mode_info; bool delay_kickoff; + bool autorefresh_solver_disable; }; #define to_sde_encoder_virt(x) container_of(x, struct sde_encoder_virt, base) diff --git a/msm/sde/sde_encoder_phys_cmd.c b/msm/sde/sde_encoder_phys_cmd.c index 39d3ccc1c8..092a5a7e16 100644 --- a/msm/sde/sde_encoder_phys_cmd.c +++ b/msm/sde/sde_encoder_phys_cmd.c @@ -1184,10 +1184,7 @@ static bool sde_encoder_phys_cmd_is_autorefresh_enabled( ret = hw_pp->ops.get_autorefresh(hw_pp, &cfg); } - if (ret) - return false; - - return cfg.enable; + return ret ? false : cfg.enable; } static void sde_encoder_phys_cmd_connect_te( @@ -1308,6 +1305,7 @@ static void sde_encoder_phys_cmd_disable(struct sde_encoder_phys *phys_enc) phys_enc->hw_intf->ops.reset_counter(phys_enc->hw_intf); } + memset(&cmd_enc->autorefresh.cfg, 0, sizeof(struct sde_hw_autorefresh)); phys_enc->enable_state = SDE_ENC_DISABLED; }