📄 matroxfb_base.c
字号:
} if (!changes) return 0; matroxfb_switch(ACCESS_FBINFO(currcon), info); return 0; } case MATROXFB_GET_OUTPUT_CONNECTION: { u_int32_t conn = 0; int i; for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { if (ACCESS_FBINFO(outputs[i]).src == MATROXFB_SRC_CRTC1) { conn |= 1 << i; } } if (put_user(conn, (u_int32_t*)arg)) return -EFAULT; return 0; } case MATROXFB_GET_AVAILABLE_OUTPUTS: { u_int32_t conn = 0; int i; for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { if (ACCESS_FBINFO(outputs[i]).output) { switch (ACCESS_FBINFO(outputs[i]).src) { case MATROXFB_SRC_NONE: case MATROXFB_SRC_CRTC1: conn |= 1 << i; break; } } } if (ACCESS_FBINFO(devflags.panellink)) { if (conn & MATROXFB_OUTPUT_CONN_DFP) conn &= ~MATROXFB_OUTPUT_CONN_SECONDARY; if (conn & MATROXFB_OUTPUT_CONN_SECONDARY) conn &= ~MATROXFB_OUTPUT_CONN_DFP; } if (put_user(conn, (u_int32_t*)arg)) return -EFAULT; return 0; } case MATROXFB_GET_ALL_OUTPUTS: { u_int32_t conn = 0; int i; for (i = 0; i < MATROXFB_MAX_OUTPUTS; i++) { if (ACCESS_FBINFO(outputs[i]).output) { conn |= 1 << i; } } if (put_user(conn, (u_int32_t*)arg)) return -EFAULT; return 0; } case 0x80585600: { struct { char name[32]; int type; int inputs; int outputs; int audios; int maxwidth; int maxheight; int minwidth; int minheight; int maxframerate; __u32 flags; __u32 reserved[4]; } r; memset(&r, 0, sizeof(r)); strcat(r.name, "Matrox TVO"); r.type = 2; // output r.inputs = 0; r.outputs = 1; r.audios = 0; r.maxwidth = 1023; // max visible width r.maxheight = 625; // max picture height: full PAL r.minwidth = 512; // min visible width... ~480 r.minheight = 480; // min picture height: visible portion of NTSC r.maxframerate = 60; // max: NTSC, 60Hz interlaced r.flags = 0; // nothing is supported... if (copy_to_user((void*)arg, &r, sizeof(r))) return -EFAULT; return 0; } case MATROXFB_TVOQUERYCTRL: { struct matroxfb_queryctrl qctrl; int err; if (copy_from_user(&qctrl, (struct matroxfb_queryctrl*)arg, sizeof(qctrl))) return -EFAULT; down_read(&ACCESS_FBINFO(altout).lock); if (!ACCESS_FBINFO(outputs[1]).output) { err = -ENXIO; } else if (ACCESS_FBINFO(outputs[1]).output->getqueryctrl) { err = ACCESS_FBINFO(outputs[1]).output->getqueryctrl(ACCESS_FBINFO(outputs[1]).data, &qctrl); } else { err = -EINVAL; } up_read(&ACCESS_FBINFO(altout).lock); if (err >= 0 && copy_to_user((struct matroxfb_queryctrl*)arg, &qctrl, sizeof(qctrl))) return -EFAULT; return err; } case MATROXFB_G_TVOCTRL: { struct matroxfb_control ctrl; int err; if (copy_from_user(&ctrl, (struct matroxfb_control*)arg, sizeof(ctrl))) return -EFAULT; down_read(&ACCESS_FBINFO(altout).lock); if (!ACCESS_FBINFO(outputs[1]).output) { err = -ENXIO; } else if (ACCESS_FBINFO(outputs[1]).output->getctrl) { err = ACCESS_FBINFO(outputs[1]).output->getctrl(ACCESS_FBINFO(outputs[1]).data, &ctrl); } else { err = -EINVAL; } up_read(&ACCESS_FBINFO(altout).lock); if (err >= 0 && copy_to_user((struct matroxfb_control*)arg, &ctrl, sizeof(ctrl))) return -EFAULT; return err; } case MATROXFB_S_TVOCTRL: { struct matroxfb_control ctrl; int err; if (copy_from_user(&ctrl, (struct matroxfb_control*)arg, sizeof(ctrl))) return -EFAULT; down_read(&ACCESS_FBINFO(altout).lock); if (!ACCESS_FBINFO(outputs[1]).output) { err = -ENXIO; } else if (ACCESS_FBINFO(outputs[1]).output->setctrl) { err = ACCESS_FBINFO(outputs[1]).output->setctrl(ACCESS_FBINFO(outputs[1]).data, &ctrl); } else { err = -EINVAL; } up_read(&ACCESS_FBINFO(altout).lock); return err; } } return -ENOTTY;#undef minfo}/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */static int matroxfb_blank(int blank, struct fb_info *info){#define minfo (list_entry(info, struct matrox_fb_info, fbcon)) int seq; int crtc; CRITFLAGS DBG("matroxfb_blank") if (ACCESS_FBINFO(dead)) return 1; switch (blank) { case 1: seq = 0x20; crtc = 0x00; break; /* works ??? */ case 2: seq = 0x20; crtc = 0x10; break; case 3: seq = 0x20; crtc = 0x20; break; case 4: seq = 0x20; crtc = 0x30; break; default: seq = 0x00; crtc = 0x00; break; } CRITBEGIN mga_outb(M_SEQ_INDEX, 1); mga_outb(M_SEQ_DATA, (mga_inb(M_SEQ_DATA) & ~0x20) | seq); mga_outb(M_EXTVGA_INDEX, 1); mga_outb(M_EXTVGA_DATA, (mga_inb(M_EXTVGA_DATA) & ~0x30) | crtc); CRITEND return 0;#undef minfo}static void matroxfb_blank24(int blank, struct fb_info *info){ matroxfb_blank(blank, info);}static struct fb_ops matroxfb_ops = { owner: THIS_MODULE, fb_open: matroxfb_open, fb_release: matroxfb_release, fb_get_fix: matroxfb_get_fix, fb_get_var: matroxfb_get_var, fb_set_var: matroxfb_set_var, fb_get_cmap: matroxfb_get_cmap, fb_set_cmap: matroxfb_set_cmap, fb_pan_display: matroxfb_pan_display, fb_ioctl: matroxfb_ioctl,};int matroxfb_switch(int con, struct fb_info *info){#define minfo (list_entry(info, struct matrox_fb_info, fbcon)) struct fb_cmap* cmap; struct display *p; DBG("matroxfb_switch"); if (ACCESS_FBINFO(currcon) >= 0) { /* Do we have to save the colormap? */ cmap = &(ACCESS_FBINFO(currcon_display)->cmap); dprintk(KERN_DEBUG "switch1: con = %d, cmap.len = %d\n", ACCESS_FBINFO(currcon), cmap->len); if (cmap->len) { dprintk(KERN_DEBUG "switch1a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp); fb_get_cmap(cmap, 1, matrox_getcolreg, info);#ifdef DEBUG if (cmap->red) { dprintk(KERN_DEBUG "switch1r: %X\n", cmap->red[0]); }#endif } } ACCESS_FBINFO(currcon) = con; if (con < 0) p = ACCESS_FBINFO(fbcon.disp); else p = fb_display + con; ACCESS_FBINFO(currcon_display) = p; p->var.activate = FB_ACTIVATE_NOW;#ifdef DEBUG cmap = &p->cmap; dprintk(KERN_DEBUG "switch2: con = %d, cmap.len = %d\n", con, cmap->len); dprintk(KERN_DEBUG "switch2a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp); if (p->cmap.red) { dprintk(KERN_DEBUG "switch2r: %X\n", cmap->red[0]); }#endif matroxfb_set_var(&p->var, con, info);#ifdef DEBUG dprintk(KERN_DEBUG "switch3: con = %d, cmap.len = %d\n", con, cmap->len); dprintk(KERN_DEBUG "switch3a: %p %p %p %p\n", cmap->red, cmap->green, cmap->blue, cmap->transp); if (p->cmap.red) { dprintk(KERN_DEBUG "switch3r: %X\n", cmap->red[0]); }#endif return 0;#undef minfo}#define RSDepth(X) (((X) >> 8) & 0x0F)#define RS8bpp 0x1#define RS15bpp 0x2#define RS16bpp 0x3#define RS32bpp 0x4#define RS4bpp 0x5#define RS24bpp 0x6#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_DUALHEAD 0x0008#define DEVF_CROSS4MB 0x0010#define DEVF_TEXT4B 0x0020/* #define DEVF_recycled 0x0040 *//* #define DEVF_recycled 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)#define DEVF_G2CORE (DEVF_GCORE | DEVF_ANY_VXRES | DEVF_MAVEN_CAPABLE | DEVF_PANELLINK_CAPABLE | DEVF_SRCORG | DEVF_DUALHEAD)#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 | DEVF_DUALHEAD)#define DEVF_G550 (DEVF_G450)static struct board { unsigned short vendor, device, rev, svid, sid; unsigned int flags; unsigned int maxclk; enum mga_chip chip; 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,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -