Esempio n. 1
0
int mdp4_lcdc_off(struct platform_device *pdev)
{
    int ret = 0;
    int cndx = 0;
    struct msm_fb_data_type *mfd;
    struct vsycn_ctrl *vctrl;
    struct mdp4_overlay_pipe *pipe;
    struct vsync_update *vp;
    unsigned long flags;
    int undx, need_wait = 0;
    int mixer = 0;

    mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);

    mutex_lock(&mfd->dma->ov_mutex);
    vctrl = &vsync_ctrl_db[cndx];
    pipe = vctrl->base_pipe;

    mdp4_lcdc_wait4vsync(cndx);

    wake_up_interruptible_all(&vctrl->wait_queue);

    if (pipe->ov_blt_addr) {
        spin_lock_irqsave(&vctrl->spin_lock, flags);
        if (vctrl->ov_koff != vctrl->ov_done)
            need_wait = 1;
        spin_unlock_irqrestore(&vctrl->spin_lock, flags);
        if (need_wait)
            mdp4_lcdc_wait4ov(0);
    }

    mdp_histogram_ctrl_all(FALSE);

    lcdc_enabled = 0;

    undx =  vctrl->update_ndx;
    vp = &vctrl->vlist[undx];
    if (vp->update_cnt) {
        /*
         * pipe's iommu will be freed at next overlay play
         * and iommu_drop statistic will be increased by one
         */
        pr_warn("%s: update_cnt=%d\n", __func__, vp->update_cnt);
        mdp4_lcdc_pipe_clean(vp);
    }

    if (pipe) {
        /* sanity check, free pipes besides base layer */
        mixer = pipe->mixer_num;
        mdp4_overlay_unset_mixer(mixer);
        if (mfd->ref_cnt == 0) {
            /* adb stop */
            if (pipe->pipe_type == OVERLAY_TYPE_BF)
                mdp4_overlay_borderfill_stage_down(pipe);

            /* base pipe may change after borderfill_stage_down */
            pipe = vctrl->base_pipe;
            mdp4_mixer_stage_down(pipe, 1);
            mdp4_overlay_pipe_free(pipe, 1);
            vctrl->base_pipe = NULL;
        } else {
            /* system suspending */
            mdp4_mixer_stage_down(vctrl->base_pipe, 1);
            mdp4_overlay_iommu_pipe_free(
                vctrl->base_pipe->pipe_ndx, 1);
        }
    }

    mdp4_lcdc_tg_off(vctrl);

    atomic_set(&vctrl->suspend, 1);

    /*
     * clean up ion freelist
     * there need two stage to empty ion free list
     * therefore need call unmap freelist twice
     */
    mdp4_overlay_iommu_unmap_freelist(mixer);
    mdp4_overlay_iommu_unmap_freelist(mixer);

    /* MDP clock disable */
    mdp_clk_ctrl(0);
    mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);

    mutex_unlock(&mfd->dma->ov_mutex);

    return ret;
}
Esempio n. 2
0
int mdp4_lcdc_off(struct platform_device *pdev)
{
	int ret = 0;
	int cndx = 0;
	struct msm_fb_data_type *mfd;
	struct vsycn_ctrl *vctrl;
	struct mdp4_overlay_pipe *pipe;
	struct vsync_update *vp;
	unsigned long flags;
	int undx, need_wait = 0;

	mfd = (struct msm_fb_data_type *)platform_get_drvdata(pdev);
	vctrl = &vsync_ctrl_db[cndx];
	pipe = vctrl->base_pipe;

	atomic_set(&vctrl->suspend, 1);
	atomic_set(&vctrl->vsync_resume, 0);

	msleep(20);	/* >= 17 ms */

	complete_all(&vctrl->vsync_comp);
	vctrl->wait_vsync_cnt = 0;
	if (pipe == NULL)
		return -EINVAL;
	if (pipe->ov_blt_addr) {
		spin_lock_irqsave(&vctrl->spin_lock, flags);
		if (vctrl->ov_koff != vctrl->ov_done)
			need_wait = 1;
		spin_unlock_irqrestore(&vctrl->spin_lock, flags);
		if (need_wait)
			mdp4_lcdc_wait4ov(0);
	}

	mdp_histogram_ctrl_all(FALSE);

	MDP_OUTP(MDP_BASE + LCDC_BASE, 0);

	lcdc_enabled = 0;

	undx =  vctrl->update_ndx;
	vp = &vctrl->vlist[undx];
	if (vp->update_cnt) {
		/*
		 * pipe's iommu will be freed at next overlay play
		 * and iommu_drop statistic will be increased by one
		 */
		pr_warn("%s: update_cnt=%d\n", __func__, vp->update_cnt);
		mdp4_lcdc_pipe_clean(vp);
	}

	if (pipe) {
		/* sanity check, free pipes besides base layer */
		mdp4_overlay_unset_mixer(pipe->mixer_num);
		if (mfd->ref_cnt == 0) {
			/* adb stop */
			if (pipe->pipe_type == OVERLAY_TYPE_BF)
				mdp4_overlay_borderfill_stage_down(pipe);

			/* base pipe may change after borderfill_stage_down */
			pipe = vctrl->base_pipe;
			mdp4_mixer_stage_down(pipe, 1);
			mdp4_overlay_pipe_free(pipe);
			vctrl->base_pipe = NULL;
		} else {
			/* system suspending */
			mdp4_mixer_stage_down(vctrl->base_pipe, 1);
			mdp4_overlay_iommu_pipe_free(
				vctrl->base_pipe->pipe_ndx, 1);
		}
	}

	/* MDP clock disable */
	mdp_clk_ctrl(0);
	mdp_pipe_ctrl(MDP_OVERLAY0_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);

	return ret;
}