diff --git a/msm/sde/sde_core_perf.c b/msm/sde/sde_core_perf.c index 02d992d06fb3..91c52867ed16 100644 --- a/msm/sde/sde_core_perf.c +++ b/msm/sde/sde_core_perf.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ @@ -494,7 +494,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_uidle_setup_ctl(struct drm_crtc *crtc, bool enable) { struct drm_encoder *drm_enc; @@ -522,7 +522,7 @@ static int _sde_core_perf_enable_uidle(struct sde_kms *kms, SDE_EVT32(enable); _sde_core_uidle_setup_wd(kms, enable); _sde_core_uidle_setup_cfg(kms, enable); - _sde_core_uidle_setup_ctl(crtc, enable); + sde_core_uidle_setup_ctl(crtc, true); kms->perf.uidle_enabled = enable; @@ -577,7 +577,7 @@ void sde_core_perf_crtc_update_uidle(struct drm_crtc *crtc, struct drm_crtc *tmp_crtc; struct sde_kms *kms; bool disable_uidle = false; - u32 fps; + u32 fps, num_crtc = 0; if (!crtc) { SDE_ERROR("invalid crtc\n"); @@ -603,6 +603,7 @@ void sde_core_perf_crtc_update_uidle(struct drm_crtc *crtc, drm_for_each_crtc(tmp_crtc, crtc->dev) { 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 @@ -620,7 +621,7 @@ void sde_core_perf_crtc_update_uidle(struct drm_crtc *crtc, _sde_core_perf_is_cwb(tmp_crtc), disable_uidle, 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 || fps > kms->perf.catalog->uidle_cfg.max_fps)) { disable_uidle = true; @@ -632,6 +633,8 @@ void sde_core_perf_crtc_update_uidle(struct drm_crtc *crtc, _sde_core_perf_enable_uidle(kms, crtc, (enable && !disable_uidle) ? true : false); + 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 8e9ac9b79547..ba51bbce92c3 100644 --- a/msm/sde/sde_core_perf.h +++ b/msm/sde/sde_core_perf.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2016-2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ #ifndef _SDE_CORE_PERF_H_ @@ -138,6 +138,13 @@ void sde_core_perf_crtc_release_bw(struct drm_crtc *crtc); */ void sde_core_perf_crtc_update_uidle(struct drm_crtc *crtc, bool enable); +/** + * sde_core_uidle_setup_ctl - enable uidle DB control + * @crtc: Pointer to crtc + * @enable: enable/disable uidle DB + */ +void sde_core_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 61b5c692ec85..e6811e616a58 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -3322,8 +3322,13 @@ static void sde_crtc_atomic_begin(struct drm_crtc *crtc, _sde_crtc_blend_setup(crtc, old_state, true); _sde_crtc_dest_scaler_setup(crtc); - 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_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 @@ -3994,6 +3999,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 e5b924dba454..43db78485c69 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -399,6 +399,7 @@ struct sde_crtc { enum sde_crtc_dirty_flags { SDE_CRTC_DIRTY_DEST_SCALER, SDE_CRTC_DIRTY_DIM_LAYERS, + SDE_CRTC_DIRTY_UIDLE, SDE_CRTC_DIRTY_MAX, }; diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index 9cb8fc2c9229..2f4ccf9ae938 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -141,7 +141,6 @@ void sde_encoder_uidle_enable(struct drm_encoder *drm_enc, bool enable) struct sde_encoder_phys *phys = sde_enc->phys_encs[i]; if (phys && phys->hw_ctl && phys->hw_ctl->ops.uidle_enable) { - SDE_EVT32(DRMID(drm_enc), enable); phys->hw_ctl->ops.uidle_enable(phys->hw_ctl, enable); } } diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index 3e7ab2ad90d2..bbe785d87754 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -938,6 +938,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