📄 matroxfb_base.c
字号:
#define RSText 0x7#define RSText8 0x8/* 9-F */static struct { struct fb_bitfield red, green, blue, transp; int bits_per_pixel; } colors[] = { { { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 8 }, { { 10, 5, 0}, { 5, 5, 0}, { 0, 5, 0}, { 15, 1, 0}, 16 }, { { 11, 5, 0}, { 5, 6, 0}, { 0, 5, 0}, { 0, 0, 0}, 16 }, { { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 24, 8, 0}, 32 }, { { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 4 }, { { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 24 }, { { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 }, /* textmode with (default) VGA8x16 */ { { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 }, /* textmode hardwired to VGA8x8 */};/* initialized by setup, see explanation at end of file (search for MODULE_PARM_DESC) */static unsigned int mem; /* "matrox:mem:xxxxxM" */static int option_precise_width = 1; /* cannot be changed, option_precise_width==0 must imply noaccel */static int inv24; /* "matrox:inv24" */static int cross4MB = -1; /* "matrox:cross4MB" */static int disabled; /* "matrox:disabled" */static int noaccel; /* "matrox:noaccel" */static int nopan; /* "matrox:nopan" */static int no_pci_retry; /* "matrox:nopciretry" */static int novga; /* "matrox:novga" */static int nobios; /* "matrox:nobios" */static int noinit = 1; /* "matrox:init" */static int inverse; /* "matrox:inverse" */static int hwcursor = 1; /* "matrox:nohwcursor" */static int blink = 1; /* "matrox:noblink" */static int sgram; /* "matrox:sgram" */#ifdef CONFIG_MTRRstatic int mtrr = 1; /* "matrox:nomtrr" */#endifstatic int grayscale; /* "matrox:grayscale" */static unsigned int fastfont; /* "matrox:fastfont:xxxxx" */static int dev = -1; /* "matrox:dev:xxxxx" */static unsigned int vesa = ~0; /* "matrox:vesa:xxxxx" */static int depth = -1; /* "matrox:depth:xxxxx" */static unsigned int xres; /* "matrox:xres:xxxxx" */static unsigned int yres; /* "matrox:yres:xxxxx" */static unsigned int upper = ~0; /* "matrox:upper:xxxxx" */static unsigned int lower = ~0; /* "matrox:lower:xxxxx" */static unsigned int vslen; /* "matrox:vslen:xxxxx" */static unsigned int left = ~0; /* "matrox:left:xxxxx" */static unsigned int right = ~0; /* "matrox:right:xxxxx" */static unsigned int hslen; /* "matrox:hslen:xxxxx" */static unsigned int pixclock; /* "matrox:pixclock:xxxxx" */static int sync = -1; /* "matrox:sync:xxxxx" */static unsigned int fv; /* "matrox:fv:xxxxx" */static unsigned int fh; /* "matrox:fh:xxxxxk" */static unsigned int maxclk; /* "matrox:maxclk:xxxxM" */static int dfp; /* "matrox:dfp */static int dfp_type = -1; /* "matrox:dfp:xxx */static int memtype = -1; /* "matrox:memtype:xxx" */static char fontname[64]; /* "matrox:font:xxxxx" */#ifndef MODULEstatic char videomode[64]; /* "matrox:mode:xxxxx" or "matrox:xxxxx" */#endifstatic int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int *realSize){ vaddr_t vm; unsigned int offs; unsigned int offs2; unsigned char store; unsigned char bytes[32]; unsigned char* tmp; DBG("matroxfb_getmemory") vm = ACCESS_FBINFO(video.vbase); maxSize &= ~0x1FFFFF; /* must be X*2MB (really it must be 2 or X*4MB) */ /* at least 2MB */ if (maxSize < 0x0200000) return 0; if (maxSize > 0x2000000) maxSize = 0x2000000; mga_outb(M_EXTVGA_INDEX, 0x03); mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) | 0x80); store = mga_readb(vm, 0x1234); tmp = bytes; for (offs = 0x100000; offs < maxSize; offs += 0x200000) *tmp++ = mga_readb(vm, offs); for (offs = 0x100000; offs < maxSize; offs += 0x200000) mga_writeb(vm, offs, 0x02); if (ACCESS_FBINFO(features.accel.has_cacheflush)) mga_outb(M_CACHEFLUSH, 0x00); else mga_writeb(vm, 0x1234, 0x99); for (offs = 0x100000; offs < maxSize; offs += 0x200000) { if (mga_readb(vm, offs) != 0x02) break; mga_writeb(vm, offs, mga_readb(vm, offs) - 0x02); if (mga_readb(vm, offs)) break; } tmp = bytes; for (offs2 = 0x100000; offs2 < maxSize; offs2 += 0x200000) mga_writeb(vm, offs2, *tmp++); mga_writeb(vm, 0x1234, store); mga_outb(M_EXTVGA_INDEX, 0x03); mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) & ~0x80); *realSize = offs - 0x100000;#ifdef CONFIG_FB_MATROX_MILLENIUM ACCESS_FBINFO(interleave) = !(!isMillenium(MINFO) || ((offs - 0x100000) & 0x3FFFFF));#endif return 1;}struct video_board { int maxvram; int maxdisplayable; int accelID; struct matrox_switch* lowlevel; };#ifdef CONFIG_FB_MATROX_MILLENIUMstatic struct video_board vbMillennium = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA2064W, &matrox_millennium};static struct video_board vbMillennium2 = {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W, &matrox_millennium};static struct video_board vbMillennium2A = {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W_AGP, &matrox_millennium};#endif /* CONFIG_FB_MATROX_MILLENIUM */#ifdef CONFIG_FB_MATROX_MYSTIQUEstatic struct video_board vbMystique = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA1064SG, &matrox_mystique};#endif /* CONFIG_FB_MATROX_MYSTIQUE */#ifdef CONFIG_FB_MATROX_G100static struct video_board vbG100 = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100, &matrox_G100};static struct video_board vbG200 = {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200, &matrox_G100};#ifdef CONFIG_FB_MATROX_32MB/* from doc it looks like that accelerator can draw only to low 16MB :-( Direct accesses & displaying are OK for whole 32MB */static struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100};#elsestatic struct video_board vbG400 = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100};#endif#endif#define DEVF_VIDEO64BIT 0x0001#define DEVF_SWAPS 0x0002#define DEVF_SRCORG 0x0004#define DEVF_BOTHDACS 0x0008 /* put CRTC1 on both outputs by default */#define DEVF_CROSS4MB 0x0010#define DEVF_TEXT4B 0x0020#define DEVF_DDC_8_2 0x0040#define DEVF_G550DAC 0x0080#define DEVF_SUPPORT32MB 0x0100#define DEVF_ANY_VXRES 0x0200#define DEVF_TEXT16B 0x0400#define DEVF_CRTC2 0x0800#define DEVF_MAVEN_CAPABLE 0x1000#define DEVF_PANELLINK_CAPABLE 0x2000#define DEVF_G450DAC 0x4000#define DEVF_GCORE (DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2)#define DEVF_G2CORE (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_MAVEN_CAPABLE | DEVF_PANELLINK_CAPABLE | DEVF_SRCORG)#define DEVF_G100 (DEVF_GCORE) /* no doc, no vxres... */#define DEVF_G200 (DEVF_G2CORE)#define DEVF_G400 (DEVF_G2CORE | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2)/* if you'll find how to drive DFP... */#define DEVF_G450 (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_SUPPORT32MB | DEVF_TEXT16B | DEVF_CRTC2 | DEVF_G450DAC | DEVF_SRCORG)#define DEVF_G550 (DEVF_G450 | DEVF_G550DAC | DEVF_BOTHDACS)static struct board { unsigned short vendor, device, rev, svid, sid; unsigned int flags; unsigned int maxclk; struct video_board* base; const char* name; } dev_list[] = {#ifdef CONFIG_FB_MATROX_MILLENIUM {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL, 0xFF, 0, 0, DEVF_TEXT4B, 230000, &vbMillennium, "Millennium (PCI)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2, 0xFF, 0, 0, DEVF_SWAPS, 220000, &vbMillennium2, "Millennium II (PCI)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MIL_2_AGP, 0xFF, 0, 0, DEVF_SWAPS, 250000, &vbMillennium2A, "Millennium II (AGP)"},#endif#ifdef CONFIG_FB_MATROX_MYSTIQUE {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS, 0x02, 0, 0, DEVF_VIDEO64BIT | DEVF_CROSS4MB, 180000, &vbMystique, "Mystique (PCI)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_MYS, 0xFF, 0, 0, DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB, 220000, &vbMystique, "Mystique 220 (PCI)"},#endif#ifdef CONFIG_FB_MATROX_G100 {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF, PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MGA_G100_PCI, DEVF_G100, 230000, &vbG100, "MGA-G100 (PCI)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_MM, 0xFF, 0, 0, DEVF_G100, 230000, &vbG100, "unknown G100 (PCI)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF, PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_GENERIC, DEVF_G100, 230000, &vbG100, "MGA-G100 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF, PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MGA_G100_AGP, DEVF_G100, 230000, &vbG100, "MGA-G100 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF, PCI_SS_VENDOR_ID_SIEMENS_NIXDORF, PCI_SS_ID_SIEMENS_MGA_G100_AGP, DEVF_G100, 230000, &vbG100, "MGA-G100 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF, PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP, DEVF_G100, 230000, &vbG100, "Productiva G100 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF, 0, 0, DEVF_G100, 230000, &vbG100, "unknown G100 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF, 0, 0, DEVF_G200, 250000, &vbG200, "unknown G200 (PCI)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_GENERIC, DEVF_G200, 220000, &vbG200, "MGA-G200 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MYSTIQUE_G200_AGP, DEVF_G200, 230000, &vbG200, "Mystique G200 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MILLENIUM_G200_AGP, DEVF_G200, 250000, &vbG200, "Millennium G200 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MARVEL_G200_AGP, DEVF_G200, 230000, &vbG200, "Marvel G200 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, PCI_SS_VENDOR_ID_SIEMENS_NIXDORF, PCI_SS_ID_SIEMENS_MGA_G200_AGP, DEVF_G200, 230000, &vbG200, "MGA-G200 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF, 0, 0, DEVF_G200, 230000, &vbG200, "G200 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0x80, PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MILLENNIUM_G400_MAX_AGP, DEVF_G400, 360000, &vbG400, "Millennium G400 MAX (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0x80, 0, 0, DEVF_G400, 300000, &vbG400, "G400 (AGP)"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400, 0xFF, 0, 0, DEVF_G450, 500000, /* ??? vco goes up to 900MHz... */ &vbG400, "G450"}, {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G550, 0xFF, 0, 0, DEVF_G550, 500000, &vbG400, "G550"},#endif {0, 0, 0xFF, 0, 0, 0, 0, NULL, NULL}};#ifndef MODULEstatic struct fb_videomode defaultmode = { /* 640x480 @ 60Hz, 31.5 kHz */ NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2, 0, FB_VMODE_NONINTERLACED};#endif /* !MODULE */static int hotplug = 0;static int initMatrox2(WPMINFO struct display* d, struct board* b){ unsigned long ctrlptr_phys = 0; unsigned long video_base_phys = 0; unsigned int memsize; struct matrox_hw_state* hw = ACCESS_FBINFO(currenthw); int err; DBG("initMatrox2") /* set default values... */ vesafb_defined.accel_flags = FB_ACCELF_TEXT; ACCESS_FBINFO(hw_switch) = b->base->lowlevel; ACCESS_FBINFO(devflags.accelerator) = b->base->accelID; ACCESS_FBINFO(max_pixel_clock) = b->maxclk; printk(KERN_INFO "matroxfb: Matrox %s detected\n", b->name); ACCESS_FBINFO(capable.plnwt) = 1; ACCESS_FBINFO(capable.srcorg) = b->flags & DEVF_SRCORG; ACCESS_FBINFO(devflags.video64bits) = b->flags & DEVF_VIDEO64BIT; if (b->flags & DEVF_TEXT4B) { ACCESS_FBINFO(devflags.vgastep) = 4; ACCESS_FBINFO(devflags.textmode) = 4; ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP16; } else if (b->flags & DEVF_TEXT16B) { ACCESS_FBINFO(devflags.vgastep) = 16; ACCESS_FBINFO(devflags.textmode) = 1; ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP16; } else { ACCESS_FBINFO(devflags.vgastep) = 8; ACCESS_FBINFO(devflags.textmode) = 1; ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP8; }#ifdef CONFIG_FB_MATROX_32MB ACCESS_FBINFO(devflags.support32MB) = b->flags & DEVF_SUPPORT32MB;#endif ACCESS_FBINFO(devflags.precise_width) = !(b->flags & DEVF_ANY_VXRES); ACCESS_FBINFO(devflags.crtc2) = b->flags & DEVF_CRTC2; ACCESS_FBINFO(devflags.maven_capable) = b->flags & DEVF_MAVEN_CAPABLE; if (b->flags & DEVF_PANELLINK_CAPABLE) { ACCESS_FBINFO(output.all) |= MATROXFB_OUTPUT_CONN_DFP; if (dfp) ACCESS_FBINFO(output.ph) |= MATROXFB_OUTPUT_CONN_DFP; } if (b->flags & DEVF_BOTHDACS) {#ifdef CONFIG_FB_MATROX_G450 ACCESS_FBINFO(output.all) |= MATROXFB_OUTPUT_CONN_SECONDARY; ACCESS_FBINFO(output.ph) |= MATROXFB_OUTPUT_CONN_SECONDARY;#else printk(KERN_INFO "Only digital output of G550 is now working (in analog mode). Enable G450 support in\n"); printk(KERN_INFO "kernel configuration if you have analog monitor connected to G550 analog output.\n");#endif } ACCESS_FBINFO(devflags.dfp_type) = dfp_type; ACCESS_FBINFO(devflags.g450dac) = b->flags & DEVF_G450DAC; ACCESS_FBINFO(devflags.g550dac) = b->flags & DEVF_G550DAC; ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode); ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode); if (ACCESS_FBINFO(capable.cross4MB) < 0) ACCESS_FBINFO(capable.cross4MB) = b->flags & DEVF_CROSS4MB; if (b->flags & DEVF_SWAPS) { ctrlptr_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 1); video_base_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 0); } else { ctrlptr_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 0); video_base_phys = pci_resource_start(ACCESS_FBINFO(pcidev), 1); } err = -EINVAL; if (!ctrlptr_phys) { printk(KERN_ERR "matroxfb: control registers are not available, matroxfb disabled\n"); goto fail; } if (!video_base_phys) { printk(KERN_ERR "matroxfb: video RAM is not available in PCI address space, matroxfb disabled\n"); goto fail; } memsize = b->base->maxvram; if (!request_mem_region(ctrlptr_phys, 16384, "matroxfb MMIO")) { goto fail; } if (!request_mem_region(video_base_phys, memsize, "matroxfb FB")) { goto failCtrlMR; } ACCESS_FBINFO(video.len_maximum) = memsize; /* convert mem (autodetect k, M) */ if (mem < 1024) mem *= 1024; if (mem < 0x00100000) mem *= 1024; if (mem && (mem < memsize)) memsize = mem; err = -ENOMEM; if (mga_ioremap(ctrlptr_phys, 16384, MGA_IOREMAP_MMIO, &ACCESS_FBINFO(mmio.vbase))) { printk(KERN_ERR "matroxfb: cannot ioremap(%lX, 16384), matroxfb disabled\n", ctrlptr_phys); goto failVideoMR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -