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

📄 au1100fb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 2 页
字号:
		p_lcd_reg->lcd_control &= ~LCD_CONTROL_GO;#endif		au_sync();		break;	default: 		break;	}	return 0;}static void au1100_set_disp(const void *unused, struct display *disp,			 struct fb_info_gen *info){	disp->screen_base = (char *)fb_info.fb_virt_start;	switch (disp->var.bits_per_pixel) {#ifdef FBCON_HAS_CFB8	case 8:		disp->dispsw = &fbcon_cfb8;		if (fb_info.nohwcursor)			fbcon_cfb8.cursor = au1100_nocursor;		break;#endif#ifdef FBCON_HAS_CFB16	case 16:		disp->dispsw = &fbcon_cfb16;		disp->dispsw_data = fb_info.fbcon_cmap16;		if (fb_info.nohwcursor)			fbcon_cfb16.cursor = au1100_nocursor;		break;#endif	default:		disp->dispsw = &fbcon_dummy;		disp->dispsw_data = NULL;		break;	}}static intau1100fb_mmap(struct fb_info *_fb,	     struct file *file,	     struct vm_area_struct *vma){	unsigned int len;	unsigned long start=0, off;	struct au1100fb_info *fb = (struct au1100fb_info *)_fb;	if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT)) {		return -EINVAL;	}    	start = fb_info.fb_phys & PAGE_MASK;	len = PAGE_ALIGN((start & ~PAGE_MASK) + fb_info.fb_size);	off = vma->vm_pgoff << PAGE_SHIFT;	if ((vma->vm_end - vma->vm_start + off) > len) {		return -EINVAL;	}	off += start;	vma->vm_pgoff = off >> PAGE_SHIFT;	pgprot_val(vma->vm_page_prot) &= ~_CACHE_MASK;	//pgprot_val(vma->vm_page_prot) |= _CACHE_CACHABLE_NONCOHERENT;	pgprot_val(vma->vm_page_prot) |= (6 << 9); //CCA=6	/* This is an IO map - tell maydump to skip this VMA */	vma->vm_flags |= VM_IO;    	if (io_remap_page_range(vma->vm_start, off,				vma->vm_end - vma->vm_start,				vma->vm_page_prot)) {		return -EAGAIN;	}	fb->mmaped = 1;	return 0;}int au1100_pan_display(const struct fb_var_screeninfo *var,		       struct fb_info_gen *info){	return 0;}static int au1100fb_ioctl(struct inode *inode, struct file *file, u_int cmd,			  u_long arg, int con, struct fb_info *info){	/* nothing to do yet */	return -EINVAL;}static struct fbgen_hwswitch au1100_switch = {	au1100_detect, 	au1100_encode_fix, 	au1100_decode_var, 	au1100_encode_var, 	au1100_get_par, 	au1100_set_par, 	au1100_getcolreg, 	au1100_setcolreg, 	au1100_pan_display, 	au1100_blank, 	au1100_set_disp};int au1100_setmode(void) {	int words;	/* FIXME Need to accomodate for swivel mode and 12bpp, <8bpp*/	switch (p_lcd->mode_control & LCD_CONTROL_SM)	{		case LCD_CONTROL_SM_0:		case LCD_CONTROL_SM_180:		words = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 32;			break;		case LCD_CONTROL_SM_90:		case LCD_CONTROL_SM_270:			/* is this correct? */		words = (p_lcd->xres * p_lcd->bpp) / 8;			break;		default:			printk("mode_control reg not initialized\n");			return -EINVAL;	}	/*	 * Setup LCD controller	 */	p_lcd_reg->lcd_control = p_lcd->mode_control;	p_lcd_reg->lcd_intstatus = 0;	p_lcd_reg->lcd_intenable = 0;	p_lcd_reg->lcd_horztiming = p_lcd->mode_horztiming;	p_lcd_reg->lcd_verttiming = p_lcd->mode_verttiming;	p_lcd_reg->lcd_clkcontrol = p_lcd->mode_clkcontrol;	p_lcd_reg->lcd_words = words - 1;	p_lcd_reg->lcd_dmaaddr0 = fb_info.fb_phys;	/* turn on panel */#ifdef CONFIG_MIPS_PB1100	au_writew(au_readw(PB1100_G_CONTROL) | p_lcd->mode_backlight, 			PB1100_G_CONTROL);#endif	p_lcd_reg->lcd_control |= LCD_CONTROL_GO;	return 0;}int __init au1100fb_init(void){	uint32 sys_clksrc;	unsigned long page;	/*	* Get the panel information/display mode and update the registry	*/	p_lcd = &panels[my_lcd_index];	switch (p_lcd->mode_control & LCD_CONTROL_SM)	{		case LCD_CONTROL_SM_0:		case LCD_CONTROL_SM_180:		p_lcd->xres = 			(p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;		p_lcd->yres = 			(p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;			break;		case LCD_CONTROL_SM_90:		case LCD_CONTROL_SM_270:		p_lcd->yres = 			(p_lcd->mode_horztiming & LCD_HORZTIMING_PPL) + 1;		p_lcd->xres = 			(p_lcd->mode_verttiming & LCD_VERTTIMING_LPP) + 1;			break;	}	/*	 * Panel dimensions x bpp must be divisible by 32	 */	if (((p_lcd->yres * p_lcd->bpp) % 32) != 0) 		printk("VERT %% 32\n");	if (((p_lcd->xres * p_lcd->bpp) % 32) != 0) 		printk("HORZ %% 32\n");	/*	 * Allocate LCD framebuffer from system memory	 */	fb_info.fb_size = (p_lcd->xres * p_lcd->yres * p_lcd->bpp) / 8;		current_par.var.xres = p_lcd->xres;	current_par.var.xres_virtual = p_lcd->xres;	current_par.var.yres = p_lcd->yres;	current_par.var.yres_virtual = p_lcd->yres;	current_par.var.bits_per_pixel = p_lcd->bpp;	/* FIX!!! only works for 8/16 bpp */	current_par.line_length = p_lcd->xres * p_lcd->bpp / 8; /* in bytes */	fb_info.fb_virt_start = (unsigned long )		__get_free_pages(GFP_ATOMIC | GFP_DMA, 				get_order(fb_info.fb_size + 0x1000));	if (!fb_info.fb_virt_start) {		printk("Unable to allocate fb memory\n");		return -ENOMEM;	}	fb_info.fb_phys = virt_to_bus((void *)fb_info.fb_virt_start);	/*	 * Set page reserved so that mmap will work. This is necessary	 * since we'll be remapping normal memory.	 */	for (page = fb_info.fb_virt_start;	     page < PAGE_ALIGN(fb_info.fb_virt_start + fb_info.fb_size); 	     page += PAGE_SIZE) {		SetPageReserved(virt_to_page(page));	}	memset((void *)fb_info.fb_virt_start, 0, fb_info.fb_size);	/* set freqctrl now to allow more time to stabilize */	/* zero-out out LCD bits */	sys_clksrc = au_readl(SYS_CLKSRC) & ~0x000003e0; 	sys_clksrc |= p_lcd->mode_toyclksrc;	au_writel(sys_clksrc, SYS_CLKSRC);	/* FIXME add check to make sure auxpll is what is expected! */	au1100_setmode();	fb_info.gen.parsize = sizeof(struct au1100fb_par);	fb_info.gen.fbhw = &au1100_switch;	strcpy(fb_info.gen.info.modename, "Au1100 LCD");	fb_info.gen.info.changevar = NULL;	fb_info.gen.info.node = -1;	fb_info.gen.info.fbops = &au1100fb_ops;	fb_info.gen.info.disp = &disp;	fb_info.gen.info.switch_con = &fbgen_switch;	fb_info.gen.info.updatevar = &fbgen_update_var;	fb_info.gen.info.blank = &fbgen_blank;	fb_info.gen.info.flags = FBINFO_FLAG_DEFAULT;	/* This should give a reasonable default video mode */	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);	fbgen_do_set_var(&disp.var, 1, &fb_info.gen);	fbgen_set_disp(-1, &fb_info.gen);	fbgen_install_cmap(0, &fb_info.gen);	if (register_framebuffer(&fb_info.gen.info) < 0)		return -EINVAL;	printk(KERN_INFO "fb%d: %s frame buffer device\n", 			GET_FB_IDX(fb_info.gen.info.node), 			fb_info.gen.info.modename);	/* uncomment this if your driver cannot be unloaded */	/* MOD_INC_USE_COUNT; */	return 0;}void au1100fb_cleanup(struct fb_info *info){	unregister_framebuffer(info);}void au1100fb_setup(char *options, int *ints){	char* this_opt;	int i;	int num_panels = sizeof(panels)/sizeof(struct known_lcd_panels);    	if (!options || !*options)		return;	for(this_opt=strtok(options, ","); this_opt;	    this_opt=strtok(NULL, ",")) {		if (!strncmp(this_opt, "panel:", 6)) {#if defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100)			/* Read Pb1100 Switch S10 ? */			if (!strncmp(this_opt+6, "s10", 3))			{				int panel;				panel = *(volatile int *)0xAE000008; /* BCSR SWITCHES */				panel >>= 8;				panel &= 0x0F;				if (panel >= num_panels) panel = 0;				my_lcd_index = panel;			}			else#endif			/* Get the panel name, everything else if fixed */			for (i=0; i<num_panels; i++) {				if (!strncmp(this_opt+6, panels[i].panel_name, 							strlen(this_opt))) {					my_lcd_index = i;					break;				}			}		}		else if (!strncmp(this_opt, "nohwcursor", 10)) {			printk("nohwcursor\n");			fb_info.nohwcursor = 1;		}	} 	printk("au1100fb: Panel %d %s\n", my_lcd_index,		panels[my_lcd_index].panel_name);}#ifdef MODULEMODULE_LICENSE("GPL");int init_module(void){	return au1100fb_init();}void cleanup_module(void){	au1100fb_cleanup(void);}MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>");MODULE_DESCRIPTION("Au1100 LCD framebuffer device driver");#endif /* MODULE */

⌨️ 快捷键说明

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