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

📄 tridentfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	if (p->vdispend & 0x200) tmp |= 0x40;	if (p->vsyncstart & 0x200) tmp |= 0x80;	write3X4(CRTOverflow, tmp);	tmp = read3X4(CRTHiOrd) | 0x08;	//line compare bit 10	if (p->vtotal & 0x400) tmp |= 0x80;	if (p->vblankstart & 0x400) tmp |= 0x40;	if (p->vsyncstart & 0x400) tmp |= 0x20;	if (p->vdispend & 0x400) tmp |= 0x10;	write3X4(CRTHiOrd, tmp);	write3X4(HorizOverflow, 0);	tmp = 0x40;	if (p->vblankstart & 0x200) tmp |= 0x20;	if (p->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80;  //double scan for 200 line modes	write3X4(CRTMaxScanLine, tmp);	write3X4(CRTLineCompare,0xFF);	write3X4(CRTPRowScan,0);	write3X4(CRTModeControl,0xC3);	write3X4(LinearAddReg,0x20);	//enable linear addressing	tmp = (p->var.vmode & FB_VMODE_INTERLACED) ? 0x84:0x80;	write3X4(CRTCModuleTest,tmp);	//enable access extended memory	write3X4(GraphEngReg, 0x80);	//enable GE for text acceleration	if (p->var.accel_flags & FB_ACCELF_TEXT)		acc->init_accel(p->hres,p->bpp);	switch (p->bpp) {		case 8:tmp=0;break;		case 16:tmp=5;break;		case 24:			/* tmp=0x29;break; */			/* seems like 24bpp is same as 32bpp when using vesafb */		case 32:tmp=9;break;	}	write3X4(PixelBusReg, tmp);	write3X4(InterfaceSel, 0x5B);	//32bit internal data path	write3X4(DRAMControl, 0x30);	//both IO,linear enable	write3X4(Performance, 0xBF);	write3X4(PCIReg,0x07);		//MMIO & PCI read and write burst enable	set_vclk(p->vclk);	write3C4(0,3);	write3C4(1,1);		//set char clock 8 dots wide	write3C4(2,0x0F);	//enable 4 maps because needed in chain4 mode	write3C4(3,0);	write3C4(4,0x0E);	//memory mode enable bitmaps ??	write3CE(MiscExtFunc,(p->bpp==32)?0x1A:0x12);	//divide clock by 2 if 32bpp							//chain4 mode display and CPU path	write3CE(0x5,0x40);	//no CGA compat,allow 256 col	write3CE(0x6,0x05);	//graphics mode	write3CE(0x7,0x0F);	//planes?	writeAttr(0x10,0x41);	//graphics mode and support 256 color modes	writeAttr(0x12,0x0F);	//planes	writeAttr(0x13,0);	//horizontal pel panning	//colors	for(tmp = 0;tmp < 0x10;tmp++)		writeAttr(tmp,tmp);	readb(fb_info.io_virt + CRT + 0x0A);	//flip-flop to index	t_outb(0x20, 0x3C0);			//enable attr	switch (p->bpp) {		case 8:	tmp = 0;break;		//256 colors		case 15: tmp = 0x10;break;		case 16: tmp = 0x30;break;	//hicolor		case 24: 			//truecolor		case 32: tmp = 0xD0;break;	}	t_inb(0x3C8);	t_inb(0x3C6);	t_inb(0x3C6);	t_inb(0x3C6);	t_inb(0x3C6);	t_outb(tmp,0x3C6);	t_inb(0x3C8);	if (flatpanel)		set_number_of_lines(p->vres);	set_lwidth(p->hres*p->bpp/(4*16));	trident_pan_display(&p->var,info);	debug("exit\n");}/* Get value of one color register */static int trident_getcolreg(unsigned regno, unsigned *red,				 unsigned *green, unsigned *blue,				 unsigned *transp, struct fb_info *info){	struct tridentfb_info * i = (struct tridentfb_info *)info;	int m = i->currentmode.bpp==8?256:16;	debug("enter %d\n",regno);	if (regno >= m)		return 1;	*red = palette[regno].red;	*green = palette[regno].green;	*blue = palette[regno].blue;	*transp = palette[regno].transp;	debug("exit\n");	return 0;}/* Set one color register */static int trident_setcolreg(unsigned regno, unsigned red, unsigned green,				 unsigned blue, unsigned transp,				 struct fb_info *info){	struct tridentfb_info * i = (struct tridentfb_info *)info;	int bpp = i->currentmode.bpp;	int m = bpp==8?256:16;	debug("enter %d\n",regno);	if (regno >= m)		return 1;	palette[regno].red = red;	palette[regno].green = green;	palette[regno].blue = blue;	palette[regno].transp = transp;	if (bpp==8) {		t_outb(0xFF,0x3C6);		t_outb(regno,0x3C8);		t_outb(red>>10,0x3C9);		t_outb(green>>10,0x3C9);		t_outb(blue>>10,0x3C9);	} else	if (bpp == 16) 			/* RGB 565 */			((u16*)info->pseudo_palette)[regno] = (red & 0xF800) |			((green & 0xFC00) >> 5) | ((blue & 0xF800) >> 11);	else	if (bpp == 32)		/* ARGB 8888 */		((u32*)info->pseudo_palette)[regno] =			((transp & 0xFF00) <<16) 	|			((red & 0xFF00) << 8) 		|			((green & 0xFF00))		|			((blue & 0xFF00)>>8);	debug("exit\n");	return 0;}/* Try blanking the screen.For flat panels it does nothing */static int trident_blank(int blank_mode, struct fb_info_gen *info){	unsigned char PMCont,DPMSCont;	debug("enter\n");	if (flatpanel)		return 0;	t_outb(0x04,0x83C8); /* Read DPMS Control */	PMCont = t_inb(0x83C6) & 0xFC;	DPMSCont = read3CE(PowerStatus) & 0xFC;	switch (blank_mode)	{	case VESA_NO_BLANKING:		/* Screen: On, HSync: On, VSync: On */		PMCont |= 0x03;		DPMSCont |= 0x00;		break;	case VESA_HSYNC_SUSPEND:		/* Screen: Off, HSync: Off, VSync: On */		PMCont |= 0x02;		DPMSCont |= 0x01;		break;	case VESA_VSYNC_SUSPEND:		/* Screen: Off, HSync: On, VSync: Off */		PMCont |= 0x02;		DPMSCont |= 0x02;		break;	case VESA_POWERDOWN:		/* Screen: Off, HSync: Off, VSync: Off */		PMCont |= 0x00;		DPMSCont |= 0x03;		break;    	}	write3CE(PowerStatus,DPMSCont);	t_outb(4,0x83C8);	t_outb(PMCont,0x83C6);	debug("exit\n");	return 0;}/* Set display switch used by console */static void trident_set_disp(const void *par, struct display *disp,				 struct fb_info_gen *info){	struct tridentfb_info * i = (struct tridentfb_info *)info;	struct fb_info * ii = (struct fb_info *)info;	struct tridentfb_par * p = (struct tridentfb_par *)par;	int isaccel = p->var.accel_flags & FB_ACCELF_TEXT;	disp->screen_base = (char *)i->fbmem_virt;	debug("enter\n");#ifdef FBCON_HAS_CFB8	if (p->bpp == 8 ) {		if (isaccel)			disp->dispsw = &trident_8bpp;		else			disp->dispsw = &fbcon_cfb8;	} else#endif#ifdef FBCON_HAS_CFB16	if (p->bpp == 16) {		if (isaccel)			disp->dispsw = &trident_16bpp;		else			disp->dispsw = &fbcon_cfb16;		disp->dispsw_data =ii->pseudo_palette;	/* console palette */	} else#endif#ifdef FBCON_HAS_CFB32	if (p->bpp == 32) {		if (isaccel)			disp->dispsw = &trident_32bpp;		else			disp->dispsw = &fbcon_cfb32;		disp->dispsw_data =ii->pseudo_palette;	/* console palette */	} else#endif	disp->dispsw = &fbcon_dummy;	debug("exit\n");}static struct fbgen_hwswitch trident_hwswitch = {	NULL, /* detect not needed */	trident_encode_fix,	trident_decode_var,	trident_encode_var,	trident_get_par,	trident_set_par,	trident_getcolreg,	trident_setcolreg,	trident_pan_display,	trident_blank,	trident_set_disp};static int trident_iosize;static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_device_id * id){	int err;	unsigned char revision;	err = pci_enable_device(dev);	if (err)		return err;	chip_id = id->device;	/* If PCI id is 0x9660 then further detect chip type */		if (chip_id == TGUI9660) {		outb(RevisionID,0x3C4);		revision = inb(0x3C5);				switch (revision) {			case 0x22:			case 0x23: chip_id = CYBER9397;break;			case 0x2A: chip_id = CYBER9397DVD;break;			case 0x30:			case 0x33:			case 0x34:			case 0x35:			case 0x38:			case 0x3A:			case 0xB3: chip_id = CYBER9385;break;			case 0x40 ... 0x43: chip_id = CYBER9382;break;			case 0x4A: chip_id = CYBER9388;break;			default:break;			}	}	chip3D = is3Dchip(chip_id);	if (is_xp(chip_id)) {		acc = &accel_xp;	} else 	if (is_blade(chip_id)) {		acc = &accel_blade;	} else {		acc = &accel_image;	}	/* acceleration is on by default for 3D chips */	defaultaccel = chip3D && !noaccel;	fb_info.io = pci_resource_start(dev,1);	fb_info.fbmem = pci_resource_start(dev,0);	trident_iosize = chip3D ? 0x20000:0x10000;	if (!request_mem_region(fb_info.io, trident_iosize, "tridentfb")) {		debug("request_region failed!\n");		return -1;	}	fb_info.io_virt = (unsigned long)ioremap_nocache(fb_info.io, trident_iosize);	if (!fb_info.io_virt) {		release_region(fb_info.io, trident_iosize);		debug("ioremap failed\n");		return -1;	}	enable_mmio();	fb_info.memsize = get_memsize();	if (!request_mem_region(fb_info.fbmem, fb_info.memsize, "tridentfb")) {		debug("request_mem_region failed!\n");		return -1;	}	fb_info.fbmem_virt = (unsigned long)ioremap_nocache(fb_info.fbmem, fb_info.memsize);	if (!fb_info.fbmem_virt) {		release_mem_region(fb_info.fbmem, fb_info.memsize);		debug("ioremap failed\n");		return -1;	}	output("%s board found\n", dev->name);	debug("Trident board found : mem = %X,io = %X, mem_v = %X, io_v = %X\n",		fb_info.fbmem, fb_info.io, fb_info.fbmem_virt, fb_info.io_virt);	fb_info.gen.parsize = sizeof (struct tridentfb_par);	fb_info.gen.fbhw = &trident_hwswitch;	strcpy(fb_info.gen.info.modename, tridentfb_name);	displaytype = get_displaytype();	if(flatpanel)		fb_info.nativex = get_nativex();	fb_info.gen.info.changevar = NULL;	fb_info.gen.info.node = NODEV;	fb_info.gen.info.fbops = &tridentfb_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;	fb_info.gen.info.fontname[0] = '\0';	fb_info.gen.info.pseudo_palette = pseudo_pal;	/* This should give a reasonable default video mode */	fb_find_mode(&default_var,&fb_info.gen.info,mode,NULL,0,NULL,bpp);	if (defaultaccel && acc)		default_var.accel_flags |= FB_ACCELF_TEXT;	else		default_var.accel_flags &= ~FB_ACCELF_TEXT;	trident_decode_var(&default_var, &fb_info.currentmode, &fb_info.gen);	fbgen_get_var(&disp.var, -1, &fb_info.gen.info);	default_var.activate |= FB_ACTIVATE_NOW;	fbgen_set_disp(-1, &fb_info.gen);	if (register_framebuffer(&fb_info.gen.info) < 0) {		printk("Could not register Trident framebuffer\n");		return -EINVAL;	}	output("fb%d: %s frame buffer device %dx%d-%dbpp\n",	   GET_FB_IDX(fb_info.gen.info.node), fb_info.gen.info.modename,default_var.xres,	   default_var.yres,default_var.bits_per_pixel);	return 0;}static void __devexit trident_pci_remove(struct pci_dev * dev){	unregister_framebuffer(&fb_info.gen.info);	iounmap((void *)fb_info.io_virt);	iounmap((void *)fb_info.fbmem_virt);	release_mem_region(fb_info.fbmem, fb_info.memsize);	release_region(fb_info.io, trident_iosize);}/* List of boards that we are trying to support */static struct pci_device_id trident_devices[] __devinitdata = {	{PCI_VENDOR_ID_TRIDENT,	BLADE3D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEi7, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEi7D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEi1D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEAi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEAi1D, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEE4, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	TGUI9660, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	IMAGE975, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	IMAGE985, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBER9320, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBER9388, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBER9520, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBER9525DVD, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBER9397, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBER9397DVD, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEXPAi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEXPm8, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{PCI_VENDOR_ID_TRIDENT,	CYBERBLADEXPm16, PCI_ANY_ID,PCI_ANY_ID,0,0,0},	{0,}};		MODULE_DEVICE_TABLE(pci,trident_devices); static struct pci_driver tridentfb_pci_driver = {	name:"tridentfb",	id_table:trident_devices,	probe:trident_pci_probe,	remove:__devexit_p(trident_pci_remove),};int __init tridentfb_init(void){	output("Trident framebuffer %s initializing\n", VERSION);	return pci_module_init(&tridentfb_pci_driver);}void __exit tridentfb_exit(void){	pci_unregister_driver(&tridentfb_pci_driver);}/* * Parse user specified options (`video=trident:') * example: * 	video=trident:800x600,bpp=16,noaccel */int tridentfb_setup(char *options){	char * opt;	if (!options || !*options)		return 0;	while((opt = strsep(&options,",")) != NULL ) {		if (!*opt) continue;		if (!strncmp(opt,"noaccel",7))			noaccel = 1;		else if (!strncmp(opt,"fp",2))			displaytype = DISPLAY_FP;		else if (!strncmp(opt,"crt",3))			displaytype = DISPLAY_CRT;		else if (!strncmp(opt,"bpp=",4))			bpp = simple_strtoul(opt+4,NULL,0);		else if (!strncmp(opt,"center",6))			center = 1;		else if (!strncmp(opt,"stretch",7))			stretch = 1;		else if (!strncmp(opt,"memsize=",8))			memsize = simple_strtoul(opt+8,NULL,0);		else if (!strncmp(opt,"memdiff=",8))			memdiff = simple_strtoul(opt+8,NULL,0);		else if (!strncmp(opt,"nativex=",8))			nativex = simple_strtoul(opt+8,NULL,0);		else			mode = opt;	}	return 0;}static struct fb_ops tridentfb_ops = {	fb_get_fix:fbgen_get_fix,	fb_get_var:fbgen_get_var,	fb_set_var:fbgen_set_var,	fb_get_cmap:fbgen_get_cmap,	fb_set_cmap:fbgen_set_cmap,	fb_pan_display:fbgen_pan_display,};#ifdef MODULEmodule_init(tridentfb_init);#endifmodule_exit(tridentfb_exit);MODULE_AUTHOR("Jani Monoses <jani@iv.ro>");MODULE_DESCRIPTION("Framebuffer driver for Trident cards");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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