diff --git a/msm/dsi/dsi_drm.c b/msm/dsi/dsi_drm.c index 3db7b37c0d..71aa22a482 100644 --- a/msm/dsi/dsi_drm.c +++ b/msm/dsi/dsi_drm.c @@ -439,6 +439,28 @@ static bool dsi_bridge_mode_fixup(struct drm_bridge *bridge, return true; } +u32 dsi_drm_get_dfps_maxfps(void *display) +{ + u32 dfps_maxfps = 0; + struct dsi_display *dsi_display = display; + + /* + * The time of SDE transmitting one frame active data + * will not be changed, if frame rate is adjusted with + * VFP method. + * So only return max fps of DFPS for UIDLE update, if DFPS + * is enabled with VFP. + */ + if (dsi_display && dsi_display->panel && + dsi_display->panel->panel_mode == DSI_OP_VIDEO_MODE && + dsi_display->panel->dfps_caps.type == + DSI_DFPS_IMMEDIATE_VFP) + dfps_maxfps = + dsi_display->panel->dfps_caps.max_refresh_rate; + + return dfps_maxfps; +} + u64 dsi_drm_find_bit_clk_rate(void *display, const struct drm_display_mode *drm_mode) { @@ -492,6 +514,7 @@ int dsi_conn_get_mode_info(struct drm_connector *connector, mode_info->jitter_numer = dsi_mode.priv_info->panel_jitter_numer; mode_info->jitter_denom = dsi_mode.priv_info->panel_jitter_denom; mode_info->clk_rate = dsi_drm_find_bit_clk_rate(display, drm_mode); + mode_info->dfps_maxfps = dsi_drm_get_dfps_maxfps(display); mode_info->mdp_transfer_time_us = dsi_mode.priv_info->mdp_transfer_time_us; diff --git a/msm/msm_drv.h b/msm/msm_drv.h index 3694fd54f3..eef1bd5f44 100644 --- a/msm/msm_drv.h +++ b/msm/msm_drv.h @@ -675,6 +675,7 @@ struct msm_display_topology { * @jitter_numer: display panel jitter numerator configuration * @jitter_denom: display panel jitter denominator configuration * @clk_rate: DSI bit clock per lane in HZ. + * @dfps_maxfps: max FPS of dynamic FPS * @topology: supported topology for the mode * @comp_info: compression info supported * @roi_caps: panel roi capabilities @@ -689,6 +690,7 @@ struct msm_mode_info { uint32_t jitter_numer; uint32_t jitter_denom; uint64_t clk_rate; + uint32_t dfps_maxfps; struct msm_display_topology topology; struct msm_compression_info comp_info; struct msm_roi_caps roi_caps; diff --git a/msm/sde/sde_core_perf.c b/msm/sde/sde_core_perf.c index 2b539de2cb..ce3156f135 100644 --- a/msm/sde/sde_core_perf.c +++ b/msm/sde/sde_core_perf.c @@ -603,7 +603,16 @@ 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)) { - fps = sde_crtc_get_fps_mode(tmp_crtc); + /* + * If DFPS is enabled with VFP, SDE clock and + * transfer time will get fixed at max FPS + * configuration of DFPS. + * So get the max FPS of DFPS firstly for + * UIDLE update, if DFPS is enabled with VFP. + */ + fps = sde_crtc_get_dfps_maxfps(tmp_crtc); + if (!fps) + fps = sde_crtc_get_fps_mode(tmp_crtc); SDE_DEBUG("crtc=%d fps:%d wb:%d cwb:%d dis:%d en:%d\n", tmp_crtc->base.id, fps, diff --git a/msm/sde/sde_crtc.c b/msm/sde/sde_crtc.c index 0bc2ea80de..0fda0a6371 100644 --- a/msm/sde/sde_crtc.c +++ b/msm/sde/sde_crtc.c @@ -2375,6 +2375,24 @@ u32 sde_crtc_get_fps_mode(struct drm_crtc *crtc) return 0; } +u32 sde_crtc_get_dfps_maxfps(struct drm_crtc *crtc) +{ + struct drm_encoder *encoder; + + if (!crtc || !crtc->dev) { + SDE_ERROR("invalid crtc\n"); + return 0; + } + + drm_for_each_encoder_mask(encoder, crtc->dev, + crtc->state->encoder_mask) { + if (!sde_encoder_in_cont_splash(encoder)) + return sde_encoder_get_dfps_maxfps(encoder); + } + + return 0; +} + static void sde_crtc_vblank_cb(void *data) { struct drm_crtc *crtc = (struct drm_crtc *)data; diff --git a/msm/sde/sde_crtc.h b/msm/sde/sde_crtc.h index 2b2cf24d51..0cb06d6977 100644 --- a/msm/sde/sde_crtc.h +++ b/msm/sde/sde_crtc.h @@ -652,6 +652,12 @@ enum sde_intf_mode sde_crtc_get_intf_mode(struct drm_crtc *crtc, */ u32 sde_crtc_get_fps_mode(struct drm_crtc *crtc); +/** + * sde_crtc_get_dfps_maxfps - get DFPS max fps of the given crtc + * @crtc: Pointert to crtc + */ +u32 sde_crtc_get_dfps_maxfps(struct drm_crtc *crtc); + /** * sde_crtc_get_client_type - check the crtc type- rt, rsc_rt, etc. * @crtc: Pointer to crtc diff --git a/msm/sde/sde_encoder.h b/msm/sde/sde_encoder.h index 504094fffc..bdc8fadd00 100644 --- a/msm/sde/sde_encoder.h +++ b/msm/sde/sde_encoder.h @@ -545,6 +545,25 @@ void sde_encoder_uidle_enable(struct drm_encoder *drm_enc, bool enable); */ void sde_encoder_irq_control(struct drm_encoder *drm_enc, bool enable); +/* + * sde_encoder_get_dfps_maxfps - get dynamic FPS max frame rate of + the given encoder + * @encoder: Pointer to drm encoder object + */ +static inline u32 sde_encoder_get_dfps_maxfps(struct drm_encoder *drm_enc) +{ + struct sde_encoder_virt *sde_enc; + + if (!drm_enc) { + SDE_ERROR("invalid encoder\n"); + return 0; + } + + sde_enc = to_sde_encoder_virt(drm_enc); + + return sde_enc->mode_info.dfps_maxfps; +} + /** * sde_encoder_get_kms - retrieve the kms from encoder * @drm_enc: Pointer to drm encoder structure