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

Commit e74899ec authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge changes I0e8ef092,I53a81b46 into dev/msm-4.14-display

* changes:
  drm/msm/sde: update qsync for intf te
  drm/msm/sde: add support for qsync cmd mode
parents 806a21d0 180e3a30
Loading
Loading
Loading
Loading
+14 −0
Original line number Diff line number Diff line
@@ -197,6 +197,15 @@ Optional properties:
- qcom,mdss-dsi-te-using-wd:		Boolean entry enables the watchdog timer support to generate the vsync signal
					for command mode panel. By default, panel TE will be used to generate the vsync.
- qcom,mdss-dsi-te-using-te-pin:	Boolean to specify whether using hardware vsync.
- qcom,mdss-dsi-qsync-min-refresh-rate: A u32 entry to specify minimum refresh rate supported by the panel to enable qsync feature.
- qcom,mdss-dsi-qsync-on-commands:	String that specifies the commands to enable qsync feature.
- qcom,mdss-dsi-qsync-on-commands-state: String that specifies the ctrl state for sending qsync on commands.
					"dsi_lp_mode" = DSI low power mode (default)
					"dsi_hs_mode" = DSI high speed mode
- qcom,mdss-dsi-qsync-off-commands:	String that specifies the commands to disable qsync feature.
- qcom,mdss-dsi-qsync-off-commands-state: String that specifies the ctrl state for sending qsync off commands.
					"dsi_lp_mode" = DSI low power mode (default)
					"dsi_hs_mode" = DSI high speed mode
- qcom,mdss-dsi-te-pin-select:		Specifies TE operating mode.
					0 = TE through embedded dcs command
					1 = TE through TE gpio pin. (default)
@@ -599,6 +608,7 @@ Example:
		qcom,mdss-dsi-te-check-enable;
		qcom,mdss-dsi-te-using-wd;
		qcom,mdss-dsi-te-using-te-pin;
		qcom,mdss-dsi-qsync-min-refresh-rate = <30>;
		qcom,mdss-dsi-te-dcs-command = <1>;
		qcom,mdss-dsi-wr-mem-continue = <0x3c>;
		qcom,mdss-dsi-wr-mem-start = <0x2c>;
@@ -712,6 +722,10 @@ Example:
					29 00 00 00 00 00 02 B0 04
					29 00 00 00 00 00 02 F1 00];
				qcom,mdss-dsi-timing-switch-command-state = "dsi_lp_mode";
				qcom,mdss-dsi-qsync-on-commands = [15 01 00 00 00 00 02 51 00];
				qcom,mdss-dsi-qsync-on-commands-state = "dsi_hs_mode";
				qcom,mdss-dsi-qsync-off-commands = [15 01 00 00 00 00 02 51 00];
				qcom,mdss-dsi-qsync-off-commands-state = "dsi_hs_mode";

				qcom,mdss-dsc-slice-height = <16>;
				qcom,mdss-dsc-slice-width = <360>;
+3 −1
Original line number Diff line number Diff line
/*
 * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -266,6 +266,8 @@ enum dsi_cmd_set_type {
	DSI_CMD_SET_ROI,
	DSI_CMD_SET_TIMING_SWITCH,
	DSI_CMD_SET_POST_TIMING_SWITCH,
	DSI_CMD_SET_QSYNC_ON,
	DSI_CMD_SET_QSYNC_OFF,
	DSI_CMD_SET_MAX
};

+49 −0
Original line number Diff line number Diff line
@@ -4532,6 +4532,8 @@ int dsi_display_get_info(struct drm_connector *connector,
	info->height_mm = phy_props.panel_height_mm;
	info->max_width = 1920;
	info->max_height = 1080;
	info->qsync_min_fps =
		display->panel->qsync_min_fps;

	switch (display->panel->panel_mode) {
	case DSI_OP_VIDEO_MODE:
@@ -5470,6 +5472,43 @@ static int dsi_display_calc_ctrl_roi(const struct dsi_display *display,
	return rc;
}

static int dsi_display_qsync(struct dsi_display *display, bool enable)
{
	int i;
	int rc = 0;

	if (!display->panel->qsync_min_fps) {
		pr_err("%s:ERROR: qsync set, but no fps\n", __func__);
		return 0;
	}

	mutex_lock(&display->display_lock);

	for (i = 0; i < display->ctrl_count; i++) {

		if (enable) {
			/* send the commands to enable qsync */
			rc = dsi_panel_send_qsync_on_dcs(display->panel, i);
			if (rc) {
				pr_err("fail qsync ON cmds rc:%d\n", rc);
				goto exit;
			}
		} else {
			/* send the commands to enable qsync */
			rc = dsi_panel_send_qsync_off_dcs(display->panel, i);
			if (rc) {
				pr_err("fail qsync OFF cmds rc:%d\n", rc);
				goto exit;
			}
		}
	}

exit:
	SDE_EVT32(enable, display->panel->qsync_min_fps, rc);
	mutex_unlock(&display->display_lock);
	return rc;
}

static int dsi_display_set_roi(struct dsi_display *display,
		struct msm_roi_list *rois)
{
@@ -5533,11 +5572,21 @@ int dsi_display_pre_kickoff(struct drm_connector *connector,
{
	int rc = 0;
	int i;
	bool enable;

	/* check and setup MISR */
	if (display->misr_enable)
		_dsi_display_setup_misr(display);

	if (params->qsync_update) {
		enable = (params->qsync_mode > 0) ? true : false;
		rc = dsi_display_qsync(display, enable);
		if (rc)
			pr_err("%s failed to send qsync commands",
				__func__);
		SDE_EVT32(params->qsync_mode, rc);
	}

	rc = dsi_display_set_roi(display, params->rois);

	/* dynamic DSI clock setting */
+2 −0
Original line number Diff line number Diff line
@@ -439,6 +439,8 @@ int dsi_conn_set_info_blob(struct drm_connector *connector,
		sde_kms_info_add_keystr(info, "panel mode", "command");
		sde_kms_info_add_keyint(info, "mdp_transfer_time_us",
				panel->cmd_config.mdp_transfer_time_us);
		sde_kms_info_add_keystr(info, "qsync support",
				panel->qsync_min_fps ? "true" : "false");
		break;
	default:
		pr_debug("invalid panel type:%d\n", panel->panel_mode);
+70 −0
Original line number Diff line number Diff line
@@ -1054,6 +1054,24 @@ static int dsi_panel_parse_host_config(struct dsi_panel *panel)
	return rc;
}

static int dsi_panel_parse_qsync_caps(struct dsi_panel *panel,
				     struct device_node *of_node)
{
	int rc = 0;
	u32 val = 0;

	rc = of_property_read_u32(of_node,
				  "qcom,mdss-dsi-qsync-min-refresh-rate",
				  &val);
	if (rc)
		pr_err("[%s] qsync min fps not defined rc:%d\n",
			panel->name, rc);

	panel->qsync_min_fps = val;

	return rc;
}

static int dsi_panel_parse_dfps_caps(struct dsi_panel *panel)
{
	int rc = 0;
@@ -1386,6 +1404,8 @@ const char *cmd_set_prop_map[DSI_CMD_SET_MAX] = {
	"ROI not parsed from DTSI, generated dynamically",
	"qcom,mdss-dsi-timing-switch-command",
	"qcom,mdss-dsi-post-mode-switch-on-command",
	"qcom,mdss-dsi-qsync-on-commands",
	"qcom,mdss-dsi-qsync-off-commands",
};

const char *cmd_set_state_map[DSI_CMD_SET_MAX] = {
@@ -1410,6 +1430,8 @@ const char *cmd_set_state_map[DSI_CMD_SET_MAX] = {
	"ROI not parsed from DTSI, generated dynamically",
	"qcom,mdss-dsi-timing-switch-command-state",
	"qcom,mdss-dsi-post-mode-switch-on-command-state",
	"qcom,mdss-dsi-qsync-on-commands-state",
	"qcom,mdss-dsi-qsync-off-commands-state",
};

static int dsi_panel_get_cmd_pkt_count(const char *data, u32 length, u32 *cnt)
@@ -2785,6 +2807,10 @@ struct dsi_panel *dsi_panel_get(struct device *parent,
	if (rc)
		pr_err("failed to parse dfps configuration, rc=%d\n", rc);

	rc = dsi_panel_parse_qsync_caps(panel, of_node);
	if (rc)
		pr_err("failed to parse qsync features, rc=%d\n", rc);

	rc = dsi_panel_parse_phy_props(panel);
	if (rc) {
		pr_err("failed to parse panel physical dimension, rc=%d\n", rc);
@@ -3404,6 +3430,50 @@ static int dsi_panel_roi_prepare_dcs_cmds(struct dsi_panel_cmd_set *set,
	return rc;
}

int dsi_panel_send_qsync_on_dcs(struct dsi_panel *panel,
		int ctrl_idx)
{
	int rc = 0;

	if (!panel) {
		pr_err("invalid params\n");
		return -EINVAL;
	}

	mutex_lock(&panel->panel_lock);

	pr_debug("ctrl:%d qsync on\n", ctrl_idx);
	rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_QSYNC_ON);
	if (rc)
		pr_err("[%s] failed to send DSI_CMD_SET_QSYNC_ON cmds rc=%d\n",
		       panel->name, rc);

	mutex_unlock(&panel->panel_lock);
	return rc;
}

int dsi_panel_send_qsync_off_dcs(struct dsi_panel *panel,
		int ctrl_idx)
{
	int rc = 0;

	if (!panel) {
		pr_err("invalid params\n");
		return -EINVAL;
	}

	mutex_lock(&panel->panel_lock);

	pr_debug("ctrl:%d qsync off\n", ctrl_idx);
	rc = dsi_panel_tx_cmd_set(panel, DSI_CMD_SET_QSYNC_OFF);
	if (rc)
		pr_err("[%s] failed to send DSI_CMD_SET_QSYNC_OFF cmds rc=%d\n",
		       panel->name, rc);

	mutex_unlock(&panel->panel_lock);
	return rc;
}

int dsi_panel_send_roi_dcs(struct dsi_panel *panel, int ctrl_idx,
		struct dsi_rect *roi)
{
Loading