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:
Veera Sundaram Sankaran
2023-01-20 15:20:10 -08:00
부모 95e583e413
커밋 2e3ba9430c
13개의 변경된 파일155개의 추가작업 그리고 141개의 파일을 삭제

파일 보기

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