Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e5ff0b8f authored by Raviteja Tamatam's avatar Raviteja Tamatam
Browse files

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



In current implementation qsync min fps is single value.
It is same for all the list of supported dfps list.
Added support for new dt entry dsi-supported-qsync-min-fps-list
corresponding to the fps supported in the dfps list
dsi-supported-dfps-list.

Change-Id: Ifd5309c2f51865a3c0d9fadb65cbcd291b6ef42b
Signed-off-by: default avatarRaviteja Tamatam <travitej@codeaurora.org>
parent 4e1159d7
Loading
Loading
Loading
Loading
+25 −3
Original line number Diff line number Diff line
@@ -6445,7 +6445,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) {
@@ -6907,6 +6910,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)
@@ -7754,7 +7776,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;
	}
@@ -7782,7 +7804,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;
}
+10 −0
Original line number Diff line number Diff line
@@ -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.
+4 −2
Original line number Diff line number Diff line
@@ -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);
+76 −7
Original line number Diff line number Diff line
@@ -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);
+8 −1
Original line number Diff line number Diff line
@@ -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;
Loading