diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.c | 34 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi_host.c | 11 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.c | 11 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 23 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_panel.h | 3 |
5 files changed, 71 insertions, 11 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index c7cac996e5c0..797c8b4a2eb1 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -1815,6 +1815,18 @@ static int mdss_dsi_post_panel_on(struct mdss_panel_data *pdata) return 0; } +irqreturn_t test_hw_vsync_handler(int irq, void *data) +{ + struct mdss_panel_data *pdata = (struct mdss_panel_data *)data; + + pr_debug("HW VSYNC\n"); + MDSS_XLOG(0xaaa, irq); + complete_all(&pdata->te_done); + if (pdata->next) + complete_all(&pdata->next->te_done); + return IRQ_HANDLED; +} + int mdss_dsi_cont_splash_on(struct mdss_panel_data *pdata) { int ret = 0; @@ -3296,6 +3308,8 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev) struct device_node *dsi_pan_node = NULL; const char *ctrl_name; struct mdss_util_intf *util; + static int te_irq_registered; + struct mdss_panel_data *pdata; if (!pdev || !pdev->dev.of_node) { pr_err("%s: pdev not found for DSI controller\n", __func__); @@ -3421,6 +3435,23 @@ static int mdss_dsi_ctrl_probe(struct platform_device *pdev) disable_irq(gpio_to_irq(ctrl_pdata->disp_te_gpio)); } + pdata = &ctrl_pdata->panel_data; + init_completion(&pdata->te_done); + if (pdata->panel_info.type == MIPI_CMD_PANEL) { + if (!te_irq_registered) { + rc = devm_request_irq(&pdev->dev, + gpio_to_irq(pdata->panel_te_gpio), + test_hw_vsync_handler, IRQF_TRIGGER_FALLING, + "VSYNC_GPIO", &ctrl_pdata->panel_data); + if (rc) { + pr_err("%s: TE request_irq failed\n", __func__); + goto error_shadow_clk_deinit; + } + te_irq_registered = 1; + disable_irq_nosync(gpio_to_irq(pdata->panel_te_gpio)); + } + } + rc = mdss_dsi_get_bridge_chip_params(pinfo, ctrl_pdata, pdev); if (rc) { pr_err("%s: Failed to get bridge params\n", __func__); @@ -4241,6 +4272,8 @@ static int mdss_dsi_parse_gpio_params(struct platform_device *ctrl_pdev, * If disp_en_gpio has been set previously (disp_en_gpio > 0) * while parsing the panel node, then do not override it */ + struct mdss_panel_data *pdata = &ctrl_pdata->panel_data; + if (ctrl_pdata->disp_en_gpio <= 0) { ctrl_pdata->disp_en_gpio = of_get_named_gpio( ctrl_pdev->dev.of_node, @@ -4257,6 +4290,7 @@ static int mdss_dsi_parse_gpio_params(struct platform_device *ctrl_pdev, if (!gpio_is_valid(ctrl_pdata->disp_te_gpio)) pr_err("%s:%d, TE gpio not specified\n", __func__, __LINE__); + pdata->panel_te_gpio = ctrl_pdata->disp_te_gpio; ctrl_pdata->bklt_en_gpio = of_get_named_gpio(ctrl_pdev->dev.of_node, "qcom,platform-bklight-en-gpio", 0); diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c index 1a471155072b..007272dabae2 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_host.c +++ b/drivers/video/fbdev/msm/mdss_dsi_host.c @@ -2558,15 +2558,8 @@ void mdss_dsi_cmd_mdp_busy(struct mdss_dsi_ctrl_pdata *ctrl) if (!ctrl->mdp_busy) rc = 1; spin_unlock_irqrestore(&ctrl->mdp_lock, flags); - if (!rc) { - if (mdss_dsi_mdp_busy_tout_check(ctrl)) { - pr_err("%s: timeout error\n", __func__); - MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl", - "dsi0_phy", "dsi1_ctrl", "dsi1_phy", - "vbif", "vbif_nrt", "dbg_bus", - "vbif_dbg_bus", "dsi_dbg_bus", "panic"); - } - } + if (!rc && mdss_dsi_mdp_busy_tout_check(ctrl)) + pr_err("%s: timeout error\n", __func__); } pr_debug("%s: done pid=%d\n", __func__, current->pid); MDSS_XLOG(ctrl->ndx, ctrl->mdp_busy, current->pid, XLOG_FUNC_EXIT); diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index 4eca9cb39223..c0fd48519124 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -4630,6 +4630,7 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info, struct mdp_output_layer __user *output_layer_user; struct mdp_destination_scaler_data *ds_data = NULL; struct mdp_destination_scaler_data __user *ds_data_user; + struct msm_fb_data_type *mfd; ret = copy_from_user(&commit, argp, sizeof(struct mdp_layer_commit)); if (ret) { @@ -4637,6 +4638,16 @@ static int mdss_fb_atomic_commit_ioctl(struct fb_info *info, return ret; } + mfd = (struct msm_fb_data_type *)info->par; + if (!mfd) + return -EINVAL; + + if (mfd->panel_info->panel_dead) { + pr_debug("early commit return\n"); + MDSS_XLOG(mfd->panel_info->panel_dead); + return 0; + } + output_layer_user = commit.commit_v1.output_layer; if (output_layer_user) { buffer_size = sizeof(struct mdp_output_layer); diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index bdbec0b4e721..2e017fe5ec02 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -21,6 +21,7 @@ #include "mdss_debug.h" #include "mdss_mdp_trace.h" #include "mdss_dsi_clk.h" +#include <linux/interrupt.h> #define MAX_RECOVERY_TRIALS 10 #define MAX_SESSIONS 2 @@ -2090,7 +2091,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) struct mdss_mdp_cmd_ctx *ctx; struct mdss_panel_data *pdata; unsigned long flags; - int rc = 0; + int rc = 0, te_irq; ctx = (struct mdss_mdp_cmd_ctx *) ctl->intf_ctx[MASTER_CTX]; if (!ctx) { @@ -2144,7 +2145,21 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) __func__, ctl->num, rc, ctx->pp_timeout_report_cnt, atomic_read(&ctx->koff_cnt)); - if (ctx->pp_timeout_report_cnt == 0) { + + /* enable TE irq to check if it is coming from the panel */ + te_irq = gpio_to_irq(pdata->panel_te_gpio); + enable_irq(te_irq); + + /* wait for 20ms to ensure we are getting the next TE */ + usleep_range(20000, 20010); + + reinit_completion(&pdata->te_done); + rc = wait_for_completion_timeout(&pdata->te_done, KOFF_TIMEOUT); + + if (!rc) { + MDSS_XLOG(0xbac); + mdss_fb_report_panel_dead(ctl->mfd); + } else if (ctx->pp_timeout_report_cnt == 0) { MDSS_XLOG(0xbad); MDSS_XLOG_TOUT_HANDLER("mdp", "dsi0_ctrl", "dsi0_phy", "dsi1_ctrl", "dsi1_phy", "vbif", "vbif_nrt", @@ -2158,6 +2173,10 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) "dsi_dbg_bus", "panic"); mdss_fb_report_panel_dead(ctl->mfd); } + + /* disable te irq */ + disable_irq_nosync(te_irq); + ctx->pp_timeout_report_cnt++; rc = -EPERM; diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index fa1df94976f9..37b0ca7aa44b 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -997,6 +997,9 @@ struct mdss_panel_data { * are still on; panel will recover after unblank */ bool panel_disable_mode; + + int panel_te_gpio; + struct completion te_done; }; struct mdss_panel_debugfs_info { |
