예제 #1
0
static void lcdc_overlay_start(void *priv, uint32_t addr, uint32_t stride,
			   uint32_t width, uint32_t height, uint32_t x,
			   uint32_t y)
{
	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);

	struct mdp4_overlay_pipe *pipe;
	pipe = lcdc_pipe;
	pipe->srcp0_addr = addr;

	if (mdp->dma_config_dirty)
	{
		if(mdp->dma_format == DMA_IBUF_FORMAT_RGB565) {
			pipe->src_format = MDP_RGB_565;
			pipe->srcp0_ystride = pipe->src_width * 2;
		} else if(mdp->dma_format == DMA_IBUF_FORMAT_XRGB8888) {
			pipe->src_format = MDP_RGBA_8888;
			pipe->srcp0_ystride = pipe->src_width * 4;
		}
		mdp4_overlay_format2pipe(pipe);
		mdp_writel(pipe->mdp, 0, MDP_LCDC_EN);
		mdelay(30);
		mdp4_overlay_dmap_xy(pipe);
		mdp4_overlay_dmap_cfg(pipe, 1);
		mdp4_overlayproc_cfg(pipe);
		mdp4_overlay_rgb_setup(pipe);
		mdp4_overlay_reg_flush(pipe, 1); /* rgb1 and mixer0 */
		mdp_writel(pipe->mdp, 1, MDP_LCDC_EN);
		mdp->dma_config_dirty = false;
	} else {
		mdp4_overlay_rgb_setup(pipe);
		mdp4_overlay_reg_flush(pipe, 1); /* rgb1 and mixer0 */
	}

}
예제 #2
0
static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride,
			    uint32_t width, uint32_t height, uint32_t x,
			    uint32_t y)
{
	struct mdp_info *mdp = priv;
	uint32_t dma2_cfg;
	uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */

	dma2_cfg = DMA_PACK_TIGHT |
		DMA_PACK_ALIGN_LSB;

	dma2_cfg |= mdp->dma_format;
	dma2_cfg |= mdp->dma_pack_pattern;
	dma2_cfg |= DMA_DITHER_EN;

	/* 666 18BPP */
	dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;

	/* setup size, address, and stride */
	mdp_writel(mdp, (height << 16) | (width), MDP_DMA_P_SIZE);
	mdp_writel(mdp, addr, MDP_DMA_P_IBUF_ADDR);
	mdp_writel(mdp, stride, MDP_DMA_P_IBUF_Y_STRIDE);

	/* set y & x offset and MDDI transaction parameters */
	mdp_writel(mdp, (y << 16) | (x), MDP_DMA_P_OUT_XY);
	mdp_writel(mdp, ld_param, MDP_MDDI_PARAM_WR_SEL);
	mdp_writel(mdp, (MDDI_VDO_PACKET_DESC << 16) | MDDI_VDO_PACKET_PRIM,
		   MDP_MDDI_PARAM);

	mdp_writel(mdp, 0x1, MDP_MDDI_DATA_XFR);
	mdp_writel(mdp, dma2_cfg, MDP_DMA_P_CONFIG);
	mdp_writel(mdp, 0, MDP_DMA_P_START);
}
예제 #3
0
static int icm_thread(void *data)
{
	struct mdp_lcdc_info *lcdc;
	struct msm_lcdc_panel_ops *panel_ops;
	int rc;
	unsigned long irq_flags = 0;

	lcdc = data;
	panel_ops = lcdc->pdata->panel_ops;
	while (1) {
		rc = wait_event_timeout(panel_update_wait_queue, icm_check_panel_update() == 1, PANEL_ENTER_IDLE_TIMEOUT);
		ICM_DBG("ICM Thread:wake up rc=%d \n", rc);
		mutex_lock(&panel_icm->icm_lock);
		if (rc == 0 && icm_check_panel_update() != 1) {/* wait_timeout */
			ICM_DBG("EnterICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable);
			if (panel_icm->icm_mode == false && panel_icm->icm_doable == true) {

				if (panel_ops->refresh_enable)
					panel_ops->refresh_enable(panel_ops);

				panel_icm->icm_mode = true;
				msleep(PANEL_IDLE_STABLE_TIMEOUT);

				mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
				clk_disable(lcdc->pad_pclk);
				clk_disable(lcdc->pclk);
				clk_disable(lcdc->mdp_clk);
				panel_icm->clock_enabled = false;
				PR_DISP_DEBUG("EnterICM: enter ICM MODE done!!!\n");
			}
		} else {/* get update event, no timeout */
			ICM_DBG("Leave ICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable);
			if (panel_icm->icm_mode == true && panel_icm->icm_doable == true) {
				clk_enable(lcdc->mdp_clk);
				clk_enable(lcdc->pclk);
				clk_enable(lcdc->pad_pclk);
				mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
				panel_icm->clock_enabled = true;

				if (panel_ops->refresh_disable)
					panel_ops->refresh_disable(panel_ops);

				panel_icm->icm_mode = false;
				PR_DISP_DEBUG("LeaveICM: leave ICM MODE done !!!\n");
			}
			spin_lock_irqsave(&panel_icm->lock, irq_flags);
			panel_icm->panel_update = 0;
			spin_unlock_irqrestore(&panel_icm->lock, irq_flags);
		}
		mutex_unlock(&panel_icm->icm_lock);
	} /* end while */
	return 0;
}
예제 #4
0
void mdp4_lcdc_overlay_blt(ulong addr)
{
       unsigned long flag;

       spin_lock_irqsave(&mdp_spin_lock, flag);
       lcdc_pipe->blt_addr = addr;
       lcdc_pipe->blt_cnt = 0;
       spin_unlock_irqrestore(&mdp_spin_lock, flag);
       mdp_writel(lcdc_pipe->mdp,0x0,0xc0000);
       mdelay(100);
       mdp4_overlayproc_cfg(lcdc_pipe);
       mdp4_overlay_dmap_xy(lcdc_pipe);
       mdelay(100);
       mdp_writel(lcdc_pipe->mdp,0x1,0xc0000);
}
예제 #5
0
static int lcdc_unblank(struct msm_panel_data *fb_panel)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

	HDMI_DBG("%s\n", __func__);

#if 0
	HDMI_DBG("%s: enable clocks\n", __func__);
	clk_enable(lcdc->mdp_clk);
	clk_enable(lcdc->pclk);
	clk_enable(lcdc->pad_pclk);

	panel_ops->unblank(panel_ops);

	mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
	atomic_set(&lcdc->blank_count, 1);
#else
	lcdc_enable_video();
	/* TODO: need pre-test to see if it make any influence to HDCP,
	 * if ebi1_clk enabled here.
	 */
        panel_ops->unblank(panel_ops);
#endif
	return 0;
}
예제 #6
0
static void lcdc_dma_start(void *priv, uint32_t addr, uint32_t stride,
			   uint32_t width, uint32_t height, uint32_t x,
			   uint32_t y)
{
	struct mdp_lcdc_info *lcdc = priv;
	struct mdp_info *mdp = container_of(mdp_dev, struct mdp_info, mdp_dev);
	if (mdp->dma_config_dirty)
	{
		mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
		mdelay(30);
		mdp_dev->configure_dma(mdp_dev);
		mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
	}
	mdp_writel(lcdc->mdp, stride, MDP_DMA_P_IBUF_Y_STRIDE);
	mdp_writel(lcdc->mdp, addr, MDP_DMA_P_IBUF_ADDR);
}
예제 #7
0
static void icm_force_leave(void)
{
	struct msm_lcdc_panel_ops *panel_ops;
	unsigned long irq_flags = 0;

	panel_ops = panel_icm->lcdc->pdata->panel_ops;

	mutex_lock(&panel_icm->icm_lock);
	ICM_DBG("Force Leave ICM: icm_mode=%d icm_doable=%d \n", panel_icm->icm_mode, panel_icm->icm_doable);
	if (panel_icm->icm_mode == true) {
		clk_enable(panel_icm->lcdc->mdp_clk);
		clk_enable(panel_icm->lcdc->pclk);
		clk_enable(panel_icm->lcdc->pad_pclk);
		mdp_writel(panel_icm->lcdc->mdp, 1, MDP_LCDC_EN);
		panel_icm->clock_enabled = true;
		if (panel_ops->refresh_disable)
			panel_ops->refresh_disable(panel_ops);
		panel_icm->icm_mode = false;
		panel_icm->icm_doable = true;
                PR_DISP_INFO("ForceLeaveICM: leave ICM MODE done !!!\n");
	}
	spin_lock_irqsave(&panel_icm->lock, irq_flags);
        panel_icm->panel_update = 0;
        spin_unlock_irqrestore(&panel_icm->lock, irq_flags);
	mutex_unlock(&panel_icm->icm_lock);
}
예제 #8
0
/* FIXME: arrange the clock manipulating to proper place,
	  integrate with the counter of fb_hdmi
*/
int lcdc_enable_video(void)
{
        //struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
        struct mdp_lcdc_info *lcdc = _lcdc;
        struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

	mutex_lock(&lcdc->blank_lock);
	if (atomic_read(&lcdc->blank_count))
		goto end_enable_video;
        HDMI_DBG("%s: enable clocks\n", __func__);
        clk_enable(lcdc->mdp_clk);
        clk_enable(lcdc->pclk);
        clk_enable(lcdc->pad_pclk);

	/* TODO: need pre-test to see if it make any influence to HDCP,
	 * if ebi1_clk doesn't enabled here.
	 */
	//panel_ops->unblank(panel_ops);

        mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
        atomic_inc(&lcdc->blank_count);
        HDMI_DBG("%s, blank_count=%d\n", __func__,
		atomic_read(&lcdc->blank_count));
end_enable_video:
	mutex_unlock(&lcdc->blank_lock);

        return 0;
}
예제 #9
0
void mdp4_mddi_overlay_kickoff(struct mdp_info *mdp,
                               struct mdp4_overlay_pipe *pipe)
{
#ifdef MDP4_NONBLOCKING
    mdp_writel(mdp, 0, 0x0004);
#endif
}
예제 #10
0
static int lcdc_resume(struct msm_panel_data *fb_panel)
{
//	unsigned int status;
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

	pr_info("%s: resuming\n", __func__);

	if (panel_ops->init) {
		if (panel_ops->init(panel_ops) < 0)
			printk(KERN_ERR "LCD init fail!\n");
	}

	clk_enable(lcdc->mdp_clk);
	clk_enable(lcdc->pclk);
	clk_enable(lcdc->pad_pclk);
#if defined(CONFIG_ARCH_MSM7227)
	writel(0x1, LCDC_MUX_CTL);
	status = readl(LCDC_MUX_CTL);
	D("resume_lcdc_mux_ctl = %x\n",status);
#endif

	mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);

	return 0;
}
예제 #11
0
static void lcdc_request_vsync(struct msm_panel_data *fb_panel,
			       struct msmfb_callback *vsync_cb)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);

	/* the vsync callback will start the dma */
	vsync_cb->func(vsync_cb);
// CotullaFIX start
// F**K, who make calls from console with disabled interrupts, F**K THEM!
	if (irqs_disabled())
	{
	    	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
		uint32_t status;
		uint32_t i;
		// do it via polling
		for (i = 0; i < 20; i++) 
		{
        		status = mdp_readl(lcdc->mdp, MDP_INTR_STATUS);
			if (status & MDP_LCDC_FRAME_START)
		            	break;
		        mdelay(1);
        	}                
		// clear intr at the end
		mdp_writel(lcdc->mdp, MDP_LCDC_FRAME_START, MDP_INTR_CLEAR);
//		vsync_cb->func(vsync_cb);
	}
	else
	{
		lcdc->got_vsync = 0;
		mdp_out_if_req_irq(mdp_dev, MSM_LCDC_INTERFACE, MDP_LCDC_FRAME_START,
			  &lcdc->frame_start_cb);
		lcdc_wait_vsync(fb_panel);
	}
// CotullaFIX end       
}
예제 #12
0
static int lcdc_suspend(struct msm_panel_data *fb_panel)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

	pr_info("%s: suspending\n", __func__);

#if defined(CONFIG_ARCH_MSM7227)
	writel(0x0, LCDC_MUX_CTL);
	D("suspend_lcdc_mux_ctl = %x\n", readl(LCDC_MUX_CTL));
#endif
#ifdef CONFIG_PANEL_SELF_REFRESH
	if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
	mutex_lock(&panel_icm->icm_lock);
	panel_icm->icm_doable = false;
	pr_info("[ICM %s]: icm mode=%d\n", __func__, panel_icm->icm_mode);
	if (panel_icm->icm_mode == false) {
#endif
	mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
	clk_disable(lcdc->pad_pclk);
	clk_disable(lcdc->pclk);
	clk_disable(lcdc->mdp_clk);
#ifdef CONFIG_PANEL_SELF_REFRESH
	}
	mutex_unlock(&panel_icm->icm_lock);
       }
#endif
	if (panel_ops->uninit)
		panel_ops->uninit(panel_ops);

	return 0;
}
예제 #13
0
static int lcdc_blank(struct msm_panel_data *fb_panel)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
	//struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

#if 0
	mutex_lock(&lcdc->blank_lock);
	if (atomic_read(&lcdc->blank_count) == 0)
		goto blank_done;
	if (atomic_dec_return(&lcdc->blank_count) == 0) {
		HDMI_DBG("%s: disable clocks\n", __func__);
		panel_ops->blank(panel_ops);
		mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
		clk_disable(lcdc->pclk);
		clk_disable(lcdc->pad_pclk);
		clk_disable(lcdc->mdp_clk);
	}
blank_done:
	mutex_unlock(&lcdc->blank_lock);
	HDMI_DBG("%s, blank_count=%d\n", __func__,
		atomic_read(&lcdc->blank_count));
#else
	lcdc_disable_video();
#endif
	return 0;
}
예제 #14
0
static int lcdc_resume(struct msm_panel_data *fb_panel)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

	PR_DISP_INFO("%s: resuming\n", __func__);

	if (panel_ops->init) {
		if (panel_ops->init(panel_ops) < 0)
			PR_DISP_ERR("LCD init fail!\n");
	}

	clk_enable(lcdc->mdp_clk);
	clk_enable(lcdc->pclk);
	clk_enable(lcdc->pad_pclk);
#if defined(CONFIG_ARCH_MSM7227)
	writel(0x1, LCDC_MUX_CTL);
	D("resume_lcdc_mux_ctl = %x\n", readl(LCDC_MUX_CTL));
#endif

	mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);
#ifdef CONFIG_PANEL_SELF_REFRESH
	if (lcdc->mdp->mdp_dev.overrides & MSM_MDP_RGB_PANEL_SELE_REFRESH) {
		mutex_lock(&panel_icm->icm_lock);
		panel_icm->icm_doable = true;
		panel_icm->clock_enabled = true;
		panel_icm->icm_suspend = false;
		mutex_unlock(&panel_icm->icm_lock);
	}
#endif

	return 0;
}
예제 #15
0
static int lcdc_suspend(struct msm_panel_data *fb_panel)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);

	pr_info("%s: suspending\n", __func__);

	mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
<<<<<<< HEAD
예제 #16
0
void mdp4_blt_xy_update(struct mdp4_overlay_pipe *pipe)
{
       uint32_t off, addr;

       if (pipe->blt_addr == 0)
               return;

       /* overlay ouput is RG565 */
       off = 0;
       if (pipe->blt_cnt & 0x01)
               off = pipe->src_height * pipe->src_width * 2;

	addr = pipe->blt_addr+ off;

       /* dmap */
	mdp_writel(pipe->mdp, addr, 0x90008);
       /* overlay 0 */
       mdp_writel(pipe->mdp, addr, MDP4_OVERLAYPROC0_BASE + 0x000c);
       mdp_writel(pipe->mdp, addr, MDP4_OVERLAYPROC0_BASE + 0x001c);
}
예제 #17
0
/*
 * mdp4_dmap_done_mddi: called from isr
 */
void mdp4_dma_p_done_mddi(void)
{
       if (mddi_pipe->blt_end) {
               mddi_pipe->blt_addr = 0;
               mdp_intr_mask &= ~INTR_DMA_P_DONE;
	       mdp_writel(mddi_pipe->mdp,mdp_intr_mask,MDP_INTR_ENABLE);
               mdp4_overlayproc_cfg(mddi_pipe);
               mdp4_overlay_dmap_xy(mddi_pipe);
               return;
       }
}
예제 #18
0
void mdp4_dma_s_update_lcd(struct mdp_info *mdp)
{
	uint32_t mddi_ld_param = 1;
	uint16_t mddi_vdo_packet_reg = MDDI_VDO_PACKET_PRIM;
	struct mdp4_overlay_pipe *pipe = NULL;

	mddi_mdp = mdp;		/* keep it */

	pipe = mddi_pipe;

	/*config PIXELSIZE*/
	mdp4_overlay_dmas_xy(pipe);

	/*config for dma_s_cfg_reg*/
	mdp4_overlay_dmas_cfg(pipe, 0);

	mdp_writel(mdp, mddi_ld_param, 0x00090);
	mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB565 << 16) | mddi_vdo_packet_reg, 0x00094);
	mdp_writel(mdp, 1, 0x00098);
}
예제 #19
0
static int lcdc_resume(struct msm_panel_data *fb_panel)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);

	pr_info("%s: resuming\n", __func__);

	clk_prepare_enable(lcdc->mdp_clk);
	clk_prepare_enable(lcdc->pclk);
	clk_prepare_enable(lcdc->pad_pclk);
	mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);

	return 0;
}
예제 #20
0
static int lcdc_suspend(struct msm_panel_data *fb_panel)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);

	pr_info("%s: suspending\n", __func__);

	mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
	clk_disable_unprepare(lcdc->pad_pclk);
	clk_disable_unprepare(lcdc->pclk);
	clk_disable_unprepare(lcdc->mdp_clk);

	return 0;
}
예제 #21
0
/*
 * mdp4_overlay0_done_mddi: called from isr
 */
void mdp4_overlay0_done_mddi(void)
{
	if (mddi_pipe->blt_addr) {
		if (mddi_pipe->blt_cnt == 0) {
			mdp4_overlayproc_cfg(mddi_pipe);
			mdp4_overlay_dmap_xy(mddi_pipe);
			mddi_pipe->blt_cnt++;
			/* BLT start from next frame */
		} else {
			mdp4_blt_xy_update(mddi_pipe);
			mddi_pipe->blt_cnt++;

			/* start DMAP */
			mdp_writel(mddi_pipe->mdp,0x0,0x000c);
		}
	}

}
예제 #22
0
int mdp_hw_init(struct mdp_info *mdp)
{
	int ret;

	ret = mdp_out_if_register(&mdp->mdp_dev, MSM_MDDI_PMDH_INTERFACE, mdp,
				  MDP_DMA_P_DONE, mdp_dma_to_mddi);
	if (ret)
		return ret;

	mdp_writel(mdp, 0, MDP_INTR_ENABLE);
	mdp_writel(mdp, 0, MDP_DMA_P_HIST_INTR_ENABLE);

	/* XXX: why set this? QCT says it should be > mdp_pclk,
	 * but they never set the clkrate of pclk */
	mdp_set_core_clk(4);
	pr_info("%s: mdp_clk=%lu\n", __func__, clk_get_rate(mdp->clk));

	/* TODO: Configure the VG/RGB pipes fetch data */

	/* this should work for any mdp_clk freq.
	 * TODO: use different value for mdp_clk freqs >= 90Mhz */
	mdp_writel(mdp, 0x27, MDP_DMA_P_FETCH_CFG); /* 8 bytes-burst x 8 req */

	mdp_writel(mdp, 0x3, MDP_EBI2_PORTMAP_MODE);

	/* 3 pending requests */
	mdp_writel(mdp, 0x02222, MDP_MAX_RD_PENDING_CMD_CONFIG);

	/* no overlay processing, sw controls everything */
	mdp_writel(mdp, 0, MDP_LAYERMIXER_IN_CFG);
	mdp_writel(mdp, 1 << 3, MDP_OVERLAYPROC0_CFG);
	mdp_writel(mdp, 1 << 3, MDP_OVERLAYPROC1_CFG);

	/* XXX: HACK! hardcode to do mddi on primary */
	mdp_writel(mdp, 0x2, MDP_DISP_INTF_SEL);
	return 0;
}
예제 #23
0
static int lcdc_suspend(struct msm_panel_data *fb_panel)
{
	struct mdp_lcdc_info *lcdc = panel_to_lcdc(fb_panel);
	struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

	pr_info("%s: suspending\n", __func__);

#if defined(CONFIG_ARCH_MSM7227)
	writel(0x0, LCDC_MUX_CTL);
	D("suspend_lcdc_mux_ctl = %x\n", readl(LCDC_MUX_CTL));
#endif
	mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
	clk_disable(lcdc->pad_pclk);
	clk_disable(lcdc->pclk);
	clk_disable(lcdc->mdp_clk);
	if (panel_ops->uninit)
		panel_ops->uninit(panel_ops);

	return 0;
}
예제 #24
0
void mdp4_mddi_overlay_blt(ulong addr)
{
       unsigned long flag;

       spin_lock_irqsave(&mdp_spin_lock, flag);
       if (addr) {
		mdp_intr_mask |= INTR_DMA_P_DONE;
		if(mddi_pipe!=NULL){
			mdp_writel(mddi_pipe->mdp,mdp_intr_mask,MDP_INTR_ENABLE);
			mddi_pipe->blt_cnt = 0;
			mddi_pipe->blt_end = 0;
			mddi_pipe->blt_addr = addr;
			}
		blt_addr = addr;
       } else {
		mddi_pipe->blt_end = 1; /* mark as end */
		mdp4_dma_p_done_mddi();
       }
       spin_unlock_irqrestore(&mdp_spin_lock, flag);
}
예제 #25
0
int lcdc_disable_video(void)
{
        struct mdp_lcdc_info *lcdc = _lcdc;
        struct msm_lcdc_panel_ops *panel_ops = lcdc->pdata->panel_ops;

	mutex_lock(&lcdc->blank_lock);
	if (atomic_read(&lcdc->blank_count) == 0)
		goto disable_video_done;
	if (atomic_dec_return(&lcdc->blank_count) == 0) {
		HDMI_DBG("%s: disable clocks\n", __func__);
		panel_ops->blank(panel_ops);
		mdp_writel(lcdc->mdp, 0, MDP_LCDC_EN);
		clk_disable(lcdc->pclk);
		clk_disable(lcdc->pad_pclk);
		clk_disable(lcdc->mdp_clk);
	}
disable_video_done:
	mutex_unlock(&lcdc->blank_lock);
	HDMI_DBG("%s, blank_count=%d\n", __func__,
			atomic_read(&lcdc->blank_count));
	return 0;
}
예제 #26
0
static int lcdc_hw_init(struct mdp_lcdc_info *lcdc)
{
	struct msm_panel_data *fb_panel = &lcdc->fb_panel_data;
	uint32_t dma_cfg;
        unsigned int clk_id, clk_rate;

	clk_enable(lcdc->mdp_clk);
	clk_enable(lcdc->pclk);
	clk_enable(lcdc->pad_pclk);

	clk_set_rate(lcdc->pclk, lcdc->parms.clk_rate);
	clk_set_rate(lcdc->pad_pclk, lcdc->parms.clk_rate);
	printk(KERN_DEBUG "pclk = %ld, pad_pclk = %ld\n",
			clk_get_rate(lcdc->pclk),
			clk_get_rate(lcdc->pad_pclk));

	/* write the lcdc params */
	mdp_writel(lcdc->mdp, lcdc->parms.hsync_ctl, MDP_LCDC_HSYNC_CTL);
	mdp_writel(lcdc->mdp, lcdc->parms.vsync_period, MDP_LCDC_VSYNC_PERIOD);
	mdp_writel(lcdc->mdp, lcdc->parms.vsync_pulse_width,
		   MDP_LCDC_VSYNC_PULSE_WIDTH);
	mdp_writel(lcdc->mdp, lcdc->parms.display_hctl, MDP_LCDC_DISPLAY_HCTL);
	mdp_writel(lcdc->mdp, lcdc->parms.display_vstart,
		   MDP_LCDC_DISPLAY_V_START);
	mdp_writel(lcdc->mdp, lcdc->parms.display_vend, MDP_LCDC_DISPLAY_V_END);
	mdp_writel(lcdc->mdp, lcdc->parms.hsync_skew, MDP_LCDC_HSYNC_SKEW);

	mdp_writel(lcdc->mdp, 0, MDP_LCDC_BORDER_CLR);
	mdp_writel(lcdc->mdp, 0, MDP_LCDC_UNDERFLOW_CTL);
	mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_HCTL);
	mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_START);
	mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_END);
	mdp_writel(lcdc->mdp, lcdc->parms.polarity, MDP_LCDC_CTL_POLARITY);
	printk("solomon: polarity=%04x\n", mdp_readl(lcdc->mdp, MDP_LCDC_CTL_POLARITY));

	/* config the dma_p block that drives the lcdc data */
	mdp_writel(lcdc->mdp, lcdc->fb_start, MDP_DMA_P_IBUF_ADDR);
	mdp_writel(lcdc->mdp, (((fb_panel->fb_data->yres & 0x7ff) << 16) |
			       (fb_panel->fb_data->xres & 0x7ff)),
		   MDP_DMA_P_SIZE);
	/* TODO: pull in the bpp info from somewhere else? */
	mdp_writel(lcdc->mdp, fb_panel->fb_data->xres * 2,
		   MDP_DMA_P_IBUF_Y_STRIDE);
	mdp_writel(lcdc->mdp, 0, MDP_DMA_P_OUT_XY);

	dma_cfg = (DMA_PACK_ALIGN_LSB |
		   DMA_PACK_PATTERN_RGB |
		   DMA_DITHER_EN);
	dma_cfg |= DMA_OUT_SEL_LCDC;
	dma_cfg |= DMA_IBUF_FORMAT_RGB565;
	dma_cfg |= DMA_DSTC0G_8BITS | DMA_DSTC1B_8BITS | DMA_DSTC2R_8BITS;

	mdp_writel(lcdc->mdp, dma_cfg, MDP_DMA_P_CONFIG);

	/* Send customized command to ARM9 for escalating DMA_P as tier-1
	 * of AXI bus.
	 * Ref: SR#272509
	 */
	clk_id = P_USB_PHY_CLK;
	clk_rate = 0x1;
	msm_proc_comm(PCOM_CLKCTL_RPC_MIN_RATE, &clk_id, &clk_rate);

	return 0;
}
예제 #27
0
static int lcdc_hw_init(struct mdp_lcdc_info *lcdc)
{
	struct msm_panel_data *fb_panel = &lcdc->fb_panel_data;
	uint32_t dma_cfg;

	clk_prepare_enable(lcdc->mdp_clk);
	clk_prepare_enable(lcdc->pclk);
	clk_prepare_enable(lcdc->pad_pclk);

	clk_set_rate(lcdc->pclk, lcdc->parms.clk_rate);
	clk_set_rate(lcdc->pad_pclk, lcdc->parms.clk_rate);

	/* write the lcdc params */
	mdp_writel(lcdc->mdp, lcdc->parms.hsync_ctl, MDP_LCDC_HSYNC_CTL);
	mdp_writel(lcdc->mdp, lcdc->parms.vsync_period, MDP_LCDC_VSYNC_PERIOD);
	mdp_writel(lcdc->mdp, lcdc->parms.vsync_pulse_width,
		   MDP_LCDC_VSYNC_PULSE_WIDTH);
	mdp_writel(lcdc->mdp, lcdc->parms.display_hctl, MDP_LCDC_DISPLAY_HCTL);
	mdp_writel(lcdc->mdp, lcdc->parms.display_vstart,
		   MDP_LCDC_DISPLAY_V_START);
	mdp_writel(lcdc->mdp, lcdc->parms.display_vend, MDP_LCDC_DISPLAY_V_END);
	mdp_writel(lcdc->mdp, lcdc->parms.hsync_skew, MDP_LCDC_HSYNC_SKEW);

	mdp_writel(lcdc->mdp, 0, MDP_LCDC_BORDER_CLR);
	mdp_writel(lcdc->mdp, 0xff, MDP_LCDC_UNDERFLOW_CTL);
	mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_HCTL);
	mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_START);
	mdp_writel(lcdc->mdp, 0, MDP_LCDC_ACTIVE_V_END);
	mdp_writel(lcdc->mdp, lcdc->parms.polarity, MDP_LCDC_CTL_POLARITY);

	/* config the dma_p block that drives the lcdc data */
	mdp_writel(lcdc->mdp, lcdc->fb_start, MDP_DMA_P_IBUF_ADDR);
	mdp_writel(lcdc->mdp, (((fb_panel->fb_data->yres & 0x7ff) << 16) |
			       (fb_panel->fb_data->xres & 0x7ff)),
		   MDP_DMA_P_SIZE);

	mdp_writel(lcdc->mdp, 0, MDP_DMA_P_OUT_XY);

	dma_cfg = mdp_readl(lcdc->mdp, MDP_DMA_P_CONFIG);
	dma_cfg |= (DMA_PACK_ALIGN_LSB |
		   DMA_PACK_PATTERN_RGB |
		   DMA_DITHER_EN);
	dma_cfg |= DMA_OUT_SEL_LCDC;
	dma_cfg &= ~DMA_DST_BITS_MASK;

	if (fb_panel->fb_data->output_format == MSM_MDP_OUT_IF_FMT_RGB666)
		dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;
	else
		dma_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_5BITS | DMA_DSTC2R_5BITS;

	mdp_writel(lcdc->mdp, dma_cfg, MDP_DMA_P_CONFIG);

	/* enable the lcdc timing generation */
	mdp_writel(lcdc->mdp, 1, MDP_LCDC_EN);

	return 0;
}
예제 #28
0
void mdp_check_tearing(struct mdp_info *mdp, struct msm_mdp_platform_data *pdata)
{	mdp_writel(mdp, pdata->sync_config, MDP_SYNC_CONFIG_0);
	mdp_writel(mdp, 1, MDP_TEAR_CHECK_EN);
	mdp_writel(mdp, pdata->sync_thresh, MDP_SYNC_THRESH_0);
	mdp_writel(mdp, pdata->sync_start_pos, MDP_PRIM_START_POS);
}
예제 #29
0
static void mdp_dma_to_mddi(void *priv, uint32_t addr, uint32_t stride,
			    uint32_t width, uint32_t height, uint32_t x,
			    uint32_t y)
{
	struct mdp_info *mdp = priv;
	uint32_t dma2_cfg;
	uint16_t ld_param = 0; /* 0=PRIM, 1=SECD, 2=EXT */

	dma2_cfg = DMA_PACK_TIGHT |
		DMA_PACK_ALIGN_LSB |
		DMA_OUT_SEL_AHB |
		DMA_IBUF_NONCONTIGUOUS;

	dma2_cfg |= mdp->dma_format;
	dma2_cfg |= mdp->dma_pack_pattern;

	dma2_cfg |= DMA_OUT_SEL_MDDI;

	dma2_cfg |= DMA_MDDI_DMAOUT_LCD_SEL_PRIMARY;

	dma2_cfg |= DMA_DITHER_EN;

	/* 666 18BPP */
	dma2_cfg |= DMA_DSTC0G_6BITS | DMA_DSTC1B_6BITS | DMA_DSTC2R_6BITS;

#ifdef CONFIG_MSM_MDP22
	/* setup size, address, and stride */
	mdp_writel(mdp, (height << 16) | (width),
		   MDP_CMD_DEBUG_ACCESS_BASE + 0x0184);
	mdp_writel(mdp, addr, MDP_CMD_DEBUG_ACCESS_BASE + 0x0188);
	mdp_writel(mdp, stride, MDP_CMD_DEBUG_ACCESS_BASE + 0x018C);

	/* set y & x offset and MDDI transaction parameters */
	mdp_writel(mdp, (y << 16) | (x), MDP_CMD_DEBUG_ACCESS_BASE + 0x0194);
	mdp_writel(mdp, ld_param, MDP_CMD_DEBUG_ACCESS_BASE + 0x01a0);
	if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565)
		mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB565 << 16) | MDDI_VDO_PACKET_PRIM,
		   MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4);
	else
		mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB666 << 16) | MDDI_VDO_PACKET_PRIM,
		   MDP_CMD_DEBUG_ACCESS_BASE + 0x01a4);
	mdp_writel(mdp, dma2_cfg, MDP_CMD_DEBUG_ACCESS_BASE + 0x0180);

	/* start DMA2 */
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0044);
#else
	/* setup size, address, and stride */
	mdp_writel(mdp, (height << 16) | (width), MDP_DMA_P_SIZE);
	mdp_writel(mdp, addr, MDP_DMA_P_IBUF_ADDR);
	mdp_writel(mdp, stride, MDP_DMA_P_IBUF_Y_STRIDE);

	/* set y & x offset and MDDI transaction parameters */
	mdp_writel(mdp, (y << 16) | (x), MDP_DMA_P_OUT_XY);
	mdp_writel(mdp, ld_param, MDP_MDDI_PARAM_WR_SEL);
	if (mdp->mdp_dev.color_format == MSM_MDP_OUT_IF_FMT_RGB565)
		mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB565 << 16) | MDDI_VDO_PACKET_PRIM,
			MDP_MDDI_PARAM);
	else
		mdp_writel(mdp, (MDDI_VDO_PACKET_DESC_RGB666 << 16) | MDDI_VDO_PACKET_PRIM,
			MDP_MDDI_PARAM);

	mdp_writel(mdp, 0x1, MDP_MDDI_DATA_XFR);
	mdp_writel(mdp, dma2_cfg, MDP_DMA_P_CONFIG);
	mdp_writel(mdp, 0, MDP_DMA_P_START);
#endif
}
예제 #30
0
int mdp_hw_init(struct mdp_info *mdp)
{
	int n;
	int lcdc_enabled;

	mdp_irq_mask = 0;

	mdp_writel(mdp, 0, MDP_INTR_ENABLE);

	/* debug interface write access */
	mdp_writel(mdp, 1, 0x60);
	mdp_writel(mdp, 1, MDP_EBI2_PORTMAP_MODE);

#ifndef CONFIG_MSM_MDP22
	lcdc_enabled = mdp_readl(mdp, MDP_LCDC_EN);
	/* disable lcdc */
	mdp_writel(mdp, 0, MDP_LCDC_EN);
	/* enable auto clock gating for all blocks by default */
	mdp_writel(mdp, 0xffffffff, MDP_CGC_EN);
	/* reset color/gamma correct parms */
	mdp_writel(mdp, 0, MDP_DMA_P_COLOR_CORRECT_CONFIG);
#endif

	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01f8);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01fc);
	mdp_writel(mdp, 1, 0x60);

	for (n = 0; n < ARRAY_SIZE(csc_color_lut); n++)
		mdp_writel(mdp, csc_color_lut[n].val, csc_color_lut[n].reg);

	/* clear up unused fg/main registers */
	/* comp.plane 2&3 ystride */
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0120);

	/* unpacked pattern */
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x012c);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0130);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0134);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0158);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x015c);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0160);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0170);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0174);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x017c);

	/* comp.plane 2 & 3 */
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0114);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x0118);

	/* clear unused bg registers */
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01c8);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01d0);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01dc);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0);
	mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4);

	for (n = 0; n < ARRAY_SIZE(csc_matrix_config_table); n++)
		mdp_writel(mdp, csc_matrix_config_table[n].val,
			   csc_matrix_config_table[n].reg);

	mdp_ppp_init_scale(mdp);

#ifndef CONFIG_MSM_MDP31
	mdp_writel(mdp, 0x04000400, MDP_COMMAND_CONFIG);
#endif
#ifndef CONFIG_MSM_MDP22
	if (lcdc_enabled)
		mdp_writel(mdp, 1, MDP_LCDC_EN);
#endif
	return 0;
}