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

Commit 72944c51 authored by Krishna Manikandan's avatar Krishna Manikandan
Browse files

disp: msm: sde: add support to handle qsync-min-fps list property



Qsync min fps is same for all the fps in the dfps list in
the current implementation. Added support to parse
qcom,dsi-supported-qsync-min-fps-list where each value
is the qsync min fps corresponding to the mode in the
dfps list with same index.

Change-Id: I68b179f6eacbf9cc14c1bd90d71d5661c2255750
Signed-off-by: default avatarKrishna Manikandan <mkrishn@codeaurora.org>
parent 213d0449
Loading
Loading
Loading
Loading
+25 −3
Original line number Diff line number Diff line
@@ -6064,7 +6064,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;

	switch (display->panel->panel_mode) {
	case DSI_OP_VIDEO_MODE:
@@ -6509,6 +6512,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)
@@ -7340,7 +7362,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;
	}
@@ -7368,7 +7390,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
@@ -394,6 +394,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
@@ -587,14 +587,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
@@ -1314,8 +1314,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);
@@ -1323,8 +1330,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;
}

@@ -3313,11 +3387,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
@@ -84,6 +84,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;
@@ -207,7 +214,7 @@ struct dsi_panel {

	bool panel_initialized;
	bool te_using_watchdog_timer;
	u32 qsync_min_fps;
	struct dsi_qsync_capabilities qsync_caps;

	char dsc_pps_cmd[DSI_CMD_PPS_SIZE];
	enum dsi_dms_mode dms_mode;
Loading