📄 mga4xx.c
字号:
/* Philippe Anel <philippe.anel@noos.fr> - 2001-08-12 : First release. - 2001-08-15 : Added G450, with source code "adapted from" from Xfree86 4.1.0 - 2001-08-23 : Added 'palettedepth 8' and a few 'ultradebug' ... - 2001-08-24 : Removed a possible lock in initialization. - 2001-08-30 : Hey ! The 32 bits mode is PALETIZED (Gamma Control I presume) ! And it seems plan9 assume the frame buffer is organized in Big Endian format ! (+ Fix for the palette init. ) - 2001-09-06 : Added Full 2D Accel ! (see drivers in /sys/src/9/pc) - 2001-10-01 : Rid Fix. - 2006-04-01 : Add MGA550 support. - 2006-08-07 : Add support for 16 and 24bits modes. HW accel now works for the G200 cards too (see kernel). by Leonardo Valencia <leoval@anixcorp.com> Greets and Acknowledgements go to : - Sylvain Chipaux <a.k.a. asle>. - Nigel Roles. - Jean Mehat (the man who introduced me into the world of plan9). - Nicolas Stojanovic. ... and for those who wrote plan9 of course ... :)*/ #include <u.h>#include <libc.h>#include <bio.h>#include "pci.h"#include "vga.h"static int ultradebug = 0;/* * Matrox G4xx 3D graphics accelerators */enum { Kilo = 1024, Meg = 1024*1024, MATROX = 0x102B, /* pci chip manufacturer */ MGA550 = 0x2527, /* pci chip device ids */ MGA4XX = 0x0525, MGA200 = 0x0521, /* Pci configuration space mapping */ PCfgMgaFBAA = 0x10, /* Frame buffer Aperture Address */ PCfgMgaCAA = 0x14, /* Control Aperture Address base */ PCfgMgaIAA = 0x18, /* ILOAD Aperture base Address */ PCfgMgaOption1 = 0x40, /* Option Register 1 */ PCfgMgaOption2 = 0x50, /* Option Register 2 */ PCfgMgaOption3 = 0x54, /* Option Register 3 */ PCfgMgaDevCtrl = 0x04, /* Device Control */ /* control aperture offsets */ DMAWIN = 0x0000, /* 7KByte Pseudo-DMA Window */ STATUS0 = 0x1FC2, /* Input Status 0 */ STATUS1 = 0x1FDA, /* Input Status 1 */ SEQIDX = 0x1FC4, /* Sequencer Index */ SEQDATA = 0x1FC5, /* Sequencer Data */ MISC_W = 0x1FC2, /* Misc. WO */ MISC_R = 0x1FCC, /* Misc. RO */ GCTLIDX = 0x1FCE, /* Graphic Controler Index */ GCTLDATA = 0x1FCF, /* Graphic Controler Data */ CRTCIDX = 0x1FD4, /* CRTC Index */ CRTCDATA = 0x1FD5, /* CRTC Data */ CRTCEXTIDX = 0x1FDE, /* CRTC Extension Index */ CRTCEXTDATA = 0x1FDF, /* CRTC Extension Data */ RAMDACIDX = 0x3C00, /* RAMDAC registers Index */ RAMDACDATA = 0x3C0A, /* RAMDAC Indexed Data */ RAMDACPALDATA = 0x3C01, ATTRIDX = 0x1FC0, /* Attribute Index */ ATTRDATA = 0x1FC1, /* Attribute Data */ CACHEFLUSH = 0x1FFF, C2_CTL = 0X3C10, MGA_STATUS = 0X1E14, Z_DEPTH_ORG = 0X1C0C, /* ... */ Seq_ClockingMode = 0x01, Dotmode = (1<<0), Shftldrt = (1<<2), Dotclkrt = (1<<3), Shiftfour = (1<<4), Scroff = (1<<5), CrtcExt_Horizontcount = 0x01, Htotal = (1<<0), Hblkstr = (1<<1), Hsyncstr = (1<<2), Hrsten = (1<<3), Hsyncoff = (1<<4), Vsyncoff = (1<<5), Hblkend = (1<<6), Vrsten = (1<<7), CrtcExt_Miscellaneous = 0x03, Mgamode = (1<<7), Dac_Xpixclkctrl = 0x1a, Pixclksl = (3<<0), Pixclkdis = (1<<2), Pixpllpdn = (1<<3), Dac_Xpixpllstat = 0x4f, Pixlock = (1<<6), Dac_Xpixpllan = 0x45, Dac_Xpixpllbn = 0x49, Dac_Xpixpllcn = 0x4d, Dac_Xpixpllam = 0x44, Dac_Xpixpllbm = 0x48, Dac_Xpixpllcm = 0x4c, Dac_Xpixpllap = 0x46, Dac_Xpixpllbp = 0x4a, Dac_Xpixpllcp = 0x4e, Dac_Xmulctrl = 0x19, ColorDepth = (7<<0), _8bitsPerPixel = 0, _15bitsPerPixel = 1, _16bitsPerPixel = 2, _24bitsPerPixel = 3, _32bitsPerPixelWithOv = 4, _32bitsPerPixel = 7, Dac_Xpanelmode = 0x1f, Dac_Xmiscctrl = 0x1e, Dacpdn = (1<<0), Mfcsel = (3<<1), Vga8dac = (1<<3), Ramcs = (1<<4), Vdoutsel = (7<<5), Dac_Xcurctrl = 0x06, CursorDis = 0, Cursor3Color = 1, CursorXGA = 2, CursorX11 = 3, Cursor16Color = 4, Dac_Xzoomctrl = 0x38, Misc_loaddsel = (1<<0), Misc_rammapen = (1<<1), Misc_clksel = (3<<2), Misc_videodis = (1<<4), Misc_hpgoddev = (1<<5), Misc_hsyncpol = (1<<6), Misc_vsyncpol = (1<<7), MNP_TABLE_SIZE = 64, TRUE = (1 == 1), FALSE = (1 == 0),};typedef struct { Pcidev* pci; int devid; int revid; uchar* mmio; uchar* mmfb; int fbsize; ulong iload; uchar syspll_m; uchar syspll_n; uchar syspll_p; uchar syspll_s; uchar pixpll_m; uchar pixpll_n; uchar pixpll_p; uchar pixpll_s; ulong option1; ulong option2; ulong option3; ulong Fneeded; /* From plan9.ini ... later */ uchar sdram; uchar colorkey; uchar maskkey; ulong maxpclk; uchar graphics[9]; uchar attribute[0x14]; uchar sequencer[5]; uchar crtc[0x19]; uchar crtcext[9]; ulong htotal; ulong hdispend; ulong hblkstr; ulong hblkend; ulong hsyncstr; ulong hsyncend; ulong vtotal; ulong vdispend; ulong vblkstr; ulong vblkend; ulong vsyncstr; ulong vsyncend; ulong linecomp; ulong hsyncsel; ulong startadd; ulong offset; ulong maxscan; ulong curloc; ulong prowscan; ulong currowstr; ulong currowend; ulong curoff; ulong undrow; ulong curskew; ulong conv2t4; ulong interlace; ulong hsyncdel; ulong hdispskew; ulong bytepan; ulong dotclkrt; ulong dword; ulong wbmode; ulong addwrap; ulong selrowscan; ulong cms; ulong csynccen; ulong hrsten; ulong vrsten; ulong vinten; ulong vintclr; ulong hsyncoff; ulong vsyncoff; ulong crtcrstN; ulong mgamode; ulong scale; ulong hiprilvl; ulong maxhipri; ulong c2hiprilvl; ulong c2maxhipri; ulong misc; ulong crtcprotect; ulong winsize; ulong winfreq; ulong mgaapsize;} Mga;static voidmgawrite32(Mga* mga, int index, ulong val){ ((ulong*)mga->mmio)[index] = val;}static ulongmgaread32(Mga* mga, int index){ return ((ulong*)mga->mmio)[index];}static voidmgawrite8(Mga* mga, int index, uchar val){ mga->mmio[index] = val;}static ucharmgaread8(Mga* mga, int index){ return mga->mmio[index];}static ucharseqget(Mga* mga, int index){ mgawrite8(mga, SEQIDX, index); return mgaread8(mga, SEQDATA);}static ucharseqset(Mga* mga, int index, uchar set, uchar clr){ uchar tmp; mgawrite8(mga, SEQIDX, index); tmp = mgaread8(mga, SEQDATA); mgawrite8(mga, SEQIDX, index); mgawrite8(mga, SEQDATA, (tmp & ~clr) | set); return tmp;}static ucharcrtcget(Mga* mga, int index){ mgawrite8(mga, CRTCIDX, index); return mgaread8(mga, CRTCDATA);}static ucharcrtcset(Mga* mga, int index, uchar set, uchar clr){ uchar tmp; mgawrite8(mga, CRTCIDX, index); tmp = mgaread8(mga, CRTCDATA); mgawrite8(mga, CRTCIDX, index); mgawrite8(mga, CRTCDATA, (tmp & ~clr) | set); return tmp;}static ucharcrtcextget(Mga* mga, int index){ mgawrite8(mga, CRTCEXTIDX, index); return mgaread8(mga, CRTCEXTDATA);}static ucharcrtcextset(Mga* mga, int index, uchar set, uchar clr){ uchar tmp; mgawrite8(mga, CRTCEXTIDX, index); tmp = mgaread8(mga, CRTCEXTDATA); mgawrite8(mga, CRTCEXTIDX, index); mgawrite8(mga, CRTCEXTDATA, (tmp & ~clr) | set); return tmp;}static uchardacget(Mga* mga, int index){ mgawrite8(mga, RAMDACIDX, index); return mgaread8(mga, RAMDACDATA);}static uchardacset(Mga* mga, int index, uchar set, uchar clr){ uchar tmp; mgawrite8(mga, RAMDACIDX, index); tmp = mgaread8(mga, RAMDACDATA); mgawrite8(mga, RAMDACIDX, index); mgawrite8(mga, RAMDACDATA, (tmp & ~clr) | set); return tmp;}static uchargctlget(Mga* mga, int index){ mgawrite8(mga, GCTLIDX, index); return mgaread8(mga, GCTLDATA);}static uchargctlset(Mga* mga, int index, uchar set, uchar clr){ uchar tmp; mgawrite8(mga, GCTLIDX, index); tmp = mgaread8(mga, GCTLDATA); mgawrite8(mga, GCTLIDX, index); mgawrite8(mga, GCTLDATA, (tmp & ~clr) | set); return tmp;}static ucharattrget(Mga* mga, int index){ mgawrite8(mga, ATTRIDX, index); return mgaread8(mga, ATTRDATA);}static ucharattrset(Mga* mga, int index, uchar set, uchar clr){ uchar tmp; mgawrite8(mga, ATTRIDX, index); tmp = mgaread8(mga, ATTRDATA); mgawrite8(mga, ATTRIDX, index); mgawrite8(mga, ATTRDATA, (tmp & ~clr) | set); return tmp;}static ucharmiscget(Mga* mga){ return mgaread8(mga, MISC_R);}static ucharmiscset(Mga* mga, uchar set, uchar clr){ uchar tmp; tmp = mgaread8(mga, MISC_R); mgawrite8(mga, MISC_W, (tmp & ~clr) | set); return tmp;}/* ************************************************************ */static voiddump_all_regs(Mga* mga){ int i; for (i = 0; i < 25; i++) trace("crtc[%d] = 0x%x\n", i, crtcget(mga, i)); for (i = 0; i < 9; i++) trace("crtcext[%d] = 0x%x\n", i, crtcextget(mga, i)); for (i = 0; i < 5; i++) trace("seq[%d] = 0x%x\n", i, seqget(mga, i)); for (i = 0; i < 9; i++) trace("gctl[%d] = 0x%x\n", i, gctlget(mga, i)); trace("misc = 0x%x\n", mgaread8(mga, MISC_R)); for (i = 0; i < 0x87; i++) trace("dac[%d] = 0x%x\n", i, dacget(mga, i));}/* ************************************************************ */static voiddump(Vga* vga, Ctlr* ctlr){ dump_all_regs(vga->private); ctlr->flag |= Fdump;}static voidsetpalettedepth(int depth){ int fd; char *cmd = strdup("palettedepth X"); if ((depth != 8) && (depth != 6) && (depth != 16)) error("mga: invalid palette depth %d\n", depth); fd = open("#v/vgactl", OWRITE); if(fd < 0) error("mga: can't open vgactl\n"); cmd[13] = '0' + depth; if(write(fd, cmd, 14) != 14) error("mga: can't set palette depth to %d\n", depth); close(fd);}static voidmapmga4xx(Vga* vga, Ctlr* ctlr){ int f; uchar* m; Mga * mga; if(vga->private == nil) error("%s: g4xxio: no *mga4xx\n", ctlr->name); mga = vga->private; f = open("#v/vgactl", OWRITE); if(f < 0) error("%s: can't open vgactl\n", ctlr->name); if(write(f, "type mga4xx", 11) != 11) error("%s: can't set mga type\n", ctlr->name); m = segattach(0, "mga4xxmmio", 0, 16*Kilo); if(m == (void*)-1) error("%s: can't attach mga4xxmmio segment\n", ctlr->name); mga->mmio = m; trace("%s: mmio at %#p\n", ctlr->name, mga->mmio); m = segattach(0, "mga4xxscreen", 0, 32*Meg); if(m == (void*)-1) { mga->mgaapsize = 8*Meg; m = segattach(0, "mga4xxscreen", 0, 8*Meg); if(m == (void*)-1) error("%s: can't attach mga4xxscreen segment\n", ctlr->name); } else { mga->mgaapsize = 32*Meg; } mga->mmfb = m; trace("%s: frame buffer at %#p\n", ctlr->name, mga->mmfb); close(f);}static voidsnarf(Vga* vga, Ctlr* ctlr){ int i, k, n; uchar * p; uchar x[16]; Pcidev * pci; Mga * mga; uchar crtcext3; uchar rid; trace("%s->snarf\n", ctlr->name); if(vga->private == nil) { pci = pcimatch(nil, MATROX, MGA4XX); if(pci == nil) pci = pcimatch(nil, MATROX, MGA550); if(pci == nil) pci = pcimatch(nil, MATROX, MGA200); if(pci == nil) error("%s: cannot find matrox adapter\n", ctlr->name); rid = pcicfgr8(pci, PciRID); // PciRID = 0x08 trace("%s: G%d%d0 rev %d\n", ctlr->name, 2*(pci->did==MGA200) +4*(pci->did==MGA4XX) +5*(pci->did==MGA550), rid&0x80 ? 5 : 0, rid&~0x80); i = pcicfgr32(pci, PCfgMgaDevCtrl); if ((i & 2) != 2) error("%s: Memory Space not enabled ... Aborting ...\n", ctlr->name); vga->private = alloc(sizeof(Mga)); mga = (Mga*)vga->private; mga->devid = pci->did; mga->revid = rid; mga->pci = pci; mapmga4xx(vga, ctlr); } else { mga = (Mga*)vga->private; } /* Find out how much memory is here, some multiple of 2Meg */ /* First Set MGA Mode ... */ crtcext3 = crtcextset(mga, 3, 0x80, 0x00); p = mga->mmfb; n = (mga->mgaapsize / Meg) / 2;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -