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

Commit 290557b2 authored by Shivaraj Shetty's avatar Shivaraj Shetty
Browse files

msm: mdss: Add support for checking panel status through register read



ESD feature may need to check the status of the panel by reading specific
panel register depending on the panel. Add support for ESD status check
through status register read and to configure the method used for checking
panel status through panel dtsi entry.

CRs-Fixed: 660805
Change-Id: I13b11362722eb2ad379162944eafff04ec01d1cb
Signed-off-by: default avatarShivaraj Shetty <shivaraj@codeaurora.org>
parent 8c5fb457
Loading
Loading
Loading
Loading
+25 −0
Original line number Diff line number Diff line
@@ -307,6 +307,27 @@ Optional properties:
					left, top, width, height alignments and minimum width and
					height values
- qcom,esd-check-enabled:		Boolean used to enable ESD recovery feature.
- qcom,mdss-dsi-panel-status-command:	A byte stream formed by multiple dcs packets based on
					qcom dsi controller protocol, to read the panel status.
					This value is used to kick in the ESD recovery.
					byte 0: dcs data type
					byte 1: set to indicate this is an individual packet
						 (no chain)
					byte 2: virtual channel number
					byte 3: expect ack from client (dcs read command)
					byte 4: wait number of specified ms after dcs command
						 transmitted
					byte 5, 6: 16 bits length in network byte order
					byte 7 and beyond: number byte of payload
- qcom,mdss-dsi-panel-status-command-mode:
					String that specifies the ctrl state for reading the panel status.
					"dsi_lp_mode" = DSI low power mode
					"dsi_hs_mode" = DSI high speed mode
- qcom,mdss-dsi-panel-status-check-mode:Specifies the panel status check method for ESD recovery.
					"bta_check" = Uses BTA to check the panel status
					"reg_read" = Reads panel status register to check the panel status
- qcom,mdss-dsi-panel-status-value:	Specifies the value of the panel status register when the panel is
					in good state.

Note, if a given optional qcom,* binding is not present, then the driver will configure
the default values specified.
@@ -414,5 +435,9 @@ Example:
		qcom,ulps-enabled;
		qcom,panel-roi-alignment = <4 4 2 2 20 20>;
		qcom,esd-check-enabled;
		qcom,mdss-dsi-panel-status-command = [06 01 00 01 05 00 02 0A 08];
		qcom,mdss-dsi-panel-status-command-state = "dsi_lp_mode";
		qcom,mdss-dsi-panel-status-check-mode = "reg_read";
		qcom,mdss-dsi-panel-status-value = <0x9c>;
	};
};
+1 −1
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ void mdss_check_dsi_ctrl_status(struct work_struct *work, uint32_t interval)
		mutex_unlock(&mdp5_data->ov_lock);
		if (ctl->shared_lock)
			mutex_unlock(ctl->shared_lock);
		pr_err("%s: DSI turning off, avoiding BTA status check\n",
		pr_err("%s: DSI turning off, avoiding panel status check\n",
							__func__);
		return;
	}
+9 −1
Original line number Diff line number Diff line
@@ -1680,8 +1680,16 @@ int dsi_panel_device_register(struct device_node *pan_node,
	}

	ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler;

	if (ctrl_pdata->status_mode == ESD_REG)
		ctrl_pdata->check_status = mdss_dsi_reg_status_check;
	else if (ctrl_pdata->status_mode == ESD_BTA)
		ctrl_pdata->check_status = mdss_dsi_bta_status_check;

	if (ctrl_pdata->status_mode == ESD_MAX) {
		pr_err("%s: Using default BTA for ESD check\n", __func__);
		ctrl_pdata->check_status = mdss_dsi_bta_status_check;
	}
	if (ctrl_pdata->bklt_ctrl == BL_PWM)
		mdss_dsi_panel_pwm_cfg(ctrl_pdata);

+11 −0
Original line number Diff line number Diff line
@@ -81,6 +81,12 @@ enum dsi_panel_bl_ctrl {
	UNKNOWN_CTRL,
};

enum dsi_panel_status_mode {
	ESD_BTA,
	ESD_REG,
	ESD_MAX,
};

enum dsi_ctrl_op_mode {
	DSI_LP_MODE,
	DSI_HS_MODE,
@@ -292,6 +298,8 @@ struct mdss_dsi_ctrl_pdata {

	struct dsi_panel_cmds on_cmds;
	struct dsi_panel_cmds off_cmds;
	struct dsi_panel_cmds status_cmds;
	u32 status_value;

	struct dcs_cmd_list cmdlist;
	struct completion dma_comp;
@@ -308,6 +316,8 @@ struct mdss_dsi_ctrl_pdata {

	struct dsi_buf tx_buf;
	struct dsi_buf rx_buf;
	struct dsi_buf status_buf;
	int status_mode;

	struct dsi_pinctrl_res pin_res;
};
@@ -369,6 +379,7 @@ void mdss_dsi_wait4video_done(struct mdss_dsi_ctrl_pdata *ctrl);
int mdss_dsi_cmdlist_commit(struct mdss_dsi_ctrl_pdata *ctrl, int from_mdp);
void mdss_dsi_cmdlist_kickoff(int intf);
int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl);
int mdss_dsi_reg_status_check(struct mdss_dsi_ctrl_pdata *ctrl);
bool __mdss_dsi_clk_enabled(struct mdss_dsi_ctrl_pdata *ctrl, u8 clk_type);

int mdss_dsi_panel_init(struct device_node *node,
+77 −0
Original line number Diff line number Diff line
@@ -100,6 +100,7 @@ void mdss_dsi_ctrl_init(struct device *ctrl_dev,
	mutex_init(&ctrl->cmd_mutex);
	mdss_dsi_buf_alloc(ctrl_dev, &ctrl->tx_buf, SZ_4K);
	mdss_dsi_buf_alloc(ctrl_dev, &ctrl->rx_buf, SZ_4K);
	mdss_dsi_buf_alloc(ctrl_dev, &ctrl->status_buf, SZ_4K);
	ctrl->cmdlist_commit = mdss_dsi_cmdlist_commit;


@@ -613,6 +614,82 @@ void mdss_dsi_cmd_bta_sw_trigger(struct mdss_panel_data *pdata)
	pr_debug("%s: BTA done, status = %d\n", __func__, status);
}

static int mdss_dsi_read_status(struct mdss_dsi_ctrl_pdata *ctrl)
{
	struct dcs_cmd_req cmdreq;

	memset(&cmdreq, 0, sizeof(cmdreq));
	cmdreq.cmds = ctrl->status_cmds.cmds;
	cmdreq.cmds_cnt = ctrl->status_cmds.cmd_cnt;
	cmdreq.flags = CMD_REQ_COMMIT | CMD_CLK_CTRL | CMD_REQ_RX;
	cmdreq.rlen = 0;
	cmdreq.cb = NULL;
	cmdreq.rbuf = ctrl->status_buf.data;

	return mdss_dsi_cmdlist_put(ctrl, &cmdreq);
}


/**
 * mdss_dsi_reg_status_check() - Check dsi panel status through reg read
 * @ctrl_pdata: pointer to the dsi controller structure
 *
 * This function can be used to check the panel status through reading the
 * status register from the panel.
 *
 * Return: positive value if the panel is in good state, negative value or
 * zero otherwise.
 */
int mdss_dsi_reg_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
	int ret = 0;

	if (ctrl_pdata == NULL) {
		pr_err("%s: Invalid input data\n", __func__);
		return 0;
	}

	pr_debug("%s: Checking Register status\n", __func__);

	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1);

	if (ctrl_pdata->status_cmds.link_state == DSI_HS_MODE)
		mdss_dsi_set_tx_power_mode(0, &ctrl_pdata->panel_data);

	ret = mdss_dsi_read_status(ctrl_pdata);

	if (ctrl_pdata->status_cmds.link_state == DSI_HS_MODE)
		mdss_dsi_set_tx_power_mode(1, &ctrl_pdata->panel_data);

	if (ret == 0) {
		if (ctrl_pdata->status_buf.data[0] !=
						ctrl_pdata->status_value) {
			pr_err("%s: Read back value from panel is incorrect\n",
								__func__);
			ret = -EINVAL;
		} else {
			ret = 1;
		}
	} else {
		pr_err("%s: Read status register returned error\n", __func__);
	}

	mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0);
	pr_debug("%s: Read register done with ret: %d\n", __func__, ret);

	return ret;
}

/**
 * mdss_dsi_bta_status_check() - Check dsi panel status through bta check
 * @ctrl_pdata: pointer to the dsi controller structure
 *
 * This function can be used to check status of the panel using bta check
 * for the panel.
 *
 * Return: positive value if the panel is in good state, negative value or
 * zero otherwise.
 */
int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
	int ret = 0;
Loading