From d9f194e6f733fca6ada5572a6b37176002618752 Mon Sep 17 00:00:00 2001 From: Dhaval Patel Date: Wed, 7 Oct 2020 22:44:53 -0700 Subject: [PATCH] disp: msm: sde: avoid tx wait during cwb disable and reset Avoid TX wait during CWB encoder disable and delay reset call after last CWB frame trigger. Change-Id: I9f96d522cfe4205e0272b6b3fa9edd409cab3648 Signed-off-by: Dhaval Patel --- msm/sde/sde_encoder.c | 51 +++++++++++++++++++++-------------- msm/sde/sde_encoder.h | 6 +++++ msm/sde/sde_encoder_phys_wb.c | 5 +++- msm/sde/sde_kms.c | 15 ++++++++--- 4 files changed, 53 insertions(+), 24 deletions(-) diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 7633a3af8b..24227c0b6e 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -2785,6 +2785,33 @@ static void sde_encoder_virt_enable(struct drm_encoder *drm_enc) _sde_encoder_virt_enable_helper(drm_enc); } +void sde_encoder_virt_reset(struct drm_encoder *drm_enc) +{ + struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(drm_enc); + struct sde_kms *sde_kms = sde_encoder_get_kms(drm_enc); + int i = 0; + + for (i = 0; i < sde_enc->num_phys_encs; i++) { + if (sde_enc->phys_encs[i]) { + sde_enc->phys_encs[i]->cont_splash_enabled = false; + sde_enc->phys_encs[i]->connector = NULL; + } + atomic_set(&sde_enc->frame_done_cnt[i], 0); + } + + sde_enc->cur_master = NULL; + /* + * clear the cached crtc in sde_enc on use case finish, after all the + * outstanding events and timers have been completed + */ + sde_enc->crtc = NULL; + memset(&sde_enc->mode_info, 0, sizeof(sde_enc->mode_info)); + + SDE_DEBUG_ENC(sde_enc, "encoder disabled\n"); + + sde_rm_release(&sde_kms->rm, drm_enc, false); +} + static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc = NULL; @@ -2820,7 +2847,8 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) SDE_EVT32(DRMID(drm_enc)); /* wait for idle */ - sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE); + if (!sde_encoder_in_clone_mode(drm_enc)) + sde_encoder_wait_for_event(drm_enc, MSM_ENC_TX_COMPLETE); _sde_encoder_input_handler_unregister(drm_enc); @@ -2864,25 +2892,8 @@ static void sde_encoder_virt_disable(struct drm_encoder *drm_enc) sde_encoder_resource_control(drm_enc, SDE_ENC_RC_EVENT_STOP); - for (i = 0; i < sde_enc->num_phys_encs; i++) { - if (sde_enc->phys_encs[i]) { - sde_enc->phys_encs[i]->cont_splash_enabled = false; - sde_enc->phys_encs[i]->connector = NULL; - } - atomic_set(&sde_enc->frame_done_cnt[i], 0); - } - - sde_enc->cur_master = NULL; - /* - * clear the cached crtc in sde_enc on use case finish, after all the - * outstanding events and timers have been completed - */ - sde_enc->crtc = NULL; - memset(&sde_enc->mode_info, 0, sizeof(sde_enc->mode_info)); - - SDE_DEBUG_ENC(sde_enc, "encoder disabled\n"); - - sde_rm_release(&sde_kms->rm, drm_enc, false); + if (!sde_encoder_in_clone_mode(drm_enc)) + sde_encoder_virt_reset(drm_enc); } void sde_encoder_helper_phys_disable(struct sde_encoder_phys *phys_enc, diff --git a/msm/sde/sde_encoder.h b/msm/sde/sde_encoder.h index 17aec63fcd..24f66221de 100644 --- a/msm/sde/sde_encoder.h +++ b/msm/sde/sde_encoder.h @@ -573,6 +573,12 @@ static inline u32 sde_encoder_get_dfps_maxfps(struct drm_encoder *drm_enc) return sde_enc->mode_info.dfps_maxfps; } +/** + * sde_encoder_virt_reset - delay encoder virt reset + * @drm_enc: Pointer to drm encoder structure + */ +void sde_encoder_virt_reset(struct drm_encoder *drm_enc); + /** * sde_encoder_get_kms - retrieve the kms from encoder * @drm_enc: Pointer to drm encoder structure diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index 4de9be9b7a..77fe857549 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -1390,6 +1390,7 @@ static int sde_encoder_phys_wb_wait_for_commit_done( phys_enc->in_clone_mode) { rc = _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, true); _sde_encoder_phys_wb_reset_state(phys_enc); + sde_encoder_phys_wb_irq_ctrl(phys_enc, false); } else { rc = _sde_encoder_phys_wb_wait_for_commit_done(phys_enc, false); } @@ -1676,8 +1677,10 @@ static void sde_encoder_phys_wb_disable(struct sde_encoder_phys *phys_enc) _sde_encoder_phys_wb_update_cwb_flush(phys_enc, false); phys_enc->enable_state = SDE_ENC_DISABLING; - if (wb_enc->crtc->state->active) + if (wb_enc->crtc->state->active) { + sde_encoder_phys_wb_irq_ctrl(phys_enc, true); return; + } goto exit; } diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 239e5dfb59..a68de1763b 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -1532,6 +1532,7 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms, struct drm_encoder *encoder; struct drm_device *dev; int ret; + bool cwb_disabling; if (!kms || !crtc || !crtc->state) { SDE_ERROR("invalid params\n"); @@ -1557,9 +1558,14 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms, SDE_ATRACE_BEGIN("sde_kms_wait_for_commit_done"); list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { - if (encoder->crtc != crtc && - !sde_encoder_is_cwb_disabling(encoder, crtc)) - continue; + cwb_disabling = false; + if (encoder->crtc != crtc) { + cwb_disabling = sde_encoder_is_cwb_disabling(encoder, + crtc); + if (!cwb_disabling) + continue; + } + /* * Wait for post-flush if necessary to delay before * plane_cleanup. For example, wait for vsync in case of video @@ -1574,6 +1580,9 @@ static void sde_kms_wait_for_commit_done(struct msm_kms *kms, } sde_crtc_complete_flip(crtc, NULL); + + if (cwb_disabling) + sde_encoder_virt_reset(encoder); } sde_crtc_static_cache_read_kickoff(crtc);