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

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

Merge "msm: mdss: add support to handle LP_RX_TO/BTA_TO errors for DSI 12nm PHY"

parents 91470e42 b8881edf
Loading
Loading
Loading
Loading
+92 −15
Original line number Original line Diff line number Diff line
@@ -82,6 +82,8 @@ struct mdss_dsi_event {
static struct mdss_dsi_event dsi_event;
static struct mdss_dsi_event dsi_event;


static int dsi_event_thread(void *data);
static int dsi_event_thread(void *data);
static void dsi_send_events(struct mdss_dsi_ctrl_pdata *ctrl,
					u32 events, u32 arg);


void mdss_dsi_ctrl_init(struct device *ctrl_dev,
void mdss_dsi_ctrl_init(struct device *ctrl_dev,
			struct mdss_dsi_ctrl_pdata *ctrl)
			struct mdss_dsi_ctrl_pdata *ctrl)
@@ -820,8 +822,10 @@ static void mdss_dsi_ctl_phy_reset(struct mdss_dsi_ctrl_pdata *ctrl, u32 event)
		 * Disable PHY contention detection and receive.
		 * Disable PHY contention detection and receive.
		 * Configure the strength ctrl 1 register.
		 * Configure the strength ctrl 1 register.
		 */
		 */
		if (ctrl0->shared_data->phy_rev != DSI_PHY_REV_12NM) {
			MIPI_OUTP((ctrl0->phy_io.base) + 0x0188, 0);
			MIPI_OUTP((ctrl0->phy_io.base) + 0x0188, 0);
			MIPI_OUTP((ctrl1->phy_io.base) + 0x0188, 0);
			MIPI_OUTP((ctrl1->phy_io.base) + 0x0188, 0);
		}


		data0 = MIPI_INP(ctrl0->ctrl_base + 0x0004);
		data0 = MIPI_INP(ctrl0->ctrl_base + 0x0004);
		data1 = MIPI_INP(ctrl1->ctrl_base + 0x0004);
		data1 = MIPI_INP(ctrl1->ctrl_base + 0x0004);
@@ -876,6 +880,18 @@ static void mdss_dsi_ctl_phy_reset(struct mdss_dsi_ctrl_pdata *ctrl, u32 event)
			udelay(u_dly);
			udelay(u_dly);
		}
		}
		if (i == loop) {
		if (i == loop) {
			if ((ctrl0->shared_data->phy_rev == DSI_PHY_REV_12NM) &&
				(event == DSI_EV_LP_RX_TIMEOUT)) {
				struct mdss_panel_info *pinfo =
					&ctrl0->panel_data.panel_info;
				/* If ESD is not enabled, report panel dead */
				if (!pinfo->esd_check_enabled &&
					ctrl0->recovery)
					ctrl0->recovery->fxn(
						ctrl0->recovery->data,
						MDP_INTF_DSI_PANEL_DEAD);
				return;
			}
			MDSS_XLOG(ctrl0->ndx, ln0, 0x1f1f);
			MDSS_XLOG(ctrl0->ndx, ln0, 0x1f1f);
			MDSS_XLOG(ctrl1->ndx, ln1, 0x1f1f);
			MDSS_XLOG(ctrl1->ndx, ln1, 0x1f1f);
			pr_err("%s: Clock lane still in stop state\n",
			pr_err("%s: Clock lane still in stop state\n",
@@ -896,13 +912,20 @@ static void mdss_dsi_ctl_phy_reset(struct mdss_dsi_ctrl_pdata *ctrl, u32 event)
		 * Enable PHY contention detection and receive.
		 * Enable PHY contention detection and receive.
		 * Configure the strength ctrl 1 register.
		 * Configure the strength ctrl 1 register.
		 */
		 */
		if (ctrl0->shared_data->phy_rev != DSI_PHY_REV_12NM) {
			MIPI_OUTP((ctrl0->phy_io.base) + 0x0188, 0x6);
			MIPI_OUTP((ctrl0->phy_io.base) + 0x0188, 0x6);
			MIPI_OUTP((ctrl1->phy_io.base) + 0x0188, 0x6);
			MIPI_OUTP((ctrl1->phy_io.base) + 0x0188, 0x6);
		}
		/*
		/*
		 * Add sufficient delay to make sure
		 * Add sufficient delay to make sure
		 * pixel transmission as started
		 * pixel transmission as started
		 */
		 */
		udelay(200);
		udelay(200);
		/* Un-mask LP_RX_TIMEOUT error if recovery successful */
		if (event == DSI_EV_LP_RX_TIMEOUT) {
			mdss_dsi_set_reg(ctrl0, 0x10c, BIT(5), 0);
			mdss_dsi_set_reg(ctrl1, 0x10c, BIT(5), 0);
		}
	} else {
	} else {
		if (ctrl->recovery) {
		if (ctrl->recovery) {
			rc = ctrl->recovery->fxn(ctrl->recovery->data,
			rc = ctrl->recovery->fxn(ctrl->recovery->data,
@@ -914,6 +937,7 @@ static void mdss_dsi_ctl_phy_reset(struct mdss_dsi_ctrl_pdata *ctrl, u32 event)
			}
			}
		}
		}
		/* Disable PHY contention detection and receive */
		/* Disable PHY contention detection and receive */
		if (ctrl->shared_data->phy_rev != DSI_PHY_REV_12NM)
			MIPI_OUTP((ctrl->phy_io.base) + 0x0188, 0);
			MIPI_OUTP((ctrl->phy_io.base) + 0x0188, 0);


		data0 = MIPI_INP(ctrl->ctrl_base + 0x0004);
		data0 = MIPI_INP(ctrl->ctrl_base + 0x0004);
@@ -955,6 +979,17 @@ static void mdss_dsi_ctl_phy_reset(struct mdss_dsi_ctrl_pdata *ctrl, u32 event)
			udelay(u_dly);
			udelay(u_dly);
		}
		}
		if (i == loop) {
		if (i == loop) {
			if ((ctrl->shared_data->phy_rev == DSI_PHY_REV_12NM) &&
				(event == DSI_EV_LP_RX_TIMEOUT)) {
				struct mdss_panel_info *pinfo =
					&ctrl->panel_data.panel_info;
				/* If ESD is not enabled, report panel dead */
				if (!pinfo->esd_check_enabled && ctrl->recovery)
					ctrl->recovery->fxn(
						ctrl->recovery->data,
						MDP_INTF_DSI_PANEL_DEAD);
				return;
			}
			MDSS_XLOG(ctrl->ndx, ln0, 0x1f1f);
			MDSS_XLOG(ctrl->ndx, ln0, 0x1f1f);
			pr_err("%s: Clock lane still in stop state\n",
			pr_err("%s: Clock lane still in stop state\n",
					__func__);
					__func__);
@@ -968,12 +1003,16 @@ static void mdss_dsi_ctl_phy_reset(struct mdss_dsi_ctrl_pdata *ctrl, u32 event)
		/* Enable Video mode for DSI controller */
		/* Enable Video mode for DSI controller */
		MIPI_OUTP(ctrl->ctrl_base + 0x004, data0);
		MIPI_OUTP(ctrl->ctrl_base + 0x004, data0);
		/* Enable PHY contention detection and receiver */
		/* Enable PHY contention detection and receiver */
		if (ctrl->shared_data->phy_rev != DSI_PHY_REV_12NM)
			MIPI_OUTP((ctrl->phy_io.base) + 0x0188, 0x6);
			MIPI_OUTP((ctrl->phy_io.base) + 0x0188, 0x6);
		/*
		/*
		 * Add sufficient delay to make sure
		 * Add sufficient delay to make sure
		 * pixel transmission as started
		 * pixel transmission as started
		 */
		 */
		udelay(200);
		udelay(200);
		/* Un-mask LP_RX_TIMEOUT error if recovery successful */
		if (event == DSI_EV_LP_RX_TIMEOUT)
			mdss_dsi_set_reg(ctrl, 0x10c, BIT(5), 0);
	}
	}
	pr_debug("Recovery done\n");
	pr_debug("Recovery done\n");
}
}
@@ -1513,14 +1552,44 @@ int mdss_dsi_bta_status_check(struct mdss_dsi_ctrl_pdata *ctrl_pdata)
	ret = wait_for_completion_killable_timeout(&ctrl_pdata->bta_comp,
	ret = wait_for_completion_killable_timeout(&ctrl_pdata->bta_comp,
						DSI_BTA_EVENT_TIMEOUT);
						DSI_BTA_EVENT_TIMEOUT);
	if (ret <= 0) {
	if (ret <= 0) {
		u32 reg_val, status;

		reg_val = MIPI_INP(ctrl_pdata->ctrl_base + 0x0110);
		status = reg_val & DSI_INTR_BTA_DONE;
		if (status) {
			reg_val &= DSI_INTR_MASK_ALL;
			/* clear BTA_DONE isr only */
			reg_val |= DSI_INTR_BTA_DONE;
			MIPI_OUTP(ctrl_pdata->ctrl_base + 0x0110, reg_val);
			mdss_dsi_disable_irq(ctrl_pdata, DSI_BTA_TERM);
			mdss_dsi_disable_irq(ctrl_pdata, DSI_BTA_TERM);
			complete(&ctrl_pdata->bta_comp);
			ret = 1;
			pr_warn("%s: bta done but irq not triggered\n",
				__func__);
		} else {
			pr_err("%s: DSI BTA error: %i\n", __func__, ret);
			pr_err("%s: DSI BTA error: %i\n", __func__, ret);
			/*
			 * For 12nm DSI PHY, BTA_TO interrupt may not trigger.
			 * Treat software timer timeout as BTA_TO.
			 */
			if (ctrl_pdata->shared_data->phy_rev ==
				DSI_PHY_REV_12NM) {
				/* Mask BTA_TIMEOUT/LP_RX_TIMEOUT error */
				mdss_dsi_set_reg(ctrl_pdata, 0x10c,
					(BIT(5) | BIT(7)), (BIT(5) | BIT(7)));
				dsi_send_events(ctrl_pdata,
					DSI_EV_LP_RX_TIMEOUT, 0);
			}
			ret = -ETIMEDOUT;
		}
	}
	}


	if (ignore_underflow) {
	if (ignore_underflow) {
		u32 data = MIPI_INP((ctrl_pdata->ctrl_base) + 0x10c);
		/* clear pending overflow status */
		/* clear pending overflow status */
		mdss_dsi_set_reg(ctrl_pdata, 0xc, 0xffffffff, 0x44440000);
		mdss_dsi_set_reg(ctrl_pdata, 0xc, 0xffffffff, 0x44440000);
		/* restore overflow isr */
		/* restore overflow isr if LP_RX_TO not masked*/
		if (!(data & BIT(5)))
			mdss_dsi_set_reg(ctrl_pdata, 0x10c, 0x0f0000, 0);
			mdss_dsi_set_reg(ctrl_pdata, 0x10c, 0x0f0000, 0);
	}
	}


@@ -2164,9 +2233,11 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,


	if (mctrl && mctrl->dma_addr) {
	if (mctrl && mctrl->dma_addr) {
		if (ignored) {
		if (ignored) {
			u32 data = MIPI_INP((mctrl->ctrl_base) + 0x10c);
			/* clear pending overflow status */
			/* clear pending overflow status */
			mdss_dsi_set_reg(mctrl, 0xc, 0xffffffff, 0x44440000);
			mdss_dsi_set_reg(mctrl, 0xc, 0xffffffff, 0x44440000);
			/* restore overflow isr */
			/* restore overflow isr if LP_RX_TO not masked*/
			if (!(data & BIT(5)))
				mdss_dsi_set_reg(mctrl, 0x10c, 0x0f0000, 0);
				mdss_dsi_set_reg(mctrl, 0x10c, 0x0f0000, 0);
		}
		}
		if (mctrl->dmap_iommu_map) {
		if (mctrl->dmap_iommu_map) {
@@ -2185,9 +2256,11 @@ static int mdss_dsi_cmd_dma_tx(struct mdss_dsi_ctrl_pdata *ctrl,
	}
	}


	if (ignored) {
	if (ignored) {
		u32 data = MIPI_INP((ctrl->ctrl_base) + 0x10c);
		/* clear pending overflow status */
		/* clear pending overflow status */
		mdss_dsi_set_reg(ctrl, 0xc, 0xffffffff, 0x44440000);
		mdss_dsi_set_reg(ctrl, 0xc, 0xffffffff, 0x44440000);
		/* restore overflow isr */
		/* restore overflow isr if LP_RX_TO/BTA_TO not masked*/
		if (!(data & BIT(5)))
			mdss_dsi_set_reg(ctrl, 0x10c, 0x0f0000, 0);
			mdss_dsi_set_reg(ctrl, 0x10c, 0x0f0000, 0);
	}
	}
	ctrl->dma_addr = 0;
	ctrl->dma_addr = 0;
@@ -3024,8 +3097,12 @@ static bool mdss_dsi_timeout_status(struct mdss_dsi_ctrl_pdata *ctrl)


	if (status & 0x0111) {
	if (status & 0x0111) {
		MIPI_OUTP(base + 0x00c0, status);
		MIPI_OUTP(base + 0x00c0, status);
		if (status & 0x0110)
		if (status & 0x0110) {
			/* Mask BTA_TIMEOUT/LP_RX_TIMEOUT error */
			mdss_dsi_set_reg(ctrl, 0x10c,
				(BIT(5) | BIT(7)), (BIT(5) | BIT(7)));
			dsi_send_events(ctrl, DSI_EV_LP_RX_TIMEOUT, 0);
			dsi_send_events(ctrl, DSI_EV_LP_RX_TIMEOUT, 0);
		}
		pr_err("%s: status=%x\n", __func__, status);
		pr_err("%s: status=%x\n", __func__, status);
		ret = true;
		ret = true;
	}
	}
+7 −2
Original line number Original line Diff line number Diff line
@@ -1135,16 +1135,21 @@ static int mdss_mdp_cmd_intf_recovery(void *data, int event)
		return -EINVAL;
		return -EINVAL;


	/*
	/*
	 * Currently, only intf_fifo_underflow is
	 * Currently, intf_fifo_overflow is not
	 * supported for recovery sequence for command
	 * supported for recovery sequence for command
	 * mode DSI interface
	 * mode DSI interface
	 */
	 */
	if (event != MDP_INTF_DSI_CMD_FIFO_UNDERFLOW) {
	if (event == MDP_INTF_DSI_VIDEO_FIFO_OVERFLOW) {
		pr_warn("%s: unsupported recovery event:%d\n",
		pr_warn("%s: unsupported recovery event:%d\n",
					__func__, event);
					__func__, event);
		return -EPERM;
		return -EPERM;
	}
	}


	if (event == MDP_INTF_DSI_PANEL_DEAD) {
		mdss_fb_report_panel_dead(ctx->ctl->mfd);
		return 0;
	}

	if (atomic_read(&ctx->koff_cnt)) {
	if (atomic_read(&ctx->koff_cnt)) {
		mdss_mdp_ctl_reset(ctx->ctl, true);
		mdss_mdp_ctl_reset(ctx->ctl, true);
		reset_done = true;
		reset_done = true;
+7 −2
Original line number Original line Diff line number Diff line
@@ -327,11 +327,11 @@ static int mdss_mdp_video_intf_recovery(void *data, int event)
	}
	}


	/*
	/*
	 * Currently, only intf_fifo_overflow is
	 * Currently, intf_fifo_underflow is not
	 * supported for recovery sequence for video
	 * supported for recovery sequence for video
	 * mode DSI interface
	 * mode DSI interface
	 */
	 */
	if (event != MDP_INTF_DSI_VIDEO_FIFO_OVERFLOW) {
	if (event == MDP_INTF_DSI_CMD_FIFO_UNDERFLOW) {
		pr_warn("%s: unsupported recovery event:%d\n",
		pr_warn("%s: unsupported recovery event:%d\n",
					__func__, event);
					__func__, event);
		return -EPERM;
		return -EPERM;
@@ -341,6 +341,11 @@ static int mdss_mdp_video_intf_recovery(void *data, int event)
	pr_debug("%s: ctl num = %d, event = %d\n",
	pr_debug("%s: ctl num = %d, event = %d\n",
				__func__, ctl->num, event);
				__func__, ctl->num, event);


	if (event == MDP_INTF_DSI_PANEL_DEAD) {
		mdss_fb_report_panel_dead(ctx->ctl->mfd);
		return 0;
	}

	pinfo = &ctl->panel_data->panel_info;
	pinfo = &ctl->panel_data->panel_info;
	clk_rate = ((ctl->intf_type == MDSS_INTF_DSI) ?
	clk_rate = ((ctl->intf_type == MDSS_INTF_DSI) ?
			pinfo->mipi.dsi_pclk_rate :
			pinfo->mipi.dsi_pclk_rate :
+1 −0
Original line number Original line Diff line number Diff line
@@ -167,6 +167,7 @@ struct mdss_panel_cfg {


#define MDP_INTF_DSI_CMD_FIFO_UNDERFLOW		0x0001
#define MDP_INTF_DSI_CMD_FIFO_UNDERFLOW		0x0001
#define MDP_INTF_DSI_VIDEO_FIFO_OVERFLOW	0x0002
#define MDP_INTF_DSI_VIDEO_FIFO_OVERFLOW	0x0002
#define MDP_INTF_DSI_PANEL_DEAD			0x0003




enum {
enum {