Merge "disp: msm: dsi: optimize wait time in DSI timing DB update"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
76cbb717c4
@@ -2516,13 +2516,14 @@ exit:
|
|||||||
* dsi_ctrl_timing_db_update() - update only controller Timing DB
|
* dsi_ctrl_timing_db_update() - update only controller Timing DB
|
||||||
* @dsi_ctrl: DSI controller handle.
|
* @dsi_ctrl: DSI controller handle.
|
||||||
* @enable: Enable/disable Timing DB register
|
* @enable: Enable/disable Timing DB register
|
||||||
|
* @pf_time_in_us: Programmable fetch time in micro-seconds
|
||||||
*
|
*
|
||||||
* Update timing db register value during dfps usecases
|
* Update timing db register value during dfps usecases
|
||||||
*
|
*
|
||||||
* Return: error code.
|
* Return: error code.
|
||||||
*/
|
*/
|
||||||
int dsi_ctrl_timing_db_update(struct dsi_ctrl *dsi_ctrl,
|
int dsi_ctrl_timing_db_update(struct dsi_ctrl *dsi_ctrl,
|
||||||
bool enable)
|
bool enable, u32 pf_time_in_us)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
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
|
* flush is after panel_vsync. So, added the recommended
|
||||||
* delays after dfps update.
|
* 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);
|
dsi_ctrl->hw.ops.set_timing_db(&dsi_ctrl->hw, enable);
|
||||||
|
|
||||||
|
@@ -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_timing_db_update() - update only controller Timing DB
|
||||||
* @dsi_ctrl: DSI controller handle.
|
* @dsi_ctrl: DSI controller handle.
|
||||||
* @enable: Enable/disable Timing DB register
|
* @enable: Enable/disable Timing DB register
|
||||||
|
* @pf_time_in_us: Programmable fetch time in micro-seconds
|
||||||
*
|
*
|
||||||
* Update timing db register value during dfps usecases
|
* Update timing db register value during dfps usecases
|
||||||
*
|
*
|
||||||
* Return: error code.
|
* Return: error code.
|
||||||
*/
|
*/
|
||||||
int dsi_ctrl_timing_db_update(struct dsi_ctrl *dsi_ctrl,
|
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
|
* dsi_ctrl_async_timing_update() - update only controller timing
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// 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.
|
* 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 *display;
|
||||||
struct dsi_display_ctrl *m_ctrl, *ctrl;
|
struct dsi_display_ctrl *m_ctrl, *ctrl;
|
||||||
int i, rc = 0, ctrl_version;
|
int i, rc = 0, ctrl_version;
|
||||||
|
u32 pf_time_in_us = 0;
|
||||||
bool enable;
|
bool enable;
|
||||||
struct dsi_dyn_clk_caps *dyn_clk_caps;
|
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;
|
display = c_bridge->display;
|
||||||
dyn_clk_caps = &(display->panel->dyn_clk_caps);
|
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) {
|
if (adj_mode.dsi_mode_flags & DSI_MODE_FLAG_VRR) {
|
||||||
m_ctrl = &display->ctrl[display->clk_master_idx];
|
m_ctrl = &display->ctrl[display->clk_master_idx];
|
||||||
ctrl_version = m_ctrl->ctrl->version;
|
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) {
|
if (rc) {
|
||||||
DSI_ERR("[%s] failed to dfps update rc=%d\n",
|
DSI_ERR("[%s] failed to dfps update rc=%d\n",
|
||||||
display->name, rc);
|
display->name, rc);
|
||||||
@@ -1354,7 +1357,7 @@ int dsi_conn_post_kickoff(struct drm_connector *connector,
|
|||||||
if (!ctrl->ctrl || (ctrl == m_ctrl))
|
if (!ctrl->ctrl || (ctrl == m_ctrl))
|
||||||
continue;
|
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) {
|
if (rc) {
|
||||||
DSI_ERR("[%s] failed to dfps update rc=%d\n",
|
DSI_ERR("[%s] failed to dfps update rc=%d\n",
|
||||||
display->name, rc);
|
display->name, rc);
|
||||||
|
@@ -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)
|
ktime_t sde_encoder_calc_last_vsync_timestamp(struct drm_encoder *drm_enc)
|
||||||
{
|
{
|
||||||
struct sde_encoder_virt *sde_enc;
|
struct sde_encoder_virt *sde_enc;
|
||||||
|
@@ -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);
|
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);
|
void sde_encoder_add_data_to_minidump_va(struct drm_encoder *drm_enc);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -335,6 +335,7 @@ struct sde_encoder_irq {
|
|||||||
* @in_clone_mode Indicates if encoder is in clone mode ref@CWB
|
* @in_clone_mode Indicates if encoder is in clone mode ref@CWB
|
||||||
* @vfp_cached: cached vertical front porch to be used for
|
* @vfp_cached: cached vertical front porch to be used for
|
||||||
* programming ROT and MDP fetch start
|
* 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
|
* @frame_trigger_mode: frame trigger mode indication for command
|
||||||
* mode display
|
* mode display
|
||||||
* @recovered: flag set to true when recovered from pp timeout
|
* @recovered: flag set to true when recovered from pp timeout
|
||||||
@@ -385,6 +386,7 @@ struct sde_encoder_phys {
|
|||||||
bool cont_splash_enabled;
|
bool cont_splash_enabled;
|
||||||
bool in_clone_mode;
|
bool in_clone_mode;
|
||||||
int vfp_cached;
|
int vfp_cached;
|
||||||
|
u32 pf_time_in_us;
|
||||||
enum frame_trigger_mode_type frame_trigger_mode;
|
enum frame_trigger_mode_type frame_trigger_mode;
|
||||||
bool recovered;
|
bool recovered;
|
||||||
bool autorefresh_disable_trans;
|
bool autorefresh_disable_trans;
|
||||||
|
@@ -283,6 +283,7 @@ static void programmable_fetch_config(struct sde_encoder_phys *phys_enc,
|
|||||||
|
|
||||||
m = phys_enc->sde_kms->catalog;
|
m = phys_enc->sde_kms->catalog;
|
||||||
|
|
||||||
|
phys_enc->pf_time_in_us = 0;
|
||||||
vfp_fetch_lines = programmable_fetch_get_num_lines(vid_enc, timing);
|
vfp_fetch_lines = programmable_fetch_get_num_lines(vid_enc, timing);
|
||||||
if (vfp_fetch_lines) {
|
if (vfp_fetch_lines) {
|
||||||
vert_total = get_vertical_total(timing);
|
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 =
|
vfp_fetch_start_vsync_counter =
|
||||||
(vert_total - vfp_fetch_lines) * horiz_total + 1;
|
(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
|
* Check if we need to throttle the fetch to start
|
||||||
* from second line after the active region.
|
* from second line after the active region.
|
||||||
|
Reference in New Issue
Block a user