Example #1
0
static void mdp4_dsi_cmd_wait4ov(int cndx)
{
	struct vsycn_ctrl *vctrl;

	if (cndx >= MAX_CONTROLLER) {
		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
		return;
	}

	vctrl = &vsync_ctrl_db[cndx];

	if (atomic_read(&vctrl->suspend) > 0)
		return;

#ifdef MDP_HANG_DEBUG
	if (!wait_for_completion_timeout(&vctrl->ov_comp,
		msecs_to_jiffies(VSYNC_PERIOD*30))) {
		/* Does not receive interrupt from MDP,
		Something wrong */
		mdp4_dump_regs();
		panic("vctrl->ov_comp interrupt missing");
	}
#else
	wait_for_completion(&vctrl->ov_comp);
#endif	
}
Example #2
0
static void mdp4_dsi_video_wait4dmap(int cndx)
{
    struct vsycn_ctrl *vctrl;
    ssize_t ret = 0;

    if (cndx >= MAX_CONTROLLER) {
        pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
        return;
    }

    vctrl = &vsync_ctrl_db[cndx];

    if (atomic_read(&vctrl->suspend) > 0)
        return;

    ret = wait_for_completion_interruptible_timeout(
              &vctrl->dmap_comp,
              msecs_to_jiffies(WAIT_FOR_COMPLETION_TIMEOUT));
    if (ret < 0) {
#ifdef MDP_HANG_DEBUG
        mdp4_dump_regs();
        panic("vctrl->dmap_comp interrupt missing");
#endif
        pr_err("%s wait for completion error %x",
               __func__, ret);
        return;
    } else if (!ret) {
#ifdef MDP_HANG_DEBUG
        mdp4_dump_regs();
        panic("vctrl->dmap_comp interrupt missing");
#endif
        pr_err("%s wait for commit_comp timeout",
               __func__);
        wait_for_completion(&vctrl->dmap_comp);
    }

}
Example #3
0
void mdp4_dsi_cmd_wait4vsync(int cndx)
{
	struct vsycn_ctrl *vctrl;
	struct mdp4_overlay_pipe *pipe;
	unsigned long flags;

	if (cndx >= MAX_CONTROLLER) {
		pr_err("%s: out or range: cndx=%d\n", __func__, cndx);
		return;
	}

	vctrl = &vsync_ctrl_db[cndx];
	pipe = vctrl->base_pipe;

	if (atomic_read(&vctrl->suspend) > 0)
		return;

	spin_lock_irqsave(&vctrl->spin_lock, flags);
	if (vctrl->wait_vsync_cnt == 0)
		INIT_COMPLETION(vctrl->vsync_comp);
	vctrl->wait_vsync_cnt++;
	spin_unlock_irqrestore(&vctrl->spin_lock, flags);

#ifdef MDP_HANG_DEBUG
		if (!wait_for_completion_timeout(&vctrl->vsync_comp,
			msecs_to_jiffies(VSYNC_PERIOD*30))) {
			/* Does not receive interrupt from MDP,
			Something wrong */
			mdp4_dump_regs();
			panic("vctrl->vsync_comp interrupt missing");
		}
#else
		wait_for_completion(&vctrl->vsync_comp);
#endif
	
	mdp4_stat.wait4vsync0++;
}
int mdp4_dsi_video_pipe_commit(int cndx, int wait)
{
    static uint32 frameDropCnt = 0; // QC_1206
    int lmCfg; // QC_1204
    int  i, undx;
    int mixer = 0;
    struct vsycn_ctrl *vctrl;
    struct vsync_update *vp;
    struct mdp4_overlay_pipe *pipe;
    struct mdp4_overlay_pipe *real_pipe;
    unsigned long flags;
    int cnt = 0;

    vctrl = &vsync_ctrl_db[cndx];

    mutex_lock(&vctrl->update_lock);
    undx =  vctrl->update_ndx;
    vp = &vctrl->vlist[undx];
    pipe = vctrl->base_pipe;
    mixer = pipe->mixer_num;

    if (vp->update_cnt == 0) {
        mutex_unlock(&vctrl->update_lock);
        return cnt;
    }

    vctrl->update_ndx++;
    vctrl->update_ndx &= 0x01;
    vp->update_cnt = 0;     /* reset */
    if (vctrl->blt_free) {
        vctrl->blt_free--;
//		if (vctrl->blt_free == 0)
//			mdp4_free_writeback_buf(vctrl->mfd, mixer);
    }
    mutex_unlock(&vctrl->update_lock);

    /* free previous committed iommu back to pool */
    mdp4_overlay_iommu_unmap_freelist(mixer);

    spin_lock_irqsave(&vctrl->spin_lock, flags);


    if (vctrl->ov_koff != vctrl->ov_done) {
        frameDropCnt++; // QC_1206
        spin_unlock_irqrestore(&vctrl->spin_lock, flags);
        pr_err("%s: Error, frame dropped %d %d\n", __func__,
               vctrl->ov_koff, vctrl->ov_done);


        if (frameDropCnt >= 2) { // QC_1206
            mdp4_dump_regs(); // QC_1205
            lmCfg = inpdw(MDP_BASE + 0x10100); // QC_1204
            pr_err("*** %s: lmCfg=%x, frameDropCnt=%d\n", __func__, lmCfg, frameDropCnt); // QC_1204

            // retry ov0
            pr_err("*** %s: Retrying OV0\n", __func__); // QC_1204
            INIT_COMPLETION(vctrl->ov_comp); // QC_1204
            vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM); // QC_1204
            mb(); // QC_1204
            outpdw(MDP_BASE + 0x0004, 0); // QC_1204
        }
        return 0;
    } else {
        frameDropCnt = 0; // QC_1206
    }

    spin_unlock_irqrestore(&vctrl->spin_lock, flags);

    mdp4_overlay_mdp_perf_upd(vctrl->mfd, 1);

    if (vctrl->blt_change) {
        pipe = vctrl->base_pipe;
        spin_lock_irqsave(&vctrl->spin_lock, flags);
        INIT_COMPLETION(vctrl->dmap_comp);
        INIT_COMPLETION(vctrl->ov_comp);
        vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
        spin_unlock_irqrestore(&vctrl->spin_lock, flags);
        mdp4_dsi_video_wait4dmap(0);
        if (pipe->ov_blt_addr)
            mdp4_dsi_video_wait4ov(0);
    }

    pipe = vp->plist;

    for (i = 0; i < OVERLAY_PIPE_MAX; i++, pipe++) {
        if (pipe->pipe_used) {
            cnt++;
            real_pipe = mdp4_overlay_ndx2pipe(pipe->pipe_ndx);
            if (real_pipe && real_pipe->pipe_used) {
                /* pipe not unset */
                mdp4_overlay_vsync_commit(pipe);
            }
            /* free previous iommu to freelist
            * which will be freed at next
            * pipe_commit
            */
            mdp4_overlay_iommu_pipe_free(pipe->pipe_ndx, 0);
            pipe->pipe_used = 0; /* clear */
        }
    }

    mdp4_mixer_stage_commit(mixer);

    /* start timing generator & mmu if they are not started yet */
    mdp4_overlay_dsi_video_start();

    pipe = vctrl->base_pipe;
    spin_lock_irqsave(&vctrl->spin_lock, flags);
    if (pipe->ov_blt_addr) {
        mdp4_dsi_video_blt_ov_update(pipe);
        pipe->ov_cnt++;
        INIT_COMPLETION(vctrl->ov_comp);
        vsync_irq_enable(INTR_OVERLAY0_DONE, MDP_OVERLAY0_TERM);
        mb();
        vctrl->ov_koff++;

        pr_err("*** %s: vctrl->ov_koff++=%d\n", __func__, vctrl->ov_koff); // QC_1204

        lmCfg = inpdw(MDP_BASE + 0x10100); // QC_1204
        pr_err("*** %s: lmCfg=%x\n", __func__, lmCfg); // QC_1204


        /* kickoff overlay engine */
        mdp4_stat.kickoff_ov0++;
        outpdw(MDP_BASE + 0x0004, 0);
    } else {
        /* schedule second phase update  at dmap */
        INIT_COMPLETION(vctrl->dmap_comp);
        vsync_irq_enable(INTR_DMA_P_DONE, MDP_DMAP_TERM);
    }
    spin_unlock_irqrestore(&vctrl->spin_lock, flags);

    mdp4_stat.overlay_commit[pipe->mixer_num]++;

    if (wait) {
        if (pipe->ov_blt_addr)
            mdp4_dsi_video_wait4ov(0);
        else
            mdp4_dsi_video_wait4dmap(0);
    }

    return cnt;
}