Merge "disp: msm: dsi: optimize wait time in DSI timing DB update"

This commit is contained in:
qctecmdr
2023-01-29 22:32:25 -08:00
committed by Gerrit - the friendly Code Review server
7 changed files with 49 additions and 6 deletions

View File

@@ -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);

View File

@@ -414,13 +414,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

View File

@@ -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);

View File

@@ -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;

View File

@@ -716,6 +716,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);
/**

View File

@@ -335,6 +335,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
@@ -385,6 +386,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;

View File

@@ -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.