Ejemplo n.º 1
0
static int rk30_load_screen(struct rk_lcdc_device_driver *dev_drv, bool initscreen)
{
	int ret = -EINVAL;
	struct rk30_lcdc_device *lcdc_dev = container_of(dev_drv,struct rk30_lcdc_device,driver);
	rk_screen *screen = dev_drv->cur_screen;
	u64 ft;
	int fps;
	u16 face;
	u16 mcu_total, mcu_rwstart, mcu_csstart, mcu_rwend, mcu_csend;
	u16 right_margin = screen->right_margin;
	u16 lower_margin = screen->lower_margin;
	u16 x_res = screen->x_res, y_res = screen->y_res;

	
	// set the rgb or mcu
	spin_lock(&lcdc_dev->reg_lock);
	if(likely(lcdc_dev->clk_on))
	{
		if(screen->type==SCREEN_MCU)
		{
	    		lcdc_msk_reg(lcdc_dev, MCU_CTRL, m_MCU_OUTPUT_SELECT,v_MCU_OUTPUT_SELECT(1));
			// set out format and mcu timing
	   		mcu_total  = (screen->mcu_wrperiod*150*1000)/1000000;
	    		if(mcu_total>31)    
				mcu_total = 31;
	   		if(mcu_total<3)    
				mcu_total = 3;
	    		mcu_rwstart = (mcu_total+1)/4 - 1;
	    		mcu_rwend = ((mcu_total+1)*3)/4 - 1;
	    		mcu_csstart = (mcu_rwstart>2) ? (mcu_rwstart-3) : (0);
	    		mcu_csend = (mcu_rwend>15) ? (mcu_rwend-1) : (mcu_rwend);

	    		//DBG(1,">> mcu_total=%d, mcu_rwstart=%d, mcu_csstart=%d, mcu_rwend=%d, mcu_csend=%d \n",
	        	//	mcu_total, mcu_rwstart, mcu_csstart, mcu_rwend, mcu_csend);

			// set horizontal & vertical out timing
		
		    	right_margin = x_res/6; 
			screen->pixclock = 150000000; //mcu fix to 150 MHz
			lcdc_msk_reg(lcdc_dev, MCU_CTRL,m_MCU_CS_ST | m_MCU_CS_END| m_MCU_RW_ST | m_MCU_RW_END |
	             		m_MCU_WRITE_PERIOD | m_MCU_HOLDMODE_SELECT | m_MCU_HOLDMODE_FRAME_ST,
	            		v_MCU_CS_ST(mcu_csstart) | v_MCU_CS_END(mcu_csend) | v_MCU_RW_ST(mcu_rwstart) |
	            		v_MCU_RW_END(mcu_rwend) |  v_MCU_WRITE_PERIOD(mcu_total) |
	            		v_MCU_HOLDMODE_SELECT((SCREEN_MCU==screen->type)?(1):(0)) | v_MCU_HOLDMODE_FRAME_ST(0));
	
		}

		switch (screen->face)
		{
	        	case OUT_P565:
	            		face = OUT_P565;
	            		lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0));
	            		break;
	        	case OUT_P666:
	            		face = OUT_P666;
	            		lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1));
	            		break;
	        	case OUT_D888_P565:
	            		face = OUT_P888;
	            		lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0));
	            		break;
	        	case OUT_D888_P666:
	            		face = OUT_P888;
	            		lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1));
	            		break;
	        	case OUT_P888:
	            		face = OUT_P888;
	            		lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_UP_EN, v_DITHER_UP_EN(1));
	            		lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(0) | v_DITHER_DOWN_MODE(0));
	            		break;
	        	default:
	            		lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_UP_EN, v_DITHER_UP_EN(0));
	            		lcdc_msk_reg(lcdc_dev, DSP_CTRL0, m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE, v_DITHER_DOWN_EN(0) | v_DITHER_DOWN_MODE(0));
	            		face = screen->face;
	            		break;
		}

		//use default overlay,set vsyn hsync den dclk polarity
		lcdc_msk_reg(lcdc_dev, DSP_CTRL0,m_DISPLAY_FORMAT | m_HSYNC_POLARITY | m_VSYNC_POLARITY |
	     		m_DEN_POLARITY |m_DCLK_POLARITY,v_DISPLAY_FORMAT(face) | 
	     		v_HSYNC_POLARITY(screen->pin_hsync) | v_VSYNC_POLARITY(screen->pin_vsync) |
	        	v_DEN_POLARITY(screen->pin_den) | v_DCLK_POLARITY(screen->pin_dclk));

		//set background color to black,set swap according to the screen panel,disable blank mode
		lcdc_msk_reg(lcdc_dev, DSP_CTRL1, m_BG_COLOR | m_OUTPUT_RB_SWAP | m_OUTPUT_RG_SWAP | m_DELTA_SWAP | 
		 	m_DUMMY_SWAP | m_BLANK_MODE,v_BG_COLOR(0x000000) | v_OUTPUT_RB_SWAP(screen->swap_rb) | 
		 	v_OUTPUT_RG_SWAP(screen->swap_rg) | v_DELTA_SWAP(screen->swap_delta) | v_DUMMY_SWAP(screen->swap_dumy) |
		 	v_BLACK_MODE(0));

		
		lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END,v_HSYNC(screen->hsync_len) |
	             v_HORPRD(screen->hsync_len + screen->left_margin + x_res + right_margin));
		lcdc_writel(lcdc_dev, DSP_HACT_ST_END, v_HAEP(screen->hsync_len + screen->left_margin + x_res) |
	             v_HASP(screen->hsync_len + screen->left_margin));

		lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, v_VSYNC(screen->vsync_len) |
	              v_VERPRD(screen->vsync_len + screen->upper_margin + y_res + lower_margin));
		lcdc_writel(lcdc_dev, DSP_VACT_ST_END,  v_VAEP(screen->vsync_len + screen->upper_margin+y_res)|
	              v_VASP(screen->vsync_len + screen->upper_margin));
		// let above to take effect
		lcdc_cfg_done(lcdc_dev);
	}
 	spin_unlock(&lcdc_dev->reg_lock);

	ret = clk_set_rate(lcdc_dev->dclk, screen->pixclock);
	if(ret)
	{
        	printk(KERN_ERR ">>>>>> set lcdc%d dclk failed\n",lcdc_dev->id);
	}
    	lcdc_dev->driver.pixclock = lcdc_dev->pixclock = div_u64(1000000000000llu, clk_get_rate(lcdc_dev->dclk));
	
	ft = (u64)(screen->upper_margin + screen->lower_margin + screen->y_res +screen->vsync_len)*
		(screen->left_margin + screen->right_margin + screen->x_res + screen->hsync_len)*
		(dev_drv->pixclock);       // one frame time ,(pico seconds)
	fps = div64_u64(1000000000000llu,ft);
	screen->ft = 1000/fps;
    	printk("%s: dclk:%lu>>fps:%d ",lcdc_dev->driver.name,clk_get_rate(lcdc_dev->dclk),fps);

    	if(screen->init)
    	{
    		screen->init();
    	}
	
	printk("%s for lcdc%d ok!\n",__func__,lcdc_dev->id);
	return 0;
}
Ejemplo n.º 2
0
int rk_lcdc_load_screen(vidinfo_t *vid)
{
	struct lcdc_device *lcdc_dev = &rk32_lcdc;
	struct rk_screen *screen =  lcdc_dev->screen;
	int face = 0;
	u32 msk, val;

	rk_fb_vidinfo_to_screen(vid, screen);
	if (vid->screen_type == SCREEN_MIPI ||
	    vid->screen_type == SCREEN_DUAL_MIPI) {
		rk32_mipi_enable(vid);
		if (vid->screen_type == SCREEN_MIPI) {
			msk = m_MIPI_OUT_EN | m_EDP_OUT_EN |
				m_HDMI_OUT_EN | m_RGB_OUT_EN;
			val = v_MIPI_OUT_EN(1);
		} else {
			msk = m_MIPI_OUT_EN | m_EDP_OUT_EN |
				m_HDMI_OUT_EN | m_RGB_OUT_EN |
				m_DOUB_CHANNEL_EN;
			val = v_MIPI_OUT_EN(1) | v_DOUB_CHANNEL_EN(1);
		}
	} else if (vid->screen_type == SCREEN_EDP) {
		msk = m_MIPI_OUT_EN | m_EDP_OUT_EN |
			m_HDMI_OUT_EN | m_RGB_OUT_EN;
		val = v_EDP_OUT_EN(1);
	} else if (vid->screen_type == SCREEN_HDMI) {
		msk = m_MIPI_OUT_EN | m_EDP_OUT_EN |
			m_HDMI_OUT_EN | m_RGB_OUT_EN;
		val = v_HDMI_OUT_EN(1);
	} else if (vid->screen_type == SCREEN_RGB ||
		   vid->screen_type == SCREEN_LVDS ||
		   vid->screen_type == SCREEN_DUAL_LVDS) {
		msk = m_MIPI_OUT_EN | m_EDP_OUT_EN |
			m_HDMI_OUT_EN | m_RGB_OUT_EN;
		val = v_RGB_OUT_EN(1);
	} else {
		msk = m_MIPI_OUT_EN | m_EDP_OUT_EN |
			m_HDMI_OUT_EN | m_RGB_OUT_EN;
		val = v_HDMI_OUT_EN(1);
	}
	lcdc_msk_reg(lcdc_dev, SYS_CTRL, msk, val);

	msk = m_DSP_BLACK_EN | m_DSP_BLANK_EN | m_DSP_OUT_ZERO |
		m_DSP_DCLK_POL | m_DSP_DEN_POL | m_DSP_VSYNC_POL |
		m_DSP_HSYNC_POL;
	val = v_DSP_BLACK_EN(0) | v_DSP_BLANK_EN(0) | v_DSP_OUT_ZERO(0) |
		v_DSP_DCLK_POL(vid->vl_clkp) | v_DSP_DEN_POL(vid->vl_oep) |
		v_DSP_VSYNC_POL(vid->vl_vsp) | v_DSP_HSYNC_POL(vid->vl_hsp);
	lcdc_msk_reg(lcdc_dev, DSP_CTRL0, msk, val);
	switch (vid->lcd_face) {
	case OUT_P565:
		face = OUT_P565;
		msk = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE;
		val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0);
		break;
	case OUT_P666:
		face = OUT_P666;
		msk = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
			m_DITHER_DOWN_SEL;
		val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
			v_DITHER_DOWN_SEL(1);
		break;
	case OUT_D888_P565:
		face = OUT_P888;
		msk = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE;
		val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(0);
		break;
	case OUT_D888_P666:
		face = OUT_P888;
		msk = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
			m_DITHER_DOWN_SEL;
		val = v_DITHER_DOWN_EN(1) | v_DITHER_DOWN_MODE(1) |
			v_DITHER_DOWN_SEL(1);
		break;
	case OUT_P888:
		face = OUT_P888;
		msk = m_DITHER_DOWN_EN | m_DITHER_UP_EN |
		      m_PRE_DITHER_DOWN_EN;
		val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(1) |
		      v_PRE_DITHER_DOWN_EN(1);
		break;
	case OUT_P101010:
		face = OUT_P101010;
		msk = m_DITHER_DOWN_EN | m_DITHER_UP_EN |
		      m_PRE_DITHER_DOWN_EN;
		val = v_DITHER_DOWN_EN(0) | v_DITHER_UP_EN(1) |
		    v_PRE_DITHER_DOWN_EN(0);
		break;
	default:
		face = vid->lcd_face;
		msk = m_DITHER_DOWN_EN | m_DITHER_DOWN_MODE |
			m_DITHER_UP_EN;
		val = v_DITHER_DOWN_EN(0) | v_DITHER_DOWN_MODE(0) |
			v_DITHER_UP_EN(1);
		break;
	}
	lcdc_msk_reg(lcdc_dev, DSP_CTRL1, msk, val);
	if (vid->screen_type == SCREEN_EDP || vid->screen_type == SCREEN_HDMI)
		face = OUT_P101010;
	msk = m_DSP_RG_SWAP | m_DSP_RB_SWAP | m_DSP_DELTA_SWAP |
		m_DSP_FIELD_POL | m_DSP_DUMMY_SWAP | m_DSP_BG_SWAP |
		m_DSP_OUT_MODE;
	val = v_DSP_RG_SWAP(0) | v_DSP_RB_SWAP(vid->vl_swap_rb) |
		v_DSP_DELTA_SWAP(0) | v_DSP_DUMMY_SWAP(0) |
		v_DSP_FIELD_POL(0) | v_DSP_BG_SWAP(0) |
		v_DSP_OUT_MODE(face);
	lcdc_msk_reg(lcdc_dev, DSP_CTRL0, msk, val);
	lcdc_writel(lcdc_dev, DSP_BG, 0);
	val = v_DSP_HS_PW(vid->vl_hspw) | v_DSP_HTOTAL(vid->vl_hspw +
		vid->vl_hbpd + vid->vl_col + vid->vl_hfpd);
	lcdc_writel(lcdc_dev, DSP_HTOTAL_HS_END, val);
	val = v_DSP_HACT_END(vid->vl_hspw + vid->vl_hbpd + vid->vl_col) |
		v_DSP_HACT_ST(vid->vl_hspw + vid->vl_hbpd);
	lcdc_writel(lcdc_dev, DSP_HACT_ST_END, val);
	val = v_DSP_VTOTAL(vid->vl_vspw + vid->vl_vbpd +
		vid->vl_row + vid->vl_vfpd) | v_DSP_VS_PW(vid->vl_vspw);
	lcdc_writel(lcdc_dev, DSP_VTOTAL_VS_END, val);
	val = v_DSP_VACT_END(vid->vl_vspw + vid->vl_vbpd + vid->vl_row)|
		v_DSP_VACT_ST(vid->vl_vspw + vid->vl_vbpd);
	lcdc_writel(lcdc_dev, DSP_VACT_ST_END, val);
	val = v_DSP_HACT_END_POST(vid->vl_hspw + vid->vl_hbpd + vid->vl_col) |
		v_DSP_HACT_ST_POST(vid->vl_hspw + vid->vl_hbpd);
	lcdc_writel(lcdc_dev, POST_DSP_HACT_INFO, val);
	val = v_DSP_HACT_END_POST(vid->vl_vspw + vid->vl_vbpd + vid->vl_row)|
	      v_DSP_HACT_ST_POST(vid->vl_vspw + vid->vl_vbpd);
	lcdc_writel(lcdc_dev, POST_DSP_VACT_INFO, val);
	lcdc_writel(lcdc_dev, POST_DSP_VACT_INFO_F1, 0);
	lcdc_writel(lcdc_dev, POST_RESERVED, 0x10001000);
	lcdc_writel(lcdc_dev, MCU_CTRL, 0);

	msk = m_DSP_LINE_FLAG_NUM | m_LINE_FLAG_INTR_EN;
	val = v_DSP_LINE_FLAG_NUM(vid->vl_vspw + vid->vl_vbpd + vid->vl_row) |
	      v_LINE_FLAG_INTR_EN(0);
	lcdc_msk_reg(lcdc_dev, INTR_CTRL0, msk, val);
	lcdc_cfg_done(lcdc_dev);
	if ((vid->screen_type == SCREEN_LVDS) ||
	    (vid->screen_type == SCREEN_DUAL_LVDS) ||
	    (vid->screen_type == SCREEN_RGB)) {
		rk32_lvds_en(vid);
	} else if (vid->screen_type == SCREEN_EDP) {
		rk32_edp_enable(vid);
	} else if ((vid->screen_type == SCREEN_MIPI) ||
		   (vid->screen_type == SCREEN_DUAL_MIPI)) {
		rk32_dsi_sync();
	}

	return 0;
}