diff --git a/msm/sde/sde_core_perf.c b/msm/sde/sde_core_perf.c index 69749a0468..257aac4fba 100644 --- a/msm/sde/sde_core_perf.c +++ b/msm/sde/sde_core_perf.c @@ -514,7 +514,7 @@ static void _sde_core_uidle_setup_cfg(struct sde_kms *kms, uidle->ops.set_uidle_ctl(uidle, &cfg); } -static void _sde_core_uidle_setup_ctl(struct drm_crtc *crtc, +void sde_core_perf_uidle_setup_ctl(struct drm_crtc *crtc, bool enable) { struct drm_encoder *drm_enc; @@ -544,7 +544,7 @@ static int _sde_core_perf_enable_uidle(struct sde_kms *kms, SDE_EVT32(uidle_state); _sde_core_uidle_setup_wd(kms, enable); _sde_core_uidle_setup_cfg(kms, uidle_state); - _sde_core_uidle_setup_ctl(crtc, enable); + sde_core_perf_uidle_setup_ctl(crtc, true); kms->perf.uidle_enabled = enable; @@ -599,7 +599,7 @@ void sde_core_perf_crtc_update_uidle(struct drm_crtc *crtc, struct drm_crtc *tmp_crtc; struct sde_kms *kms; enum sde_uidle_state uidle_status = UIDLE_STATE_FAL1_FAL10; - u32 fps; + u32 fps, num_crtc = 0; if (!crtc) { SDE_ERROR("invalid crtc\n"); @@ -627,6 +627,7 @@ void sde_core_perf_crtc_update_uidle(struct drm_crtc *crtc, if (_sde_core_perf_crtc_is_power_on(tmp_crtc)) { + num_crtc++; /* * If DFPS is enabled with VFP, SDE clock and * transfer time will get fixed at max FPS @@ -644,7 +645,7 @@ void sde_core_perf_crtc_update_uidle(struct drm_crtc *crtc, _sde_core_perf_is_cwb(tmp_crtc), uidle_status, uidle_crtc_status, enable); - if (_sde_core_perf_is_wb(tmp_crtc) || + if ((num_crtc > 1) || _sde_core_perf_is_wb(tmp_crtc) || _sde_core_perf_is_cwb(tmp_crtc) || !fps) { uidle_status = UIDLE_STATE_DISABLE; break; @@ -669,6 +670,8 @@ void sde_core_perf_crtc_update_uidle(struct drm_crtc *crtc, _sde_core_perf_enable_uidle(kms, crtc, enable ? uidle_status : UIDLE_STATE_DISABLE); + kms->perf.catalog->uidle_cfg.dirty = !enable; + /* If perf counters enabled, set them up now */ if (kms->catalog->uidle_cfg.debugfs_perf) _sde_core_perf_uidle_setup_cntr(kms, enable); diff --git a/msm/sde/sde_core_perf.h b/msm/sde/sde_core_perf.h index 884e0334ad..718a2729ce 100644 --- a/msm/sde/sde_core_perf.h +++ b/msm/sde/sde_core_perf.h @@ -147,6 +147,13 @@ void sde_core_perf_crtc_reserve_res(struct drm_crtc *crtc, u64 reserve_rate); */ void sde_core_perf_crtc_update_uidle(struct drm_crtc *crtc, bool enable); +/** + * sde_core_perf_uidle_setup_ctl - enable uidle DB control + * @crtc: Pointer to crtc + * @enable: enable/disable uidle DB + */ +void sde_core_perf_uidle_setup_ctl(struct drm_crtc *crtc, bool enable); + /** * sde_core_perf_destroy - destroy the given core performance context * @perf: Pointer to core performance context diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 5e024cb106..ec5b24b3f8 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -3599,8 +3599,13 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, _sde_crtc_dest_scaler_setup(crtc); sde_cp_crtc_apply_noise(crtc, old_state); - if (crtc->state->mode_changed) + if (crtc->state->mode_changed || sde_kms->perf.catalog->uidle_cfg.dirty) { sde_core_perf_crtc_update_uidle(crtc, true); + } else if (!test_bit(SDE_CRTC_DIRTY_UIDLE, &sde_crtc->revalidate_mask) && + sde_kms->perf.uidle_enabled) + sde_core_perf_uidle_setup_ctl(crtc, false); + + test_and_clear_bit(SDE_CRTC_DIRTY_UIDLE, &sde_crtc->revalidate_mask); /* * Since CP properties use AXI buffer to program the @@ -4317,6 +4322,7 @@ void sde_crtc_reset_sw_state(struct drm_crtc *crtc) /* mark other properties which need to be dirty for next update */ set_bit(SDE_CRTC_DIRTY_DIM_LAYERS, &sde_crtc->revalidate_mask); + set_bit(SDE_CRTC_DIRTY_UIDLE, &sde_crtc->revalidate_mask); if (cstate->num_ds_enabled) set_bit(SDE_CRTC_DIRTY_DEST_SCALER, cstate->dirty); } diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index 44d94ce990..09787a1c6f 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -444,6 +444,7 @@ enum sde_crtc_dirty_flags { SDE_CRTC_DIRTY_DEST_SCALER, SDE_CRTC_DIRTY_DIM_LAYERS, SDE_CRTC_NOISE_LAYER, + SDE_CRTC_DIRTY_UIDLE, SDE_CRTC_DIRTY_MAX, }; diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index eff6deaf85..9051f96420 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -1008,6 +1008,7 @@ struct sde_mdp_cfg { * logging * @debugfs_ctrl: uidle is enabled/disabled through debugfs * @perf_cntr_en: performance counters are enabled/disabled + * @dirty: dirty flag for uidle update */ struct sde_uidle_cfg { SDE_HW_BLK_INFO; @@ -1027,6 +1028,7 @@ struct sde_uidle_cfg { u32 debugfs_perf; bool debugfs_ctrl; bool perf_cntr_en; + bool dirty; }; /* struct sde_mdp_cfg : MDP TOP-BLK instance info