12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634 |
- /* 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.
- 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 void
- mgawrite32(Mga* mga, int index, ulong val)
- {
- ((ulong*)mga->mmio)[index] = val;
- }
- static ulong
- mgaread32(Mga* mga, int index)
- {
- return ((ulong*)mga->mmio)[index];
- }
- static void
- mgawrite8(Mga* mga, int index, uchar val)
- {
- mga->mmio[index] = val;
- }
- static uchar
- mgaread8(Mga* mga, int index)
- {
- return mga->mmio[index];
- }
- static uchar
- seqget(Mga* mga, int index)
- {
- mgawrite8(mga, SEQIDX, index);
- return mgaread8(mga, SEQDATA);
- }
- static uchar
- seqset(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 uchar
- crtcget(Mga* mga, int index)
- {
- mgawrite8(mga, CRTCIDX, index);
- return mgaread8(mga, CRTCDATA);
- }
- static uchar
- crtcset(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 uchar
- crtcextget(Mga* mga, int index)
- {
- mgawrite8(mga, CRTCEXTIDX, index);
- return mgaread8(mga, CRTCEXTDATA);
- }
- static uchar
- crtcextset(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 uchar
- dacget(Mga* mga, int index)
- {
- mgawrite8(mga, RAMDACIDX, index);
- return mgaread8(mga, RAMDACDATA);
- }
- static uchar
- dacset(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 uchar
- gctlget(Mga* mga, int index)
- {
- mgawrite8(mga, GCTLIDX, index);
- return mgaread8(mga, GCTLDATA);
- }
- static uchar
- gctlset(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 uchar
- attrget(Mga* mga, int index)
- {
- mgawrite8(mga, ATTRIDX, index);
- return mgaread8(mga, ATTRDATA);
- }
- static uchar
- attrset(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 uchar
- miscget(Mga* mga)
- {
- return mgaread8(mga, MISC_R);
- }
- static uchar
- miscset(Mga* mga, uchar set, uchar clr)
- {
- uchar tmp;
- tmp = mgaread8(mga, MISC_R);
- mgawrite8(mga, MISC_W, (tmp & ~clr) | set);
- return tmp;
- }
- /* ************************************************************ */
- static void
- dump_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 void
- dump(Vga* vga, Ctlr* ctlr)
- {
- dump_all_regs(vga->private);
- ctlr->flag |= Fdump;
- }
- static void
- setpalettedepth(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 void
- mapmga4xx(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 void
- snarf(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;
- for (i = 0; i < n; i++) {
- k = (2*i+1)*Meg;
- p[k] = 0;
- p[k] = i+1;
- *(mga->mmio + CACHEFLUSH) = 0;
- x[i] = p[k];
- trace("x[%d]=%d\n", i, x[i]);
- }
- for(i = 1; i < n; i++)
- if(x[i] != i+1)
- break;
- vga->vmz = mga->fbsize = 2*i*Meg;
- trace("probe found %d megabytes\n", 2*i);
- crtcextset(mga, 3, crtcext3, 0xff);
- ctlr->flag |= Fsnarf;
- }
- static void
- options(Vga* vga, Ctlr* ctlr)
- {
- if(vga->virtx & 127)
- vga->virtx = (vga->virtx+127)&~127;
- ctlr->flag |= Foptions;
- }
- /* ************************************************************ */
- static void
- G450ApplyPFactor(Mga*, uchar ucP, ulong *pulFIn)
- {
- if(!(ucP & 0x40))
- {
- *pulFIn = *pulFIn / (2L << (ucP & 3));
- }
- }
- static void
- G450RemovePFactor(Mga*, uchar ucP, ulong *pulFIn)
- {
- if(!(ucP & 0x40))
- {
- *pulFIn = *pulFIn * (2L << (ucP & 3));
- }
- }
- static void
- G450CalculVCO(Mga*, ulong ulMNP, ulong *pulF)
- {
- uchar ucM, ucN;
- ucM = (uchar)((ulMNP >> 16) & 0xff);
- ucN = (uchar)((ulMNP >> 8) & 0xff);
- *pulF = (27000 * (2 * (ucN + 2)) + ((ucM + 1) >> 1)) / (ucM + 1);
- trace("G450CalculVCO: ulMNP %lx, pulF %ld\n", ulMNP, *pulF);
- }
- static void
- G450CalculDeltaFreq(Mga*, ulong ulF1, ulong ulF2, ulong *pulDelta)
- {
- if(ulF2 < ulF1)
- {
- *pulDelta = ((ulF1 - ulF2) * 1000) / ulF1;
- }
- else
- {
- *pulDelta = ((ulF2 - ulF1) * 1000) / ulF1;
- }
- trace("G450CalculDeltaFreq: ulF1 %ld, ulF2 %ld, pulDelta %ld\n", ulF1, ulF2, *pulDelta);
- }
- static void
- G450FindNextPLLParam(Mga* mga, ulong ulFout, ulong *pulPLLMNP)
- {
- uchar ucM, ucN, ucP, ucS;
- ulong ulVCO, ulVCOMin;
- ucM = (uchar)((*pulPLLMNP >> 16) & 0xff);
- /* ucN = (uchar)((*pulPLLMNP >> 8) & 0xff); */
- ucP = (uchar)(*pulPLLMNP & 0x43);
- ulVCOMin = 256000;
- if(ulVCOMin >= (255L * 8000))
- {
- ulVCOMin = 230000;
- }
-
- if((ucM == 9) && (ucP & 0x40))
- {
- *pulPLLMNP = 0xffffffff;
- } else if (ucM == 9)
- {
- if(ucP)
- {
- ucP--;
- }
- else
- {
- ucP = 0x40;
- }
- ucM = 0;
- }
- else
- {
- ucM++;
- }
- ulVCO = ulFout;
- G450RemovePFactor(mga, ucP, &ulVCO);
- if(ulVCO < ulVCOMin)
- {
- *pulPLLMNP = 0xffffffff;
- }
- if(*pulPLLMNP != 0xffffffff)
- {
- ucN = (uchar)(((ulVCO * (ucM+1) + 27000)/(27000 * 2)) - 2);
- ucS = 5;
- if(ulVCO < 1300000) ucS = 4;
- if(ulVCO < 1100000) ucS = 3;
- if(ulVCO < 900000) ucS = 2;
- if(ulVCO < 700000) ucS = 1;
- if(ulVCO < 550000) ucS = 0;
- ucP |= (uchar)(ucS << 3);
- *pulPLLMNP &= 0xff000000;
- *pulPLLMNP |= (ulong)ucM << 16;
- *pulPLLMNP |= (ulong)ucN << 8;
- *pulPLLMNP |= (ulong)ucP;
- }
- }
-
- static void
- G450FindFirstPLLParam(Mga* mga, ulong ulFout, ulong *pulPLLMNP)
- {
- uchar ucP;
- ulong ulVCO;
- ulong ulVCOMax;
- /* Default value */
- ulVCOMax = 1300000;
- if(ulFout > (ulVCOMax/2))
- {
- ucP = 0x40;
- ulVCO = ulFout;
- }
- else
- {
- ucP = 3;
- ulVCO = ulFout;
- G450RemovePFactor(mga, ucP, &ulVCO);
- while(ucP && (ulVCO > ulVCOMax))
- {
- ucP--;
- ulVCO = ulFout;
- G450RemovePFactor(mga, ucP, &ulVCO);
- }
- }
- if(ulVCO > ulVCOMax)
- {
- *pulPLLMNP = 0xffffffff;
- }
- else
- {
- /* Pixel clock: 1 */
- *pulPLLMNP = (1 << 24) + 0xff0000 + ucP;
- G450FindNextPLLParam(mga, ulFout, pulPLLMNP);
- }
- }
- static void
- G450WriteMNP(Mga* mga, ulong ulMNP)
- {
- if (0) trace("G450WriteMNP : 0x%lx\n", ulMNP);
- dacset(mga, Dac_Xpixpllcm, (uchar)(ulMNP >> 16), 0xff);
- dacset(mga, Dac_Xpixpllcn, (uchar)(ulMNP >> 8), 0xff);
- dacset(mga, Dac_Xpixpllcp, (uchar)ulMNP, 0xff);
- }
- static void
- G450CompareMNP(Mga* mga, ulong ulFout, ulong ulMNP1,
- ulong ulMNP2, long *pulResult)
- {
- ulong ulFreq, ulDelta1, ulDelta2;
- G450CalculVCO(mga, ulMNP1, &ulFreq);
- G450ApplyPFactor(mga, (uchar) ulMNP1, &ulFreq);
- G450CalculDeltaFreq(mga, ulFout, ulFreq, &ulDelta1);
- G450CalculVCO(mga, ulMNP2, &ulFreq);
- G450ApplyPFactor(mga, (uchar) ulMNP2, &ulFreq);
- G450CalculDeltaFreq(mga, ulFout, ulFreq, &ulDelta2);
- if(ulDelta1 < ulDelta2)
- {
- *pulResult = -1;
- }
- else if(ulDelta1 > ulDelta2)
- {
- *pulResult = 1;
- }
- else
- {
- *pulResult = 0;
- }
- if((ulDelta1 <= 5) && (ulDelta2 <= 5))
- {
- if((ulMNP1 & 0xff0000) < (ulMNP2 & 0xff0000))
- {
- *pulResult = -1;
- }
- else if((ulMNP1 & 0xff0000) > (ulMNP2 & 0xff0000))
- {
- *pulResult = 1;
- }
- }
- }
- static void
- G450IsPllLocked(Mga* mga, int *lpbLocked)
- {
- ulong ulFallBackCounter, ulLockCount, ulCount;
- uchar ucPLLStatus;
- /* Pixel PLL */
- mgawrite8(mga, 0x3c00, 0x4f);
- ulFallBackCounter = 0;
- do
- {
- ucPLLStatus = mgaread8(mga, 0x3c0a);
- if (0) trace("ucPLLStatus[1] : 0x%x\n", ucPLLStatus);
- ulFallBackCounter++;
- } while(!(ucPLLStatus & 0x40) && (ulFallBackCounter < 1000));
- ulLockCount = 0;
- if(ulFallBackCounter < 1000)
- {
- for(ulCount = 0; ulCount < 100; ulCount++)
- {
- ucPLLStatus = mgaread8(mga, 0x3c0a);
- if (0) trace("ucPLLStatus[2] : 0x%x\n", ucPLLStatus);
- if(ucPLLStatus & 0x40)
- {
- ulLockCount++;
- }
- }
- }
- *lpbLocked = ulLockCount >= 90;
- }
- static void
- G450SetPLLFreq(Mga* mga, long f_out)
- {
- int bFoundValidPLL;
- int bLocked;
- ulong ulMaxIndex;
- ulong ulMNP;
- ulong ulMNPTable[MNP_TABLE_SIZE];
- ulong ulIndex;
- ulong ulTryMNP;
- long lCompareResult;
- trace("f_out : %ld\n", f_out);
- G450FindFirstPLLParam(mga, f_out, &ulMNP);
- ulMNPTable[0] = ulMNP;
- G450FindNextPLLParam(mga, f_out, &ulMNP);
- ulMaxIndex = 1;
- while(ulMNP != 0xffffffff)
- {
- int ulIndex;
- int bSkipValue;
- bSkipValue = FALSE;
- if(ulMaxIndex == MNP_TABLE_SIZE)
- {
- G450CompareMNP(mga, f_out, ulMNP, ulMNPTable[MNP_TABLE_SIZE - 1],
- &lCompareResult);
- if(lCompareResult > 0)
- {
- bSkipValue = TRUE;
- }
- else
- {
- ulMaxIndex--;
- }
- }
- if(!bSkipValue)
- {
- for(ulIndex = ulMaxIndex; !bSkipValue && (ulIndex > 0); ulIndex--)
- {
- G450CompareMNP(mga, f_out, ulMNP, ulMNPTable[ulIndex - 1],
- &lCompareResult);
- if(lCompareResult < 0)
- {
- ulMNPTable[ulIndex] = ulMNPTable[ulIndex - 1];
- }
- else
- {
- break;
- }
- }
- ulMNPTable[ulIndex] = ulMNP;
- ulMaxIndex++;
- }
- G450FindNextPLLParam(mga, f_out, &ulMNP);
- }
- bFoundValidPLL = FALSE;
- ulMNP = 0;
- for(ulIndex = 0; !bFoundValidPLL && (ulIndex < ulMaxIndex); ulIndex++)
- {
- ulTryMNP = ulMNPTable[ulIndex];
- {
- bLocked = TRUE;
- if((ulMNPTable[ulIndex] & 0xff00) < 0x300 ||
- (ulMNPTable[ulIndex] & 0xff00) > 0x7a00)
- {
- bLocked = FALSE;
- }
- if(bLocked)
- {
- G450WriteMNP(mga, ulTryMNP - 0x300);
- G450IsPllLocked(mga, &bLocked);
- }
- if(bLocked)
- {
- G450WriteMNP(mga, ulTryMNP + 0x300);
- G450IsPllLocked(mga, &bLocked);
- }
- if(bLocked)
- {
- G450WriteMNP(mga, ulTryMNP - 0x200);
- G450IsPllLocked(mga, &bLocked);
- }
- if(bLocked)
- {
- G450WriteMNP(mga, ulTryMNP + 0x200);
- G450IsPllLocked(mga, &bLocked);
- }
- if(bLocked)
- {
- G450WriteMNP(mga, ulTryMNP - 0x100);
- G450IsPllLocked(mga, &bLocked);
- }
- if(bLocked)
- {
- G450WriteMNP(mga, ulTryMNP + 0x100);
- G450IsPllLocked(mga, &bLocked);
- }
- if(bLocked)
- {
- G450WriteMNP(mga, ulTryMNP);
- G450IsPllLocked(mga, &bLocked);
- }
- else if(!ulMNP)
- {
- G450WriteMNP(mga, ulTryMNP);
- G450IsPllLocked(mga, &bLocked);
- if(bLocked)
- {
- ulMNP = ulMNPTable[ulIndex];
- }
- bLocked = FALSE;
- }
- if(bLocked)
- {
- bFoundValidPLL = TRUE;
- }
- }
- }
- if(!bFoundValidPLL)
- {
- if(ulMNP)
- {
- G450WriteMNP(mga, ulMNP);
- }
- else
- {
- G450WriteMNP(mga, ulMNPTable[0]);
- }
- }
- }
- /* ************************************************************ */
- /*
- calcclock - Calculate the PLL settings (m, n, p, s).
- */
- static double
- g400_calcclock(Mga* mga, long Fneeded)
- {
- double Fpll;
- double Fvco;
- double Fref;
- int pixpll_m_min;
- int pixpll_m_max;
- int pixpll_n_min;
- int pixpll_n_max;
- int pixpll_p_max;
- double Ferr, Fcalc;
- int m, n, p;
-
- if (mga->devid == MGA4XX || mga->devid == MGA550) {
- /* These values are taken from Matrox G400 Specification - p 4-91 */
- Fref = 27000000.0;
- pixpll_n_min = 7;
- pixpll_n_max = 127;
- pixpll_m_min = 1;
- pixpll_m_max = 31;
- pixpll_p_max = 7;
- } else { /* MGA200 */
- /* These values are taken from Matrox G200 Specification - p 4-77 */
- //Fref = 14318180.0;
- Fref = 27050500.0;
- pixpll_n_min = 7;
- pixpll_n_max = 127;
- pixpll_m_min = 1;
- pixpll_m_max = 6;
- pixpll_p_max = 7;
- }
- Fvco = ( double ) Fneeded;
- for (p = 0; p <= pixpll_p_max && Fvco < mga->maxpclk; p = p * 2 + 1, Fvco *= 2.0)
- ;
- mga->pixpll_p = p;
- Ferr = Fneeded;
- for ( m = pixpll_m_min ; m <= pixpll_m_max ; m++ )
- for ( n = pixpll_n_min; n <= pixpll_n_max; n++ )
- {
- Fcalc = Fref * (n + 1) / (m + 1) ;
- /*
- * Pick the closest frequency.
- */
- if ( labs(Fcalc - Fvco) < Ferr ) {
- Ferr = abs(Fcalc - Fvco);
- mga->pixpll_m = m;
- mga->pixpll_n = n;
- }
- }
-
- Fvco = Fref * (mga->pixpll_n + 1) / (mga->pixpll_m + 1);
- if (mga->devid == MGA4XX || mga->devid == MGA550) {
- if ( (50000000.0 <= Fvco) && (Fvco < 110000000.0) )
- mga->pixpll_p |= 0;
- if ( (110000000.0 <= Fvco) && (Fvco < 170000000.0) )
- mga->pixpll_p |= (1<<3);
- if ( (170000000.0 <= Fvco) && (Fvco < 240000000.0) )
- mga->pixpll_p |= (2<<3);
- if ( (300000000.0 <= Fvco) )
- mga->pixpll_p |= (3<<3);
- } else {
- if ( (50000000.0 <= Fvco) && (Fvco < 100000000.0) )
- mga->pixpll_p |= 0;
- if ( (100000000.0 <= Fvco) && (Fvco < 140000000.0) )
- mga->pixpll_p |= (1<<3);
- if ( (140000000.0 <= Fvco) && (Fvco < 180000000.0) )
- mga->pixpll_p |= (2<<3);
- if ( (250000000.0 <= Fvco) )
- mga->pixpll_p |= (3<<3);
- }
-
- Fpll = Fvco / (p + 1);
- return Fpll;
- }
- /* ************************************************************ */
- static void
- init(Vga* vga, Ctlr* ctlr)
- {
- Mode* mode;
- Mga* mga;
- double Fpll;
- Ctlr* c;
- int i;
- ulong t;
- mga = vga->private;
- mode = vga->mode;
- trace("mga mmio at %#p\n", mga->mmio);
- ctlr->flag |= Ulinear;
- if ((mode->z != 32) && (mode->z != 8))
- error("depth %d not supported !\n", mode->z);
- if (mode->interlace)
- error("interlaced mode not supported !\n");
- trace("%s: Initializing mode %dx%dx%d on %s\n", ctlr->name, mode->x, mode->y, mode->z, mode->type);
- trace("%s: Suggested Dot Clock : %d\n", ctlr->name, mode->frequency);
- trace("%s: Horizontal Total = %d\n", ctlr->name, mode->ht);
- trace("%s: Start Horizontal Blank = %d\n", ctlr->name, mode->shb);
- trace("%s: End Horizontal Blank = %d\n", ctlr->name, mode->ehb);
- trace("%s: Vertical Total = %d\n", ctlr->name, mode->vt);
- trace("%s: Vertical Retrace Start = %d\n", ctlr->name, mode->vrs);
- trace("%s: Vertical Retrace End = %d\n", ctlr->name, mode->vre);
- trace("%s: Start Horizontal Sync = %d\n", ctlr->name, mode->shs);
- trace("%s: End Horizontal Sync = %d\n", ctlr->name, mode->ehs);
- trace("%s: HSync = %c\n", ctlr->name, mode->hsync);
- trace("%s: VSync = %c\n", ctlr->name, mode->vsync);
- trace("%s: Interlace = %d\n", ctlr->name, mode->interlace);
- /* TODO : G400 Max : 360000000 */
- if (mga->devid == MGA4XX || mga->devid == MGA550)
- mga->maxpclk = 300000000;
- else
- mga->maxpclk = 250000000;
- if (mode->frequency < 50000)
- error("mga: Too little Frequency %d : Minimum supported by PLL is %d",
- mode->frequency, 50000);
- if (mode->frequency > mga->maxpclk)
- error("mga: Too big Frequency %d : Maximum supported by PLL is %ld",
- mode->frequency, mga->maxpclk);
-
- trace("mga: revision ID is %x\n", mga->revid);
- if ((mga->devid == MGA200) || ((mga->devid == MGA4XX) && (mga->revid & 0x80) == 0x00)) {
- /* Is it G200/G400 or G450 ? */
- Fpll = g400_calcclock(mga, mode->frequency);
- trace("Fpll set to %f\n", Fpll);
- trace("pixclks : n = %d m = %d p = %d\n", mga->pixpll_n, mga->pixpll_m, mga->pixpll_p & 0x7);
- } else
- mga->Fneeded = mode->frequency;
- trace("PCI Option1 = 0x%x\n", pcicfgr32(mga->pci, PCfgMgaOption1));
- trace("PCI Option2 = 0x%x\n", pcicfgr32(mga->pci, PCfgMgaOption2));
- trace("PCI Option3 = 0x%x\n", pcicfgr32(mga->pci, PCfgMgaOption3));
- mga->htotal = (mode->ht >> 3) - 5;
- mga->hdispend = (mode->x >> 3) - 1;
- mga->hblkstr = mga->hdispend; /* (mode->shb >> 3); */
- mga->hblkend = mga->htotal + 4; /* (mode->ehb >> 3); */
- mga->hsyncstr = (mode->shs >> 3) - 1; // Was (mode->shs >> 3);
- mga->hsyncend = (mode->ehs >> 3) - 1; // Was (mode->ehs >> 3);
- mga->hsyncdel = 0;
- mga->vtotal = mode->vt - 2;
- mga->vdispend = mode->y - 1;
- mga->vblkstr = mode->y - 1;
- mga->vblkend = mode->vt - 1;
- mga->vsyncstr = mode->vrs;
- mga->vsyncend = mode->vre;
- mga->linecomp = mode->y;
- mga->hsyncsel = 0; /* Do not double lines ... */
- mga->startadd = 0;
- mga->offset = (vga->virtx * mode->z) / 128;
- /* No Zoom */
- mga->maxscan = 0;
- /* Not used in Power Graphic mode */
- mga->curloc = 0;
- mga->prowscan = 0;
- mga->currowstr = 0;
- mga->currowend = 0;
- mga->curoff = 1;
- mga->undrow = 0;
- mga->curskew = 0;
- mga->conv2t4 = 0;
- mga->interlace = 0;
- mga->hdispskew = 0;
- mga->bytepan = 0;
- mga->dotclkrt = 0;
- mga->dword = 0;
- mga->wbmode = 1;
- mga->addwrap = 0; /* Not Used ! */
- mga->selrowscan = 1;
- mga->cms = 1;
- mga->csynccen = 0; /* Disable composite sync */
- /* VIDRST Pin */
- mga->hrsten = 0; // Was 1;
- mga->vrsten = 0; // Was 1;
- /* vertical interrupt control ... disabled */
- mga->vinten = 1;
- mga->vintclr = 0;
- /* Let [hv]sync run freely */
- mga->hsyncoff = 0;
- mga->vsyncoff = 0;
- mga->crtcrstN = 1;
- mga->mgamode = 1;
- mga->scale = (mode->z == 8) ? 0 : 3; /* 8 or 32 bits mode */
-
- mga->crtcprotect = 1;
- mga->winsize = 0;
- mga->winfreq = 0;
- if ((mga->htotal == 0)
- || (mga->hblkend <= (mga->hblkstr + 1))
- || ((mga->htotal - mga->hdispend) == 0)
- || ((mga->htotal - mga->bytepan + 2) <= mga->hdispend)
- || (mga->hsyncstr <= (mga->hdispend + 2))
- || (mga->vtotal == 0))
- {
- error("Invalid Power Graphic Mode :\n"
- "mga->htotal = %ld\n"
- "mga->hdispend = %ld\n"
- "mga->hblkstr = %ld\n"
- "mga->hblkend = %ld\n"
- "mga->hsyncstr = %ld\n"
- "mga->hsyncend = %ld\n"
- "mga->hsyncdel = %ld\n"
- "mga->vtotal = %ld\n"
- "mga->vdispend = %ld\n"
- "mga->vblkstr = %ld\n"
- "mga->vblkend = %ld\n"
- "mga->vsyncstr = %ld\n"
- "mga->vsyncend = %ld\n"
- "mga->linecomp = %ld\n",
- mga->htotal,
- mga->hdispend,
- mga->hblkstr,
- mga->hblkend,
- mga->hsyncstr,
- mga->hsyncend,
- mga->hsyncdel,
- mga->vtotal,
- mga->vdispend,
- mga->vblkstr,
- mga->vblkend,
- mga->vsyncstr,
- mga->vsyncend,
- mga->linecomp
- );
- }
- mga->hiprilvl = 0;
- mga->maxhipri = 0;
- mga->c2hiprilvl = 0;
- mga->c2maxhipri = 0;
- mga->misc = ((mode->hsync != '-')?0:(1<<6)) | ((mode->vsync != '-')?0:(1<<7));
- trace("mga->htotal = %ld\n"
- "mga->hdispend = %ld\n"
- "mga->hblkstr = %ld\n"
- "mga->hblkend = %ld\n"
- "mga->hsyncstr = %ld\n"
- "mga->hsyncend = %ld\n"
- "mga->hsyncdel = %ld\n"
- "mga->vtotal = %ld\n"
- "mga->vdispend = %ld\n"
- "mga->vblkstr = %ld\n"
- "mga->vblkend = %ld\n"
- "mga->vsyncstr = %ld\n"
- "mga->vsyncend = %ld\n"
- "mga->linecomp = %ld\n",
- mga->htotal,
- mga->hdispend,
- mga->hblkstr,
- mga->hblkend,
- mga->hsyncstr,
- mga->hsyncend,
- mga->hsyncdel,
- mga->vtotal,
- mga->vdispend,
- mga->vblkstr,
- mga->vblkend,
- mga->vsyncstr,
- mga->vsyncend,
- mga->linecomp
- );
- mga->crtc[0x00] = 0xff & mga->htotal;
- mga->crtc[0x01] = 0xff & mga->hdispend;
- mga->crtc[0x02] = 0xff & mga->hblkstr;
- mga->crtc[0x03] = (0x1f & mga->hblkend)
- | ((0x03 & mga->hdispskew) << 5)
- | 0x80 /* cf 3-304 */
- ;
- mga->crtc[0x04] = 0xff & mga->hsyncstr;
- mga->crtc[0x05] = (0x1f & mga->hsyncend)
- | ((0x03 & mga->hsyncdel) << 5)
- | ((0x01 & (mga->hblkend >> 5)) << 7)
- ;
- mga->crtc[0x06] = 0xff & mga->vtotal;
- t = ((0x01 & (mga->vtotal >> 8)) << 0)
- | ((0x01 & (mga->vdispend >> 8)) << 1)
- | ((0x01 & (mga->vsyncstr >> 8)) << 2)
- | ((0x01 & (mga->vblkstr >> 8)) << 3)
- | ((0x01 & (mga->linecomp >> 8)) << 4)
- | ((0x01 & (mga->vtotal >> 9)) << 5)
- | ((0x01 & (mga->vdispend >> 9)) << 6)
- | ((0x01 & (mga->vsyncstr >> 9)) << 7)
- ;
- mga->crtc[0x07] = 0xff & t;
- mga->crtc[0x08] = (0x1f & mga->prowscan)
- | ((0x03 & mga->bytepan) << 5)
- ;
- mga->crtc[0x09] = (0x1f & mga->maxscan)
- | ((0x01 & (mga->vblkstr >> 9)) << 5)
- | ((0x01 & (mga->linecomp >> 9)) << 6)
- | ((0x01 & mga->conv2t4) << 7)
- ;
- mga->crtc[0x0a] = (0x1f & mga->currowstr)
- | ((0x01 & mga->curoff) << 5)
- ;
- mga->crtc[0x0b] = (0x1f & mga->currowend)
- | ((0x03 & mga->curskew) << 5)
- ;
- mga->crtc[0x0c] = 0xff & (mga->startadd >> 8);
- mga->crtc[0x0d] = 0xff & mga->startadd;
- mga->crtc[0x0e] = 0xff & (mga->curloc >> 8);
- mga->crtc[0x0f] = 0xff & mga->curloc;
- mga->crtc[0x10] = 0xff & mga->vsyncstr;
- mga->crtc[0x11] = (0x0f & mga->vsyncend)
- | ((0x01 & mga->vintclr) << 4)
- | ((0x01 & mga->vinten) << 5)
- | ((0x01 & mga->crtcprotect) << 7)
- ;
- mga->crtc[0x12] = 0xff & mga->vdispend;
- mga->crtc[0x13] = 0xff & mga->offset;
- mga->crtc[0x14] = 0x1f & mga->undrow; /* vga only */
- mga->crtc[0x15] = 0xff & mga->vblkstr;
- mga->crtc[0x16] = 0xff & mga->vblkend;
- mga->crtc[0x17] = ((0x01 & mga->cms) << 0)
- | ((0x01 & mga->selrowscan) << 1)
- | ((0x01 & mga->hsyncsel) << 2)
- | ((0x01 & mga->addwrap) << 5)
- | ((0x01 & mga->wbmode) << 6)
- | ((0x01 & mga->crtcrstN) << 7)
- ;
- mga->crtc[0x18] = 0xff & mga->linecomp;
-
- mga->crtcext[0] = (0x0f & (mga->startadd >> 16))
- | ((0x03 & (mga->offset >> 8)) << 4)
- | ((0x01 & (mga->startadd >> 20)) << 6)
- | ((0x01 & mga->interlace) << 7)
- ;
- mga->crtcext[1] = ((0x01 & (mga->htotal >> 8)) << 0)
- | ((0x01 & (mga->hblkstr >> 8)) << 1)
- | ((0x01 & (mga->hsyncstr >> 8)) << 2)
- | ((0x01 & mga->hrsten) << 3)
- | ((0x01 & mga->hsyncoff) << 4)
- | ((0x01 & mga->vsyncoff) << 5)
- | ((0x01 & (mga->hblkend >> 6)) << 6)
- | ((0x01 & mga->vrsten) << 7)
- ;
- mga->crtcext[2] = ((0x03 & (mga->vtotal >> 10)) << 0)
- | ((0x01 & (mga->vdispend >> 10)) << 2)
- | ((0x03 & (mga->vblkstr >> 10)) << 3)
- | ((0x03 & (mga->vsyncstr >> 10)) << 5)
- | ((0x01 & (mga->linecomp >> 10)) << 7)
- ;
- mga->crtcext[3] = ((0x07 & mga->scale) << 0)
- | ((0x01 & mga->csynccen) << 6)
- | ((0x01 & mga->mgamode) << 7)
- ;
- mga->crtcext[4] = 0; /* memory page ... not used in Power Graphic Mode */
- mga->crtcext[5] = 0; /* Not used in non-interlaced mode */
- mga->crtcext[6] = ((0x07 & mga->hiprilvl) << 0)
- | ((0x07 & mga->maxhipri) << 4)
- ;
- mga->crtcext[7] = ((0x07 & mga->winsize) << 1)
- | ((0x07 & mga->winfreq) << 5)
- ;
- mga->crtcext[8] = (0x01 & (mga->startadd >> 21)) << 0;
- /* Initialize Sequencer */
- mga->sequencer[0] = 0;
- mga->sequencer[1] = 0;
- mga->sequencer[2] = 0x03;
- mga->sequencer[3] = 0;
- mga->sequencer[4] = 0x02;
- /* Graphic Control registers are ignored when not using 0xA0000 aperture */
- for (i = 0; i < 9; i++)
- mga->graphics[i] = 0;
- /* The Attribute Controler is not available in Power Graphics mode */
- for (i = 0; i < 0x15; i++)
- mga->attribute[i] = i;
- /* disable vga load (want to do fields in different order) */
- for(c = vga->link; c; c = c->link)
- if (strncmp(c->name, "vga", 3) == 0)
- c->load = nil;
- }
- static void
- load(Vga* vga, Ctlr* ctlr)
- {
- Mga* mga;
- int i;
- uchar* p;
- Mode* mode;
- uchar cursor;
- mga = vga->private;
- mode = vga->mode;
- trace("mga: Loading ...\n");
- dump_all_regs(mga);
- if (mode->z == 8)
- setpalettedepth(mode->z);
- trace("mga mmio at %#p\n", mga->mmio);
- trace("mga: loading vga registers ...\n" );
- if (ultradebug) Bflush(&stdout);
- /* Initialize Sequencer registers */
- for(i = 0; i < 5; i++)
- seqset(mga, i, mga->sequencer[i], 0xff);
- /* Initialize Attribute register */
- for(i = 0; i < 0x15; i++)
- attrset(mga, i, mga->attribute[i], 0xff);
- /* Initialize Graphic Control registers */
- for(i = 0; i < 9; i++)
- gctlset(mga, i, mga->graphics[i], 0xff);
- /* Wait VSYNC */
- while (mgaread8(mga, STATUS1) & 0x08);
- while (! (mgaread8(mga, STATUS1) & ~0x08));
- /* Turn off the video. */
- seqset(mga, Seq_ClockingMode, Scroff, 0);
- /* Crtc2 Off */
- mgawrite32(mga, C2_CTL, 0);
- /* Disable Cursor */
- cursor = dacset(mga, Dac_Xcurctrl, CursorDis, 0xff);
- /* Pixel Pll UP and set Pixel clock source to Pixel Clock PLL */
- dacset(mga, Dac_Xpixclkctrl, 0x01 | 0x08, 0x0f);
- trace("mga: waiting for the clock source becomes stable ...\n");
- while ((dacget(mga, Dac_Xpixpllstat) & Pixlock) != Pixlock)
- ;
- trace("mga: pixpll locked !\n");
- if (ultradebug) Bflush(&stdout);
- /* Enable LUT, Disable MAFC */
- dacset(mga, Dac_Xmiscctrl, Ramcs | Mfcsel, Vdoutsel);
- /* Disable Dac */
- dacset(mga, Dac_Xmiscctrl, 0, Dacpdn);
- /* Initialize Panel Mode */
- dacset(mga, Dac_Xpanelmode, 0, 0xff);
- /* Disable the PIXCLK and set Pixel clock source to Pixel Clock PLL */
- dacset(mga, Dac_Xpixclkctrl, Pixclkdis | 0x01, 0x3);
- /* Disable mapping of the memory */
- miscset(mga, 0, Misc_rammapen);
- /* Enable 8 bit palette */
- dacset(mga, Dac_Xmiscctrl, Vga8dac, 0);
- /* Select MGA Pixel Clock */
- miscset(mga, Misc_clksel, 0);
- /* Initialize Z Buffer ... (useful?) */
- mgawrite32(mga, Z_DEPTH_ORG, 0);
- /* Wait */
- for (i = 0; i < 50; i++)
- mgaread32(mga, MGA_STATUS);
- if ((mga->devid == MGA200) || ((mga->devid == MGA4XX) && (mga->revid & 0x80) == 0x00)) {
- dacset(mga, Dac_Xpixpllcm, mga->pixpll_m, 0xff);
- dacset(mga, Dac_Xpixpllcn, mga->pixpll_n, 0xff);
- dacset(mga, Dac_Xpixpllcp, mga->pixpll_p, 0xff);
- /* Wait until new clock becomes stable */
- trace("mga: waiting for the clock source becomes stable ...\n");
- while ((dacget(mga, Dac_Xpixpllstat) & Pixlock) != Pixlock)
- ;
- trace("mga: pixpll locked !\n");
- } else {
- /* MGA450 and MGA550 */
- /* Wait until new clock becomes stable */
- trace("mga450: waiting for the clock source becomes stable ...\n");
- while ((dacget(mga, Dac_Xpixpllstat) & Pixlock) != Pixlock)
- ;
- trace("mga: pixpll locked !\n");
- G450SetPLLFreq(mga, (long) mga->Fneeded / 1000);
- }
- /* Enable Pixel Clock Oscillation */
- dacset(mga, Dac_Xpixclkctrl, 0, Pixclkdis);
- if (ultradebug) Bflush(&stdout);
- /* Enable Dac */
- dacset(mga, Dac_Xmiscctrl, Dacpdn, 0);
- /* Set Video Mode */
- switch (mode->z) {
- case 8:
- dacset(mga, Dac_Xmulctrl, _8bitsPerPixel, ColorDepth);
- break;
- case 32:
- dacset(mga, Dac_Xmulctrl, _32bitsPerPixel, ColorDepth);
- break;
- default:
- error("Unsupported depth %d\n", mode->z);
- }
- /* Wait */
- for (i = 0; i < 50; i++)
- mgaread32(mga, MGA_STATUS);
- /* Wait until new clock becomes stable */
- trace("mga: waiting for the clock source becomes stable ...\n");
- if (ultradebug) Bflush(&stdout);
- while ((dacget(mga, Dac_Xpixpllstat) & Pixlock) != Pixlock)
- ;
- trace("mga: pixpll locked !\n");
- if (ultradebug) Bflush(&stdout);
- /* Initialize CRTC registers and remove irq */
- crtcset(mga, 0x11, (1<<4), (1<<5)|0x80);
- for (i = 0; i < 25; i++)
- crtcset(mga, i, mga->crtc[i], 0xff);
- trace("mga: crtc loaded !\n");
- if (ultradebug) Bflush(&stdout);
- /* Initialize CRTC Extension registers */
- for (i = 0; i < 9; i++)
- crtcextset(mga, i, mga->crtcext[i], 0xff);
- trace("mga: ext loaded !\n");
- if (ultradebug) Bflush(&stdout);
- /* Disable Zoom */
- dacset(mga, Dac_Xzoomctrl, 0, 0xff);
- trace("mga: XzoomCtrl Loaded !\n");
- if (ultradebug) Bflush(&stdout);
- /* Enable mga mode again ... Just in case :) */
- crtcextset(mga, CrtcExt_Miscellaneous, Mgamode, 0);
- trace("mga: crtcext MgaMode loaded !\n");
- if (ultradebug) Bflush(&stdout);
- if (mode->z == 32) {
- /* Initialize Big Endian Mode ! */
- mgawrite32(mga, 0x1e54, 0x02 << 16);
- }
- /* Set final misc ... enable mapping ... */
- miscset(mga, mga->misc | Misc_rammapen, 0);
- trace("mga: mapping enabled !\n");
- if (ultradebug) Bflush(&stdout);
- /* Enable Screen */
- seqset(mga, 1, 0, 0xff);
- trace("screen enabled ...\n");
- if (0) {
- p = mga->mmfb;
- for (i = 0; i < mga->fbsize; i++)
- *p++ = (0xff & i);
- }
- trace("mga: Loaded !\n" );
- dump_all_regs(mga);
- if (ultradebug) Bflush(&stdout);
- trace("mga: Loaded [bis]!\n" );
- if (mode->z != 8) {
- /* Initialize Palette */
- mgawrite8(mga, RAMDACIDX, 0);
- for (i = 0; i < 0x100; i++) {
- mgawrite8(mga, RAMDACPALDATA, i);
- mgawrite8(mga, RAMDACPALDATA, i);
- mgawrite8(mga, RAMDACPALDATA, i);
- }
- }
- trace("mga: Palette initialised !\n");
- /* Enable Cursor */
- dacset(mga, Dac_Xcurctrl, cursor, 0xff);
- ctlr->flag |= Fload;
- if (ultradebug) Bflush(&stdout);
- }
- Ctlr mga4xx = {
- "mga4xx", /* name */
- snarf, /* snarf */
- options, /* options */
- init, /* init */
- load, /* load */
- dump, /* dump */
- };
- Ctlr mga4xxhwgc = {
- "mga4xxhwgc", /* name */
- 0, /* snarf */
- 0, /* options */
- 0, /* init */
- 0, /* load */
- dump, /* dump */
- };
|