From 39b9b459574ce6356c782105ec49769c5a3f7d45 Mon Sep 17 00:00:00 2001 From: Veera Sundaram Sankaran Date: Fri, 1 Apr 2016 14:41:11 -0700 Subject: [PATCH] msm: mdss: update lineptr instantly in cmd mode panels w/autorefresh The lineptr interrupt is expected to be triggered and have the ability to be updated instantly whenever the panel is fetching data. Previously, enabling lineptr was tied to kickoff and disabling to pp_done work. Add capability to change the lineptr value instantly, when auto-refresh is enabled and avoid disabling lineptr during that time. Once enabled, lineptr can only be disabled when 0 is written to the node while auto-refresh is enabled. Change-Id: I9a1a478c857efd988984a0efb0a2b6475030c7ec Signed-off-by: Veera Sundaram Sankaran --- drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 40 +++++++++++++++++++-- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index 0779f7e7afae..e2859e3b684b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -903,6 +903,22 @@ exit: return rc; } +static bool mdss_mdp_cmd_is_autorefresh_enabled(struct mdss_mdp_ctl *mctl) +{ + struct mdss_mdp_cmd_ctx *ctx = mctl->intf_ctx[MASTER_CTX]; + bool enabled = false; + + /* check the ctl to make sure the lock was initialized */ + if (!ctx || !ctx->ctl) + return 0; + + mutex_lock(&ctx->autorefresh_lock); + if (ctx->autorefresh_state == MDP_AUTOREFRESH_ON) + enabled = true; + mutex_unlock(&ctx->autorefresh_lock); + + return enabled; +} static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx) { @@ -1069,7 +1085,7 @@ static void mdss_mdp_cmd_intf_callback(void *data, int event) } } -static void mdss_mdp_cmd_writeptr_done(void *arg) +static void mdss_mdp_cmd_lineptr_done(void *arg) { struct mdss_mdp_ctl *ctl = arg; struct mdss_mdp_cmd_ctx *ctx = ctl->intf_ctx[MASTER_CTX]; @@ -1082,6 +1098,7 @@ static void mdss_mdp_cmd_writeptr_done(void *arg) } lineptr_time = ktime_get(); + pr_debug("intr lineptr_time=%lld\n", ktime_to_ms(lineptr_time)); spin_lock(&ctx->clk_lock); list_for_each_entry(tmp, &ctx->lineptr_handlers, list) { @@ -1376,6 +1393,19 @@ static int mdss_mdp_cmd_lineptr_ctrl(struct mdss_mdp_ctl *ctl, bool enable) return rc; } +/* + * Interface used to update the new lineptr value set by the sysfs node. + * Value is instantly updated only when autorefresh is enabled, else + * new value would be set in the next kickoff. + */ +static int mdss_mdp_cmd_update_lineptr(struct mdss_mdp_ctl *ctl, bool enable) +{ + if (mdss_mdp_cmd_is_autorefresh_enabled(ctl)) + return mdss_mdp_cmd_lineptr_ctrl(ctl, enable); + + return 0; +} + /** * mdss_mdp_cmd_autorefresh_pp_done() - pp done irq callback for autorefresh * @arg: void pointer to the controller context. @@ -1423,7 +1453,10 @@ static void pingpong_done_work(struct work_struct *work) if (!ctl->is_master) ctl = mdss_mdp_get_main_ctl(ctl); - if (mdss_mdp_is_lineptr_supported(ctl)) + + /* do not disable lineptr when autorefresh is enabled */ + if (mdss_mdp_is_lineptr_supported(ctl) + && !mdss_mdp_cmd_is_autorefresh_enabled(ctl)) mdss_mdp_cmd_lineptr_ctrl(ctl, false); } } @@ -3182,7 +3215,7 @@ static int mdss_mdp_cmd_ctx_setup(struct mdss_mdp_ctl *ctl, ctx->default_pp_num, mdss_mdp_cmd_readptr_done, ctl); mdss_mdp_set_intr_callback(MDSS_MDP_IRQ_TYPE_PING_PONG_WR_PTR, - ctx->default_pp_num, mdss_mdp_cmd_writeptr_done, ctl); + ctx->default_pp_num, mdss_mdp_cmd_lineptr_done, ctl); ret = mdss_mdp_cmd_tearcheck_setup(ctx, false); if (ret) @@ -3447,6 +3480,7 @@ int mdss_mdp_cmd_start(struct mdss_mdp_ctl *ctl) ctl->ops.early_wake_up_fnc = mdss_mdp_cmd_early_wake_up; ctl->ops.reconfigure = mdss_mdp_cmd_reconfigure; ctl->ops.pre_programming = mdss_mdp_cmd_pre_programming; + ctl->ops.update_lineptr = mdss_mdp_cmd_update_lineptr; pr_debug("%s:-\n", __func__); return 0;