Exemple #1
0
void mdp_vsync_cfg_regs(struct msm_fb_data_type *mfd,
                        boolean first_time)
{
    /* MDP cmd block enable */
    mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON,
                  FALSE);
    if (first_time)
        mdp_hw_vsync_clk_enable(mfd);

    mdp_set_sync_cfg_0(mfd, vsync_cnt_cfg);

#ifdef CONFIG_FB_MSM_MDP40
    if (mdp_hw_revision < MDP4_REVISION_V2_1)
        mdp_set_sync_cfg_1(mfd, vsync_cnt_cfg);
#endif

    /*
     * load the last line + 1 to be in the
     * safety zone
     */
    vsync_load_cnt = mfd->panel_info.yres;

    /* line counter init value at the next pulse */
    MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_INIT_VAL,
             vsync_load_cnt);
#ifdef CONFIG_FB_MSM_MDP40
    if (mdp_hw_revision < MDP4_REVISION_V2_1) {
        MDP_OUTP(MDP_BASE +	MDP_SEC_VSYNC_INIT_VAL,
                 vsync_load_cnt);
    }
#endif

    /*
     * external vsync source pulse width and
     * polarity flip
     */
    MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_OUT_CTRL, BIT(0));
#ifdef CONFIG_FB_MSM_MDP40
    if (mdp_hw_revision < MDP4_REVISION_V2_1) {
        MDP_OUTP(MDP_BASE +	MDP_SEC_VSYNC_OUT_CTRL, BIT(0));
        MDP_OUTP(MDP_BASE +	MDP_VSYNC_SEL, 0x20);
    }
#endif

    /* threshold */
    MDP_OUTP(MDP_BASE + 0x200, (vsync_above_th << 16) |
             (vsync_start_th));

    if (first_time)
        mdp_hw_vsync_clk_disable(mfd);

    /* MDP cmd block disable */
    mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
void mdp_vsync_cfg_regs(struct msm_fb_data_type *mfd,
	boolean first_time)
{
	/*                      */
	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON,
			  FALSE);
	if (first_time)
		mdp_hw_vsync_clk_enable(mfd);

	mdp_set_sync_cfg_0(mfd, vsync_cnt_cfg);

#ifdef CONFIG_FB_MSM_MDP40
	if (mdp_hw_revision < MDP4_REVISION_V2_1)
		mdp_set_sync_cfg_1(mfd, vsync_cnt_cfg);
#endif

	/*
                                       
               
  */
	vsync_load_cnt = mfd->panel_info.yres;

	/*                                           */
	MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_INIT_VAL,
		vsync_load_cnt);
#ifdef CONFIG_FB_MSM_MDP40
	if (mdp_hw_revision < MDP4_REVISION_V2_1) {
		MDP_OUTP(MDP_BASE +	MDP_SEC_VSYNC_INIT_VAL,
			vsync_load_cnt);
	}
#endif

	/*
                                         
                 
  */
	MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_OUT_CTRL, BIT(0));
#ifdef CONFIG_FB_MSM_MDP40
	if (mdp_hw_revision < MDP4_REVISION_V2_1) {
		MDP_OUTP(MDP_BASE +	MDP_SEC_VSYNC_OUT_CTRL, BIT(0));
		MDP_OUTP(MDP_BASE +	MDP_VSYNC_SEL, 0x20);
	}
#endif

	/*           */
	MDP_OUTP(MDP_BASE + 0x200, (vsync_above_th << 16) |
		 (vsync_start_th));

	if (first_time)
		mdp_hw_vsync_clk_disable(mfd);

	/*                       */
	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
}
Exemple #3
0
void mdp_config_vsync(struct msm_fb_data_type *mfd)
{
	/* vsync on primary lcd only for now */
	if ((mfd->dest != DISPLAY_LCD) || (mfd->panel_info.pdest != DISPLAY_1)
	    || (!vsync_mode)) {
		goto err_handle;
	}

	vsync_clk_status = 0;
	if (mfd->panel_info.lcd.vsync_enable) {
		mfd->total_porch_lines = mfd->panel_info.lcd.v_back_porch +
		    mfd->panel_info.lcd.v_front_porch +
		    mfd->panel_info.lcd.v_pulse_width;
		mfd->total_lcd_lines =
		    mfd->panel_info.yres + mfd->total_porch_lines;
		mfd->lcd_ref_usec_time =
		    100000000 / mfd->panel_info.lcd.refx100;
		mfd->vsync_handler_pending = FALSE;
		mfd->last_vsync_timetick.tv.sec = 0;
		mfd->last_vsync_timetick.tv.nsec = 0;

#ifdef MDP_HW_VSYNC
		if (mdp_vsync_clk == NULL)
			mdp_vsync_clk = clk_get(NULL, "mdp_vsync_clk");

		if (IS_ERR(mdp_vsync_clk)) {
			printk(KERN_ERR "error: can't get mdp_vsync_clk!\n");
			mfd->use_mdp_vsync = 0;
		} else
			mfd->use_mdp_vsync = 1;

		if (mfd->use_mdp_vsync) {
			uint32 vsync_cnt_cfg, vsync_cnt_cfg_dem;
			uint32 mdp_vsync_clk_speed_hz;

			mdp_vsync_clk_speed_hz = clk_get_rate(mdp_vsync_clk);

			if (mdp_vsync_clk_speed_hz == 0) {
				mfd->use_mdp_vsync = 0;
			} else {
				/*
				 * Do this calculation in 2 steps for
				 * rounding uint32 properly.
				 */
				vsync_cnt_cfg_dem =
				    (mfd->panel_info.lcd.refx100 *
				     mfd->total_lcd_lines) / 100;
				vsync_cnt_cfg =
				    (mdp_vsync_clk_speed_hz) /
				    vsync_cnt_cfg_dem;

				/* MDP cmd block enable */
				mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON,
					      FALSE);
				mdp_hw_vsync_clk_enable(mfd);

				mdp_set_sync_cfg_0(mfd, vsync_cnt_cfg);


#ifdef CONFIG_FB_MSM_MDP40
				if (mdp_hw_revision < MDP4_REVISION_V2_1)
					mdp_set_sync_cfg_1(mfd, vsync_cnt_cfg);
#endif

				/*
				 * load the last line + 1 to be in the
				 * safety zone
				 */
				vsync_load_cnt = mfd->panel_info.yres;

				/* line counter init value at the next pulse */
				MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_INIT_VAL,
							vsync_load_cnt);
#ifdef CONFIG_FB_MSM_MDP40
				if (mdp_hw_revision < MDP4_REVISION_V2_1) {
					MDP_OUTP(MDP_BASE +
					MDP_SEC_VSYNC_INIT_VAL, vsync_load_cnt);
				}
#endif

				/*
				 * external vsync source pulse width and
				 * polarity flip
				 */
				MDP_OUTP(MDP_BASE + MDP_PRIM_VSYNC_OUT_CTRL,
							BIT(0));
#ifdef CONFIG_FB_MSM_MDP40
				if (mdp_hw_revision < MDP4_REVISION_V2_1) {
					MDP_OUTP(MDP_BASE +
					MDP_SEC_VSYNC_OUT_CTRL, BIT(0));
					MDP_OUTP(MDP_BASE +
						MDP_VSYNC_SEL, 0x20);
				}
#endif

				/* threshold */
#ifdef CONFIG_MACH_ACER_A4
				MDP_OUTP(MDP_BASE + MDP_SYNC_THRESH_0, (vsync_above_th << 16) | (vsync_start_th));
				MDP_OUTP(MDP_BASE + MDP_SYNC_THRESH_1, (vsync_above_th << 16) | (vsync_start_th));
#else
				MDP_OUTP(MDP_BASE + 0x200,
					 (vsync_above_th << 16) |
					 (vsync_start_th));
#endif

				mdp_hw_vsync_clk_disable(mfd);
				/* MDP cmd block disable */
				mdp_pipe_ctrl(MDP_CMD_BLOCK,
					      MDP_BLOCK_POWER_OFF, FALSE);
			}
		}
#else
		mfd->use_mdp_vsync = 0;
		hrtimer_init(&mfd->dma_hrtimer, CLOCK_MONOTONIC,
			     HRTIMER_MODE_REL);
		mfd->dma_hrtimer.function = mdp_dma2_vsync_hrtimer_handler;
		mfd->vsync_width_boundary = vmalloc(mfd->panel_info.xres * 4);
#endif

#ifdef CONFIG_FB_MSM_MDDI
		mfd->channel_irq = 0;
		if (mfd->panel_info.lcd.hw_vsync_mode) {
			u32 vsync_gpio = mfd->vsync_gpio;
			u32 ret;

			if (vsync_gpio == -1) {
				MSM_FB_INFO("vsync_gpio not defined!\n");
				goto err_handle;
			}

			ret = gpio_tlmm_config(GPIO_CFG
					(vsync_gpio,
					(mfd->use_mdp_vsync) ? 1 : 0,
					GPIO_CFG_INPUT,
					GPIO_CFG_PULL_DOWN,
					GPIO_CFG_2MA),
					GPIO_CFG_ENABLE);
			if (ret)
				goto err_handle;

			/*
			 * if use_mdp_vsync, then no interrupt need since
			 * mdp_vsync is feed directly to mdp to reset the
			 * write pointer counter. therefore no irq_handler
			 * need to reset write pointer counter.
			 */
			if (!mfd->use_mdp_vsync) {
				mfd->channel_irq = MSM_GPIO_TO_INT(vsync_gpio);
				if (request_irq
				    (mfd->channel_irq,
				     &mdp_hw_vsync_handler_proxy,
				     IRQF_TRIGGER_FALLING, "VSYNC_GPIO",
				     (void *)mfd)) {
					MSM_FB_INFO
					("irq=%d failed! vsync_gpio=%d\n",
						mfd->channel_irq,
						vsync_gpio);
					goto err_handle;
				}
			}
		}
#endif
		mdp_hw_vsync_clk_enable(mfd);
		mdp_set_vsync((unsigned long)mfd);
	}

	return;

err_handle:
	if (mfd->vsync_width_boundary)
		vfree(mfd->vsync_width_boundary);
	mfd->panel_info.lcd.vsync_enable = FALSE;
	printk(KERN_ERR "%s: failed!\n", __func__);
}