diff options
| author | Jeevan Shriram <jshriram@codeaurora.org> | 2014-09-30 11:11:04 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:34:55 -0700 |
| commit | e4cf22a1fe47e554496c04e2f2aabfcaba5abd92 (patch) | |
| tree | f7bb15bc93651579fcc633e50f86a22c55ec687c | |
| parent | 5f4a8f2bcb89625846b9d43e757eeccfb936d1d7 (diff) | |
mdss: dsi: add support for data lane workaround for command mode
Add support for DSI data lane workaround if the DSI data lanes
are in stop state and not active for MDSS v1.5 and v1.9.
Also, always check for the DSI lane status when the frame is
being sent to DSI host.
Change-Id: Id1cfcdcaf709c571840449e4517db760d5058c90
Signed-off-by: Jeevan Shriram <jshriram@codeaurora.org>
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.c | 3 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.h | 2 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi_host.c | 103 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_panel.h | 3 |
5 files changed, 114 insertions, 1 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index a7cc68925608..cc0060fd6955 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -1253,6 +1253,9 @@ static int mdss_dsi_event_handler(struct mdss_panel_data *pdata, rc = mdss_dsi_register_recovery_handler(ctrl_pdata, (struct mdss_intf_recovery *)arg); break; + case MDSS_EVENT_INTF_RESTORE: + mdss_dsi_ctrl_phy_restore(ctrl_pdata); + break; default: pr_debug("%s: unhandled event=%d\n", __func__, event); break; diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h index 4a59131cda79..86a30e6e10a9 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.h +++ b/drivers/video/fbdev/msm/mdss_dsi.h @@ -440,7 +440,7 @@ void mdss_dsi_phy_disable(struct mdss_dsi_ctrl_pdata *ctrl); void mdss_dsi_cmd_test_pattern(struct mdss_dsi_ctrl_pdata *ctrl); void mdss_dsi_video_test_pattern(struct mdss_dsi_ctrl_pdata *ctrl); void mdss_dsi_panel_pwm_cfg(struct mdss_dsi_ctrl_pdata *ctrl); - +void mdss_dsi_ctrl_phy_restore(struct mdss_dsi_ctrl_pdata *ctrl); void mdss_dsi_ctrl_init(struct device *ctrl_dev, struct mdss_dsi_ctrl_pdata *ctrl); void mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl); diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c index 03f0fe0226a3..d411cd776f88 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_host.c +++ b/drivers/video/fbdev/msm/mdss_dsi_host.c @@ -434,6 +434,109 @@ void mdss_dsi_sw_reset(struct mdss_dsi_ctrl_pdata *ctrl, bool restore) } } +void mdss_dsi_ctrl_phy_restore(struct mdss_dsi_ctrl_pdata *ctrl) +{ + struct mdss_dsi_ctrl_pdata *ctrl0, *ctrl1; + u32 ln0, ln1, ln_ctrl0, ln_ctrl1, i; + /* + * Add delay suggested by HW team. + */ + u32 loop = 10; + + if (ctrl->ndx == DSI_CTRL_1) + return; + + pr_debug("MDSS DSI CTRL PHY restore. ctrl-num = %d\n", ctrl->ndx); + + ctrl0 = mdss_dsi_get_ctrl_by_index(DSI_CTRL_0); + if (mdss_dsi_split_display_enabled()) { + ctrl1 = mdss_dsi_get_ctrl_by_index(DSI_CTRL_1); + if (!ctrl1) + return; + + ln_ctrl0 = MIPI_INP(ctrl0->ctrl_base + 0x00ac); + ln_ctrl1 = MIPI_INP(ctrl1->ctrl_base + 0x00ac); + MIPI_OUTP(ctrl0->ctrl_base + 0x0ac, ln_ctrl0 & ~BIT(28)); + MIPI_OUTP(ctrl1->ctrl_base + 0x0ac, ln_ctrl1 & ~BIT(28)); + + /* + * Toggle Clk lane Force TX stop so that + * clk lane status is no more in stop state + */ + ln0 = MIPI_INP(ctrl0->ctrl_base + 0x00a8); + ln1 = MIPI_INP(ctrl1->ctrl_base + 0x00a8); + + pr_debug("%s: lane status, ctrl0 = 0x%x, ctrl1 = 0x%x\n", + __func__, ln0, ln1); + + if ((ln0 == 0x1f0f) || (ln1 == 0x1f0f)) { + ln_ctrl0 = MIPI_INP(ctrl0->ctrl_base + 0x00ac); + ln_ctrl1 = MIPI_INP(ctrl1->ctrl_base + 0x00ac); + MIPI_OUTP(ctrl0->ctrl_base + 0x0ac, ln_ctrl0 | BIT(20)); + MIPI_OUTP(ctrl1->ctrl_base + 0x0ac, ln_ctrl1 | BIT(20)); + + for (i = 0; i < loop; i++) { + ln0 = MIPI_INP(ctrl0->ctrl_base + 0x00a8); + ln1 = MIPI_INP(ctrl1->ctrl_base + 0x00a8); + if ((ln0 == 0x1f1f) && (ln1 == 0x1f1f)) + break; + else + /* + * check clk lane status for every 1 + * milli second + */ + udelay(1000); + } + pr_debug("%s: lane ctrl, ctrl0 = 0x%x, ctrl1 = 0x%x\n", + __func__, ln0, ln1); + MIPI_OUTP(ctrl0->ctrl_base + 0x0ac, + ln_ctrl0 & ~BIT(20)); + MIPI_OUTP(ctrl1->ctrl_base + 0x0ac, + ln_ctrl1 & ~BIT(20)); + } + + ln_ctrl0 = MIPI_INP(ctrl0->ctrl_base + 0x00ac); + ln_ctrl1 = MIPI_INP(ctrl1->ctrl_base + 0x00ac); + MIPI_OUTP(ctrl0->ctrl_base + 0x0ac, ln_ctrl0 | BIT(28)); + MIPI_OUTP(ctrl1->ctrl_base + 0x0ac, ln_ctrl1 | BIT(28)); + } else { + ln_ctrl0 = MIPI_INP(ctrl0->ctrl_base + 0x00ac); + MIPI_OUTP(ctrl0->ctrl_base + 0x0ac, ln_ctrl0 & ~BIT(28)); + + /* + * Toggle Clk lane Force TX stop so that + * clk lane status is no more in stop state + */ + ln0 = MIPI_INP(ctrl0->ctrl_base + 0x00a8); + + pr_debug("%s: lane status, ctrl0 = 0x%x\n", __func__, ln0); + + if (ln0 == 0x1f0f) { + ln_ctrl0 = MIPI_INP(ctrl0->ctrl_base + 0x00ac); + MIPI_OUTP(ctrl0->ctrl_base + 0x0ac, ln_ctrl0 | BIT(20)); + + for (i = 0; i < loop; i++) { + ln0 = MIPI_INP(ctrl0->ctrl_base + 0x00a8); + if (ln0 == 0x1f1f) + break; + else + /* + * check clk lane status for every 1 + * milli second + */ + udelay(1000); + } + pr_debug("%s: lane ctrl, ctrl0 = 0x%x\n", + __func__, ln0); + MIPI_OUTP(ctrl0->ctrl_base + 0x0ac, + ln_ctrl0 & ~BIT(20)); + } + + ln_ctrl0 = MIPI_INP(ctrl0->ctrl_base + 0x00ac); + MIPI_OUTP(ctrl0->ctrl_base + 0x0ac, ln_ctrl0 | BIT(28)); + } +} + static void mdss_dsi_ctl_phy_reset(struct mdss_dsi_ctrl_pdata *ctrl) { u32 data0, data1; diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index 0596a20b139a..2761f485ae25 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -775,6 +775,10 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) if (sctx) mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_COMP, sctx->pp_num); + if (ctl->mdata->mdp_rev == MDSS_MDP_HW_REV_105 || + ctl->mdata->mdp_rev == MDSS_MDP_HW_REV_109) + mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_INTF_RESTORE, NULL); + mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_START, 1); /* Kickoff */ mdss_mdp_ctl_perf_set_transaction_status(ctl, diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index b6b6f6d12481..1c9da0cc7829 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -177,6 +177,8 @@ struct mdss_intf_recovery { * - 1: update to command mode * @MDSS_EVENT_REGISTER_RECOVERY_HANDLER: Event to recover the interface in * case there was any errors detected. + * @MDSS_EVENT_INTF_RESTORE: Event to restore the interface in case there + * was any errors detected during normal operation. */ enum mdss_intf_events { MDSS_EVENT_RESET = 1, @@ -198,6 +200,7 @@ enum mdss_intf_events { MDSS_EVENT_DSI_STREAM_SIZE, MDSS_EVENT_DSI_DYNAMIC_SWITCH, MDSS_EVENT_REGISTER_RECOVERY_HANDLER, + MDSS_EVENT_INTF_RESTORE, }; struct lcd_panel_info { |
