summaryrefslogtreecommitdiff
path: root/drivers/video/fbdev
diff options
context:
space:
mode:
authorKuogee Hsieh <khsieh@codeaurora.org>2014-09-16 14:24:44 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 20:34:31 -0700
commitf74ed544d29f140eef8d17acadf85df8c31d17ce (patch)
tree496edb221432aed449fabe300cb8cfe7ce866afe /drivers/video/fbdev
parentfca1e879992a8fe9392f7ac9ea5ff418f893346e (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.c31
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;