diff options
| author | Kuogee Hsieh <khsieh@codeaurora.org> | 2014-09-16 14:24:44 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 20:34:31 -0700 |
| commit | f74ed544d29f140eef8d17acadf85df8c31d17ce (patch) | |
| tree | 496edb221432aed449fabe300cb8cfe7ce866afe /drivers/video/fbdev | |
| parent | fca1e879992a8fe9392f7ac9ea5ff418f893346e (diff) | |
msm: mdss: control both dsi controller's clock atomically
For split display case there has possibilities of race condition
may happen during dsi clocks control between add_vsync and
clokc_off thread which could end dsi clock is turned off
instead of turn on as add_vsycn thread expect. Therefore
clocks control of both dsi controllers should be atomic.
CRs-Fixed: 724861
Change-Id: I537502bad2611769d5323cd05ed50c505af6371a
Signed-off-by: Kuogee Hsieh <khsieh@codeaurora.org>
Diffstat (limited to 'drivers/video/fbdev')
| -rw-r--r-- | drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index 4d71c1dc0628..f79470df1a16 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -30,6 +30,8 @@ #define STOP_TIMEOUT(hz) msecs_to_jiffies((1000 / hz) * (VSYNC_EXPIRE_TICK + 2)) #define POWER_COLLAPSE_TIME msecs_to_jiffies(100) +static DEFINE_MUTEX(cmd_clk_mtx); + struct mdss_mdp_cmd_ctx { struct mdss_mdp_ctl *ctl; u32 pp_num; @@ -416,13 +418,36 @@ static void clk_ctrl_work(struct work_struct *work) { struct mdss_mdp_cmd_ctx *ctx = container_of(work, typeof(*ctx), clk_work); + struct mdss_mdp_ctl *ctl, *sctl; + struct mdss_mdp_cmd_ctx *sctx = NULL; if (!ctx) { pr_err("%s: invalid ctx\n", __func__); return; } + ctl = ctx->ctl; + + if (ctl->panel_data->panel_info.is_split_display) { + mutex_lock(&cmd_clk_mtx); + + sctl = mdss_mdp_get_split_ctl(ctl); + if (sctl) { + sctx = (struct mdss_mdp_cmd_ctx *) sctl->priv_data; + } else { + /* slave ctl, let master ctl do clk control */ + mutex_unlock(&cmd_clk_mtx); + return; + } + } + mdss_mdp_cmd_clk_off(ctx); + + if (ctl->panel_data->panel_info.is_split_display) { + if (sctx) + mdss_mdp_cmd_clk_off(sctx); + mutex_unlock(&cmd_clk_mtx); + } } static int mdss_mdp_cmd_add_vsync_handler(struct mdss_mdp_ctl *ctl, @@ -460,9 +485,15 @@ static int mdss_mdp_cmd_add_vsync_handler(struct mdss_mdp_ctl *ctl, spin_unlock_irqrestore(&ctx->clk_lock, flags); if (enable_rdptr) { + if (ctl->panel_data->panel_info.is_split_display) + mutex_lock(&cmd_clk_mtx); + mdss_mdp_cmd_clk_on(ctx); if (sctx) mdss_mdp_cmd_clk_on(sctx); + + if (ctl->panel_data->panel_info.is_split_display) + mutex_unlock(&cmd_clk_mtx); } return 0; |
