static int mdss_mdp_video_display(struct mdss_mdp_ctl *ctl, void *arg) { struct mdss_mdp_video_ctx *ctx; u32 intr_type = MDSS_MDP_IRQ_INTF_VSYNC; pr_debug("kickoff ctl=%d\n", ctl->num); ctx = (struct mdss_mdp_video_ctx *) ctl->priv_data; if (!ctx) { pr_err("invalid ctx\n"); return -ENODEV; } mdss_mdp_set_intr_callback(intr_type, ctl->intf_num, mdss_mdp_video_vsync_intr_done, ctx); mdss_mdp_irq_enable(intr_type, ctl->intf_num); if (!ctx->timegen_en) { int off = MDSS_MDP_REG_INTF_OFFSET(ctl->intf_num); pr_debug("enabling timing gen for intf=%d\n", ctl->intf_num); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); MDSS_MDP_REG_WRITE(off + MDSS_MDP_REG_INTF_TIMING_ENGINE_EN, 1); ctx->timegen_en = true; wmb(); } wait_for_completion_interruptible(&ctx->vsync_comp); mdss_mdp_irq_disable(intr_type, ctl->intf_num); return 0; }
static inline void mdss_mdp_cmd_clk_on(struct mdss_mdp_cmd_ctx *ctx) { unsigned long flags; mutex_lock(&ctx->clk_mtx); if (!ctx->clk_enabled) { ctx->clk_enabled = 1; mdss_mdp_ctl_intf_event (ctx->ctl, MDSS_EVENT_PANEL_CLK_CTRL, (void *)1); mdss_mdp_clk_ctrl(MDP_BLOCK_POWER_ON, false); } spin_lock_irqsave(&ctx->clk_lock, flags); if (!ctx->rdptr_enabled) mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_RD_PTR, ctx->pp_num); ctx->rdptr_enabled = VSYNC_EXPIRE_TICK; spin_unlock_irqrestore(&ctx->clk_lock, flags); mutex_unlock(&ctx->clk_mtx); }
int mdss_mdp_cmd_kickoff(struct mdss_mdp_ctl *ctl, void *arg) { struct mdss_mdp_cmd_ctx *ctx; unsigned long flags; int rc; ctx = (struct mdss_mdp_cmd_ctx *) ctl->priv_data; if (!ctx) { pr_err("invalid ctx\n"); return -ENODEV; } if (ctx->panel_on == 0) { rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_UNBLANK, NULL); WARN(rc, "intf %d unblank error (%d)\n", ctl->intf_num, rc); ctx->panel_on++; rc = mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_PANEL_ON, NULL); WARN(rc, "intf %d panel on error (%d)\n", ctl->intf_num, rc); } mdss_mdp_cmd_clk_on(ctx); /* * tx dcs command if had any */ mdss_mdp_ctl_intf_event(ctl, MDSS_EVENT_DSI_CMDLIST_KOFF, NULL); INIT_COMPLETION(ctx->pp_comp); mdss_mdp_irq_enable(MDSS_MDP_IRQ_PING_PONG_COMP, ctx->pp_num); mdss_mdp_ctl_write(ctl, MDSS_MDP_REG_CTL_START, 1); spin_lock_irqsave(&ctx->clk_lock, flags); ctx->koff_cnt++; spin_unlock_irqrestore(&ctx->clk_lock, flags); mb(); return 0; }
static int mdss_mdp_video_prepare(struct mdss_mdp_ctl *ctl, void *arg) { struct mdss_mdp_video_ctx *ctx; ctx = (struct mdss_mdp_video_ctx *) ctl->priv_data; if (!ctx) { pr_err("invalid ctx\n"); return -ENODEV; } if (ctx->timegen_en) { u32 intr_type = MDSS_MDP_IRQ_PING_PONG_COMP; pr_debug("waiting for ping pong %d done\n", ctx->pp_num); mdss_mdp_set_intr_callback(intr_type, ctx->pp_num, mdss_mdp_video_pp_intr_done, ctx); mdss_mdp_irq_enable(intr_type, ctx->pp_num); wait_for_completion_interruptible(&ctx->pp_comp); mdss_mdp_irq_disable(intr_type, ctx->pp_num); } return 0; }