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>
This commit is contained in:
Kuogee Hsieh 2014-09-16 14:24:44 -07:00 committed by David Keitel
parent fca1e87999
commit f74ed544d2

View file

@ -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;