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;
|
||||
};
|
||||
|
@@ -246,7 +246,7 @@ enum msm_mdp_conn_property {
|
||||
CONNECTOR_PROP_QSYNC_MODE,
|
||||
CONNECTOR_PROP_CMD_FRAME_TRIGGER_MODE,
|
||||
CONNECTOR_PROP_SET_PANEL_MODE,
|
||||
CONNECTOR_PROP_AVR_STEP,
|
||||
CONNECTOR_PROP_AVR_STEP_STATE,
|
||||
CONNECTOR_PROP_EPT,
|
||||
CONNECTOR_PROP_CACHE_STATE,
|
||||
CONNECTOR_PROP_DSC_MODE,
|
||||
@@ -814,6 +814,7 @@ struct msm_display_wd_jitter_config {
|
||||
* @disable_rsc_solver: Dynamically disable RSC solver for the timing mode due to lower bitclk rate.
|
||||
* @dyn_clk_list: List of dynamic clock rates for RFI.
|
||||
* @qsync_min_fps: qsync min fps rate
|
||||
* @avr_step_fps: AVR step fps rate
|
||||
* @wd_jitter: Info for WD jitter.
|
||||
* @vpadding: panel stacking height
|
||||
*/
|
||||
@@ -837,6 +838,7 @@ struct msm_mode_info {
|
||||
bool disable_rsc_solver;
|
||||
struct msm_dyn_clk_list dyn_clk_list;
|
||||
u32 qsync_min_fps;
|
||||
u32 avr_step_fps;
|
||||
struct msm_display_wd_jitter_config wd_jitter;
|
||||
u32 vpadding;
|
||||
};
|
||||
@@ -883,9 +885,9 @@ struct msm_resource_caps_info {
|
||||
* used instead of panel TE in cmd mode panels
|
||||
* @poms_align_vsync: poms with vsync aligned
|
||||
* @roi_caps: Region of interest capability info
|
||||
* @qsync_min_fps Minimum fps supported by Qsync feature
|
||||
* @qsync_min_fps Minimum fps supported by Qsync feature
|
||||
* @has_qsync_min_fps_list True if dsi-supported-qsync-min-fps-list exits
|
||||
* @has_avr_step_req Panel has defined requirement for AVR steps
|
||||
* @avr_step_fps AVR step fps supported
|
||||
* @te_source vsync source pin information
|
||||
* @dsc_count: max dsc hw blocks used by display (only available
|
||||
* for dsi display)
|
||||
@@ -915,7 +917,7 @@ struct msm_display_info {
|
||||
|
||||
uint32_t qsync_min_fps;
|
||||
bool has_qsync_min_fps_list;
|
||||
bool has_avr_step_req;
|
||||
uint32_t avr_step_fps;
|
||||
|
||||
uint32_t te_source;
|
||||
|
||||
|
@@ -854,7 +854,7 @@ void sde_connector_set_qsync_params(struct drm_connector *connector)
|
||||
{
|
||||
struct sde_connector *c_conn;
|
||||
struct sde_connector_state *c_state;
|
||||
u32 qsync_propval = 0, step_val = 0;
|
||||
u32 qsync_propval = 0;
|
||||
bool prop_dirty;
|
||||
|
||||
if (!connector)
|
||||
@@ -879,15 +879,9 @@ void sde_connector_set_qsync_params(struct drm_connector *connector)
|
||||
}
|
||||
|
||||
prop_dirty = msm_property_is_dirty(&c_conn->property_info, &c_state->property_state,
|
||||
CONNECTOR_PROP_AVR_STEP);
|
||||
if (prop_dirty) {
|
||||
step_val = sde_connector_get_property(c_conn->base.state, CONNECTOR_PROP_AVR_STEP);
|
||||
if (step_val != c_conn->avr_step) {
|
||||
SDE_DEBUG("updated avr step %d -> %d\n", c_conn->avr_step, step_val);
|
||||
c_conn->qsync_updated = true;
|
||||
c_conn->avr_step = step_val;
|
||||
}
|
||||
}
|
||||
CONNECTOR_PROP_AVR_STEP_STATE);
|
||||
if (prop_dirty)
|
||||
c_conn->qsync_updated = true;
|
||||
}
|
||||
|
||||
void sde_connector_complete_qsync_commit(struct drm_connector *conn,
|
||||
@@ -2932,6 +2926,7 @@ static int sde_connector_populate_mode_info(struct drm_connector *conn,
|
||||
}
|
||||
|
||||
sde_kms_info_add_keyint(info, "qsync_min_fps", mode_info.qsync_min_fps);
|
||||
sde_kms_info_add_keyint(info, "avr_step_fps", mode_info.avr_step_fps);
|
||||
sde_kms_info_add_keyint(info, "has_cwb_crop", test_bit(SDE_FEATURE_CWB_CROP,
|
||||
sde_kms->catalog->features));
|
||||
sde_kms_info_add_keyint(info, "has_dedicated_cwb_support",
|
||||
@@ -3058,6 +3053,33 @@ exit:
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void _sde_connector_install_qsync_properties(struct sde_kms *sde_kms,
|
||||
struct sde_connector *c_conn, struct dsi_display *dsi_display,
|
||||
struct msm_display_info *display_info)
|
||||
{
|
||||
static const struct drm_prop_enum_list e_avr_step_state[] = {
|
||||
{AVR_STEP_NONE, "avr_step_none"},
|
||||
{AVR_STEP_ENABLE, "avr_step_enable"},
|
||||
{AVR_STEP_DISABLE, "avr_step_disable"},
|
||||
};
|
||||
|
||||
if (test_bit(SDE_FEATURE_QSYNC, sde_kms->catalog->features) && dsi_display &&
|
||||
dsi_display->panel && dsi_display->panel->qsync_caps.qsync_support) {
|
||||
msm_property_install_enum(&c_conn->property_info, "qsync_mode", 0, 0, e_qsync_mode,
|
||||
ARRAY_SIZE(e_qsync_mode), 0, CONNECTOR_PROP_QSYNC_MODE);
|
||||
|
||||
if (test_bit(SDE_FEATURE_EPT, sde_kms->catalog->features))
|
||||
msm_property_install_range(&c_conn->property_info, "EPT", 0x0, 0, U64_MAX,
|
||||
0, CONNECTOR_PROP_EPT);
|
||||
|
||||
if (test_bit(SDE_FEATURE_AVR_STEP, sde_kms->catalog->features) &&
|
||||
(display_info->capabilities & MSM_DISPLAY_CAP_VID_MODE))
|
||||
msm_property_install_enum(&c_conn->property_info, "avr_step_state",
|
||||
0, 0, e_avr_step_state, ARRAY_SIZE(e_avr_step_state), 0,
|
||||
CONNECTOR_PROP_AVR_STEP_STATE);
|
||||
}
|
||||
}
|
||||
|
||||
static int _sde_connector_install_properties(struct drm_device *dev,
|
||||
struct sde_kms *sde_kms, struct sde_connector *c_conn,
|
||||
int connector_type, void *display,
|
||||
@@ -3169,21 +3191,7 @@ static int _sde_connector_install_properties(struct drm_device *dev,
|
||||
CONNECTOR_PROP_AUTOREFRESH);
|
||||
|
||||
if (connector_type == DRM_MODE_CONNECTOR_DSI) {
|
||||
if (test_bit(SDE_FEATURE_QSYNC, sde_kms->catalog->features) && dsi_display &&
|
||||
dsi_display->panel && dsi_display->panel->qsync_caps.qsync_support) {
|
||||
msm_property_install_enum(&c_conn->property_info,
|
||||
"qsync_mode", 0, 0, e_qsync_mode,
|
||||
ARRAY_SIZE(e_qsync_mode), 0,
|
||||
CONNECTOR_PROP_QSYNC_MODE);
|
||||
if (test_bit(SDE_FEATURE_EPT, sde_kms->catalog->features))
|
||||
msm_property_install_range(&c_conn->property_info,
|
||||
"EPT", 0x0, 0, U64_MAX, 0,
|
||||
CONNECTOR_PROP_EPT);
|
||||
if (test_bit(SDE_FEATURE_AVR_STEP, sde_kms->catalog->features))
|
||||
msm_property_install_range(&c_conn->property_info,
|
||||
"avr_step", 0x0, 0, U32_MAX, 0,
|
||||
CONNECTOR_PROP_AVR_STEP);
|
||||
}
|
||||
_sde_connector_install_qsync_properties(sde_kms, c_conn, dsi_display, display_info);
|
||||
|
||||
msm_property_install_enum(&c_conn->property_info, "dsc_mode", 0,
|
||||
0, e_dsc_mode, ARRAY_SIZE(e_dsc_mode), 0, CONNECTOR_PROP_DSC_MODE);
|
||||
|
@@ -408,12 +408,11 @@ struct sde_connector_ops {
|
||||
int (*get_qsync_min_fps)(struct drm_connector_state *conn_state);
|
||||
|
||||
/**
|
||||
* get_avr_step_req - Get the required avr_step for given fps rate
|
||||
* @display: Pointer to private display structure
|
||||
* @mode_fps: Fps value in dfps list
|
||||
* get_avr_step_fps - Get the required avr_step for given fps rate
|
||||
* @conn_state: Pointer to drm_connector_state structure
|
||||
* Returns: AVR step fps value on success
|
||||
*/
|
||||
int (*get_avr_step_req)(void *display, u32 mode_fps);
|
||||
int (*get_avr_step_fps)(struct drm_connector_state *conn_state);
|
||||
|
||||
/**
|
||||
* set_submode_info - populate given sub mode blob
|
||||
@@ -449,6 +448,18 @@ struct sde_connector_ops {
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sde_connector_avr_step_state: states of avr step fps
|
||||
* @AVR_STEP_NONE: no-op
|
||||
* @AVR_STEP_ENABLE: enable AVR step
|
||||
* #AVR_STEP_DISABLE: disable AVR step
|
||||
*/
|
||||
enum sde_connector_avr_step_state {
|
||||
AVR_STEP_NONE,
|
||||
AVR_STEP_ENABLE,
|
||||
AVR_STEP_DISABLE,
|
||||
};
|
||||
|
||||
/**
|
||||
* enum sde_connector_display_type - list of display types
|
||||
*/
|
||||
@@ -556,7 +567,6 @@ struct sde_misr_sign {
|
||||
* @dimming_bl_notify_enabled: Flag to indicate if dimming bl notify is enabled or not
|
||||
* @qsync_mode: Cached Qsync mode, 0=disabled, 1=continuous mode
|
||||
* @qsync_updated: Qsync settings were updated
|
||||
* @avr_step: fps rate for fixed steps in AVR mode; 0 means step is disabled
|
||||
* @colorspace_updated: Colorspace property was updated
|
||||
* @last_cmd_tx_sts: status of the last command transfer
|
||||
* @hdr_capable: external hdr support present
|
||||
@@ -631,7 +641,6 @@ struct sde_connector {
|
||||
u8 hdr_plus_app_ver;
|
||||
u32 qsync_mode;
|
||||
bool qsync_updated;
|
||||
u32 avr_step;
|
||||
|
||||
bool colorspace_updated;
|
||||
|
||||
@@ -687,13 +696,6 @@ struct sde_connector {
|
||||
#define sde_connector_get_qsync_mode(C) \
|
||||
((C) ? to_sde_connector((C))->qsync_mode : 0)
|
||||
|
||||
/**
|
||||
* sde_connector_get_avr_step - get sde connector's avr_step
|
||||
* @C: Pointer to drm connector structure
|
||||
* Returns: Current cached avr_step value for given connector
|
||||
*/
|
||||
#define sde_connector_get_avr_step(C) ((C) ? to_sde_connector((C))->avr_step : 0)
|
||||
|
||||
/**
|
||||
* sde_connector_get_propinfo - get sde connector's property info pointer
|
||||
* @C: Pointer to drm connector structure
|
||||
|
@@ -1215,40 +1215,32 @@ static void _sde_encoder_get_qsync_fps_callback(struct drm_encoder *drm_enc,
|
||||
}
|
||||
|
||||
static int _sde_encoder_avr_step_check(struct sde_connector *sde_conn,
|
||||
struct sde_connector_state *sde_conn_state, u32 step)
|
||||
struct sde_connector_state *sde_conn_state)
|
||||
{
|
||||
struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(sde_conn_state->base.best_encoder);
|
||||
u32 nom_fps = drm_mode_vrefresh(sde_conn_state->msm_mode.base);
|
||||
u32 min_fps, req_fps = 0;
|
||||
u32 min_fps, step_fps = 0;
|
||||
u32 vtotal = sde_conn_state->msm_mode.base->vtotal;
|
||||
bool has_panel_req = sde_enc->disp_info.has_avr_step_req;
|
||||
u32 qsync_mode = sde_connector_get_property(&sde_conn_state->base,
|
||||
CONNECTOR_PROP_QSYNC_MODE);
|
||||
u32 avr_step_state = sde_connector_get_property(&sde_conn_state->base,
|
||||
CONNECTOR_PROP_AVR_STEP_STATE);
|
||||
|
||||
if (has_panel_req) {
|
||||
if (!sde_conn->ops.get_avr_step_req) {
|
||||
SDE_ERROR("unable to retrieve required step rate\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((avr_step_state == AVR_STEP_NONE) || !sde_conn->ops.get_avr_step_fps)
|
||||
return 0;
|
||||
|
||||
req_fps = sde_conn->ops.get_avr_step_req(sde_conn->display, nom_fps);
|
||||
/* when qsync is enabled, the step fps *must* be set to the panel requirement */
|
||||
if (qsync_mode && req_fps != step) {
|
||||
SDE_ERROR("invalid avr_step %u, panel requires %u at nominal %u fps\n",
|
||||
step, req_fps, nom_fps);
|
||||
return -EINVAL;
|
||||
}
|
||||
if (!qsync_mode && avr_step_state) {
|
||||
SDE_ERROR("invalid config: avr-step enabled without qsync\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!step)
|
||||
return 0;
|
||||
step_fps = sde_conn->ops.get_avr_step_fps(&sde_conn_state->base);
|
||||
|
||||
_sde_encoder_get_qsync_fps_callback(sde_conn_state->base.best_encoder, &min_fps,
|
||||
&sde_conn_state->base);
|
||||
if (!min_fps || !nom_fps || step % nom_fps || step % min_fps || step < nom_fps ||
|
||||
(vtotal * nom_fps) % step) {
|
||||
if (!min_fps || !nom_fps || step_fps % nom_fps || step_fps % min_fps
|
||||
|| step_fps < nom_fps || (vtotal * nom_fps) % step_fps) {
|
||||
SDE_ERROR("invalid avr_step rate! nom:%u min:%u step:%u vtotal:%u\n", nom_fps,
|
||||
min_fps, step, vtotal);
|
||||
min_fps, step_fps, vtotal);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -1259,11 +1251,9 @@ static int _sde_encoder_atomic_check_qsync(struct sde_connector *sde_conn,
|
||||
struct sde_connector_state *sde_conn_state)
|
||||
{
|
||||
int rc = 0;
|
||||
u32 avr_step;
|
||||
bool qsync_dirty, has_modeset, ept;
|
||||
struct drm_connector_state *conn_state = &sde_conn_state->base;
|
||||
u32 qsync_mode = sde_connector_get_property(&sde_conn_state->base,
|
||||
CONNECTOR_PROP_QSYNC_MODE);
|
||||
u32 qsync_mode;
|
||||
|
||||
has_modeset = sde_crtc_atomic_check_has_modeset(conn_state->state, conn_state->crtc);
|
||||
qsync_dirty = msm_property_is_dirty(&sde_conn->property_info,
|
||||
@@ -1279,9 +1269,9 @@ static int _sde_encoder_atomic_check_qsync(struct sde_connector *sde_conn,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
avr_step = sde_connector_get_property(conn_state, CONNECTOR_PROP_AVR_STEP);
|
||||
if (qsync_dirty || (avr_step != sde_conn->avr_step) || (qsync_mode && has_modeset))
|
||||
rc = _sde_encoder_avr_step_check(sde_conn, sde_conn_state, avr_step);
|
||||
qsync_mode = sde_connector_get_property(conn_state, CONNECTOR_PROP_QSYNC_MODE);
|
||||
if (qsync_dirty || (qsync_mode && has_modeset))
|
||||
rc = _sde_encoder_avr_step_check(sde_conn, sde_conn_state);
|
||||
|
||||
return rc;
|
||||
}
|
||||
@@ -4670,6 +4660,7 @@ void _sde_encoder_delay_kickoff_processing(struct sde_encoder_virt *sde_enc)
|
||||
u32 avr_step_fps, min_fps = 0, qsync_mode;
|
||||
u64 timeout_us = 0, ept;
|
||||
struct drm_connector *drm_conn;
|
||||
struct msm_mode_info *info = &sde_enc->mode_info;
|
||||
|
||||
if (!sde_enc->cur_master || !sde_enc->cur_master->connector)
|
||||
return;
|
||||
@@ -4679,13 +4670,13 @@ void _sde_encoder_delay_kickoff_processing(struct sde_encoder_virt *sde_enc)
|
||||
if (!ept)
|
||||
return;
|
||||
|
||||
avr_step_fps = sde_connector_get_avr_step(drm_conn);
|
||||
qsync_mode = sde_connector_get_property(drm_conn->state, CONNECTOR_PROP_QSYNC_MODE);
|
||||
if (qsync_mode)
|
||||
_sde_encoder_get_qsync_fps_callback(&sde_enc->base, &min_fps, drm_conn->state);
|
||||
/* use min qsync fps, if feature is enabled; otherwise min default fps */
|
||||
min_fps = min_fps ? min_fps : DEFAULT_MIN_FPS;
|
||||
|
||||
avr_step_fps = info->avr_step_fps;
|
||||
current_ts = ktime_get_ns();
|
||||
/* ept is in ns and avr_step is mulitple of refresh rate */
|
||||
ept_ts = avr_step_fps ? ept - DIV_ROUND_UP(NSEC_PER_SEC, avr_step_fps) + NSEC_PER_MSEC
|
||||
|
@@ -373,19 +373,30 @@ static void _sde_encoder_phys_vid_avr_ctrl(struct sde_encoder_phys *phys_enc)
|
||||
{
|
||||
struct intf_avr_params avr_params;
|
||||
struct sde_encoder_phys_vid *vid_enc = to_sde_encoder_phys_vid(phys_enc);
|
||||
u32 avr_step_fps = sde_connector_get_avr_step(phys_enc->connector);
|
||||
struct drm_connector *conn = phys_enc->connector;
|
||||
struct sde_encoder_virt *sde_enc = to_sde_encoder_virt(phys_enc->parent);
|
||||
struct msm_mode_info *info = &sde_enc->mode_info;
|
||||
u32 avr_step_state;
|
||||
|
||||
if (!conn || !conn->state)
|
||||
return;
|
||||
|
||||
avr_step_state = sde_connector_get_property(conn->state, CONNECTOR_PROP_AVR_STEP_STATE);
|
||||
if (avr_step_state == AVR_STEP_NONE)
|
||||
return;
|
||||
|
||||
memset(&avr_params, 0, sizeof(avr_params));
|
||||
avr_params.avr_mode = sde_connector_get_qsync_mode(phys_enc->connector);
|
||||
if (avr_step_fps)
|
||||
|
||||
if (info->avr_step_fps && (avr_step_state == AVR_STEP_ENABLE))
|
||||
avr_params.avr_step_lines = mult_frac(phys_enc->cached_mode.vtotal,
|
||||
vid_enc->timing_params.vrefresh, avr_step_fps);
|
||||
vid_enc->timing_params.vrefresh, info->avr_step_fps);
|
||||
|
||||
if (vid_enc->base.hw_intf->ops.avr_ctrl)
|
||||
vid_enc->base.hw_intf->ops.avr_ctrl(vid_enc->base.hw_intf, &avr_params);
|
||||
|
||||
SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0,
|
||||
avr_params.avr_mode, avr_params.avr_step_lines, avr_step_fps);
|
||||
SDE_EVT32(DRMID(phys_enc->parent), phys_enc->hw_intf->idx - INTF_0, avr_params.avr_mode,
|
||||
avr_params.avr_step_lines, info->avr_step_fps, avr_step_state);
|
||||
}
|
||||
|
||||
static void sde_encoder_phys_vid_setup_timing_engine(
|
||||
|
@@ -1829,7 +1829,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
|
||||
.set_allowed_mode_switch = dsi_conn_set_allowed_mode_switch,
|
||||
.set_dyn_bit_clk = dsi_conn_set_dyn_bit_clk,
|
||||
.get_qsync_min_fps = dsi_conn_get_qsync_min_fps,
|
||||
.get_avr_step_req = dsi_display_get_avr_step_req_fps,
|
||||
.get_avr_step_fps = dsi_conn_get_avr_step_fps,
|
||||
.prepare_commit = dsi_conn_prepare_commit,
|
||||
.set_submode_info = dsi_conn_set_submode_blob_info,
|
||||
.get_num_lm_from_mode = dsi_conn_get_lm_from_mode,
|
||||
|
Reference in New Issue
Block a user