⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 jzlcd.c

📁 jzlcd linux参考代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	lcd_palette_desc->databuf = (int)virt_to_phys((void *)lcd_palette);	lcd_palette_desc->frame_id = (unsigned int)0xdeadbeaf;	lcd_palette_desc->cmd = pal_size|LCD_CMD_PAL; /* Palette Descriptor */	/* Frame Descriptor 0 */	if (jzfb.bpp <= 8)		lcd_frame_desc0->next_desc = (int)virt_to_phys(lcd_palette_desc);	else		lcd_frame_desc0->next_desc = (int)virt_to_phys(lcd_frame_desc0);	lcd_frame_desc0->databuf = virt_to_phys((void *)lcd_frame[0]);	lcd_frame_desc0->frame_id = (unsigned int)0xbeafbeaf;	lcd_frame_desc0->cmd = LCD_CMD_SOFINT | LCD_CMD_EOFINT | frm_size;	dma_cache_wback_inv((unsigned int)(lcd_palette_desc),0x10);	dma_cache_wback_inv((unsigned int)(lcd_frame_desc0),0x10);	if (!(dual_panel))		return;	/* Frame Descriptor 1 */	lcd_frame_desc1->next_desc = (int)virt_to_phys(lcd_frame_desc1);	lcd_frame_desc1->databuf = virt_to_phys((void *)(lcd_frame[0] + frm_size * 4));	lcd_frame_desc1->frame_id = (unsigned int)0xdeaddead;	lcd_frame_desc1->cmd = LCD_CMD_SOFINT | LCD_CMD_EOFINT | frm_size;	dma_cache_wback_inv((unsigned int)(lcd_frame_desc1),0x10);}static int lcd_hw_init(void){	unsigned int val = 0;	unsigned int pclk;	unsigned int stnH;	int ret = 0;	/* Setting Control register */	switch (jzfb.bpp) {	case 1:		val |= LCD_CTRL_BPP_1;		break;	case 2:		val |= LCD_CTRL_BPP_2;		break;	case 4:		val |= LCD_CTRL_BPP_4;		break;	case 8:		val |= LCD_CTRL_BPP_8;		break;	case 15:		val |= LCD_CTRL_RGB555;	case 16:		val |= LCD_CTRL_BPP_16;		break;#if defined(CONFIG_SOC_JZ4740)	case 17 ... 32:		val |= LCD_CTRL_BPP_18_24;	/* target is 4bytes/pixel */		break;#endif	default:		printk("The BPP %d is not supported\n", jzfb.bpp);		val |= LCD_CTRL_BPP_16;		break;	}	switch (jzfb.cfg & MODE_MASK) {	case MODE_STN_MONO_DUAL:	case MODE_STN_COLOR_DUAL:	case MODE_STN_MONO_SINGLE:	case MODE_STN_COLOR_SINGLE:		switch (jzfb.bpp) {		case 1:		case 2:			val |= LCD_CTRL_FRC_2;			break;		case 4:			val |= LCD_CTRL_FRC_4;			break;		case 8:		default:			val |= LCD_CTRL_FRC_16;			break;		}		break;	}	val |= LCD_CTRL_BST_16;		/* Burst Length is 16WORD=64Byte */	switch (jzfb.cfg & MODE_MASK) {	case MODE_STN_MONO_DUAL:	case MODE_STN_COLOR_DUAL:	case MODE_STN_MONO_SINGLE:	case MODE_STN_COLOR_SINGLE:		switch (jzfb.cfg & STN_DAT_PINMASK) {#define align2(n) (n)=((((n)+1)>>1)<<1)#define align4(n) (n)=((((n)+3)>>2)<<2)#define align8(n) (n)=((((n)+7)>>3)<<3)		case STN_DAT_PIN1:			/* Do not adjust the hori-param value. */			break;		case STN_DAT_PIN2:			align2(jzfb.hsw);			align2(jzfb.elw);			align2(jzfb.blw);			break;		case STN_DAT_PIN4:			align4(jzfb.hsw);			align4(jzfb.elw);			align4(jzfb.blw);			break;		case STN_DAT_PIN8:			align8(jzfb.hsw);			align8(jzfb.elw);			align8(jzfb.blw);			break;		}		break;	}	val |=  1 << 26;               /* Output FIFO underrun protection */	REG_LCD_CTRL = val;	switch (jzfb.cfg & MODE_MASK) {	case MODE_STN_MONO_DUAL:	case MODE_STN_COLOR_DUAL:	case MODE_STN_MONO_SINGLE:	case MODE_STN_COLOR_SINGLE:		if (((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL) ||		    ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))			stnH = jzfb.h >> 1;		else			stnH = jzfb.h;		REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;		REG_LCD_HSYNC = ((jzfb.blw+jzfb.w) << 16) | (jzfb.blw+jzfb.w+jzfb.hsw);		/* Screen setting */		REG_LCD_VAT = ((jzfb.blw + jzfb.w + jzfb.hsw + jzfb.elw) << 16) | (stnH + jzfb.vsw + jzfb.bfw + jzfb.efw);		REG_LCD_DAH = (jzfb.blw << 16) | (jzfb.blw + jzfb.w);		REG_LCD_DAV = (0 << 16) | (stnH);		/* AC BIAs signal */		REG_LCD_PS = (0 << 16) | (stnH+jzfb.vsw+jzfb.efw+jzfb.bfw);		break;	case MODE_TFT_GEN:	case MODE_TFT_SHARP:	case MODE_TFT_CASIO:	case MODE_TFT_SAMSUNG:	case MODE_8BIT_SERIAL_TFT:	case MODE_TFT_18BIT:		REG_LCD_VSYNC = (0 << 16) | jzfb.vsw;#if defined(CONFIG_JZLCD_INNOLUX_AT080TN42)		REG_LCD_DAV = (0 << 16) | ( jzfb.h );#else		REG_LCD_DAV = ((jzfb.vsw + jzfb.bfw) << 16) | (jzfb.vsw + jzfb.bfw + jzfb.h);#endif /*#if defined(CONFIG_JZLCD_INNOLUX_AT080TN42)*/		REG_LCD_VAT = (((jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw)) << 16) | (jzfb.vsw + jzfb.bfw + jzfb.h + jzfb.efw);		REG_LCD_HSYNC = (0 << 16) | jzfb.hsw;		REG_LCD_DAH = ((jzfb.hsw + jzfb.blw) << 16) | (jzfb.hsw + jzfb.blw + jzfb.w);		break;	}	switch (jzfb.cfg & MODE_MASK) {	case MODE_TFT_SAMSUNG:	{		unsigned int total, tp_s, tp_e, ckv_s, ckv_e;		unsigned int rev_s, rev_e, inv_s, inv_e;		total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;		tp_s = jzfb.blw + jzfb.w + 1;		tp_e = tp_s + 1;		ckv_s = tp_s - jz_clocks.pixclk/(1000000000/4100);		ckv_e = tp_s + total;		rev_s = tp_s - 11;	/* -11.5 clk */		rev_e = rev_s + total;		inv_s = tp_s;		inv_e = inv_s + total;		REG_LCD_CLS = (tp_s << 16) | tp_e;		REG_LCD_PS = (ckv_s << 16) | ckv_e;		REG_LCD_SPL = (rev_s << 16) | rev_e;		REG_LCD_REV = (inv_s << 16) | inv_e;		jzfb.cfg |= STFT_REVHI | STFT_SPLHI;		break;	}	case MODE_TFT_SHARP:	{		unsigned int total, cls_s, cls_e, ps_s, ps_e;		unsigned int spl_s, spl_e, rev_s, rev_e;		total = jzfb.blw + jzfb.w + jzfb.elw + jzfb.hsw;#if !defined(CONFIG_JZLCD_INNOLUX_AT080TN42)		spl_s = 1;		spl_e = spl_s + 1;		cls_s = 0;		cls_e = total - 60;	/* > 4us (pclk = 80ns) */		ps_s = cls_s;		ps_e = cls_e;		rev_s = total - 40;	/* > 3us (pclk = 80ns) */		rev_e = rev_s + total;		jzfb.cfg |= STFT_PSHI;#else           /*#if defined(CONFIG_JZLCD_INNOLUX_AT080TN42)*/		spl_s = total - 5; /* LD */		spl_e = total - 3;		cls_s = 32;	/* CKV */		cls_e = 145;		ps_s  = 0;      /* OEV */		ps_e  = 45;		rev_s = 0;	/* POL */		rev_e = 0;#endif          /*#if defined(CONFIG_JZLCD_INNOLUX_AT080TN42)*/		REG_LCD_SPL = (spl_s << 16) | spl_e;		REG_LCD_CLS = (cls_s << 16) | cls_e;		REG_LCD_PS = (ps_s << 16) | ps_e;		REG_LCD_REV = (rev_s << 16) | rev_e;		break;	}	case MODE_TFT_CASIO:		break;	}	/* Configure the LCD panel */	REG_LCD_CFG = jzfb.cfg;	/* Timing setting */	__cpm_stop_lcd();	val = jzfb.fclk; /* frame clk */	if ( (jzfb.cfg & MODE_MASK) != MODE_8BIT_SERIAL_TFT) {		pclk = val * (jzfb.w + jzfb.hsw + jzfb.elw + jzfb.blw) *			(jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */	}	else {		/* serial mode: Hsync period = 3*Width_Pixel */		pclk = val * (jzfb.w*3 + jzfb.hsw + jzfb.elw + jzfb.blw) *			(jzfb.h + jzfb.vsw + jzfb.efw + jzfb.bfw); /* Pixclk */	}	if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||	    ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL))		pclk = (pclk * 3);	if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_SINGLE) ||	    ((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||	    ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_SINGLE) ||	    ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))		pclk = pclk >> ((jzfb.cfg & STN_DAT_PINMASK) >> 4);	if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||	    ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))		pclk >>= 1;#if defined(CONFIG_SOC_JZ4730)	val = __cpm_get_pllout() / pclk;	REG_CPM_CFCR2 = val - 1;	val = __cpm_get_pllout() / (pclk * 4);	val = __cpm_divisor_encode(val);	__cpm_set_lcdclk_div(val);	REG_CPM_CFCR |= CPM_CFCR_UPE;#elif defined(CONFIG_SOC_JZ4740)	val = ( __cpm_get_pllout2()) / pclk;	val--;	if ( val > 0x3ff ) {		printk("pixel clock divid is too large, set it to 0x3ff\n");		val = 0x3ff;	}	__cpm_set_pixdiv(val);	val = pclk * 3 ;	/* LCDClock > 2.5*Pixclock */	val =__cpm_get_pllout() / val;	if ( val > 0x1f ) {		printk("lcd clock divide is too large, set it to 0x1f\n");		val = 0x1f;	}	__cpm_set_ldiv( val );	REG_CPM_CPCCR |= CPM_CPCCR_CE ; /* update divide */#else	printk("drivers/video/Jzlcd.c, CONFIG_MIPS, please set chip type.\n");#endif /*#ifdef CONFIG_MIPS_JZ4730 */	jz_clocks.pixclk = __cpm_get_pixclk();	jz_clocks.lcdclk = __cpm_get_lcdclk();	printk("LCDC: PixClock:%d LcdClock:%d\n",	       jz_clocks.pixclk, jz_clocks.lcdclk);	__cpm_start_lcd();	udelay(1000);	return ret;}static irqreturn_t lcd_interrupt_handler(int irq, void *dev_id){	unsigned int state;	state = REG_LCD_STATE;	if (state & LCD_STATE_EOF) /* End of frame */		REG_LCD_STATE = state & ~LCD_STATE_EOF;	if (state & LCD_STATE_IFU0) {		dprintk("InFiFo0 underrun\n");		REG_LCD_STATE = state & ~LCD_STATE_IFU0;	}	if (state & LCD_STATE_OFU) { /* Out fifo underrun */		REG_LCD_STATE = state & ~LCD_STATE_OFU;		dprintk("Out FiFo underrun.\n");	}	return IRQ_HANDLED;}#ifdef CONFIG_PM/* * Suspend the LCDC. */static int jzfb_suspend(void){	__lcd_clr_ena(); /* Quick Disable */	__lcd_display_off();	__cpm_stop_lcd();	return 0;}/* * Resume the LCDC. */#ifdef CONFIG_SOC_JZ4730static int jzfb_resume(void){	__cpm_start_lcd();	__lcd_display_pin_init();	__lcd_display_on();	lcd_hw_init();	if (jzfb.bpp <= 8)		REG_LCD_DA0 = virt_to_phys(lcd_palette_desc);	else		REG_LCD_DA0 = virt_to_phys(lcd_frame_desc0);	if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||	    ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))		REG_LCD_DA1 = virt_to_phys(lcd_frame_desc1);	__lcd_set_ena();	return 0;}#else/* * Resume the LCDC. */static int jzfb_resume(void){	__cpm_start_lcd();	__gpio_set_pin(GPIO_DISP_OFF_N); 	__lcd_special_on();	__lcd_set_ena();	mdelay(200);	__lcd_set_backlight_level(80); 	return 0;}#endif  /* CONFIG_MIPS_JZ4730 *//* * Power management hook.  Note that we won't be called from IRQ context, * unlike the blank functions above, so we may sleep. */static int jzlcd_pm_callback(struct pm_dev *pm_dev, pm_request_t req, void *data){	int ret;	struct lcd_cfb_info *cfb = pm_dev->data;	if (!cfb) return -EINVAL;	switch (req) {	case PM_SUSPEND:		ret = jzfb_suspend();		break;	case PM_RESUME:		ret = jzfb_resume();		break;	default:		ret = -EINVAL;		break;	}	return ret;}#else#define jzfb_suspend      NULL#define jzfb_resume       NULL#endif /* CONFIG_PM */static int __init jzfb_init(void){	struct lcd_cfb_info *cfb;	int err = 0;	/* In special mode, we only need init special pin, 	 * as general lcd pin has init in uboot */#if defined(CONFIG_SOC_JZ4740) || defined(CONFIG_SOC_JZ4750)	switch (jzfb.cfg & MODE_MASK) {	case LCD_CFG_MODE_SPECIAL_TFT_1:	case LCD_CFG_MODE_SPECIAL_TFT_2:	case LCD_CFG_MODE_SPECIAL_TFT_3:		__gpio_as_lcd_special();		break;	default:		;	}#endif	__lcd_display_pin_init();	cfb = jzfb_alloc_fb_info();	if (!cfb)		goto failed;	err = jzfb_map_smem(cfb);	if (err)		goto failed;	jzfb_set_var(&cfb->fb.var, -1, &cfb->fb);	lcd_descriptor_init();	err = lcd_hw_init();	if (err)		goto failed;	if (jzfb.bpp <= 8)		REG_LCD_DA0 = virt_to_phys(lcd_palette_desc);	else		REG_LCD_DA0 = virt_to_phys(lcd_frame_desc0);	if (((jzfb.cfg & MODE_MASK) == MODE_STN_COLOR_DUAL) ||	    ((jzfb.cfg & MODE_MASK) == MODE_STN_MONO_DUAL))		REG_LCD_DA1 = virt_to_phys(lcd_frame_desc1);	__lcd_set_ena();	if (request_irq(IRQ_LCD, lcd_interrupt_handler, IRQF_DISABLED,			"lcd", 0)) {		err = -EBUSY;		goto failed;	}	__lcd_enable_ofu_intr(); /* enable OutFifo underrun *///	__lcd_enable_ifu0_intr(); /* needn't enable InFifo underrun */#if defined(CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT)	jzfb_rotate_change(rotate_angle);	/* sleep n??? */#endif	err = register_framebuffer(&cfb->fb);	if (err < 0) {		dprintk("jzfb_init(): register framebuffer err.\n");		goto failed;	}	printk("fb%d: %s frame buffer device, using %dK of video memory\n",	       cfb->fb.node, cfb->fb.fix.id, cfb->fb.fix.smem_len>>10);#ifdef CONFIG_PM	/*	 * Note that the console registers this as well, but we want to	 * power down the display prior to sleeping.	 */	cfb->pm = pm_register(PM_SYS_DEV, PM_SYS_VGA, jzlcd_pm_callback);	if (cfb->pm)		cfb->pm->data = cfb;#endif	__lcd_display_on();	return 0;failed:	jzfb_unmap_smem(cfb);	jzfb_free_fb_info(cfb);	return err;}#if 0static int jzfb_remove(struct device *dev){	struct lcd_cfb_info *cfb = dev_get_drvdata(dev);	jzfb_unmap_smem(cfb);	jzfb_free_fb_info(cfb);	return 0;}#endif#if 0static struct device_driver jzfb_driver = {	.name		= "jz-lcd",	.bus 		= &platform_bus_type,	.probe		= jzfb_probe,        .remove		= jzfb_remove,	.suspend	= jzfb_suspend,        .resume		= jzfb_resume,};#endifstatic void __exit jzfb_cleanup(void){#if defined(CONFIG_JZLCD_FRAMEBUFFER_ROTATE_SUPPORT)	kthread_stop(jzlcd_info->rotate_daemon_thread);#endif//	driver_unregister(&jzfb_driver);//	jzfb_remove();}module_init(jzfb_init);module_exit(jzfb_cleanup);MODULE_DESCRIPTION("JzSOC LCD Controller driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -