📄 matroxfb_base.c
字号:
} ACCESS_FBINFO(mmio.base) = ctrlptr_phys; ACCESS_FBINFO(mmio.len) = 16384; ACCESS_FBINFO(video.base) = video_base_phys; if (mga_ioremap(video_base_phys, memsize, MGA_IOREMAP_FB, &ACCESS_FBINFO(video.vbase))) { printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n", video_base_phys, memsize); goto failCtrlIO; } { u_int32_t cmd; u_int32_t mga_option; pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, &mga_option); pci_read_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, &cmd); mga_option &= 0x7FFFFFFF; /* clear BIG_ENDIAN */ mga_option |= MX_OPTION_BSWAP; /* disable palette snooping */ cmd &= ~PCI_COMMAND_VGA_PALETTE; if (pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82437, NULL)) { if (!(mga_option & 0x20000000) && !ACCESS_FBINFO(devflags.nopciretry)) { printk(KERN_WARNING "matroxfb: Disabling PCI retries due to i82437 present\n"); } mga_option |= 0x20000000; ACCESS_FBINFO(devflags.nopciretry) = 1; } pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_COMMAND, cmd); pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, mga_option); hw->MXoptionReg = mga_option; /* select non-DMA memory for PCI_MGA_DATA, otherwise dump of PCI cfg space can lock PCI bus */ /* maybe preinit() candidate, but it is same... for all devices... at this time... */ pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_MGA_INDEX, 0x00003C00); } err = -ENXIO; if (ACCESS_FBINFO(hw_switch)->preinit(PMINFO hw)) { goto failVideoIO; } err = -ENOMEM; if (!matroxfb_getmemory(PMINFO memsize, &ACCESS_FBINFO(video.len)) || !ACCESS_FBINFO(video.len)) { printk(KERN_ERR "matroxfb: cannot determine memory size\n"); goto failVideoIO; } ACCESS_FBINFO(devflags.ydstorg) = 0; ACCESS_FBINFO(currcon) = -1; ACCESS_FBINFO(currcon_display) = d; mga_iounmap(ACCESS_FBINFO(video.vbase)); ACCESS_FBINFO(video.base) = video_base_phys; if (mga_ioremap(video_base_phys, ACCESS_FBINFO(video.len), MGA_IOREMAP_FB, &ACCESS_FBINFO(video.vbase))) { printk(KERN_ERR "matroxfb: cannot ioremap(%lX, %d), matroxfb disabled\n", video_base_phys, ACCESS_FBINFO(video.len)); goto failCtrlIO; } ACCESS_FBINFO(video.len_usable) = ACCESS_FBINFO(video.len); if (ACCESS_FBINFO(video.len_usable) > b->base->maxdisplayable) ACCESS_FBINFO(video.len_usable) = b->base->maxdisplayable;#ifdef CONFIG_MTRR if (mtrr) { ACCESS_FBINFO(mtrr.vram) = mtrr_add(video_base_phys, ACCESS_FBINFO(video.len), MTRR_TYPE_WRCOMB, 1); ACCESS_FBINFO(mtrr.vram_valid) = 1; printk(KERN_INFO "matroxfb: MTRR's turned on\n"); }#endif /* CONFIG_MTRR */ if (!ACCESS_FBINFO(devflags.novga)) request_region(0x3C0, 32, "matrox"); ACCESS_FBINFO(hw_switch->reset(PMINFO hw)); ACCESS_FBINFO(fbcon.monspecs.hfmin) = 0; ACCESS_FBINFO(fbcon.monspecs.hfmax) = fh; ACCESS_FBINFO(fbcon.monspecs.vfmin) = 0; ACCESS_FBINFO(fbcon.monspecs.vfmax) = fv; ACCESS_FBINFO(fbcon.monspecs.dpms) = 0; /* TBD */ /* static settings */ if ((depth == RSText8) && (!*ACCESS_FBINFO(fbcon.fontname))) { strcpy(ACCESS_FBINFO(fbcon.fontname), "VGA8x8"); } vesafb_defined.red = colors[depth-1].red; vesafb_defined.green = colors[depth-1].green; vesafb_defined.blue = colors[depth-1].blue; vesafb_defined.bits_per_pixel = colors[depth-1].bits_per_pixel; vesafb_defined.grayscale = grayscale; vesafb_defined.vmode = 0; if (noaccel) vesafb_defined.accel_flags &= ~FB_ACCELF_TEXT; strcpy(ACCESS_FBINFO(fbcon.modename), "MATROX VGA"); ACCESS_FBINFO(fbcon.changevar) = NULL; ACCESS_FBINFO(fbcon.node) = -1; ACCESS_FBINFO(fbcon.fbops) = &matroxfb_ops; ACCESS_FBINFO(fbcon.disp) = d; ACCESS_FBINFO(fbcon.switch_con) = &matroxfb_switch; ACCESS_FBINFO(fbcon.updatevar) = &matroxfb_updatevar; ACCESS_FBINFO(fbcon.blank) = &matroxfb_blank; /* after __init time we are like module... no logo */ ACCESS_FBINFO(fbcon.flags) = hotplug ? FBINFO_FLAG_MODULE : FBINFO_FLAG_DEFAULT; ACCESS_FBINFO(video.len_usable) &= PAGE_MASK;#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; } maxclk = (maxclk + 499) / 500; if (maxclk) { tmp = (2000000000 + maxclk) / maxclk; 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_ALL_PPC)#if defined(CONFIG_FB_COMPAT_XPMAC) strcpy(ACCESS_FBINFO(matrox_name), "MTRX,"); /* OpenFirmware naming convension */ strncat(ACCESS_FBINFO(matrox_name), b->name, 26); if (!console_fb_info) console_fb_info = &ACCESS_FBINFO(fbcon);#endif#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_ALL_PPC */ 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 */ } err = -EINVAL; if (matroxfb_set_var(&vesafb_defined, -2, &ACCESS_FBINFO(fbcon))) { printk(KERN_ERR "matroxfb: cannot set required parameters\n"); goto failVideoIO; } 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 */ if (register_framebuffer(&ACCESS_FBINFO(fbcon)) < 0) { goto failVideoIO; } printk("fb%d: %s frame buffer device\n", GET_FB_IDX(ACCESS_FBINFO(fbcon.node)), ACCESS_FBINFO(fbcon.modename)); if (ACCESS_FBINFO(currcon) < 0) { /* there is no console on this fb... but we have to initialize hardware * until someone tells me what is proper thing to do */ printk(KERN_INFO "fb%d: initializing hardware\n", GET_FB_IDX(ACCESS_FBINFO(fbcon.node))); matroxfb_set_var(&vesafb_defined, -1, &ACCESS_FBINFO(fbcon)); } return 0;failVideoIO:; 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;}LIST_HEAD(matroxfb_list);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; struct display* d; int err; u_int32_t cmd;#ifndef CONFIG_FB_MATROX_MULTIHEAD static int registered = 0; static struct display global_disp;#endif DBG("matroxfb_probe") 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 -1; if (dev > 0) { /* not requested one... */ dev--; return -1; } 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; d = (struct display*)kmalloc(sizeof(*d), GFP_KERNEL); if (!d) { kfree(minfo); return -1; }#else if (registered) /* singlehead driver... */ return -1; minfo = &matroxfb_global_mxinfo; d = &global_disp;#endif memset(MINFO, 0, sizeof(*MINFO)); memset(d, 0, sizeof(*d)); ACCESS_FBINFO(currenthw) = &ACCESS_FBINFO(hw1); ACCESS_FBINFO(newhw) = &ACCESS_FBINFO(hw2); ACCESS_FBINFO(pcidev) = pdev; ACCESS_FBINFO(dead) = 0; ACCESS_FBINFO(usecount) = 0; pci_set_drvdata(pdev, MINFO); /* CMDLINE */ memcpy(ACCESS_FBINFO(fbcon.fontname), fontname, sizeof(ACCESS_FBINFO(fbcon.fontname))); /* DEVFLAGS */ ACCESS_FBINFO(devflags.inverse) = inverse; 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.hwcursor) = hwcursor; ACCESS_FBINFO(devflags.blink) = blink; ACCESS_FBINFO(devflags.sgram) = sgram; ACCESS_FBINFO(capable.cross4MB) = cross4MB; ACCESS_FBINFO(fastfont.size) = fastfont; ACCESS_FBINFO(cursor.state) = CM_ERASE; init_timer (&ACCESS_FBINFO(cursor.timer)); ACCESS_FBINFO(cursor.timer.data) = (unsigned long)MINFO; 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(output.all) = MATROXFB_OUTPUT_CONN_PRIMARY; ACCESS_FBINFO(output.ph) = MATROXFB_OUTPUT_CONN_PRIMARY; ACCESS_FBINFO(output.sh) = 0; err = initMatrox2(PMINFO d, b); if (!err) {#ifndef CONF
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -