diff options
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.c | 1 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi.h | 6 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_dsi_host.c | 53 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_fb.c | 4 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 17 | ||||
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_panel.h | 2 |
6 files changed, 79 insertions, 4 deletions
diff --git a/drivers/video/fbdev/msm/mdss_dsi.c b/drivers/video/fbdev/msm/mdss_dsi.c index 23aa047d1c6d..a9942fd0ba5d 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.c +++ b/drivers/video/fbdev/msm/mdss_dsi.c @@ -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); diff --git a/drivers/video/fbdev/msm/mdss_dsi.h b/drivers/video/fbdev/msm/mdss_dsi.h index 54e4d49569ff..681190381774 100644 --- a/drivers/video/fbdev/msm/mdss_dsi.h +++ b/drivers/video/fbdev/msm/mdss_dsi.h @@ -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, diff --git a/drivers/video/fbdev/msm/mdss_dsi_host.c b/drivers/video/fbdev/msm/mdss_dsi_host.c index 77dd4c44d299..058695c49705 100644 --- a/drivers/video/fbdev/msm/mdss_dsi_host.c +++ b/drivers/video/fbdev/msm/mdss_dsi_host.c @@ -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; } diff --git a/drivers/video/fbdev/msm/mdss_fb.c b/drivers/video/fbdev/msm/mdss_fb.c index f6c5074e87ec..2a3519e8f3df 100644 --- a/drivers/video/fbdev/msm/mdss_fb.c +++ b/drivers/video/fbdev/msm/mdss_fb.c @@ -709,8 +709,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); diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index 496206996638..c490862df453 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -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"); diff --git a/drivers/video/fbdev/msm/mdss_panel.h b/drivers/video/fbdev/msm/mdss_panel.h index 82411153bb86..30408f837979 100644 --- a/drivers/video/fbdev/msm/mdss_panel.h +++ b/drivers/video/fbdev/msm/mdss_panel.h @@ -314,6 +314,8 @@ struct mdss_panel_info { struct ion_handle *splash_ihdl; u32 panel_power_on; + uint32_t panel_dead; + struct mdss_mdp_pp_tear_check te; struct lcd_panel_info lcdc; |
