disp: msm: expose qsync avr step as part of conn mode caps
Add capability to read avr step for each timing mode. This will be in addition to the existing avr-step-list which is defined when dfps is enabled. Expose the avr-step as part of each mode in connector caps to user-mode. Additionally, change the avr_step connector property to enum to give usermode just the capability to enable/disable avr-step and not alter the step value as its fixed from the device tree. Change-Id: I6d7f8e9fcf03f98abef7640fc741e5e1be8597a1 Signed-off-by: Veera Sundaram Sankaran <quic_veeras@quicinc.com>
This commit is contained in:
@@ -418,7 +418,8 @@ struct dsi_panel_cmd_set {
|
||||
* @vdc: VDC compression configuration.
|
||||
* @pclk_scale: pclk scale factor, target bpp to source bpp
|
||||
* @roi_caps: Panel ROI capabilities.
|
||||
* @qsync_min_fps: Qsync min fps rate
|
||||
* @qsync_min_fps: Qsync min fps rate
|
||||
* @avr_step_fps: AVR step fps rate
|
||||
*/
|
||||
struct dsi_mode_info {
|
||||
u32 h_active;
|
||||
@@ -446,6 +447,7 @@ struct dsi_mode_info {
|
||||
struct msm_ratio pclk_scale;
|
||||
struct msm_roi_caps roi_caps;
|
||||
u32 qsync_min_fps;
|
||||
u32 avr_step_fps;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -625,6 +627,7 @@ struct dsi_host_config {
|
||||
* for command mode panels in microseconds.
|
||||
* @dsi_transfer_time_us: Specifies the dsi transfer time for cmd panels.
|
||||
* @qsync_min_fps: Qsync min fps value for the mode
|
||||
* @avr_step_fps: AVR step fps value for the mode
|
||||
* @clk_rate_hz: DSI bit clock per lane in hz.
|
||||
* @min_dsi_clk_hz: Min dsi clk per lane to transfer frame in vsync time.
|
||||
* @bit_clk_list: List of dynamic bit clock rates supported.
|
||||
@@ -654,6 +657,7 @@ struct dsi_display_mode_priv_info {
|
||||
u32 mdp_transfer_time_us_max;
|
||||
u32 dsi_transfer_time_us;
|
||||
u32 qsync_min_fps;
|
||||
u32 avr_step_fps;
|
||||
u64 clk_rate_hz;
|
||||
u64 min_dsi_clk_hz;
|
||||
struct msm_dyn_clk_list bit_clk_list;
|
||||
|
@@ -6754,7 +6754,7 @@ int dsi_display_get_info(struct drm_connector *connector,
|
||||
info->max_height = 1080;
|
||||
info->qsync_min_fps = display->panel->qsync_caps.qsync_min_fps;
|
||||
info->has_qsync_min_fps_list = (display->panel->qsync_caps.qsync_min_fps_list_len > 0);
|
||||
info->has_avr_step_req = (display->panel->avr_caps.avr_step_fps_list_len > 0);
|
||||
info->avr_step_fps = display->panel->avr_caps.avr_step_fps;
|
||||
info->poms_align_vsync = display->panel->poms_align_vsync;
|
||||
|
||||
switch (display->panel->panel_mode) {
|
||||
@@ -7040,7 +7040,7 @@ void dsi_display_put_mode(struct dsi_display *display,
|
||||
int dsi_display_get_modes_helper(struct dsi_display *display,
|
||||
struct dsi_display_ctrl *ctrl, u32 timing_mode_count,
|
||||
struct dsi_dfps_capabilities dfps_caps, struct dsi_qsync_capabilities *qsync_caps,
|
||||
struct dsi_dyn_clk_caps *dyn_clk_caps)
|
||||
struct dsi_dyn_clk_caps *dyn_clk_caps, struct dsi_avr_capabilities *avr_caps)
|
||||
{
|
||||
int dsc_modes = 0, nondsc_modes = 0, rc = 0, i, start, end;
|
||||
u32 num_dfps_rates, mode_idx, sublinks_count, array_idx = 0;
|
||||
@@ -7143,6 +7143,10 @@ int dsi_display_get_modes_helper(struct dsi_display *display,
|
||||
if (!sub_mode->timing.qsync_min_fps && qsync_caps->qsync_min_fps)
|
||||
sub_mode->timing.qsync_min_fps = qsync_caps->qsync_min_fps;
|
||||
|
||||
/* populate avr step fps, same way as qsync min fps */
|
||||
if (!sub_mode->timing.avr_step_fps && avr_caps->avr_step_fps)
|
||||
sub_mode->timing.avr_step_fps = avr_caps->avr_step_fps;
|
||||
|
||||
/*
|
||||
* Qsync min fps for the mode will be populated in the timing info
|
||||
* in dsi_panel_get_mode function.
|
||||
@@ -7175,6 +7179,12 @@ int dsi_display_get_modes_helper(struct dsi_display *display,
|
||||
sub_mode->priv_info->qsync_min_fps = sub_mode->timing.qsync_min_fps;
|
||||
}
|
||||
|
||||
/* Override with avr step fps list in dfps usecases */
|
||||
if (avr_caps->avr_step_fps_list_len) {
|
||||
sub_mode->timing.avr_step_fps = avr_caps->avr_step_fps_list[i];
|
||||
sub_mode->priv_info->avr_step_fps = sub_mode->timing.avr_step_fps;
|
||||
}
|
||||
|
||||
dsi_display_get_dfps_timing(display, sub_mode,
|
||||
curr_refresh_rate);
|
||||
sub_mode->panel_mode_caps = DSI_OP_VIDEO_MODE;
|
||||
@@ -7215,6 +7225,7 @@ int dsi_display_get_modes(struct dsi_display *display,
|
||||
struct dsi_dyn_clk_caps *dyn_clk_caps;
|
||||
int rc = -EINVAL;
|
||||
struct dsi_qsync_capabilities *qsync_caps;
|
||||
struct dsi_avr_capabilities *avr_caps;
|
||||
|
||||
if (!display || !out_modes) {
|
||||
DSI_ERR("Invalid params\n");
|
||||
@@ -7247,6 +7258,7 @@ int dsi_display_get_modes(struct dsi_display *display,
|
||||
|
||||
qsync_caps = &(display->panel->qsync_caps);
|
||||
dyn_clk_caps = &(display->panel->dyn_clk_caps);
|
||||
avr_caps = &(display->panel->avr_caps);
|
||||
|
||||
timing_mode_count = display->panel->num_timing_nodes;
|
||||
|
||||
@@ -7256,7 +7268,7 @@ int dsi_display_get_modes(struct dsi_display *display,
|
||||
display->cmdline_timing = NO_OVERRIDE;
|
||||
|
||||
rc = dsi_display_get_modes_helper(display, ctrl, timing_mode_count,
|
||||
dfps_caps, qsync_caps, dyn_clk_caps);
|
||||
dfps_caps, qsync_caps, dyn_clk_caps, avr_caps);
|
||||
if (rc)
|
||||
goto error;
|
||||
|
||||
@@ -7353,31 +7365,6 @@ int dsi_display_get_default_lms(void *dsi_display, u32 *num_lm)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int dsi_display_get_avr_step_req_fps(void *display_dsi, u32 mode_fps)
|
||||
{
|
||||
struct dsi_display *display = (struct dsi_display *)display_dsi;
|
||||
struct dsi_panel *panel;
|
||||
u32 i, step = 0;
|
||||
|
||||
if (!display || !display->panel)
|
||||
return -EINVAL;
|
||||
|
||||
panel = display->panel;
|
||||
|
||||
/* support a single fixed rate, or rate corresponding to dfps list entry */
|
||||
if (panel->avr_caps.avr_step_fps_list_len == 1) {
|
||||
step = panel->avr_caps.avr_step_fps_list[0];
|
||||
} else if (panel->avr_caps.avr_step_fps_list_len > 1) {
|
||||
for (i = 0; i < panel->dfps_caps.dfps_list_len; i++) {
|
||||
if (panel->dfps_caps.dfps_list[i] == mode_fps)
|
||||
step = panel->avr_caps.avr_step_fps_list[i];
|
||||
}
|
||||
}
|
||||
|
||||
DSI_DEBUG("mode_fps %u, avr_step fps %u\n", mode_fps, step);
|
||||
return step;
|
||||
}
|
||||
|
||||
int dsi_display_update_transfer_time(void *display, u32 transfer_time)
|
||||
{
|
||||
struct dsi_display *disp = (struct dsi_display *)display;
|
||||
|
@@ -421,15 +421,6 @@ void dsi_display_put_mode(struct dsi_display *display,
|
||||
*/
|
||||
int dsi_display_get_default_lms(void *dsi_display, u32 *num_lm);
|
||||
|
||||
/**
|
||||
* dsi_display_get_avr_step_req_fps() - get avr step rate for given fps
|
||||
* @display: Handle to display.
|
||||
* @mode_fps: Fps value of current mode
|
||||
*
|
||||
* Return: AVR step rate or -ve error code.
|
||||
*/
|
||||
int dsi_display_get_avr_step_req_fps(void *dsi_display, u32 mode_fps);
|
||||
|
||||
/*
|
||||
* dsi_conn_get_lm_from_mode() - retrieves LM count from dsi mode priv info
|
||||
* @display: Handle to display.
|
||||
|
@@ -641,6 +641,7 @@ int dsi_conn_get_mode_info(struct drm_connector *connector,
|
||||
mode_info->mdp_transfer_time_us_max = dsi_mode->priv_info->mdp_transfer_time_us_max;
|
||||
mode_info->disable_rsc_solver = dsi_mode->priv_info->disable_rsc_solver;
|
||||
mode_info->qsync_min_fps = dsi_mode->timing.qsync_min_fps;
|
||||
mode_info->avr_step_fps = dsi_mode->timing.avr_step_fps;
|
||||
mode_info->wd_jitter = dsi_mode->priv_info->wd_jitter;
|
||||
|
||||
mode_info->vpadding = dsi_display->panel->host_config.vpadding;
|
||||
@@ -711,28 +712,6 @@ static const struct drm_bridge_funcs dsi_bridge_ops = {
|
||||
.mode_set = dsi_bridge_mode_set,
|
||||
};
|
||||
|
||||
int dsi_conn_set_avr_step_info(struct dsi_panel *panel, void *info)
|
||||
{
|
||||
u32 i;
|
||||
int idx = 0;
|
||||
size_t buff_sz = PAGE_SIZE;
|
||||
char *buff;
|
||||
|
||||
buff = kzalloc(buff_sz, GFP_KERNEL);
|
||||
if (!buff)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < panel->avr_caps.avr_step_fps_list_len && (idx < (buff_sz - 1)); i++)
|
||||
idx += scnprintf(&buff[idx], buff_sz - idx, "%u@%u ",
|
||||
panel->avr_caps.avr_step_fps_list[i],
|
||||
panel->dfps_caps.dfps_list[i]);
|
||||
|
||||
sde_kms_info_add_keystr(info, "avr step requirement", buff);
|
||||
kfree(buff);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dsi_conn_get_qsync_min_fps(struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct sde_connector_state *sde_conn_state = to_sde_connector_state(conn_state);
|
||||
@@ -750,6 +729,23 @@ int dsi_conn_get_qsync_min_fps(struct drm_connector_state *conn_state)
|
||||
return priv_info->qsync_min_fps;
|
||||
}
|
||||
|
||||
int dsi_conn_get_avr_step_fps(struct drm_connector_state *conn_state)
|
||||
{
|
||||
struct sde_connector_state *sde_conn_state = to_sde_connector_state(conn_state);
|
||||
struct msm_display_mode *msm_mode;
|
||||
struct dsi_display_mode_priv_info *priv_info;
|
||||
|
||||
if (!sde_conn_state)
|
||||
return -EINVAL;
|
||||
|
||||
msm_mode = &sde_conn_state->msm_mode;
|
||||
if (!msm_mode || !msm_mode->private)
|
||||
return -EINVAL;
|
||||
|
||||
priv_info = (struct dsi_display_mode_priv_info *)(msm_mode->private);
|
||||
return priv_info->avr_step_fps;
|
||||
}
|
||||
|
||||
int dsi_conn_set_info_blob(struct drm_connector *connector,
|
||||
void *info, void *display, struct msm_mode_info *mode_info)
|
||||
{
|
||||
@@ -798,8 +794,6 @@ int dsi_conn_set_info_blob(struct drm_connector *connector,
|
||||
switch (panel->panel_mode) {
|
||||
case DSI_OP_VIDEO_MODE:
|
||||
sde_kms_info_add_keystr(info, "panel mode", "video");
|
||||
if (panel->avr_caps.avr_step_fps_list_len)
|
||||
dsi_conn_set_avr_step_info(panel, info);
|
||||
break;
|
||||
case DSI_OP_CMD_MODE:
|
||||
sde_kms_info_add_keystr(info, "panel mode", "command");
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -179,4 +180,12 @@ void dsi_conn_set_submode_blob_info(struct drm_connector *conn,
|
||||
* Return: Qsync min fps rate or -ve error code.
|
||||
*/
|
||||
int dsi_conn_get_qsync_min_fps(struct drm_connector_state *conn_state);
|
||||
|
||||
/**
|
||||
* dsi_conn_get_avr_step_fps() - get avr step fps for given mode
|
||||
* @conn_state: Pointer to drm_connector_state structure
|
||||
*
|
||||
* Return: AVR step fps rate or -ve error code.
|
||||
*/
|
||||
int dsi_conn_get_avr_step_fps(struct drm_connector_state *conn_state);
|
||||
#endif /* _DSI_DRM_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) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -925,6 +925,12 @@ static int dsi_panel_parse_timing(struct dsi_mode_info *mode,
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
rc = utils->read_u32(utils->data, "qcom,dsi-qsync-mode-avr-step-fps", &mode->avr_step_fps);
|
||||
if (rc) {
|
||||
DSI_DEBUG("avr step fps not defined in timing node\n");
|
||||
rc = 0;
|
||||
}
|
||||
|
||||
DSI_DEBUG("panel vert active:%d front_portch:%d back_porch:%d pulse_width:%d\n",
|
||||
mode->v_active, mode->v_front_porch, mode->v_back_porch,
|
||||
mode->v_sync_width);
|
||||
@@ -1292,14 +1298,22 @@ static int dsi_panel_parse_avr_caps(struct dsi_panel *panel,
|
||||
struct dsi_parser_utils *utils = &panel->utils;
|
||||
int val, rc = 0;
|
||||
|
||||
rc = of_property_read_u32(of_node, "qcom,dsi-qsync-avr-step-fps", &val);
|
||||
if (rc)
|
||||
DSI_DEBUG("[%s] avr step fps not defined rc:%d\n", panel->name, rc);
|
||||
avr_caps->avr_step_fps = rc ? 0 : val;
|
||||
|
||||
val = utils->count_u32_elems(utils->data, "qcom,dsi-qsync-avr-step-list");
|
||||
if (val <= 0) {
|
||||
DSI_DEBUG("[%s] optional avr step list not defined, val:%d\n", panel->name, val);
|
||||
return rc;
|
||||
return 0;
|
||||
} else if (val > 1 && val != panel->dfps_caps.dfps_list_len) {
|
||||
DSI_ERR("[%s] avr step list size %d not same as dfps list %d\n",
|
||||
panel->name, val, panel->dfps_caps.dfps_list_len);
|
||||
return -EINVAL;
|
||||
} else if ((val > 0) && (avr_caps->avr_step_fps)) {
|
||||
DSI_ERR("[%s] both modes of avr-steps are defined\n", panel->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
avr_caps->avr_step_fps_list = kcalloc(val, sizeof(u32), GFP_KERNEL);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2022-2023 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) 2016-2021, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
@@ -99,6 +99,7 @@ struct dsi_qsync_capabilities {
|
||||
};
|
||||
|
||||
struct dsi_avr_capabilities {
|
||||
u32 avr_step_fps;
|
||||
u32 *avr_step_fps_list;
|
||||
u32 avr_step_fps_list_len;
|
||||
};
|
||||
|
Reference in New Issue
Block a user