i810_main.c

来自「优龙2410linux2.6.8内核源代码」· C语言 代码 · 共 2,063 行 · 第 1/4 页

C
2,063
字号
	par->cursor_heap.virtual = par->aperture.virtual+		(par->cursor_heap.offset << 12);}static void __devinit i810_fix_offsets(struct i810fb_par *par){	if (vram + 1 > par->aperture.size >> 20)		vram = (par->aperture.size >> 20) - 1;	if (v_offset_default > (par->aperture.size >> 20))		v_offset_default = (par->aperture.size >> 20);	if (vram + v_offset_default + 1 > par->aperture.size >> 20)		v_offset_default = (par->aperture.size >> 20) - (vram + 1);	par->fb.size = vram << 20;	par->fb.offset = v_offset_default << 20;	par->fb.offset >>= 12;	par->iring.offset = par->fb.offset + (par->fb.size >> 12);	par->iring.size = RINGBUFFER_SIZE;	par->cursor_heap.offset = par->iring.offset + (RINGBUFFER_SIZE >> 12);	par->cursor_heap.size = 4096;}static int __devinit i810_alloc_agp_mem(struct fb_info *info){	struct i810fb_par *par = (struct i810fb_par *) info->par;	int size;		i810_fix_offsets(par);	size = par->fb.size + par->iring.size;	par->drm_agp = (drm_agp_t *) inter_module_get("drm_agp");	if (!par->drm_agp) {		printk("i810fb: cannot acquire agp\n");		return -ENODEV;	}	par->drm_agp->acquire(); 	if (!(par->i810_gtt.i810_fb_memory = 	      par->drm_agp->allocate_memory(size >> 12, AGP_NORMAL_MEMORY))) {		printk("i810fb_alloc_fbmem: can't allocate framebuffer "		       "memory\n");		par->drm_agp->release();		return -ENOMEM;	}	if (par->drm_agp->bind_memory(par->i810_gtt.i810_fb_memory, 				      par->fb.offset)) {		printk("i810fb_alloc_fbmem: can't bind framebuffer memory\n");		par->drm_agp->release();		return -EBUSY;	}			if (!(par->i810_gtt.i810_cursor_memory = 	      par->drm_agp->allocate_memory(par->cursor_heap.size >> 12, 					    AGP_PHYSICAL_MEMORY))) {		printk("i810fb_alloc_cursormem:  can't allocate" 		       "cursor memory\n");		par->drm_agp->release();		return -ENOMEM;	}	if (par->drm_agp->bind_memory(par->i810_gtt.i810_cursor_memory, 			    par->cursor_heap.offset)) {		printk("i810fb_alloc_cursormem: cannot bind cursor memory\n");		par->drm_agp->release();		return -EBUSY;	}		par->cursor_heap.physical = par->i810_gtt.i810_cursor_memory->physical;	i810_fix_pointers(par);	par->drm_agp->release();	return 0;}/***************************************************************  *                    Initialization                           *  ***************************************************************//** * i810_init_monspecs * @info: pointer to device specific info structure * * DESCRIPTION: * Sets the the user monitor's horizontal and vertical * frequency limits */static void __devinit i810_init_monspecs(struct fb_info *info){	if (!hsync1)		hsync1 = HFMIN;	if (!hsync2) 		hsync2 = HFMAX;	info->monspecs.hfmax = hsync2;	info->monspecs.hfmin = hsync1;	if (hsync2 < hsync1) 		info->monspecs.hfmin = hsync2;	if (!vsync1)		vsync1 = VFMIN;	if (!vsync2) 		vsync2 = VFMAX;	if (IS_DVT && vsync1 < 60)		vsync1 = 60;	info->monspecs.vfmax = vsync2;	info->monspecs.vfmin = vsync1;			if (vsync2 < vsync1) 		info->monspecs.vfmin = vsync2;}/** * i810_init_defaults - initializes default values to use * @par: pointer to i810fb_par structure * @info: pointer to current fb_info structure */static void __devinit i810_init_defaults(struct i810fb_par *par, 				      struct fb_info *info){	if (voffset) 		v_offset_default = voffset;	else if (par->aperture.size > 32 * 1024 * 1024)		v_offset_default = 16;	else		v_offset_default = 8;	if (!vram) 		vram = 1;	if (accel) 		par->dev_flags |= HAS_ACCELERATION;	if (sync) 		par->dev_flags |= ALWAYS_SYNC;	if (bpp < 8)		bpp = 8;		if (!vyres) 		vyres = (vram << 20)/(xres*bpp >> 3);	par->i810fb_ops = i810fb_ops;	info->var.xres = xres;	info->var.yres = yres;	info->var.yres_virtual = vyres;	info->var.bits_per_pixel = bpp;	if (dcolor)		info->var.nonstd = 1;	if (par->dev_flags & HAS_ACCELERATION) 		info->var.accel_flags = 1;	i810_init_monspecs(info);}	/** * i810_init_device - initialize device * @par: pointer to i810fb_par structure */static void __devinit i810_init_device(struct i810fb_par *par){	u8 reg, *mmio = par->mmio_start_virtual;	if (mtrr) set_mtrr(par);	i810_init_cursor(par);	/* mvo: enable external vga-connector (for laptops) */	if (ext_vga) {		i810_writel(HVSYNC, mmio, 0);		i810_writel(PWR_CLKC, mmio, 3);	}	pci_read_config_byte(par->dev, 0x50, &reg);	reg &= FREQ_MASK;	par->mem_freq = (reg) ? 133 : 100;}static int __devinit i810_allocate_pci_resource(struct i810fb_par *par, 			   const struct pci_device_id *entry){	int err;	if ((err = pci_enable_device(par->dev))) { 		printk("i810fb_init: cannot enable device\n");		return err;			}	par->res_flags |= PCI_DEVICE_ENABLED;	if (pci_resource_len(par->dev, 0) > 512 * 1024) {		par->aperture.physical = pci_resource_start(par->dev, 0);		par->aperture.size = pci_resource_len(par->dev, 0);		par->mmio_start_phys = pci_resource_start(par->dev, 1);	} else {		par->aperture.physical = pci_resource_start(par->dev, 1);		par->aperture.size = pci_resource_len(par->dev, 1);		par->mmio_start_phys = pci_resource_start(par->dev, 0);	}	if (!par->aperture.size) {		printk("i810fb_init: device is disabled\n");		return -ENOMEM;	}	if (!request_mem_region(par->aperture.physical, 				par->aperture.size, 				i810_pci_list[entry->driver_data])) {		printk("i810fb_init: cannot request framebuffer region\n");		return -ENODEV;	}	par->res_flags |= FRAMEBUFFER_REQ;	par->aperture.virtual = ioremap_nocache(par->aperture.physical, 					par->aperture.size);	if (!par->aperture.virtual) {		printk("i810fb_init: cannot remap framebuffer region\n");		return -ENODEV;	}  	if (!request_mem_region(par->mmio_start_phys, 				MMIO_SIZE, 				i810_pci_list[entry->driver_data])) {		printk("i810fb_init: cannot request mmio region\n");		return -ENODEV;	}	par->res_flags |= MMIO_REQ;	par->mmio_start_virtual = ioremap_nocache(par->mmio_start_phys, 						  MMIO_SIZE);	if (!par->mmio_start_virtual) {		printk("i810fb_init: cannot remap mmio region\n");		return -ENODEV;	}	return 0;}	int __init i810fb_setup(char *options){	char *this_opt, *suffix = NULL;	if (!options || !*options)		return 0;		while ((this_opt = strsep(&options, ",")) != NULL) {		if (!strncmp(this_opt, "mtrr", 4))			mtrr = 1;		else if (!strncmp(this_opt, "accel", 5))			accel = 1;		else if (!strncmp(this_opt, "ext_vga", 7))			ext_vga = 1;		else if (!strncmp(this_opt, "sync", 4))			sync = 1;		else if (!strncmp(this_opt, "vram:", 5))			vram = (simple_strtoul(this_opt+5, NULL, 0));		else if (!strncmp(this_opt, "voffset:", 8))			voffset = (simple_strtoul(this_opt+8, NULL, 0));		else if (!strncmp(this_opt, "xres:", 5))			xres = simple_strtoul(this_opt+5, NULL, 0);		else if (!strncmp(this_opt, "yres:", 5))			yres = simple_strtoul(this_opt+5, NULL, 0);		else if (!strncmp(this_opt, "vyres:", 6))			vyres = simple_strtoul(this_opt+6, NULL, 0);		else if (!strncmp(this_opt, "bpp:", 4))			bpp = simple_strtoul(this_opt+4, NULL, 0);		else if (!strncmp(this_opt, "hsync1:", 7)) {			hsync1 = simple_strtoul(this_opt+7, &suffix, 0);			if (strncmp(suffix, "H", 1)) 				hsync1 *= 1000;		} else if (!strncmp(this_opt, "hsync2:", 7)) {			hsync2 = simple_strtoul(this_opt+7, &suffix, 0);			if (strncmp(suffix, "H", 1)) 				hsync2 *= 1000;		} else if (!strncmp(this_opt, "vsync1:", 7)) 			vsync1 = simple_strtoul(this_opt+7, NULL, 0);		else if (!strncmp(this_opt, "vsync2:", 7))			vsync2 = simple_strtoul(this_opt+7, NULL, 0);		else if (!strncmp(this_opt, "dcolor", 6))			dcolor = 1;	}	return 0;}static int __devinit i810fb_init_pci (struct pci_dev *dev, 				   const struct pci_device_id *entry){	struct fb_info    *info;	struct i810fb_par *par = NULL;	int err, vfreq, hfreq, pixclock;	if (!(info = kmalloc(sizeof(struct fb_info), GFP_KERNEL))) {		i810fb_release_resource(info, par);		return -ENOMEM;	}	memset(info, 0, sizeof(struct fb_info));	if(!(par = kmalloc(sizeof(struct i810fb_par), GFP_KERNEL))) {		i810fb_release_resource(info, par);		return -ENOMEM;	}	memset(par, 0, sizeof(struct i810fb_par));	par->dev = dev;	info->par = par;	if (!(info->pixmap.addr = kmalloc(64*1024, GFP_KERNEL))) {		i810fb_release_resource(info, par);		return -ENOMEM;	}	memset(info->pixmap.addr, 0, 64*1024);	info->pixmap.size = 64*1024;	info->pixmap.buf_align = 8;	info->pixmap.flags = FB_PIXMAP_SYSTEM;	if ((err = i810_allocate_pci_resource(par, entry))) {		i810fb_release_resource(info, par);		return err;	}	i810_init_defaults(par, info);	if ((err = i810_alloc_agp_mem(info))) {		i810fb_release_resource(info, par);		return err;	}	i810_init_device(par);        	info->screen_base = par->fb.virtual;	info->fbops = &par->i810fb_ops;	info->pseudo_palette = par->pseudo_palette;	info->flags = FBINFO_FLAG_DEFAULT;		fb_alloc_cmap(&info->cmap, 256, 0);	if ((err = info->fbops->fb_check_var(&info->var, info))) {		i810fb_release_resource(info, par);		return err;	}	encode_fix(&info->fix, info); 	 	    	i810fb_init_ringbuffer(info);	err = register_framebuffer(info);	if (err < 0) {    		i810fb_release_resource(info, par); 		printk("i810fb_init: cannot register framebuffer device\n");    		return err;      	}   	pci_set_drvdata(dev, info);	pixclock = 1000000000/(info->var.pixclock);	pixclock *= 1000;	hfreq = pixclock/(info->var.xres + info->var.left_margin + 			  info->var.hsync_len + info->var.right_margin);	vfreq = hfreq/(info->var.yres + info->var.upper_margin +		       info->var.vsync_len + info->var.lower_margin);      	printk("I810FB: fb%d         : %s v%d.%d.%d%s\n"      	       "I810FB: Video RAM   : %dK\n" 	       "I810FB: Monitor     : H: %d-%d KHz V: %d-%d Hz\n"	       "I810FB: Mode        : %dx%d-%dbpp@%dHz\n",	       info->node,	       i810_pci_list[entry->driver_data],	       VERSION_MAJOR, VERSION_MINOR, VERSION_TEENIE, BRANCH_VERSION,	       (int) par->fb.size>>10, info->monspecs.hfmin/1000,	       info->monspecs.hfmax/1000, info->monspecs.vfmin,	       info->monspecs.vfmax, info->var.xres, 	       info->var.yres, info->var.bits_per_pixel, vfreq);	return 0;}/*************************************************************** *                     De-initialization                        * ***************************************************************/static void i810fb_release_resource(struct fb_info *info, 				    struct i810fb_par *par){	if (par) {		unset_mtrr(par);		if (par->drm_agp) {			drm_agp_t *agp = par->drm_agp;			struct gtt_data *gtt = &par->i810_gtt;			if (par->i810_gtt.i810_cursor_memory) 				agp->free_memory(gtt->i810_cursor_memory);			if (par->i810_gtt.i810_fb_memory) 				agp->free_memory(gtt->i810_fb_memory);			inter_module_put("drm_agp");			par->drm_agp = NULL;		}		if (par->mmio_start_virtual) 			iounmap(par->mmio_start_virtual);		if (par->aperture.virtual) 			iounmap(par->aperture.virtual);		if (par->res_flags & FRAMEBUFFER_REQ)			release_mem_region(par->aperture.physical, 					   par->aperture.size);		if (par->res_flags & MMIO_REQ)			release_mem_region(par->mmio_start_phys, MMIO_SIZE);		if (par->res_flags & PCI_DEVICE_ENABLED)			pci_disable_device(par->dev); 		kfree(par);	}	if (info) 		kfree(info);}static void __exit i810fb_remove_pci(struct pci_dev *dev){	struct fb_info *info = pci_get_drvdata(dev);	struct i810fb_par *par = (struct i810fb_par *) info->par;	unregister_framebuffer(info);  	i810fb_release_resource(info, par);	pci_set_drvdata(dev, NULL);	printk("cleanup_module:  unloaded i810 framebuffer device\n");}                                                	#ifndef MODULEint __init i810fb_init(void){	if (agp_intel_init()) {		printk("i810fb_init: cannot initialize intel agpgart\n");		return -ENODEV;	}	if (pci_register_driver(&i810fb_driver) > 0)		return 0;	pci_unregister_driver(&i810fb_driver);	return -ENODEV;}#endif /********************************************************************* *                          Modularization                           * *********************************************************************/#ifdef MODULEint __init i810fb_init(void){	hsync1 *= 1000;	hsync2 *= 1000;	if (pci_register_driver(&i810fb_driver) > 0)		return 0;	pci_unregister_driver(&i810fb_driver);	return -ENODEV;}MODULE_PARM(vram, "i");MODULE_PARM_DESC(vram, "System RAM to allocate to framebuffer in MiB" 		 " (default=4)");MODULE_PARM(voffset, "i");MODULE_PARM_DESC(voffset, "at what offset to place start of framebuffer "                 "memory (0 to maximum aperture size), in MiB (default = 48)");MODULE_PARM(bpp, "i");MODULE_PARM_DESC(bpp, "Color depth for display in bits per pixel"		 " (default = 8)");MODULE_PARM(xres, "i");MODULE_PARM_DESC(xres, "Horizontal resolution in pixels (default = 640)");MODULE_PARM(yres, "i");MODULE_PARM_DESC(yres, "Vertical resolution in scanlines (default = 480)");MODULE_PARM(vyres, "i");MODULE_PARM_DESC(vyres, "Virtual vertical resolution in scanlines"		 " (default = 480)");MODULE_PARM(hsync1, "i");MODULE_PARM_DESC(hsync1, "Minimum horizontal frequency of monitor in KHz"		 " (default = 31)");MODULE_PARM(hsync2, "i");MODULE_PARM_DESC(hsync2, "Maximum horizontal frequency of monitor in KHz"		 " (default = 31)");MODULE_PARM(vsync1, "i");MODULE_PARM_DESC(vsync1, "Minimum vertical frequency of monitor in Hz"		 " (default = 50)");MODULE_PARM(vsync2, "i");MODULE_PARM_DESC(vsync2, "Maximum vertical frequency of monitor in Hz" 		 " (default = 60)");MODULE_PARM(accel, "i");MODULE_PARM_DESC(accel, "Use Acceleration (BLIT) engine (default = 0)");MODULE_PARM(mtrr, "i");MODULE_PARM_DESC(mtrr, "Use MTRR (default = 0)");MODULE_PARM(ext_vga, "i");MODULE_PARM_DESC(ext_vga, "Enable external VGA connector (default = 0)");MODULE_PARM(sync, "i");MODULE_PARM_DESC(sync, "wait for accel engine to finish drawing"		 " (default = 0)");MODULE_PARM(dcolor, "i");MODULE_PARM_DESC(dcolor, "use DirectColor visuals"		 " (default = 0 = TrueColor)");MODULE_AUTHOR("Tony A. Daplas");MODULE_DESCRIPTION("Framebuffer device for the Intel 810/815 and"		   " compatible cards");MODULE_LICENSE("GPL"); static void __exit i810fb_exit(void){	pci_unregister_driver(&i810fb_driver);}module_init(i810fb_init);module_exit(i810fb_exit);#endif /* MODULE */

⌨️ 快捷键说明

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