msm: mdss: refactor command mode vsync control logic
Current logic is prone to corner case when mdss_mdp_remove_vsync_handler
is called twice: once from mdss_mdp_cmd_stop and again from vsync ctrl
logic. Need to properly identify the second call and avoid resetting the
rdptr ticks which prevent from clocks being turned off properly.
Change-Id: I9eeebd0c16e67a249508980427c81fa2e339edec
Signed-off-by: Adrian Salido-Moreno <adrianm@codeaurora.org>
diff --git a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
index 8c7dc29..78ecf16 100644
--- a/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
+++ b/drivers/video/msm/mdss/mdss_mdp_intf_cmd.c
@@ -418,6 +418,7 @@
{
struct mdss_mdp_cmd_ctx *ctx;
unsigned long flags;
+ bool enable_rdptr = false;
ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
if (!ctx) {
@@ -429,12 +430,14 @@
if (!handle->enabled) {
handle->enabled = true;
list_add(&handle->list, &ctx->vsync_handlers);
- if (!handle->cmd_post_flush)
- ctx->vsync_enabled = 1;
+
+ enable_rdptr = !handle->cmd_post_flush;
+ if (enable_rdptr)
+ ctx->vsync_enabled++;
}
spin_unlock_irqrestore(&ctx->clk_lock, flags);
- if (!handle->cmd_post_flush)
+ if (enable_rdptr)
mdss_mdp_cmd_clk_on(ctx);
return 0;
@@ -443,11 +446,8 @@
static int mdss_mdp_cmd_remove_vsync_handler(struct mdss_mdp_ctl *ctl,
struct mdss_mdp_vsync_handler *handle)
{
-
struct mdss_mdp_cmd_ctx *ctx;
unsigned long flags;
- struct mdss_mdp_vsync_handler *tmp;
- int num_rdptr_vsync = 0;
ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data;
if (!ctx) {
@@ -455,19 +455,17 @@
return -ENODEV;
}
-
spin_lock_irqsave(&ctx->clk_lock, flags);
if (handle->enabled) {
handle->enabled = false;
list_del_init(&handle->list);
- }
- list_for_each_entry(tmp, &ctx->vsync_handlers, list) {
- if (!tmp->cmd_post_flush)
- num_rdptr_vsync++;
- }
- if (!num_rdptr_vsync) {
- ctx->vsync_enabled = 0;
- ctx->rdptr_enabled = VSYNC_EXPIRE_TICK;
+
+ if (!handle->cmd_post_flush) {
+ if (ctx->vsync_enabled)
+ ctx->vsync_enabled--;
+ else
+ WARN(1, "unbalanced vsync disable");
+ }
}
spin_unlock_irqrestore(&ctx->clk_lock, flags);
return 0;