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

Commit 67b6bbda authored by Dhaval Patel's avatar Dhaval Patel
Browse files

msm: mdss: Add BTA status check API in DSI controller



Add Bus-Turn-Around (BTA) status check API in DSI
controller to check if it is alive or not. Subscriber
of this API should send relevant notification to user
space for correct action. Update fb driver and cmd
interface to support the BTA failure scenario.

Change-Id: Ic78379b31a48278282182fdba6ba7b2e6f9c26d5
Signed-off-by: default avatarDhaval Patel <pdhaval@codeaurora.org>
parent c07b9ea7
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1307,6 +1307,7 @@ int dsi_panel_device_register(struct device_node *pan_node,
	}

	ctrl_pdata->panel_data.event_handler = mdss_dsi_event_handler;
	ctrl_pdata->check_status = mdss_dsi_bta_status_check;

	if (ctrl_pdata->bklt_ctrl == BL_PWM)
		mdss_dsi_panel_pwm_cfg(ctrl_pdata);
+6 −0
Original line number Diff line number Diff line
@@ -118,6 +118,8 @@ enum dsi_ctrl_op_mode {

#define DSI_INTR_ERROR_MASK		BIT(25)
#define DSI_INTR_ERROR			BIT(24)
#define DSI_INTR_BTA_DONE_MASK          BIT(21)
#define DSI_INTR_BTA_DONE               BIT(20)
#define DSI_INTR_VIDEO_DONE_MASK	BIT(17)
#define DSI_INTR_VIDEO_DONE		BIT(16)
#define DSI_INTR_CMD_MDP_DONE_MASK	BIT(9)
@@ -133,6 +135,7 @@ enum dsi_ctrl_op_mode {

#define DSI_VIDEO_TERM  BIT(16)
#define DSI_MDP_TERM    BIT(8)
#define DSI_BTA_TERM    BIT(1)
#define DSI_CMD_TERM    BIT(0)

extern struct device dsi_dev;
@@ -315,6 +318,7 @@ struct mdss_dsi_ctrl_pdata {
	int (*on) (struct mdss_panel_data *pdata);
	int (*off) (struct mdss_panel_data *pdata);
	int (*partial_update_fnc) (struct mdss_panel_data *pdata);
	int (*check_status) (struct mdss_dsi_ctrl_pdata *pdata);
	struct mdss_panel_data panel_data;
	unsigned char *ctrl_base;
	int reg_size;
@@ -362,6 +366,7 @@ struct mdss_dsi_ctrl_pdata {
	struct completion dma_comp;
	struct completion mdp_comp;
	struct completion video_comp;
	struct completion bta_comp;
	spinlock_t irq_lock;
	spinlock_t mdp_lock;
	int mdp_busy;
@@ -430,6 +435,7 @@ int mdss_dsi_cmdlist_put(struct mdss_dsi_ctrl_pdata *ctrl,
				struct dcs_cmd_req *cmdreq);
struct dcs_cmd_req *mdss_dsi_cmdlist_get(struct mdss_dsi_ctrl_pdata *ctrl);
void mdss_dsi_cmdlist_kickoff(int intf);
int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl);

int mdss_dsi_panel_init(struct device_node *node,
		struct mdss_dsi_ctrl_pdata *ctrl_pdata,
+51 −2
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ struct mdss_hw mdss_dsi1_hw = {

#define DSI_EVENT_Q_MAX	4

#define DSI_BTA_EVENT_TIMEOUT (HZ / 10)

/* event */
struct dsi_event_q {
	struct mdss_dsi_ctrl_pdata *ctrl;
@@ -98,6 +100,7 @@ void mdss_dsi_ctrl_init(struct mdss_dsi_ctrl_pdata *ctrl)
	init_completion(&ctrl->dma_comp);
	init_completion(&ctrl->mdp_comp);
	init_completion(&ctrl->video_comp);
	init_completion(&ctrl->bta_comp);
	spin_lock_init(&ctrl->irq_lock);
	spin_lock_init(&ctrl->mdp_lock);
	mutex_init(&ctrl->mutex);
@@ -1107,14 +1110,14 @@ void mdss_dsi_op_mode_config(int mode,

	if (mode == DSI_VIDEO_MODE) {
		dsi_ctrl |= 0x03;
		intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK;
		intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_BTA_DONE_MASK;
	} else {		/* command mode */
		dsi_ctrl |= 0x05;
		if (pdata->panel_info.type == MIPI_VIDEO_PANEL)
			dsi_ctrl |= 0x02;

		intr_ctrl = DSI_INTR_CMD_DMA_DONE_MASK | DSI_INTR_ERROR_MASK |
				DSI_INTR_CMD_MDP_DONE_MASK;
			DSI_INTR_CMD_MDP_DONE_MASK | DSI_INTR_BTA_DONE_MASK;
	}

	if (ctrl_pdata->shared_pdata.broadcast_enable)
@@ -1160,6 +1163,45 @@ void mdss_dsi_cmd_bta_sw_trigger(struct mdss_panel_data *pdata)
	pr_debug("%s: BTA done, status = %d\n", __func__, status);
}

int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
{
	int ret = 0;
	unsigned long flag;

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

		/*
		 * This should not return error otherwise
		 * BTA status thread will treat it as dead panel scenario
		 * and request for blank/unblank
		 */
		return 0;
	}

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

	mdss_dsi_clk_ctrl(ctrl_pdata, 1);
	spin_lock_irqsave(&ctrl_pdata->mdp_lock, flag);
	INIT_COMPLETION(ctrl_pdata->bta_comp);
	mdss_dsi_enable_irq(ctrl_pdata, DSI_BTA_TERM);
	spin_unlock_irqrestore(&ctrl_pdata->mdp_lock, flag);
	MIPI_OUTP(ctrl_pdata->ctrl_base + 0x098, 0x01); /* trigger  */
	wmb();

	ret = wait_for_completion_killable_timeout(&ctrl_pdata->bta_comp,
						DSI_BTA_EVENT_TIMEOUT);
	if (ret <= 0) {
		mdss_dsi_disable_irq(ctrl_pdata, DSI_BTA_TERM);
		pr_err("%s: DSI BTA error: %i\n", __func__, ret);
	}

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

	return ret;
}

static char set_tear_on[2] = {0x35, 0x00};
static struct dsi_cmd_desc dsi_tear_on_cmd = {
	{DTYPE_DCS_WRITE1, 1, 0, 0, 0, sizeof(set_tear_on)}, set_tear_on};
@@ -2079,5 +2121,12 @@ irqreturn_t mdss_dsi_isr(int irq, void *ptr)
		spin_unlock(&ctrl->mdp_lock);
	}

	if (isr & DSI_INTR_BTA_DONE) {
		spin_lock(&ctrl->mdp_lock);
		mdss_dsi_disable_irq_nosync(ctrl, DSI_BTA_TERM);
		complete(&ctrl->bta_comp);
		spin_unlock(&ctrl->mdp_lock);
	}

	return IRQ_HANDLED;
}
+3 −1
Original line number Diff line number Diff line
@@ -708,8 +708,10 @@ static int mdss_fb_blank_sub(int blank_mode, struct fb_info *info,
	case FB_BLANK_UNBLANK:
		if (!mfd->panel_power_on && mfd->mdp.on_fnc) {
			ret = mfd->mdp.on_fnc(mfd);
			if (ret == 0)
			if (ret == 0) {
				mfd->panel_power_on = true;
				mfd->panel_info->panel_dead = false;
			}
			mutex_lock(&mfd->update.lock);
			mfd->update.type = NOTIFY_TYPE_UPDATE;
			mutex_unlock(&mfd->update.lock);
+16 −1
Original line number Diff line number Diff line
@@ -509,6 +509,7 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg)
int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl)
{
	struct mdss_mdp_cmd_ctx *ctx;
	struct mdss_panel_info *pinfo;
	unsigned long flags;
	struct mdss_mdp_vsync_handler *tmp, *handle;
	int need_wait = 0;
@@ -532,9 +533,23 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl)

	if (need_wait)
		if (wait_for_completion_timeout(&ctx->stop_comp, STOP_TIMEOUT)
		    <= 0)
		    <= 0) {
			WARN(1, "stop cmd time out\n");

			if (IS_ERR_OR_NULL(ctl->panel_data)) {
				pr_err("no panel data\n");
			} else {
				pinfo = &ctl->panel_data->panel_info;

				if (pinfo->panel_dead) {
					mdss_mdp_irq_disable
						(MDSS_MDP_IRQ_PING_PONG_RD_PTR,
								ctx->pp_num);
					ctx->rdptr_enabled = 0;
				}
			}
		}

	if (cancel_work_sync(&ctx->clk_work))
		pr_debug("no pending clk work\n");

Loading