📄 matroxfb_base.c
字号:
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 + -