From 495a6a87319a11d54b82180be26f26ff8408991e Mon Sep 17 00:00:00 2001 From: Shamika Joshi Date: Wed, 11 Jan 2023 09:56:44 -0800 Subject: [PATCH] disp: msm: dsi: optimize wait time in DSI timing DB update Timing DB needs to be disabled after panel vnsyc. Update the wait time to reflect difference in line time between MDP and panel vsync. Change-Id: Ib5282d67995e8379ead928218f31a8f9fe7fa978 Signed-off-by: Shamika Joshi --- msm/dsi/dsi_ctrl.c | 11 +++++++++-- msm/dsi/dsi_ctrl.h | 3 ++- msm/dsi/dsi_drm.c | 9 ++++++--- msm/sde/sde_encoder.c | 21 ++++++++++++++++++++- msm/sde/sde_encoder.h | 9 ++++++++- msm/sde/sde_encoder_phys.h | 4 +++- msm/sde/sde_encoder_phys_vid.c | 6 +++++- 7 files changed, 53 insertions(+), 10 deletions(-) diff --git a/msm/dsi/dsi_ctrl.c b/msm/dsi/dsi_ctrl.c index 8aa33724ce..090d5d9d96 100644 --- a/msm/dsi/dsi_ctrl.c +++ b/msm/dsi/dsi_ctrl.c @@ -2516,13 +2516,14 @@ exit: * dsi_ctrl_timing_db_update() - update only controller Timing DB * @dsi_ctrl: DSI controller handle. * @enable: Enable/disable Timing DB register + * @pf_time_in_us: Programmable fetch time in micro-seconds * * Update timing db register value during dfps usecases * * Return: error code. */ int dsi_ctrl_timing_db_update(struct dsi_ctrl *dsi_ctrl, - bool enable) + bool enable, u32 pf_time_in_us) { int rc = 0; @@ -2550,7 +2551,13 @@ int dsi_ctrl_timing_db_update(struct dsi_ctrl *dsi_ctrl, * flush is after panel_vsync. So, added the recommended * delays after dfps update. */ - usleep_range(2000, 2010); + if (pf_time_in_us > 2000) { + DSI_CTRL_ERR(dsi_ctrl, "Programmable fetch time check failed, pf_time_in_us=%u\n", + pf_time_in_us); + pf_time_in_us = 2000; + } + + usleep_range(pf_time_in_us, pf_time_in_us + 10); dsi_ctrl->hw.ops.set_timing_db(&dsi_ctrl->hw, enable); diff --git a/msm/dsi/dsi_ctrl.h b/msm/dsi/dsi_ctrl.h index 858b712fbe..722024a760 100644 --- a/msm/dsi/dsi_ctrl.h +++ b/msm/dsi/dsi_ctrl.h @@ -412,13 +412,14 @@ int dsi_ctrl_update_host_config(struct dsi_ctrl *dsi_ctrl, * dsi_ctrl_timing_db_update() - update only controller Timing DB * @dsi_ctrl: DSI controller handle. * @enable: Enable/disable Timing DB register + * @pf_time_in_us: Programmable fetch time in micro-seconds * * Update timing db register value during dfps usecases * * Return: error code. */ int dsi_ctrl_timing_db_update(struct dsi_ctrl *dsi_ctrl, - bool enable); + bool enable, u32 pf_time_in_us); /** * dsi_ctrl_async_timing_update() - update only controller timing diff --git a/msm/dsi/dsi_drm.c b/msm/dsi/dsi_drm.c index 25db59db0b..4314d12928 100644 --- a/msm/dsi/dsi_drm.c +++ b/msm/dsi/dsi_drm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2016-2021, The Linux Foundation. All rights reserved. */ @@ -1292,6 +1292,7 @@ int dsi_conn_post_kickoff(struct drm_connector *connector, struct dsi_display *display; struct dsi_display_ctrl *m_ctrl, *ctrl; int i, rc = 0, ctrl_version; + u32 pf_time_in_us = 0; bool enable; struct dsi_dyn_clk_caps *dyn_clk_caps; @@ -1316,10 +1317,12 @@ int dsi_conn_post_kickoff(struct drm_connector *connector, display = c_bridge->display; dyn_clk_caps = &(display->panel->dyn_clk_caps); + pf_time_in_us = sde_encoder_get_programmed_fetch_time(encoder); + if (adj_mode.dsi_mode_flags & DSI_MODE_FLAG_VRR) { m_ctrl = &display->ctrl[display->clk_master_idx]; ctrl_version = m_ctrl->ctrl->version; - rc = dsi_ctrl_timing_db_update(m_ctrl->ctrl, false); + rc = dsi_ctrl_timing_db_update(m_ctrl->ctrl, false, pf_time_in_us); if (rc) { DSI_ERR("[%s] failed to dfps update rc=%d\n", display->name, rc); @@ -1354,7 +1357,7 @@ int dsi_conn_post_kickoff(struct drm_connector *connector, if (!ctrl->ctrl || (ctrl == m_ctrl)) continue; - rc = dsi_ctrl_timing_db_update(ctrl->ctrl, false); + rc = dsi_ctrl_timing_db_update(ctrl->ctrl, false, pf_time_in_us); if (rc) { DSI_ERR("[%s] failed to dfps update rc=%d\n", display->name, rc); diff --git a/msm/sde/sde_encoder.c b/msm/sde/sde_encoder.c index d17b7f7ba6..83732c5724 100644 --- a/msm/sde/sde_encoder.c +++ b/msm/sde/sde_encoder.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2014-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -155,6 +155,25 @@ void sde_encoder_uidle_enable(struct drm_encoder *drm_enc, bool enable) } } +u32 sde_encoder_get_programmed_fetch_time(struct drm_encoder *drm_enc) +{ + struct sde_encoder_virt *sde_enc; + struct sde_encoder_phys *phys; + bool is_vid; + + sde_enc = to_sde_encoder_virt(drm_enc); + + if (!sde_enc || !sde_enc->phys_encs[0]) { + SDE_ERROR("invalid params\n"); + return U32_MAX; + } + + phys = sde_enc->phys_encs[0]; + is_vid = sde_encoder_check_curr_mode(drm_enc, MSM_DISPLAY_VIDEO_MODE); + + return is_vid ? phys->pf_time_in_us : 0; +} + ktime_t sde_encoder_calc_last_vsync_timestamp(struct drm_encoder *drm_enc) { struct sde_encoder_virt *sde_enc; diff --git a/msm/sde/sde_encoder.h b/msm/sde/sde_encoder.h index 9a1c9e2f15..264f1f285d 100644 --- a/msm/sde/sde_encoder.h +++ b/msm/sde/sde_encoder.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. * Copyright (C) 2013 Red Hat * Author: Rob Clark @@ -704,6 +704,13 @@ bool sde_encoder_is_line_insertion_supported(struct drm_encoder *drm_enc); */ struct sde_hw_ctl *sde_encoder_get_hw_ctl(struct sde_connector *c_conn); +/* + * sde_encoder_get_programmed_fetch_time - gets the programmable fetch time for video encoders + * @drm_enc: Pointer to drm encoder structure + * @Return: programmable fetch time in microseconds + */ +u32 sde_encoder_get_programmed_fetch_time(struct drm_encoder *encoder); + void sde_encoder_add_data_to_minidump_va(struct drm_encoder *drm_enc); /** diff --git a/msm/sde/sde_encoder_phys.h b/msm/sde/sde_encoder_phys.h index e58df1cbc4..416d55edb5 100644 --- a/msm/sde/sde_encoder_phys.h +++ b/msm/sde/sde_encoder_phys.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -316,6 +316,7 @@ struct sde_encoder_irq { * @in_clone_mode Indicates if encoder is in clone mode ref@CWB * @vfp_cached: cached vertical front porch to be used for * programming ROT and MDP fetch start + * @pf_time_in_us: Programmable fetch time in micro-seconds * @frame_trigger_mode: frame trigger mode indication for command * mode display * @recovered: flag set to true when recovered from pp timeout @@ -366,6 +367,7 @@ struct sde_encoder_phys { bool cont_splash_enabled; bool in_clone_mode; int vfp_cached; + u32 pf_time_in_us; enum frame_trigger_mode_type frame_trigger_mode; bool recovered; bool autorefresh_disable_trans; diff --git a/msm/sde/sde_encoder_phys_vid.c b/msm/sde/sde_encoder_phys_vid.c index ba4c46aef0..926336c87b 100644 --- a/msm/sde/sde_encoder_phys_vid.c +++ b/msm/sde/sde_encoder_phys_vid.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2021-2022 Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. */ @@ -283,6 +283,7 @@ static void programmable_fetch_config(struct sde_encoder_phys *phys_enc, m = phys_enc->sde_kms->catalog; + phys_enc->pf_time_in_us = 0; vfp_fetch_lines = programmable_fetch_get_num_lines(vid_enc, timing); if (vfp_fetch_lines) { vert_total = get_vertical_total(timing); @@ -290,6 +291,9 @@ static void programmable_fetch_config(struct sde_encoder_phys *phys_enc, vfp_fetch_start_vsync_counter = (vert_total - vfp_fetch_lines) * horiz_total + 1; + phys_enc->pf_time_in_us = DIV_ROUND_UP(1000000 * vfp_fetch_lines, + vert_total * timing->vrefresh); + /** * Check if we need to throttle the fetch to start * from second line after the active region.