tridentfb.c

来自「Linux Kernel 2.6.9 for OMAP1710」· C语言 代码 · 共 1,298 行 · 第 1/3 页

C
1,298
字号
	if (vsyncstart & 0x400) tmp |= 0x20;	if (vdispend & 0x400) tmp |= 0x10;	write3X4(CRTHiOrd, tmp);	tmp = 0;	if (htotal & 0x800) tmp |= 0x800 >> 11;	if (hblankstart & 0x800) tmp |= 0x800 >> 7;	write3X4(HorizOverflow, tmp);		tmp = 0x40;	if (vblankstart & 0x200) tmp |= 0x20;//FIXME	if (info->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 = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84:0x80;	write3X4(CRTCModuleTest,tmp);	//enable access extended memory	write3X4(GraphEngReg, 0x80);	//enable GE for text acceleration//	if (info->var.accel_flags & FB_ACCELF_TEXT)//FIXME		acc->init_accel(info->var.xres,bpp);		switch (bpp) {		case 8:  tmp = 0x00; break;		case 16: tmp = 0x05; break;		case 24: tmp = 0x29; break;		case 32: tmp = 0x09; 	}	write3X4(PixelBusReg, tmp);	tmp = 0x10;	if (chipcyber)	    tmp |= 0x20;	write3X4(DRAMControl, tmp);	//both IO,linear enable	write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40);	write3X4(Performance,0x20);	write3X4(PCIReg,0x07);		//MMIO & PCI read and write burst enable	/* convert from picoseconds to MHz */	par->vclk = 1000000/info->var.pixclock;	if (bpp == 32)		par->vclk *=2;	set_vclk(par->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,(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?	if (chip_id == CYBERBLADEXPAi1) {		/* This fixes snow-effect in 32 bpp */		write3X4(CRTHSyncStart,0x84);	}	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(par->io_virt + CRT + 0x0A);	//flip-flop to index	t_outb(0x20, 0x3C0);			//enable attr	switch (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(info->var.yres);	set_lwidth(info->var.xres * bpp/(4*16));	info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;	info->fix.line_length = info->var.xres * (bpp >> 3);  	info->cmap.len = (bpp == 8) ? 256: 16;	debug("exit\n");	return 0;}/* Set one color register */static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,				 unsigned blue, unsigned transp,				 struct fb_info *info){	int bpp = info->var.bits_per_pixel;	if (regno >= info->cmap.len)		return 1;	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 tridentfb_blank(int blank_mode, struct fb_info *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;}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);	chipcyber = iscyber(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.par = &default_par;	/* setup MMIO region */	tridentfb_fix.mmio_start = pci_resource_start(dev,1);	tridentfb_fix.mmio_len = chip3D ? 0x20000:0x10000;	if (!request_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len, "tridentfb")) {		debug("request_region failed!\n");		return -1;	}	default_par.io_virt = ioremap_nocache(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);	if (!default_par.io_virt) {		release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);		debug("ioremap failed\n");		return -1;	}	enable_mmio();		/* setup framebuffer memory */	tridentfb_fix.smem_start = pci_resource_start(dev,0);	tridentfb_fix.smem_len = get_memsize();		if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) {		debug("request_mem_region failed!\n");		return -1;	}	fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start,		       			tridentfb_fix.smem_len);	if (!fb_info.screen_base) {		release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);		debug("ioremap failed\n");		return -1;	}	output("%s board found\n", pci_name(dev));#if 0		output("Trident board found : mem = %X,io = %X, mem_v = %X, io_v = %X\n",		tridentfb_fix.smem_start, tridentfb_fix.mmio_start, fb_info.screen_base, default_par.io_virt);#endif	displaytype = get_displaytype();	if(flatpanel)		nativex = get_nativex();	fb_info.fix = tridentfb_fix;	fb_info.fbops = &tridentfb_ops;	fb_info.flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;#ifdef CONFIG_FB_TRIDENT_ACCEL	fb_info.flags |= FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT;#endif	fb_info.pseudo_palette = pseudo_pal;	if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp))		return -EINVAL;	fb_alloc_cmap(&fb_info.cmap,256,0);	if (defaultaccel && acc)		default_var.accel_flags |= FB_ACCELF_TEXT;	else		default_var.accel_flags &= ~FB_ACCELF_TEXT;	default_var.activate |= FB_ACTIVATE_NOW;	fb_info.var = default_var;	if (register_framebuffer(&fb_info) < 0) {		output("Could not register Trident framebuffer\n");		return -EINVAL;	}	output("fb%d: %s frame buffer device %dx%d-%dbpp\n",	   fb_info.node, fb_info.fix.id,default_var.xres,	   default_var.yres,default_var.bits_per_pixel);	return 0;}static void __devexit trident_pci_remove(struct pci_dev * dev){	struct tridentfb_par *par = (struct tridentfb_par*)fb_info.par;	unregister_framebuffer(&fb_info);	iounmap(par->io_virt);	iounmap(fb_info.screen_base);	release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);	release_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len);}/* List of boards that we are trying to support */static struct pci_device_id trident_devices[] = {	{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 tridentfb_setup(char *options);int __init tridentfb_init(void){#ifndef MODULE	char *option = NULL;	if (fb_get_options("tridentfb", &option))		return -ENODEV;	tridentfb_setup(option);#endif	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 = {	.owner	= THIS_MODULE,	.fb_setcolreg = tridentfb_setcolreg,	.fb_pan_display = tridentfb_pan_display,	.fb_blank = tridentfb_blank,	.fb_check_var = tridentfb_check_var,	.fb_set_par = tridentfb_set_par,	.fb_fillrect = tridentfb_fillrect,	.fb_copyarea= tridentfb_copyarea,	.fb_imageblit = cfb_imageblit,	.fb_cursor = soft_cursor,};module_init(tridentfb_init);module_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 + =
减小字号Ctrl + -
显示快捷键?