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

📄 matroxfb_base.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
	vesafb_defined.grayscale = grayscale;	vesafb_defined.vmode = 0;	if (noaccel)		vesafb_defined.accel_flags &= ~FB_ACCELF_TEXT;	ACCESS_FBINFO(fbops) = matroxfb_ops;	ACCESS_FBINFO(fbcon.fbops) = &ACCESS_FBINFO(fbops);	ACCESS_FBINFO(fbcon.pseudo_palette) = ACCESS_FBINFO(cmap);	/* after __init time we are like module... no logo */	ACCESS_FBINFO(fbcon.flags) = hotplug ? FBINFO_FLAG_MODULE : FBINFO_FLAG_DEFAULT;	ACCESS_FBINFO(fbcon.flags) |= FBINFO_PARTIAL_PAN_OK | 	 /* Prefer panning for scroll under MC viewer/edit */				      FBINFO_HWACCEL_COPYAREA |  /* We have hw-assisted bmove */				      FBINFO_HWACCEL_FILLRECT |  /* And fillrect */				      FBINFO_HWACCEL_IMAGEBLIT | /* And imageblit */				      FBINFO_HWACCEL_XPAN |      /* And we support both horizontal */				      FBINFO_HWACCEL_YPAN;       /* And vertical panning */	ACCESS_FBINFO(video.len_usable) &= PAGE_MASK;	fb_alloc_cmap(&ACCESS_FBINFO(fbcon.cmap), 256, 1);#ifndef MODULE	/* mode database is marked __init!!! */	if (!hotplug) {		fb_find_mode(&vesafb_defined, &ACCESS_FBINFO(fbcon), videomode[0]?videomode:NULL,			NULL, 0, &defaultmode, vesafb_defined.bits_per_pixel);	}#endif /* !MODULE */	/* mode modifiers */	if (hslen)		vesafb_defined.hsync_len = hslen;	if (vslen)		vesafb_defined.vsync_len = vslen;	if (left != ~0)		vesafb_defined.left_margin = left;	if (right != ~0)		vesafb_defined.right_margin = right;	if (upper != ~0)		vesafb_defined.upper_margin = upper;	if (lower != ~0)		vesafb_defined.lower_margin = lower;	if (xres)		vesafb_defined.xres = xres;	if (yres)		vesafb_defined.yres = yres;	if (sync != -1)		vesafb_defined.sync = sync;	else if (vesafb_defined.sync == ~0) {		vesafb_defined.sync = 0;		if (yres < 400)			vesafb_defined.sync |= FB_SYNC_HOR_HIGH_ACT;		else if (yres < 480)			vesafb_defined.sync |= FB_SYNC_VERT_HIGH_ACT;	}	/* fv, fh, maxclk limits was specified */	{		unsigned int tmp;		if (fv) {			tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres			          + vesafb_defined.lower_margin + vesafb_defined.vsync_len);			if ((tmp < fh) || (fh == 0)) fh = tmp;		}		if (fh) {			tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres			          + vesafb_defined.right_margin + vesafb_defined.hsync_len);			if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp;		}		tmp = (maxclk + 499) / 500;		if (tmp) {			tmp = (2000000000 + tmp) / tmp;			if (tmp > pixclock) pixclock = tmp;		}	}	if (pixclock) {		if (pixclock < 2000)		/* > 500MHz */			pixclock = 4000;	/* 250MHz */		if (pixclock > 1000000)			pixclock = 1000000;	/* 1MHz */		vesafb_defined.pixclock = pixclock;	}	/* FIXME: Where to move this?! */#if defined(CONFIG_PPC_PMAC)#ifndef MODULE	if (_machine == _MACH_Pmac) {		struct fb_var_screeninfo var;		if (default_vmode <= 0 || default_vmode > VMODE_MAX)			default_vmode = VMODE_640_480_60;#ifdef CONFIG_NVRAM		if (default_cmode == CMODE_NVRAM)			default_cmode = nvram_read_byte(NV_CMODE);#endif		if (default_cmode < CMODE_8 || default_cmode > CMODE_32)			default_cmode = CMODE_8;		if (!mac_vmode_to_var(default_vmode, default_cmode, &var)) {			var.accel_flags = vesafb_defined.accel_flags;			var.xoffset = var.yoffset = 0;			/* Note: mac_vmode_to_var() does not set all parameters */			vesafb_defined = var;		}	}#endif /* !MODULE */#endif /* CONFIG_PPC_PMAC */	vesafb_defined.xres_virtual = vesafb_defined.xres;	if (nopan) {		vesafb_defined.yres_virtual = vesafb_defined.yres;	} else {		vesafb_defined.yres_virtual = 65536; /* large enough to be INF, but small enough							to yres_virtual * xres_virtual < 2^32 */	}	matroxfb_init_fix(PMINFO2);	ACCESS_FBINFO(fbcon.screen_base) = vaddr_va(ACCESS_FBINFO(video.vbase));	matroxfb_update_fix(PMINFO2);	/* Normalize values (namely yres_virtual) */	matroxfb_check_var(&vesafb_defined, &ACCESS_FBINFO(fbcon));	/* And put it into "current" var. Do NOT program hardware yet, or we'll not take over	 * vgacon correctly. fbcon_startup will call fb_set_par for us, WITHOUT check_var,	 * and unfortunately it will do it BEFORE vgacon contents is saved, so it won't work	 * anyway. But we at least tried... */	ACCESS_FBINFO(fbcon.var) = vesafb_defined;	err = -EINVAL;	printk(KERN_INFO "matroxfb: %dx%dx%dbpp (virtual: %dx%d)\n",		vesafb_defined.xres, vesafb_defined.yres, vesafb_defined.bits_per_pixel,		vesafb_defined.xres_virtual, vesafb_defined.yres_virtual);	printk(KERN_INFO "matroxfb: framebuffer at 0x%lX, mapped to 0x%p, size %d\n",		ACCESS_FBINFO(video.base), vaddr_va(ACCESS_FBINFO(video.vbase)), ACCESS_FBINFO(video.len));/* We do not have to set currcon to 0... register_framebuffer do it for us on first console * and we do not want currcon == 0 for subsequent framebuffers */	ACCESS_FBINFO(fbcon).device = &ACCESS_FBINFO(pcidev)->dev;	if (register_framebuffer(&ACCESS_FBINFO(fbcon)) < 0) {		goto failVideoIO;	}	printk("fb%d: %s frame buffer device\n",	       ACCESS_FBINFO(fbcon.node), ACCESS_FBINFO(fbcon.fix.id));	/* there is no console on this fb... but we have to initialize hardware	 * until someone tells me what is proper thing to do */ 	if (!ACCESS_FBINFO(initialized)) { 		printk(KERN_INFO "fb%d: initializing hardware\n", 		       ACCESS_FBINFO(fbcon.node)); 		/* We have to use FB_ACTIVATE_FORCE, as we had to put vesafb_defined to the fbcon.var 		 * already before, so register_framebuffer works correctly. */ 		vesafb_defined.activate |= FB_ACTIVATE_FORCE; 		fb_set_var(&ACCESS_FBINFO(fbcon), &vesafb_defined); 	}	return 0;failVideoIO:;	matroxfb_g450_shutdown(PMINFO2);	mga_iounmap(ACCESS_FBINFO(video.vbase));failCtrlIO:;	mga_iounmap(ACCESS_FBINFO(mmio.vbase));failVideoMR:;	release_mem_region(video_base_phys, ACCESS_FBINFO(video.len_maximum));failCtrlMR:;	release_mem_region(ctrlptr_phys, 16384);fail:;	return err;}static LIST_HEAD(matroxfb_list);static LIST_HEAD(matroxfb_driver_list);#define matroxfb_l(x) list_entry(x, struct matrox_fb_info, next_fb)#define matroxfb_driver_l(x) list_entry(x, struct matroxfb_driver, node)int matroxfb_register_driver(struct matroxfb_driver* drv) {	struct matrox_fb_info* minfo;	list_add(&drv->node, &matroxfb_driver_list);	for (minfo = matroxfb_l(matroxfb_list.next);	     minfo != matroxfb_l(&matroxfb_list);	     minfo = matroxfb_l(minfo->next_fb.next)) {		void* p;		if (minfo->drivers_count == MATROXFB_MAX_FB_DRIVERS)			continue;		p = drv->probe(minfo);		if (p) {			minfo->drivers_data[minfo->drivers_count] = p;			minfo->drivers[minfo->drivers_count++] = drv;		}	}	return 0;}void matroxfb_unregister_driver(struct matroxfb_driver* drv) {	struct matrox_fb_info* minfo;	list_del(&drv->node);	for (minfo = matroxfb_l(matroxfb_list.next);	     minfo != matroxfb_l(&matroxfb_list);	     minfo = matroxfb_l(minfo->next_fb.next)) {		int i;		for (i = 0; i < minfo->drivers_count; ) {			if (minfo->drivers[i] == drv) {				if (drv && drv->remove)					drv->remove(minfo, minfo->drivers_data[i]);				minfo->drivers[i] = minfo->drivers[--minfo->drivers_count];				minfo->drivers_data[i] = minfo->drivers_data[minfo->drivers_count];			} else				i++;		}	}}static void matroxfb_register_device(struct matrox_fb_info* minfo) {	struct matroxfb_driver* drv;	int i = 0;	list_add(&ACCESS_FBINFO(next_fb), &matroxfb_list);	for (drv = matroxfb_driver_l(matroxfb_driver_list.next);	     drv != matroxfb_driver_l(&matroxfb_driver_list);	     drv = matroxfb_driver_l(drv->node.next)) {		if (drv && drv->probe) {			void *p = drv->probe(minfo);			if (p) {				minfo->drivers_data[i] = p;				minfo->drivers[i++] = drv;				if (i == MATROXFB_MAX_FB_DRIVERS)					break;			}		}	}	minfo->drivers_count = i;}static void matroxfb_unregister_device(struct matrox_fb_info* minfo) {	int i;	list_del(&ACCESS_FBINFO(next_fb));	for (i = 0; i < minfo->drivers_count; i++) {		struct matroxfb_driver* drv = minfo->drivers[i];		if (drv && drv->remove)			drv->remove(minfo, minfo->drivers_data[i]);	}}static int matroxfb_probe(struct pci_dev* pdev, const struct pci_device_id* dummy) {	struct board* b;	u_int8_t rev;	u_int16_t svid;	u_int16_t sid;	struct matrox_fb_info* minfo;	int err;	u_int32_t cmd;#ifndef CONFIG_FB_MATROX_MULTIHEAD	static int registered = 0;#endif	DBG(__FUNCTION__)	pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);	svid = pdev->subsystem_vendor;	sid = pdev->subsystem_device;	for (b = dev_list; b->vendor; b++) {		if ((b->vendor != pdev->vendor) || (b->device != pdev->device) || (b->rev < rev)) continue;		if (b->svid)			if ((b->svid != svid) || (b->sid != sid)) continue;		break;	}	/* not match... */	if (!b->vendor)		return -ENODEV;	if (dev > 0) {		/* not requested one... */		dev--;		return -ENODEV;	}	pci_read_config_dword(pdev, PCI_COMMAND, &cmd);	if (pci_enable_device(pdev)) {		return -1;	}#ifdef CONFIG_FB_MATROX_MULTIHEAD	minfo = (struct matrox_fb_info*)kmalloc(sizeof(*minfo), GFP_KERNEL);	if (!minfo)		return -1;#else	if (registered)	/* singlehead driver... */		return -1;	minfo = &matroxfb_global_mxinfo;#endif	memset(MINFO, 0, sizeof(*MINFO));	ACCESS_FBINFO(pcidev) = pdev;	ACCESS_FBINFO(dead) = 0;	ACCESS_FBINFO(usecount) = 0;	ACCESS_FBINFO(userusecount) = 0;	pci_set_drvdata(pdev, MINFO);	/* DEVFLAGS */	ACCESS_FBINFO(devflags.memtype) = memtype;	if (memtype != -1)		noinit = 0;	if (cmd & PCI_COMMAND_MEMORY) {		ACCESS_FBINFO(devflags.novga) = novga;		ACCESS_FBINFO(devflags.nobios) = nobios;		ACCESS_FBINFO(devflags.noinit) = noinit;		/* subsequent heads always needs initialization and must not enable BIOS */		novga = 1;		nobios = 1;		noinit = 0;	} else {		ACCESS_FBINFO(devflags.novga) = 1;		ACCESS_FBINFO(devflags.nobios) = 1;		ACCESS_FBINFO(devflags.noinit) = 0;	}	ACCESS_FBINFO(devflags.nopciretry) = no_pci_retry;	ACCESS_FBINFO(devflags.mga_24bpp_fix) = inv24;	ACCESS_FBINFO(devflags.precise_width) = option_precise_width;	ACCESS_FBINFO(devflags.sgram) = sgram;	ACCESS_FBINFO(capable.cross4MB) = cross4MB;	spin_lock_init(&ACCESS_FBINFO(lock.DAC));	spin_lock_init(&ACCESS_FBINFO(lock.accel));	init_rwsem(&ACCESS_FBINFO(crtc2.lock));	init_rwsem(&ACCESS_FBINFO(altout.lock));	ACCESS_FBINFO(irq_flags) = 0;	init_waitqueue_head(&ACCESS_FBINFO(crtc1.vsync.wait));	init_waitqueue_head(&ACCESS_FBINFO(crtc2.vsync.wait));	ACCESS_FBINFO(crtc1.panpos) = -1;	err = initMatrox2(PMINFO b);	if (!err) {#ifndef CONFIG_FB_MATROX_MULTIHEAD		registered = 1;#endif		matroxfb_register_device(MINFO);		return 0;	}#ifdef CONFIG_FB_MATROX_MULTIHEAD	kfree(minfo);#endif	return -1;}static void pci_remove_matrox(struct pci_dev* pdev) {	struct matrox_fb_info* minfo;	minfo = pci_get_drvdata(pdev);	matroxfb_remove(PMINFO 1);}static struct pci_device_id matroxfb_devices[] = {#ifdef CONFIG_FB_MATROX_MILLENIUM	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL,		PCI_ANY_ID,	PCI_ANY_ID,	0, 0, 0},	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL_2,		PCI_ANY_ID,	PCI_ANY_ID,	0, 0, 0},	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MIL_2_AGP,		PCI_ANY_ID,	PCI_ANY_ID,	0, 0, 0},#endif#ifdef CONFIG_FB_MATROX_MYSTIQUE	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_MYS,		PCI_ANY_ID,	PCI_ANY_ID,	0, 0, 0},#endif#ifdef CONFIG_FB_MATROX_G	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_MM,		PCI_ANY_ID,	PCI_ANY_ID,	0, 0, 0},	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G100_AGP,		PCI_ANY_ID,	PCI_ANY_ID,	0, 0, 0},	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_PCI,		PCI_ANY_ID,	PCI_ANY_ID,	0, 0, 0},	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G200_AGP,		PCI_ANY_ID,	PCI_ANY_ID,	0, 0, 0},	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G400,		PCI_ANY_ID,	PCI_ANY_ID,	0, 0, 0},	{PCI_VENDOR_ID_MATROX,	PCI_DEVICE_ID_MATROX_G550,		PCI_ANY_ID,	PCI_ANY_ID,	0, 0, 0},#endif	{0,			0,		0,		0,		0, 0, 0}};MODULE_DEVICE_TABLE(pci, matroxfb_devices);static struct pci_driver matroxfb_driver = {	.name =		"matroxfb",	.id_table =	matroxfb_devices,	.probe =	matroxfb_probe,	.remove =	pci_remove_matrox,};/* **************************** init-time only **************************** */#define RSResolution(X)	((X) & 0x0F)#define RS640x400	1#define RS640x480	2#define RS800x600	3#define RS1024x768	4#define RS1280x1024	5#define RS1600x1200	6#define RS768x576	7#define RS960x720	8#define RS1152x864	9#define RS1408x1056	10#define RS640x350	11#define RS1056x344	12	/* 132 x 43 text */#define RS1056x400	13	/* 132 x 50 text */#define RS1056x480	14	/* 132 x 60 text */#define RSNoxNo		15/* 10-FF */static struct { int xres, yres, left, right, upper, lower, hslen, vslen, vfreq; } timmings[] __initdata = {	{  640,  400,  48, 16, 39,  8,  96, 2, 70 },	{  640,  480,  48, 16, 33, 10,  96, 2, 60 },	{  800,  600, 144, 24, 28,  8, 112, 6, 60 },	{ 1024,  768, 160, 32, 30,  4, 128, 4, 60 },	{ 1280, 1024, 224, 32, 32,  4, 136, 4, 60 },	{ 1600, 1200, 272, 48, 32,  5, 152, 5, 60 },	{  768,  576, 144, 16, 28,  6, 112, 4, 60 },	{  960,  720, 144, 24, 28,  8, 112, 4, 60 },	{ 1152,  864, 192, 32, 30,  4, 128, 4, 60 },	{ 1408, 1056, 256, 40, 32,  5, 144, 5, 60 },	{  640,  350,  48, 16, 39,  8,  96, 2, 70 },	{ 1056,  344,  96, 24, 59, 44, 160, 2, 70 },	{ 1056,  400,  96, 24, 39,  8, 160, 2, 70 },	{ 1056,  480,  96, 24, 36, 12, 160, 3, 60 },	{    0,    0,  ~0, ~0, ~0, ~0,   0, 0,  0 }};#define RSCreate(X,Y)	((X) | ((Y) << 8))static struct { unsigned int vesa; unsigned int info; } *RSptr, vesamap[] __initdata = {/* default must be first */	{    ~0, RSCreate(RSNoxNo,     RS8bpp ) },	{ 0x101, RSCreate(RS640x480,   RS8bpp ) },	{ 0x100, RSCreate(RS640x400,   RS8bpp ) },	{ 0x180, RSCreate(RS768x576,   RS8bpp ) },	{ 0x103, RSCreate(RS800x600,   RS8bpp ) },	{ 0x188, RSCreate(RS960x720,   RS8bpp ) },	{ 0x105, RSCreate(RS1024x768,  RS8bpp ) },	{ 0x190, RSCreate(RS1152x864,  RS8bpp ) },	{ 0x107, RSCreate(RS1280x1024, 

⌨️ 快捷键说明

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