1
0

Merge "disp: msm: sde: add support for qsync min fps list"

Este cometimento está contido em:
qctecmdr
2020-10-19 16:18:30 -07:00
cometido por Gerrit - the friendly Code Review server
ascendente 7d1acf4361 e5ff0b8f30
cometimento 68f4129cc6
12 ficheiros modificados com 166 adições e 17 eliminações

Ver ficheiro

@@ -6472,7 +6472,10 @@ int dsi_display_get_info(struct drm_connector *connector,
info->max_width = 1920;
info->max_height = 1080;
info->qsync_min_fps =
display->panel->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) ?
true : false;
info->poms_align_vsync = display->panel->poms_align_vsync;
switch (display->panel->panel_mode) {
@@ -6934,6 +6937,25 @@ int dsi_display_get_default_lms(void *dsi_display, u32 *num_lm)
return rc;
}
int dsi_display_get_qsync_min_fps(void *display_dsi, u32 mode_fps)
{
struct dsi_display *display = (struct dsi_display *)display_dsi;
struct dsi_panel *panel;
u32 i;
if (display == NULL || display->panel == NULL)
return -EINVAL;
panel = display->panel;
for (i = 0; i < panel->dfps_caps.dfps_list_len; i++) {
if (panel->dfps_caps.dfps_list[i] == mode_fps)
return panel->qsync_caps.qsync_min_fps_list[i];
}
SDE_EVT32(mode_fps);
DSI_DEBUG("Invalid mode_fps %d\n", mode_fps);
return -EINVAL;
}
int dsi_display_find_mode(struct dsi_display *display,
const struct dsi_display_mode *cmp,
struct dsi_display_mode **out_mode)
@@ -7781,7 +7803,7 @@ static int dsi_display_qsync(struct dsi_display *display, bool enable)
int i;
int rc = 0;
if (!display->panel->qsync_min_fps) {
if (!display->panel->qsync_caps.qsync_min_fps) {
DSI_ERR("%s:ERROR: qsync set, but no fps\n", __func__);
return 0;
}
@@ -7809,7 +7831,7 @@ static int dsi_display_qsync(struct dsi_display *display, bool enable)
}
exit:
SDE_EVT32(enable, display->panel->qsync_min_fps, rc);
SDE_EVT32(enable, display->panel->qsync_caps.qsync_min_fps, rc);
mutex_unlock(&display->display_lock);
return rc;
}

Ver ficheiro

@@ -407,6 +407,16 @@ void dsi_display_put_mode(struct dsi_display *display,
*/
int dsi_display_get_default_lms(void *dsi_display, u32 *num_lm);
/**
* dsi_display_get_qsync_min_fps() - get qsync min fps for given fps
* @display: Handle to display.
* @mode_fps: Fps value of current mode
*
* Return: error code.
*/
int dsi_display_get_qsync_min_fps(void *dsi_display, u32 mode_fps);
/**
* dsi_display_find_mode() - retrieve cached DSI mode given relevant params
* @display: Handle to display.

Ver ficheiro

@@ -628,14 +628,16 @@ int dsi_conn_set_info_blob(struct drm_connector *connector,
case DSI_OP_VIDEO_MODE:
sde_kms_info_add_keystr(info, "panel mode", "video");
sde_kms_info_add_keystr(info, "qsync support",
panel->qsync_min_fps ? "true" : "false");
panel->qsync_caps.qsync_min_fps ?
"true" : "false");
break;
case DSI_OP_CMD_MODE:
sde_kms_info_add_keystr(info, "panel mode", "command");
sde_kms_info_add_keyint(info, "mdp_transfer_time_us",
mode_info->mdp_transfer_time_us);
sde_kms_info_add_keystr(info, "qsync support",
panel->qsync_min_fps ? "true" : "false");
panel->qsync_caps.qsync_min_fps ?
"true" : "false");
break;
default:
DSI_DEBUG("invalid panel type:%d\n", panel->panel_mode);

Ver ficheiro

@@ -1219,8 +1219,15 @@ static int dsi_panel_parse_qsync_caps(struct dsi_panel *panel,
struct device_node *of_node)
{
int rc = 0;
u32 val = 0;
u32 val = 0, i;
struct dsi_qsync_capabilities *qsync_caps = &panel->qsync_caps;
struct dsi_parser_utils *utils = &panel->utils;
const char *name = panel->name;
/**
* "mdss-dsi-qsync-min-refresh-rate" is defined in cmd mode and
* video mode when there is only one qsync min fps present.
*/
rc = of_property_read_u32(of_node,
"qcom,mdss-dsi-qsync-min-refresh-rate",
&val);
@@ -1228,8 +1235,75 @@ static int dsi_panel_parse_qsync_caps(struct dsi_panel *panel,
DSI_DEBUG("[%s] qsync min fps not defined rc:%d\n",
panel->name, rc);
panel->qsync_min_fps = val;
qsync_caps->qsync_min_fps = val;
/**
* "dsi-supported-qsync-min-fps-list" may be defined in video
* mode, only in dfps case when "qcom,dsi-supported-dfps-list"
* is defined.
*/
qsync_caps->qsync_min_fps_list_len = utils->count_u32_elems(utils->data,
"qcom,dsi-supported-qsync-min-fps-list");
if (qsync_caps->qsync_min_fps_list_len < 1)
goto qsync_support;
/**
* qcom,dsi-supported-qsync-min-fps-list cannot be defined
* along with qcom,mdss-dsi-qsync-min-refresh-rate.
*/
if (qsync_caps->qsync_min_fps_list_len >= 1 &&
qsync_caps->qsync_min_fps) {
DSI_ERR("[%s] Both qsync nodes are defined\n",
name);
rc = -EINVAL;
goto error;
}
if (panel->dfps_caps.dfps_list_len !=
qsync_caps->qsync_min_fps_list_len) {
DSI_ERR("[%s] Qsync min fps list mismatch with dfps\n", name);
rc = -EINVAL;
goto error;
}
qsync_caps->qsync_min_fps_list =
kcalloc(qsync_caps->qsync_min_fps_list_len, sizeof(u32),
GFP_KERNEL);
if (!qsync_caps->qsync_min_fps_list) {
rc = -ENOMEM;
goto error;
}
rc = utils->read_u32_array(utils->data,
"qcom,dsi-supported-qsync-min-fps-list",
qsync_caps->qsync_min_fps_list,
qsync_caps->qsync_min_fps_list_len);
if (rc) {
DSI_ERR("[%s] Qsync min fps list parse failed\n", name);
rc = -EINVAL;
goto error;
}
qsync_caps->qsync_min_fps = qsync_caps->qsync_min_fps_list[0];
for (i = 1; i < qsync_caps->qsync_min_fps_list_len; i++) {
if (qsync_caps->qsync_min_fps_list[i] <
qsync_caps->qsync_min_fps)
qsync_caps->qsync_min_fps =
qsync_caps->qsync_min_fps_list[i];
}
qsync_support:
/* allow qsync support only if DFPS is with VFP approach */
if ((panel->dfps_caps.dfps_support) &&
!(panel->dfps_caps.type == DSI_DFPS_IMMEDIATE_VFP))
panel->qsync_caps.qsync_min_fps = 0;
error:
if (rc < 0) {
qsync_caps->qsync_min_fps = 0;
qsync_caps->qsync_min_fps_list_len = 0;
}
return rc;
}
@@ -3396,11 +3470,6 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
if (rc)
DSI_DEBUG("failed to parse qsync features, rc=%d\n", rc);
/* allow qsync support only if DFPS is with VFP approach */
if ((panel->dfps_caps.dfps_support) &&
!(panel->dfps_caps.type == DSI_DFPS_IMMEDIATE_VFP))
panel->qsync_min_fps = 0;
rc = dsi_panel_parse_dyn_clk_caps(panel);
if (rc)
DSI_ERR("failed to parse dynamic clk config, rc=%d\n", rc);

Ver ficheiro

@@ -86,6 +86,13 @@ struct dsi_dfps_capabilities {
bool dfps_support;
};
struct dsi_qsync_capabilities {
/* qsync disabled if qsync_min_fps = 0 */
u32 qsync_min_fps;
u32 *qsync_min_fps_list;
int qsync_min_fps_list_len;
};
struct dsi_dyn_clk_caps {
bool dyn_clk_support;
u32 *bit_clk_list;
@@ -231,7 +238,7 @@ struct dsi_panel {
bool panel_initialized;
bool te_using_watchdog_timer;
u32 qsync_min_fps;
struct dsi_qsync_capabilities qsync_caps;
char dce_pps_cmd[DSI_CMD_PPS_SIZE];
enum dsi_dms_mode dms_mode;

Ver ficheiro

@@ -739,6 +739,7 @@ struct msm_resource_caps_info {
* @poms_align_vsync: poms with vsync aligned
* @roi_caps: Region of interest capability info
* @qsync_min_fps Minimum fps supported by Qsync feature
* @has_qsync_min_fps_list True if dsi-supported-qsync-min-fps-list exits
* @te_source vsync source pin information
* @dsc_count: max dsc hw blocks used by display (only available
* for dsi display)
@@ -767,6 +768,8 @@ struct msm_display_info {
struct msm_roi_caps roi_caps;
uint32_t qsync_min_fps;
bool has_qsync_min_fps_list;
uint32_t te_source;
uint32_t dsc_count;

Ver ficheiro

@@ -374,6 +374,14 @@ struct sde_connector_ops {
*/
void (*set_allowed_mode_switch)(struct drm_connector *connector,
void *display);
/**
* get_qsync_min_fps - Get qsync min fps from qsync-min-fps-list
* @display: Pointer to private display structure
* @mode_fps: Fps value in dfps list
* Returns: Qsync min fps value on success
*/
int (*get_qsync_min_fps)(void *display, u32 mode_fps);
};
/**

Ver ficheiro

@@ -3218,10 +3218,12 @@ static void sde_encoder_frame_done_callback(
static void sde_encoder_get_qsync_fps_callback(
struct drm_encoder *drm_enc,
u32 *qsync_fps)
u32 *qsync_fps, u32 vrr_fps)
{
struct msm_display_info *disp_info;
struct sde_encoder_virt *sde_enc;
int rc = 0;
struct sde_connector *sde_conn;
if (!qsync_fps)
return;
@@ -3235,6 +3237,31 @@ static void sde_encoder_get_qsync_fps_callback(
sde_enc = to_sde_encoder_virt(drm_enc);
disp_info = &sde_enc->disp_info;
*qsync_fps = disp_info->qsync_min_fps;
/**
* If "dsi-supported-qsync-min-fps-list" is defined, get
* the qsync min fps corresponding to the fps in dfps list
*/
if (disp_info->has_qsync_min_fps_list) {
if (!sde_enc->cur_master ||
!(sde_enc->disp_info.capabilities &
MSM_DISPLAY_CAP_VID_MODE)) {
SDE_ERROR("invalid qsync settings %b\n",
!sde_enc->cur_master);
return;
}
sde_conn = to_sde_connector(sde_enc->cur_master->connector);
if (sde_conn->ops.get_qsync_min_fps)
rc = sde_conn->ops.get_qsync_min_fps(sde_conn->display,
vrr_fps);
if (rc <= 0) {
SDE_ERROR("invalid qsync min fps %d\n", rc);
return;
}
*qsync_fps = rc;
}
}
int sde_encoder_idle_request(struct drm_encoder *drm_enc)

Ver ficheiro

@@ -82,7 +82,7 @@ struct sde_encoder_virt_ops {
void (*handle_frame_done)(struct drm_encoder *parent,
struct sde_encoder_phys *phys, u32 event);
void (*get_qsync_fps)(struct drm_encoder *parent,
u32 *qsync_fps);
u32 *qsync_fps, u32 vrr_fps);
};
/**

Ver ficheiro

@@ -962,7 +962,7 @@ static int _get_tearcheck_threshold(struct sde_encoder_phys *phys_enc)
if (phys_enc->parent_ops.get_qsync_fps)
phys_enc->parent_ops.get_qsync_fps(
phys_enc->parent, &qsync_min_fps);
phys_enc->parent, &qsync_min_fps, 0);
if (!qsync_min_fps || !default_fps || !yres) {
SDE_ERROR_CMDENC(cmd_enc,

Ver ficheiro

@@ -470,7 +470,7 @@ static void sde_encoder_phys_vid_setup_timing_engine(
exit:
if (phys_enc->parent_ops.get_qsync_fps)
phys_enc->parent_ops.get_qsync_fps(
phys_enc->parent, &qsync_min_fps);
phys_enc->parent, &qsync_min_fps, mode.vrefresh);
/* only panels which support qsync will have a non-zero min fps */
if (qsync_min_fps) {

Ver ficheiro

@@ -1731,6 +1731,7 @@ static int _sde_kms_setup_displays(struct drm_device *dev,
.cmd_receive = dsi_display_cmd_receive,
.install_properties = NULL,
.set_allowed_mode_switch = dsi_conn_set_allowed_mode_switch,
.get_qsync_min_fps = dsi_display_get_qsync_min_fps,
};
static const struct sde_connector_ops wb_ops = {
.post_init = sde_wb_connector_post_init,