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

📄 fbdev.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 4 页
字号:
	wait_for_idle(par);	return 0;}/* ------------------------------------------------------------------------- * * * initialization helper functions * * ------------------------------------------------------------------------- *//* kernel interface */static struct fb_ops riva_fb_ops = {	.owner 		= THIS_MODULE,	.fb_open	= rivafb_open,	.fb_release	= rivafb_release,	.fb_check_var 	= rivafb_check_var,	.fb_set_par 	= rivafb_set_par,	.fb_setcolreg 	= rivafb_setcolreg,	.fb_pan_display	= rivafb_pan_display,	.fb_blank 	= rivafb_blank,	.fb_fillrect 	= rivafb_fillrect,	.fb_copyarea 	= rivafb_copyarea,	.fb_imageblit 	= rivafb_imageblit,	.fb_cursor	= rivafb_cursor,		.fb_sync 	= rivafb_sync,};static int __devinit riva_set_fbinfo(struct fb_info *info){	unsigned int cmap_len;	struct riva_par *par = (struct riva_par *) info->par;	NVTRACE_ENTER();	info->flags = FBINFO_DEFAULT		    | FBINFO_HWACCEL_XPAN		    | FBINFO_HWACCEL_YPAN		    | FBINFO_HWACCEL_COPYAREA		    | FBINFO_HWACCEL_FILLRECT	            | FBINFO_HWACCEL_IMAGEBLIT;	/* Accel seems to not work properly on NV30 yet...*/	if ((par->riva.Architecture == NV_ARCH_30) || noaccel) {	    	printk(KERN_DEBUG PFX "disabling acceleration\n");  		info->flags |= FBINFO_HWACCEL_DISABLED;	}	info->var = rivafb_default_var;	info->fix.visual = (info->var.bits_per_pixel == 8) ?				FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;	info->pseudo_palette = par->pseudo_palette;	cmap_len = riva_get_cmap_len(&info->var);	fb_alloc_cmap(&info->cmap, cmap_len, 0);		info->pixmap.size = 8 * 1024;	info->pixmap.buf_align = 4;	info->pixmap.access_align = 32;	info->pixmap.flags = FB_PIXMAP_SYSTEM;	info->var.yres_virtual = -1;	NVTRACE_LEAVE();	return (rivafb_check_var(&info->var, info));}#ifdef CONFIG_PPC_OFstatic int __devinit riva_get_EDID_OF(struct fb_info *info, struct pci_dev *pd){	struct riva_par *par = (struct riva_par *) info->par;	struct device_node *dp;	unsigned char *pedid = NULL;	unsigned char *disptype = NULL;	static char *propnames[] = {		"DFP,EDID", "LCD,EDID", "EDID", "EDID1", "EDID,B", "EDID,A", NULL };	int i;	NVTRACE_ENTER();	dp = pci_device_to_OF_node(pd);	for (; dp != NULL; dp = dp->child) {		disptype = (unsigned char *)get_property(dp, "display-type", NULL);		if (disptype == NULL)			continue;		if (strncmp(disptype, "LCD", 3) != 0)			continue;		for (i = 0; propnames[i] != NULL; ++i) {			pedid = (unsigned char *)				get_property(dp, propnames[i], NULL);			if (pedid != NULL) {				par->EDID = pedid;				NVTRACE("LCD found.\n");				return 1;			}		}	}	NVTRACE_LEAVE();	return 0;}#endif /* CONFIG_PPC_OF */#if defined(CONFIG_FB_RIVA_I2C) && !defined(CONFIG_PPC_OF)static int __devinit riva_get_EDID_i2c(struct fb_info *info){	struct riva_par *par = (struct riva_par *) info->par;	struct fb_var_screeninfo var;	int i;	NVTRACE_ENTER();	riva_create_i2c_busses(par);	for (i = 0; i < par->bus; i++) {		riva_probe_i2c_connector(par, i+1, &par->EDID);		if (par->EDID && !fb_parse_edid(par->EDID, &var)) {			printk(PFX "Found EDID Block from BUS %i\n", i);			break;		}	}	NVTRACE_LEAVE();	return (par->EDID) ? 1 : 0;}#endif /* CONFIG_FB_RIVA_I2C */static void __devinit riva_update_default_var(struct fb_var_screeninfo *var,					      struct fb_info *info){	struct fb_monspecs *specs = &info->monspecs;	struct fb_videomode modedb;	NVTRACE_ENTER();	/* respect mode options */	if (mode_option) {		fb_find_mode(var, info, mode_option,			     specs->modedb, specs->modedb_len,			     NULL, 8);	} else if (specs->modedb != NULL) {		/* get preferred timing */		if (info->monspecs.misc & FB_MISC_1ST_DETAIL) {			int i;			for (i = 0; i < specs->modedb_len; i++) {				if (specs->modedb[i].flag & FB_MODE_IS_FIRST) {					modedb = specs->modedb[i];					break;				}			}		} else {			/* otherwise, get first mode in database */			modedb = specs->modedb[0];		}		var->bits_per_pixel = 8;		riva_update_var(var, &modedb);	}	NVTRACE_LEAVE();}static void __devinit riva_get_EDID(struct fb_info *info, struct pci_dev *pdev){	NVTRACE_ENTER();#ifdef CONFIG_PPC_OF	if (!riva_get_EDID_OF(info, pdev))		printk(PFX "could not retrieve EDID from OF\n");#elif defined(CONFIG_FB_RIVA_I2C)	if (!riva_get_EDID_i2c(info))		printk(PFX "could not retrieve EDID from DDC/I2C\n");#endif	NVTRACE_LEAVE();}static void __devinit riva_get_edidinfo(struct fb_info *info){	struct fb_var_screeninfo *var = &rivafb_default_var;	struct riva_par *par = (struct riva_par *) info->par;	fb_edid_to_monspecs(par->EDID, &info->monspecs);	fb_videomode_to_modelist(info->monspecs.modedb, info->monspecs.modedb_len,				 &info->modelist);	riva_update_default_var(var, info);	/* if user specified flatpanel, we respect that */	if (info->monspecs.input & FB_DISP_DDI)		par->FlatPanel = 1;}/* ------------------------------------------------------------------------- * * * PCI bus * * ------------------------------------------------------------------------- */static u32 __devinit riva_get_arch(struct pci_dev *pd){    	u32 arch = 0;	switch (pd->device & 0x0ff0) {		case 0x0100:   /* GeForce 256 */		case 0x0110:   /* GeForce2 MX */		case 0x0150:   /* GeForce2 */		case 0x0170:   /* GeForce4 MX */		case 0x0180:   /* GeForce4 MX (8x AGP) */		case 0x01A0:   /* nForce */		case 0x01F0:   /* nForce2 */		     arch =  NV_ARCH_10;		     break;		case 0x0200:   /* GeForce3 */		case 0x0250:   /* GeForce4 Ti */		case 0x0280:   /* GeForce4 Ti (8x AGP) */		     arch =  NV_ARCH_20;		     break;		case 0x0300:   /* GeForceFX 5800 */		case 0x0310:   /* GeForceFX 5600 */		case 0x0320:   /* GeForceFX 5200 */		case 0x0330:   /* GeForceFX 5900 */		case 0x0340:   /* GeForceFX 5700 */		     arch =  NV_ARCH_30;		     break;		case 0x0020:   /* TNT, TNT2 */		     arch =  NV_ARCH_04;		     break;		case 0x0010:   /* Riva128 */		     arch =  NV_ARCH_03;		     break;		default:   /* unknown architecture */		     break;	}	return arch;}static int __devinit rivafb_probe(struct pci_dev *pd,			     	const struct pci_device_id *ent){	struct riva_par *default_par;	struct fb_info *info;	int ret;	NVTRACE_ENTER();	assert(pd != NULL);	info = framebuffer_alloc(sizeof(struct riva_par), &pd->dev);	if (!info) {		printk (KERN_ERR PFX "could not allocate memory\n");		ret = -ENOMEM;		goto err_ret;	}	default_par = (struct riva_par *) info->par;	default_par->pdev = pd;	info->pixmap.addr = kmalloc(8 * 1024, GFP_KERNEL);	if (info->pixmap.addr == NULL) {	    	ret = -ENOMEM;		goto err_framebuffer_release;	}	memset(info->pixmap.addr, 0, 8 * 1024);	ret = pci_enable_device(pd);	if (ret < 0) {		printk(KERN_ERR PFX "cannot enable PCI device\n");		goto err_free_pixmap;	}	ret = pci_request_regions(pd, "rivafb");	if (ret < 0) {		printk(KERN_ERR PFX "cannot request PCI regions\n");		goto err_disable_device;	}	default_par->riva.Architecture = riva_get_arch(pd);	default_par->Chipset = (pd->vendor << 16) | pd->device;	printk(KERN_INFO PFX "nVidia device/chipset %X\n",default_par->Chipset);		if(default_par->riva.Architecture == 0) {		printk(KERN_ERR PFX "unknown NV_ARCH\n");		ret=-ENODEV;		goto err_release_region;	}	if(default_par->riva.Architecture == NV_ARCH_10 ||	   default_par->riva.Architecture == NV_ARCH_20 ||	   default_par->riva.Architecture == NV_ARCH_30) {		sprintf(rivafb_fix.id, "NV%x", (pd->device & 0x0ff0) >> 4);	} else {		sprintf(rivafb_fix.id, "NV%x", default_par->riva.Architecture);	}	default_par->FlatPanel = flatpanel;	if (flatpanel == 1)		printk(KERN_INFO PFX "flatpanel support enabled\n");	default_par->forceCRTC = forceCRTC;		rivafb_fix.mmio_len = pci_resource_len(pd, 0);	rivafb_fix.smem_len = pci_resource_len(pd, 1);	{		/* enable IO and mem if not already done */		unsigned short cmd;		pci_read_config_word(pd, PCI_COMMAND, &cmd);		cmd |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY);		pci_write_config_word(pd, PCI_COMMAND, cmd);	}		rivafb_fix.mmio_start = pci_resource_start(pd, 0);	rivafb_fix.smem_start = pci_resource_start(pd, 1);	default_par->ctrl_base = ioremap(rivafb_fix.mmio_start,					 rivafb_fix.mmio_len);	if (!default_par->ctrl_base) {		printk(KERN_ERR PFX "cannot ioremap MMIO base\n");		ret = -EIO;		goto err_release_region;	}	switch (default_par->riva.Architecture) {	case NV_ARCH_03:		/* Riva128's PRAMIN is in the "framebuffer" space		 * Since these cards were never made with more than 8 megabytes		 * we can safely allocate this separately.		 */		default_par->riva.PRAMIN = ioremap(rivafb_fix.smem_start + 0x00C00000, 0x00008000);		if (!default_par->riva.PRAMIN) {			printk(KERN_ERR PFX "cannot ioremap PRAMIN region\n");			ret = -EIO;			goto err_iounmap_ctrl_base;		}		break;	case NV_ARCH_04:	case NV_ARCH_10:	case NV_ARCH_20:	case NV_ARCH_30:		default_par->riva.PCRTC0 =			(u32 __iomem *)(default_par->ctrl_base + 0x00600000);		default_par->riva.PRAMIN =			(u32 __iomem *)(default_par->ctrl_base + 0x00710000);		break;	}	riva_common_setup(default_par);	if (default_par->riva.Architecture == NV_ARCH_03) {		default_par->riva.PCRTC = default_par->riva.PCRTC0		                        = default_par->riva.PGRAPH;	}	rivafb_fix.smem_len = riva_get_memlen(default_par) * 1024;	default_par->dclk_max = riva_get_maxdclk(default_par) * 1000;	info->screen_base = ioremap(rivafb_fix.smem_start,				    rivafb_fix.smem_len);	if (!info->screen_base) {		printk(KERN_ERR PFX "cannot ioremap FB base\n");		ret = -EIO;		goto err_iounmap_pramin;	}#ifdef CONFIG_MTRR	if (!nomtrr) {		default_par->mtrr.vram = mtrr_add(rivafb_fix.smem_start,					   	  rivafb_fix.smem_len,					    	  MTRR_TYPE_WRCOMB, 1);		if (default_par->mtrr.vram < 0) {			printk(KERN_ERR PFX "unable to setup MTRR\n");		} else {			default_par->mtrr.vram_valid = 1;			/* let there be speed */			printk(KERN_INFO PFX "RIVA MTRR set to ON\n");		}	}#endif /* CONFIG_MTRR */	info->fbops = &riva_fb_ops;	info->fix = rivafb_fix;	riva_get_EDID(info, pd);	riva_get_edidinfo(info);	ret=riva_set_fbinfo(info);	if (ret < 0) {		printk(KERN_ERR PFX "error setting initial video mode\n");		goto err_iounmap_screen_base;	}	fb_destroy_modedb(info->monspecs.modedb);	info->monspecs.modedb = NULL;	ret = register_framebuffer(info);	if (ret < 0) {		printk(KERN_ERR PFX			"error registering riva framebuffer\n");		goto err_iounmap_screen_base;	}	pci_set_drvdata(pd, info);	printk(KERN_INFO PFX		"PCI nVidia %s framebuffer ver %s (%dMB @ 0x%lX)\n",		info->fix.id,		RIVAFB_VERSION,		info->fix.smem_len / (1024 * 1024),		info->fix.smem_start);#ifdef CONFIG_PMAC_BACKLIGHT	if (default_par->FlatPanel && _machine == _MACH_Pmac)	register_backlight_controller(&riva_backlight_controller,						default_par, "mnca");#endif	NVTRACE_LEAVE();	return 0;err_iounmap_screen_base:#ifdef CONFIG_FB_RIVA_I2C	riva_delete_i2c_busses((struct riva_par *) info->par);#endif	iounmap(info->screen_base);err_iounmap_pramin:	if (default_par->riva.Architecture == NV_ARCH_03) 		iounmap(default_par->riva.PRAMIN);err_iounmap_ctrl_base:	iounmap(default_par->ctrl_base);err_release_region:	pci_release_regions(pd);err_disable_device:	pci_disable_device(pd);err_free_pixmap:	kfree(info->pixmap.addr);err_framebuffer_release:	framebuffer_release(info);err_ret:	return ret;}static void __exit rivafb_remove(struct pci_dev *pd){	struct fb_info *info = pci_get_drvdata(pd);	struct riva_par *par = (struct riva_par *) info->par;		NVTRACE_ENTER();	if (!info)		return;#ifdef CONFIG_FB_RIVA_I2C	riva_delete_i2c_busses(par);	kfree(par->EDID);#endif	unregister_framebuffer(info);#ifdef CONFIG_MTRR	if (par->mtrr.vram_valid)		mtrr_del(par->mtrr.vram, info->fix.smem_start,			 info->fix.smem_len);#endif /* CONFIG_MTRR */	iounmap(par->ctrl_base);	iounmap(info->screen_base);	if (par->riva.Architecture == NV_ARCH_03)		iounmap(par->riva.PRAMIN);	pci_release_regions(pd);	pci_disable_device(pd);	kfree(info->pixmap.addr);	framebuffer_release(info);	pci_set_drvdata(pd, NULL);	NVTRACE_LEAVE();}/* ------------------------------------------------------------------------- * * * initialization * * ------------------------------------------------------------------------- */#ifndef MODULEstatic int __init rivafb_setup(char *options){	char *this_opt;	NVTRACE_ENTER();	if (!options || !*options)		return 0;	while ((this_opt = strsep(&options, ",")) != NULL) {		if (!strncmp(this_opt, "forceCRTC", 9)) {			char *p;						p = this_opt + 9;			if (!*p || !*(++p)) continue; 			forceCRTC = *p - '0';			if (forceCRTC < 0 || forceCRTC > 1) 				forceCRTC = -1;		} else if (!strncmp(this_opt, "flatpanel", 9)) {			flatpanel = 1;#ifdef CONFIG_MTRR		} else if (!strncmp(this_opt, "nomtrr", 6)) {			nomtrr = 1;#endif		} else if (!strncmp(this_opt, "strictmode", 10)) {			strictmode = 1;		} else if (!strncmp(this_opt, "noaccel", 7)) {			noaccel = 1;		} else			mode_option = this_opt;	}	NVTRACE_LEAVE();	return 0;}#endif /* !MODULE */static struct pci_driver rivafb_driver = {	.name		= "rivafb",	.id_table	= rivafb_pci_tbl,	.probe		= rivafb_probe,	.remove		= __exit_p(rivafb_remove),};/* ------------------------------------------------------------------------- * * * modularization * * ------------------------------------------------------------------------- */static int __devinit rivafb_init(void){#ifndef MODULE	char *option = NULL;	if (fb_get_options("rivafb", &option))		return -ENODEV;	rivafb_setup(option);#endif	return pci_register_driver(&rivafb_driver);}module_init(rivafb_init);#ifdef MODULEstatic void __exit rivafb_exit(void){	pci_unregister_driver(&rivafb_driver);}module_exit(rivafb_exit);#endif /* MODULE */module_param(noaccel, bool, 0);MODULE_PARM_DESC(noaccel, "bool: disable acceleration");module_param(flatpanel, int, 0);MODULE_PARM_DESC(flatpanel, "Enables experimental flat panel support for some chipsets. (0 or 1=enabled) (default=0)");module_param(forceCRTC, int, 0);MODULE_PARM_DESC(forceCRTC, "Forces usage of a particular CRTC in case autodetection fails. (0 or 1) (default=autodetect)");#ifdef CONFIG_MTRRmodule_param(nomtrr, bool, 0);MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) (default=0)");#endifmodule_param(strictmode, bool, 0);MODULE_PARM_DESC(strictmode, "Only use video modes from EDID");MODULE_AUTHOR("Ani Joshi, maintainer");MODULE_DESCRIPTION("Framebuffer driver for nVidia Riva 128, TNT, TNT2, and the GeForce series");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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