From d3a18691ec9b56c6378015a7193a312ba4326594 Mon Sep 17 00:00:00 2001 From: Ingrid Gallardo Date: Tue, 9 Aug 2016 15:17:44 -0700 Subject: [PATCH] msm: mdss: fix spurious wait4pingpong timeouts In some cases, the jiffies of the wait function can jump between reads, leading to wrongly detected ping pong timeouts. Prevent to fail in this scenario by making sure that the time elapsed during the wait is valid. CRs-Fixed: 1048727 Change-Id: I3a1ecc89f379a90d9fdacf0baa9b6c8498bb93fb Signed-off-by: Ingrid Gallardo --- drivers/video/fbdev/msm/mdss_mdp.h | 3 ++- drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c | 24 ++++++++++++++++++--- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_mdp.h b/drivers/video/fbdev/msm/mdss_mdp.h index da5e7bb8a343..9f22d7d4be7b 100644 --- a/drivers/video/fbdev/msm/mdss_mdp.h +++ b/drivers/video/fbdev/msm/mdss_mdp.h @@ -56,7 +56,8 @@ #define C0_G_Y 0 /* G/luma */ /* wait for at most 2 vsync for lowest refresh rate (24hz) */ -#define KOFF_TIMEOUT msecs_to_jiffies(84) +#define KOFF_TIMEOUT_MS 84 +#define KOFF_TIMEOUT msecs_to_jiffies(KOFF_TIMEOUT_MS) #define OVERFETCH_DISABLE_TOP BIT(0) #define OVERFETCH_DISABLE_BOTTOM BIT(1) diff --git a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c index a1e5982bccda..5a65451dc127 100644 --- a/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c +++ b/drivers/video/fbdev/msm/mdss_mdp_intf_cmd.c @@ -1835,6 +1835,26 @@ int mdss_mdp_cmd_reconfigure_splash_done(struct mdss_mdp_ctl *ctl, return ret; } +static int __mdss_mdp_wait4pingpong(struct mdss_mdp_cmd_ctx *ctx) +{ + int rc = 0; + s64 expected_time = ktime_to_ms(ktime_get()) + KOFF_TIMEOUT_MS; + s64 time; + + do { + rc = wait_event_timeout(ctx->pp_waitq, + atomic_read(&ctx->koff_cnt) == 0, + KOFF_TIMEOUT); + time = ktime_to_ms(ktime_get()); + + MDSS_XLOG(rc, time, expected_time, atomic_read(&ctx->koff_cnt)); + /* If we timed out, counter is valid and time is less, wait again */ + } while (atomic_read(&ctx->koff_cnt) && (rc == 0) && + (time < expected_time)); + + return rc; +} + static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) { struct mdss_mdp_cmd_ctx *ctx; @@ -1856,9 +1876,7 @@ static int mdss_mdp_cmd_wait4pingpong(struct mdss_mdp_ctl *ctl, void *arg) pr_debug("%s: intf_num=%d ctx=%p koff_cnt=%d\n", __func__, ctl->intf_num, ctx, atomic_read(&ctx->koff_cnt)); - rc = wait_event_timeout(ctx->pp_waitq, - atomic_read(&ctx->koff_cnt) == 0, - KOFF_TIMEOUT); + rc = __mdss_mdp_wait4pingpong(ctx); trace_mdp_cmd_wait_pingpong(ctl->num, atomic_read(&ctx->koff_cnt));