diff --git a/drivers/video/msm/mdss/mdss_dsi_host.c b/drivers/video/msm/mdss/mdss_dsi_host.c index 7145bd2884eaacc4f90dd0d7772887ad3b220622..199f3bba00711ba6d0718ff8168d7da715c04c75 100755 --- a/drivers/video/msm/mdss/mdss_dsi_host.c +++ b/drivers/video/msm/mdss/mdss_dsi_host.c @@ -231,7 +231,6 @@ void mdss_dsi_cmd_dma_trigger_sel(struct mdss_dsi_ctrl_pdata *ctrl_pdata, int temp; int mask = 0x02; - mdss_mdp_cmd_clk_enable(); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 1); temp = MIPI_INP((ctrl_pdata->ctrl_base) + 0x0084); if (enable) @@ -240,7 +239,6 @@ void mdss_dsi_cmd_dma_trigger_sel(struct mdss_dsi_ctrl_pdata *ctrl_pdata, temp &= ~mask; MIPI_OUTP((ctrl_pdata->ctrl_base) + 0x0084, temp); mdss_dsi_clk_ctrl(ctrl_pdata, DSI_ALL_CLKS, 0); -// mdss_mdp_cmd_clk_disable(); } void mdss_dsi_host_init(struct mdss_panel_data *pdata) diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c index 85e05b3e3796532161be6c207c5f84ec340868a8..6582c452e7d1c413142b15a20096255bcd6e4391 100755 --- a/drivers/video/msm/mdss/mdss_fb.c +++ b/drivers/video/msm/mdss/mdss_fb.c @@ -638,7 +638,6 @@ static int mdss_fb_suspend_sub(struct msm_fb_data_type *mfd) #if defined(CONFIG_FB_MSM_MDSS_PANEL_ALWAYS_ON) if (mfd->index == 0) { if ((pdata) && (pdata->send_alpm)) { - mfd->mdp.disable_ulps(mfd); pdata->send_alpm(pdata, true); } return mfd->mdp.off_pan_on_fnc(mfd); @@ -683,7 +682,6 @@ static int mdss_fb_resume_sub(struct msm_fb_data_type *mfd) #if defined(CONFIG_FB_MSM_MDSS_PANEL_ALWAYS_ON) if (mfd->index == 0) if ((pdata) && (pdata->send_alpm)) { - mfd->mdp.disable_ulps(mfd); pdata->send_alpm(pdata, false); } return 0; @@ -864,7 +862,6 @@ void mdss_fb_set_backlight(struct msm_fb_data_type *mfd, u32 bkl_lvl) mfd->bl_level = bkl_lvl; return; } - mfd->mdp.disable_ulps(mfd); pdata->set_backlight(pdata, temp); mfd->bl_level = bkl_lvl; mfd->bl_level_old = temp; diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c index 703a6fa4ce9390c0b5bb400d37907ee5a28f1ab1..c2abeddf799e9056e314fde844614f7155a72cb7 100755 --- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c +++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c @@ -56,6 +56,8 @@ struct mdss_mdp_cmd_ctx { struct mdss_panel_recovery recovery; bool ulps; bool off_pan_on; + int cmd_pending; + spinlock_t cmd_lock; struct mutex ulps_lock; }; @@ -188,7 +190,7 @@ static int mdss_mdp_cmd_tearcheck_setup(struct mdss_mdp_ctl *ctl) return rc; } -static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx) +static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx, bool cmd_pending) { unsigned long flags; struct mdss_data_type *mdata = mdss_mdp_get_mdata(); @@ -229,9 +231,10 @@ static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx) mdss_mdp_hist_intr_setup(&mdata->hist_intr, MDSS_IRQ_RESUME); } spin_lock_irqsave(&ctx->clk_lock, flags); - if (!ctx->rdptr_enabled) + if (!ctx->rdptr_enabled && !cmd_pending) mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num); - ctx->rdptr_enabled = VSYNC_EXPIRE_TICK; + if (!cmd_pending) + ctx->rdptr_enabled = VSYNC_EXPIRE_TICK; spin_unlock_irqrestore(&ctx->clk_lock, flags); mutex_unlock(&ctx->clk_mtx); } @@ -250,6 +253,13 @@ static inline void mdss_mdp_cmd_clk_off(struct mdss_mdp_cmd_ctx *ctx) set_clk_off = 1; spin_unlock_irqrestore(&ctx->clk_lock, flags); + spin_lock_irqsave(&ctx->cmd_lock, flags); + if (set_clk_off && !ctx->cmd_pending) + set_clk_off = 1; + else + set_clk_off = 0; + spin_unlock_irqrestore(&ctx->cmd_lock, flags); + if (ctx->clk_enabled && set_clk_off) { ctx->clk_enabled = 0; mdss_mdp_hist_intr_setup(&mdata->hist_intr, MDSS_IRQ_SUSPEND); @@ -263,6 +273,30 @@ static inline void mdss_mdp_cmd_clk_off(struct mdss_mdp_cmd_ctx *ctx) mutex_unlock(&ctx->clk_mtx); } +void mdss_mdp_cmd_clk_enable(void) +{ + if (stored_ctx) { + spin_lock(&stored_ctx->cmd_lock); + stored_ctx->cmd_pending++; + spin_unlock(&stored_ctx->cmd_lock); + mdss_mdp_cmd_clk_on(stored_ctx, true); + } +} + +void mdss_mdp_cmd_clk_disable(void) +{ + int cmd_pending; + if (stored_ctx) { + spin_lock(&stored_ctx->cmd_lock); + if (stored_ctx->cmd_pending) + stored_ctx->cmd_pending--; + cmd_pending = stored_ctx->cmd_pending; + spin_unlock(&stored_ctx->cmd_lock); + if (cmd_pending) + schedule_work(&stored_ctx->clk_work); + } +} + int mdss_mdp_cmd_disable_ulps(struct mdss_mdp_ctl *ctl) { struct mdss_mdp_cmd_ctx *ctx; @@ -273,20 +307,11 @@ int mdss_mdp_cmd_disable_ulps(struct mdss_mdp_ctl *ctl) return -ENODEV; } - mdss_mdp_cmd_clk_on(ctx); + mdss_mdp_cmd_clk_on(ctx, false); return 0; } -void mdss_mdp_cmd_clk_enable(void) -{ - if (stored_ctx) - mdss_mdp_cmd_clk_on(stored_ctx); -} -void mdss_mdp_cmd_clk_disable(void) -{ - if (stored_ctx) - mdss_mdp_cmd_clk_off(stored_ctx); -} + static void mdss_mdp_cmd_readptr_done(void *arg) { struct mdss_mdp_ctl *ctl = arg; @@ -474,7 +499,7 @@ static int mdss_mdp_cmd_add_vsync_handler(struct mdss_mdp_ctl *ctl, spin_unlock_irqrestore(&ctx->clk_lock, flags); if (enable_rdptr) - mdss_mdp_cmd_clk_on(ctx); + mdss_mdp_cmd_clk_on(ctx, false); return 0; } @@ -606,7 +631,7 @@ int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc); } - mdss_mdp_cmd_clk_on(ctx); + mdss_mdp_cmd_clk_on(ctx, false); mdss_mdp_cmd_set_partial_roi(ctl); @@ -659,10 +684,17 @@ int mdss_mdp_cmd_off_pan_on(struct mdss_mdp_ctl *ctl) } spin_unlock_irqrestore(&ctx->clk_lock, flags); + spin_lock_irqsave(&ctx->cmd_lock, flags); + if (ctx->cmd_pending) { + INIT_COMPLETION(ctx->stop_comp); + need_wait = 1; + } + spin_unlock_irqrestore(&ctx->cmd_lock, flags); + if (need_wait) { if (wait_for_completion_timeout(&ctx->stop_comp, STOP_TIMEOUT) <= 0) { - pr_debug("%s: stop cmd time out\n", __func__); + pr_err("%s: stop cmd time out\n", __func__); mdss_mdp_irq_disable(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num); ctx->rdptr_enabled = 0; @@ -671,6 +703,7 @@ int mdss_mdp_cmd_off_pan_on(struct mdss_mdp_ctl *ctl) } ctx->off_pan_on = true; + ctx->cmd_pending = 0; if (cancel_work_sync(&ctx->clk_work)) pr_debug("no pending clk work\n"); @@ -726,6 +759,13 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl) } spin_unlock_irqrestore(&ctx->clk_lock, flags); + spin_lock_irqsave(&ctx->cmd_lock, flags); + if (ctx->cmd_pending) { + INIT_COMPLETION(ctx->stop_comp); + need_wait = 1; + } + spin_unlock_irqrestore(&ctx->cmd_lock, flags); + if (need_wait) { if (pinfo->alpm_event && pinfo->alpm_event(CHECK_CURRENT_STATUS)) timeout_status = wait_for_completion_timeout(&ctx->stop_comp,\ @@ -751,6 +791,7 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl) pr_debug("deleted pending ulps work\n"); ctx->panel_on = 0; + ctx->cmd_pending = 0; mdss_mdp_cmd_clk_off(ctx); flush_work(&ctx->pp_done_work); @@ -762,6 +803,7 @@ int mdss_mdp_cmd_stop(struct mdss_mdp_ctl *ctl) NULL, NULL); memset(ctx, 0, sizeof(*ctx)); + stored_ctx = NULL; ctl->priv_data = NULL; if (ctl->num == 0) { @@ -823,6 +865,7 @@ int mdss_mdp_cmd_start(struct mdss_mdp_ctl *ctl) init_completion(&ctx->pp_comp); init_completion(&ctx->stop_comp); spin_lock_init(&ctx->clk_lock); + spin_lock_init(&ctx->cmd_lock); mutex_init(&ctx->clk_mtx); mutex_init(&ctx->ulps_lock); INIT_WORK(&ctx->clk_work, clk_ctrl_work); @@ -864,6 +907,8 @@ int mdss_mdp_cmd_start(struct mdss_mdp_ctl *ctl) ctl->off_pan_on = mdss_mdp_cmd_off_pan_on; ctl->disable_ulps = mdss_mdp_cmd_disable_ulps; pr_debug("%s:-\n", __func__); + stored_ctx = ctx; + ctx->cmd_pending = 0; return 0; } diff --git a/drivers/video/msm/mdss/mdss_samsung_oled_cmd_320p_dsi_panel.c b/drivers/video/msm/mdss/mdss_samsung_oled_cmd_320p_dsi_panel.c index 439278faeacd4f4297d7e6b24f0af4f8e4f1d6c6..e56e13154c938a245c282bf65cc0852878e5f2af 100755 --- a/drivers/video/msm/mdss/mdss_samsung_oled_cmd_320p_dsi_panel.c +++ b/drivers/video/msm/mdss/mdss_samsung_oled_cmd_320p_dsi_panel.c @@ -130,10 +130,12 @@ static void mdss_dsi_panel_bklt_dcs(struct mdss_dsi_ctrl_pdata *ctrl, cmdreq.rlen = 0; cmdreq.cb = NULL; + mdss_mdp_cmd_clk_enable(); mdss_dsi_cmd_dma_trigger_sel(ctrl, 1); mdss_dsi_cmdlist_put(ctrl, &cmdreq); mdss_dsi_cmd_dma_trigger_sel(ctrl, 0); stored_cd_level = cd_level; + mdss_mdp_cmd_clk_disable(); } void mdss_dsi_samsung_panel_reset(struct mdss_panel_data *pdata, int enable) @@ -283,7 +285,11 @@ static int mipi_samsung_disp_send_cmd( } #endif + if (cmd != PANEL_DISPLAY_ON_SEQ && cmd != PANEL_DISP_OFF) + mdss_mdp_cmd_clk_enable(); mdss_dsi_cmds_send(msd.ctrl_pdata, cmd_desc, cmd_size, flag); + if (cmd != PANEL_DISPLAY_ON_SEQ && cmd != PANEL_DISP_OFF) + mdss_mdp_cmd_clk_disable(); if (lock) mutex_unlock(&msd.lock); @@ -435,7 +441,9 @@ u32 mdss_dsi_cmd_receive(struct mdss_dsi_ctrl_pdata *ctrl, * This mutex is to sync up with dynamic FPS changes * so that DSI lockups shall not happen */ + mdss_mdp_cmd_clk_enable(); mdss_dsi_cmdlist_put(ctrl, &cmdreq); + mdss_mdp_cmd_clk_disable(); /* * blocked here, untill call back called