static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf) { unsigned long flag; int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC; pr_debug("mdp3_dmap_update\n"); if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) { cb_type |= MDP3_DMA_CALLBACK_TYPE_DMA_DONE; wait_for_completion_killable(&dma->dma_comp); } spin_lock_irqsave(&dma->dma_lock, flag); MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_ADDR, (u32)buf); dma->source_config.buf = buf; if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) MDP3_REG_WRITE(MDP3_REG_DMA_P_START, 1); wmb(); init_completion(&dma->vsync_comp); spin_unlock_irqrestore(&dma->dma_lock, flag); mdp3_dma_callback_enable(dma, cb_type); pr_debug("mdp3_dmap_update wait for vsync_comp in\n"); wait_for_completion_killable(&dma->vsync_comp); pr_debug("mdp3_dmap_update wait for vsync_comp out\n"); return 0; }
static int mdp3_dma_start(struct mdp3_dma *dma, struct mdp3_intf *intf) { unsigned long flag; int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC; u32 dma_start_offset = MDP3_REG_DMA_P_START; if (dma->dma_sel == MDP3_DMA_P) dma_start_offset = MDP3_REG_DMA_P_START; else if (dma->dma_sel == MDP3_DMA_S) dma_start_offset = MDP3_REG_DMA_S_START; else return -EINVAL; spin_lock_irqsave(&dma->dma_lock, flag); if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) { cb_type |= MDP3_DMA_CALLBACK_TYPE_DMA_DONE; MDP3_REG_WRITE(dma_start_offset, 1); } intf->start(intf); wmb(); init_completion(&dma->vsync_comp); spin_unlock_irqrestore(&dma->dma_lock, flag); mdp3_dma_callback_enable(dma, cb_type); pr_debug("mdp3_dma_start wait for vsync_comp in\n"); wait_for_completion_killable(&dma->vsync_comp); pr_debug("mdp3_dma_start wait for vsync_comp out\n"); return 0; }
static void mdp3_dma_vsync_enable(struct mdp3_dma *dma, struct mdp3_vsync_notification *vsync_client) { unsigned long flag; int updated = 0; int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC; pr_debug("mdp3_dma_vsync_enable\n"); spin_lock_irqsave(&dma->dma_lock, flag); if (vsync_client) { if (dma->vsync_client.handler != vsync_client->handler) { dma->vsync_client = *vsync_client; updated = 1; } } else { if (dma->vsync_client.handler) { dma->vsync_client.handler = NULL; dma->vsync_client.arg = NULL; updated = 1; } } spin_unlock_irqrestore(&dma->dma_lock, flag); if (updated) { if (vsync_client && vsync_client->handler) mdp3_dma_callback_enable(dma, cb_type); else mdp3_dma_callback_disable(dma, cb_type); } }
static int mdp3_dmap_histo_reset(struct mdp3_dma *dma) { unsigned long flag; int ret; spin_lock_irqsave(&dma->histo_lock, flag); init_completion(&dma->histo_comp); mdp3_dma_clk_auto_gating(dma, 0); MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_INTR_ENABLE, BIT(0)|BIT(1)); MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_RESET_SEQ_START, 1); wmb(); dma->histo_state = MDP3_DMA_HISTO_STATE_RESET; spin_unlock_irqrestore(&dma->histo_lock, flag); mdp3_dma_callback_enable(dma, MDP3_DMA_CALLBACK_TYPE_HIST_RESET_DONE); ret = wait_for_completion_killable_timeout(&dma->histo_comp, msecs_to_jiffies(DMA_HISTO_RESET_TIMEOUT_MS)); if (ret == 0) { pr_err("mdp3_dmap_histo_reset time out\n"); ret = -ETIMEDOUT; } else if (ret < 0) { pr_err("mdp3_dmap_histo_reset interrupted\n"); } else { ret = 0; } mdp3_dma_callback_disable(dma, MDP3_DMA_CALLBACK_TYPE_HIST_RESET_DONE); mdp3_dma_clk_auto_gating(dma, 1); return ret; }
static int mdp3_dmas_update(struct mdp3_dma *dma, void *buf, struct mdp3_intf *intf) { unsigned long flag; int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC; if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) { cb_type = MDP3_DMA_CALLBACK_TYPE_DMA_DONE; if (intf->active) wait_for_completion_killable(&dma->dma_comp); } spin_lock_irqsave(&dma->dma_lock, flag); MDP3_REG_WRITE(MDP3_REG_DMA_S_IBUF_ADDR, (u32)buf); dma->source_config.buf = buf; if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) MDP3_REG_WRITE(MDP3_REG_DMA_S_START, 1); if (!intf->active) { pr_debug("mdp3_dmap_update start interface\n"); intf->start(intf); } wmb(); init_completion(&dma->vsync_comp); spin_unlock_irqrestore(&dma->dma_lock, flag); mdp3_dma_callback_enable(dma, cb_type); if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) wait_for_completion_killable(&dma->vsync_comp); return 0; }
static int mdp3_dmap_update(struct mdp3_dma *dma, void *buf, struct mdp3_intf *intf) { unsigned long flag; int cb_type = MDP3_DMA_CALLBACK_TYPE_VSYNC; int rc = 0; pr_debug("mdp3_dmap_update\n"); if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) { cb_type = MDP3_DMA_CALLBACK_TYPE_DMA_DONE; if (intf->active) { rc = wait_for_completion_timeout(&dma->dma_comp, KOFF_TIMEOUT); if (rc <= 0) { WARN(1, "cmd kickoff timed out (%d)\n", rc); rc = -1; } } } if (dma->update_src_cfg) { if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO && intf->active) pr_err("configuring dma source while dma is active\n"); dma->dma_config_source(dma); dma->update_src_cfg = false; } spin_lock_irqsave(&dma->dma_lock, flag); MDP3_REG_WRITE(MDP3_REG_DMA_P_IBUF_ADDR, (u32)buf); dma->source_config.buf = buf; if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_CMD) { mdp3_ccs_update(dma); MDP3_REG_WRITE(MDP3_REG_DMA_P_START, 1); } if (!intf->active) { pr_debug("mdp3_dmap_update start interface\n"); intf->start(intf); } mb(); dma->vsync_status = MDP3_REG_READ(MDP3_REG_INTR_STATUS) & (1 << MDP3_INTR_LCDC_START_OF_FRAME); init_completion(&dma->vsync_comp); spin_unlock_irqrestore(&dma->dma_lock, flag); mdp3_dma_callback_enable(dma, cb_type); pr_debug("mdp3_dmap_update wait for vsync_comp in\n"); if (dma->output_config.out_sel == MDP3_DMA_OUTPUT_SEL_DSI_VIDEO) { rc = wait_for_completion_timeout(&dma->vsync_comp, KOFF_TIMEOUT); if (rc <= 0) rc = -1; } pr_debug("mdp3_dmap_update wait for vsync_comp out\n"); return rc; }
static int mdp3_dmap_histo_start(struct mdp3_dma *dma) { unsigned long flag; if (dma->histo_state != MDP3_DMA_HISTO_STATE_IDLE) return -EINVAL; spin_lock_irqsave(&dma->histo_lock, flag); init_completion(&dma->histo_comp); MDP3_REG_WRITE(MDP3_REG_DMA_P_HIST_START, 1); wmb(); dma->histo_state = MDP3_DMA_HISTO_STATE_START; spin_unlock_irqrestore(&dma->histo_lock, flag); mdp3_dma_callback_enable(dma, MDP3_DMA_CALLBACK_TYPE_HIST_DONE); return 0; }