mga4xx.c 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626
  1. /* Philippe Anel <philippe.anel@noos.fr>
  2. - 2001-08-12 : First release.
  3. - 2001-08-15 : Added G450, with source code "adapted from" from Xfree86 4.1.0
  4. - 2001-08-23 : Added 'palettedepth 8' and a few 'ultradebug' ...
  5. - 2001-08-24 : Removed a possible lock in initialization.
  6. - 2001-08-30 : Hey ! The 32 bits mode is PALETIZED (Gamma Control I presume) !
  7. And it seems plan9 assume the frame buffer is organized in
  8. Big Endian format ! (+ Fix for the palette init. )
  9. - 2001-09-06 : Added Full 2D Accel ! (see drivers in /sys/src/9/pc)
  10. - 2001-10-01 : Rid Fix.
  11. Greets and Acknowledgements go to :
  12. - Sylvain Chipaux <a.k.a. asle>.
  13. - Nigel Roles.
  14. - Jean Mehat (the man who introduced me into the world of plan9).
  15. - Nicolas Stojanovic.
  16. ... and for those who wrote plan9 of course ... :)
  17. */
  18. #include <u.h>
  19. #include <libc.h>
  20. #include <bio.h>
  21. #include "pci.h"
  22. #include "vga.h"
  23. static int ultradebug = 0;
  24. /*
  25. * Matrox G4xx 3D graphics accelerators
  26. */
  27. enum {
  28. Kilo = 1024,
  29. Meg = 1024*1024,
  30. MATROX = 0x102B, /* pci chip manufacturer */
  31. MGA4XX = 0x0525, /* pci chip device ids */
  32. MGA200 = 0x0521,
  33. /* Pci configuration space mapping */
  34. PCfgMgaFBAA = 0x10, /* Frame buffer Aperture Address */
  35. PCfgMgaCAA = 0x14, /* Control Aperture Address base */
  36. PCfgMgaIAA = 0x18, /* ILOAD Aperture base Address */
  37. PCfgMgaOption1 = 0x40, /* Option Register 1 */
  38. PCfgMgaOption2 = 0x50, /* Option Register 2 */
  39. PCfgMgaOption3 = 0x54, /* Option Register 3 */
  40. PCfgMgaDevCtrl = 0x04, /* Device Control */
  41. /* control aperture offsets */
  42. DMAWIN = 0x0000, /* 7KByte Pseudo-DMA Window */
  43. STATUS0 = 0x1FC2, /* Input Status 0 */
  44. STATUS1 = 0x1FDA, /* Input Status 1 */
  45. SEQIDX = 0x1FC4, /* Sequencer Index */
  46. SEQDATA = 0x1FC5, /* Sequencer Data */
  47. MISC_W = 0x1FC2, /* Misc. WO */
  48. MISC_R = 0x1FCC, /* Misc. RO */
  49. GCTLIDX = 0x1FCE, /* Graphic Controler Index */
  50. GCTLDATA = 0x1FCF, /* Graphic Controler Data */
  51. CRTCIDX = 0x1FD4, /* CRTC Index */
  52. CRTCDATA = 0x1FD5, /* CRTC Data */
  53. CRTCEXTIDX = 0x1FDE, /* CRTC Extension Index */
  54. CRTCEXTDATA = 0x1FDF, /* CRTC Extension Data */
  55. RAMDACIDX = 0x3C00, /* RAMDAC registers Index */
  56. RAMDACDATA = 0x3C0A, /* RAMDAC Indexed Data */
  57. RAMDACPALDATA = 0x3C01,
  58. ATTRIDX = 0x1FC0, /* Attribute Index */
  59. ATTRDATA = 0x1FC1, /* Attribute Data */
  60. CACHEFLUSH = 0x1FFF,
  61. C2_CTL = 0X3C10,
  62. MGA_STATUS = 0X1E14,
  63. Z_DEPTH_ORG = 0X1C0C,
  64. /* ... */
  65. Seq_ClockingMode = 0x01,
  66. Dotmode = (1<<0),
  67. Shftldrt = (1<<2),
  68. Dotclkrt = (1<<3),
  69. Shiftfour = (1<<4),
  70. Scroff = (1<<5),
  71. CrtcExt_Horizontcount = 0x01,
  72. Htotal = (1<<0),
  73. Hblkstr = (1<<1),
  74. Hsyncstr = (1<<2),
  75. Hrsten = (1<<3),
  76. Hsyncoff = (1<<4),
  77. Vsyncoff = (1<<5),
  78. Hblkend = (1<<6),
  79. Vrsten = (1<<7),
  80. CrtcExt_Miscellaneous = 0x03,
  81. Mgamode = (1<<7),
  82. Dac_Xpixclkctrl = 0x1a,
  83. Pixclksl = (3<<0),
  84. Pixclkdis = (1<<2),
  85. Pixpllpdn = (1<<3),
  86. Dac_Xpixpllstat = 0x4f,
  87. Pixlock = (1<<6),
  88. Dac_Xpixpllan = 0x45,
  89. Dac_Xpixpllbn = 0x49,
  90. Dac_Xpixpllcn = 0x4d,
  91. Dac_Xpixpllam = 0x44,
  92. Dac_Xpixpllbm = 0x48,
  93. Dac_Xpixpllcm = 0x4c,
  94. Dac_Xpixpllap = 0x46,
  95. Dac_Xpixpllbp = 0x4a,
  96. Dac_Xpixpllcp = 0x4e,
  97. Dac_Xmulctrl = 0x19,
  98. ColorDepth = (7<<0),
  99. _8bitsPerPixel = 0,
  100. _15bitsPerPixel = 1,
  101. _16bitsPerPixel = 2,
  102. _24bitsPerPixel = 3,
  103. _32bitsPerPixelWithOv = 4,
  104. _32bitsPerPixel = 7,
  105. Dac_Xpanelmode = 0x1f,
  106. Dac_Xmiscctrl = 0x1e,
  107. Dacpdn = (1<<0),
  108. Mfcsel = (3<<1),
  109. Vga8dac = (1<<3),
  110. Ramcs = (1<<4),
  111. Vdoutsel = (7<<5),
  112. Dac_Xcurctrl = 0x06,
  113. CursorDis = 0,
  114. Cursor3Color = 1,
  115. CursorXGA = 2,
  116. CursorX11 = 3,
  117. Cursor16Color = 4,
  118. Dac_Xzoomctrl = 0x38,
  119. Misc_loaddsel = (1<<0),
  120. Misc_rammapen = (1<<1),
  121. Misc_clksel = (3<<2),
  122. Misc_videodis = (1<<4),
  123. Misc_hpgoddev = (1<<5),
  124. Misc_hsyncpol = (1<<6),
  125. Misc_vsyncpol = (1<<7),
  126. MNP_TABLE_SIZE = 64,
  127. TRUE = (1 == 1),
  128. FALSE = (1 == 0),
  129. };
  130. typedef struct {
  131. Pcidev* pci;
  132. int devid;
  133. int revid;
  134. ulong mmio;
  135. ulong mmfb;
  136. int fbsize;
  137. ulong iload;
  138. uchar syspll_m;
  139. uchar syspll_n;
  140. uchar syspll_p;
  141. uchar syspll_s;
  142. uchar pixpll_m;
  143. uchar pixpll_n;
  144. uchar pixpll_p;
  145. uchar pixpll_s;
  146. ulong option1;
  147. ulong option2;
  148. ulong option3;
  149. ulong Fneeded;
  150. /* From plan9.ini ... later */
  151. uchar sdram;
  152. uchar colorkey;
  153. uchar maskkey;
  154. ulong maxpclk;
  155. uchar graphics[9];
  156. uchar attribute[0x14];
  157. uchar sequencer[5];
  158. uchar crtc[0x19];
  159. uchar crtcext[9];
  160. ulong htotal;
  161. ulong hdispend;
  162. ulong hblkstr;
  163. ulong hblkend;
  164. ulong hsyncstr;
  165. ulong hsyncend;
  166. ulong vtotal;
  167. ulong vdispend;
  168. ulong vblkstr;
  169. ulong vblkend;
  170. ulong vsyncstr;
  171. ulong vsyncend;
  172. ulong linecomp;
  173. ulong hsyncsel;
  174. ulong startadd;
  175. ulong offset;
  176. ulong maxscan;
  177. ulong curloc;
  178. ulong prowscan;
  179. ulong currowstr;
  180. ulong currowend;
  181. ulong curoff;
  182. ulong undrow;
  183. ulong curskew;
  184. ulong conv2t4;
  185. ulong interlace;
  186. ulong hsyncdel;
  187. ulong hdispskew;
  188. ulong bytepan;
  189. ulong dotclkrt;
  190. ulong dword;
  191. ulong wbmode;
  192. ulong addwrap;
  193. ulong selrowscan;
  194. ulong cms;
  195. ulong csynccen;
  196. ulong hrsten;
  197. ulong vrsten;
  198. ulong vinten;
  199. ulong vintclr;
  200. ulong hsyncoff;
  201. ulong vsyncoff;
  202. ulong crtcrstN;
  203. ulong mgamode;
  204. ulong scale;
  205. ulong hiprilvl;
  206. ulong maxhipri;
  207. ulong c2hiprilvl;
  208. ulong c2maxhipri;
  209. ulong misc;
  210. ulong crtcprotect;
  211. ulong winsize;
  212. ulong winfreq;
  213. ulong mgaapsize;
  214. } Mga;
  215. static void
  216. mgawrite32(Mga* mga, int index, ulong val)
  217. {
  218. ((ulong*)mga->mmio)[index] = val;
  219. }
  220. static ulong
  221. mgaread32(Mga* mga, int index)
  222. {
  223. return ((ulong*)mga->mmio)[index];
  224. }
  225. static void
  226. mgawrite8(Mga* mga, int index, uchar val)
  227. {
  228. ((uchar*)mga->mmio)[index] = val;
  229. }
  230. static uchar
  231. mgaread8(Mga* mga, int index)
  232. {
  233. return ((uchar*)mga->mmio)[index];
  234. }
  235. static uchar
  236. seqget(Mga* mga, int index)
  237. {
  238. mgawrite8(mga, SEQIDX, index);
  239. return mgaread8(mga, SEQDATA);
  240. }
  241. static uchar
  242. seqset(Mga* mga, int index, uchar set, uchar clr)
  243. {
  244. uchar tmp;
  245. mgawrite8(mga, SEQIDX, index);
  246. tmp = mgaread8(mga, SEQDATA);
  247. mgawrite8(mga, SEQIDX, index);
  248. mgawrite8(mga, SEQDATA, (tmp & ~clr) | set);
  249. return tmp;
  250. }
  251. static uchar
  252. crtcget(Mga* mga, int index)
  253. {
  254. mgawrite8(mga, CRTCIDX, index);
  255. return mgaread8(mga, CRTCDATA);
  256. }
  257. static uchar
  258. crtcset(Mga* mga, int index, uchar set, uchar clr)
  259. {
  260. uchar tmp;
  261. mgawrite8(mga, CRTCIDX, index);
  262. tmp = mgaread8(mga, CRTCDATA);
  263. mgawrite8(mga, CRTCIDX, index);
  264. mgawrite8(mga, CRTCDATA, (tmp & ~clr) | set);
  265. return tmp;
  266. }
  267. static uchar
  268. crtcextget(Mga* mga, int index)
  269. {
  270. mgawrite8(mga, CRTCEXTIDX, index);
  271. return mgaread8(mga, CRTCEXTDATA);
  272. }
  273. static uchar
  274. crtcextset(Mga* mga, int index, uchar set, uchar clr)
  275. {
  276. uchar tmp;
  277. mgawrite8(mga, CRTCEXTIDX, index);
  278. tmp = mgaread8(mga, CRTCEXTDATA);
  279. mgawrite8(mga, CRTCEXTIDX, index);
  280. mgawrite8(mga, CRTCEXTDATA, (tmp & ~clr) | set);
  281. return tmp;
  282. }
  283. static uchar
  284. dacget(Mga* mga, int index)
  285. {
  286. mgawrite8(mga, RAMDACIDX, index);
  287. return mgaread8(mga, RAMDACDATA);
  288. }
  289. static uchar
  290. dacset(Mga* mga, int index, uchar set, uchar clr)
  291. {
  292. uchar tmp;
  293. mgawrite8(mga, RAMDACIDX, index);
  294. tmp = mgaread8(mga, RAMDACDATA);
  295. mgawrite8(mga, RAMDACIDX, index);
  296. mgawrite8(mga, RAMDACDATA, (tmp & ~clr) | set);
  297. return tmp;
  298. }
  299. static uchar
  300. gctlget(Mga* mga, int index)
  301. {
  302. mgawrite8(mga, GCTLIDX, index);
  303. return mgaread8(mga, GCTLDATA);
  304. }
  305. static uchar
  306. gctlset(Mga* mga, int index, uchar set, uchar clr)
  307. {
  308. uchar tmp;
  309. mgawrite8(mga, GCTLIDX, index);
  310. tmp = mgaread8(mga, GCTLDATA);
  311. mgawrite8(mga, GCTLIDX, index);
  312. mgawrite8(mga, GCTLDATA, (tmp & ~clr) | set);
  313. return tmp;
  314. }
  315. static uchar
  316. attrget(Mga* mga, int index)
  317. {
  318. mgawrite8(mga, ATTRIDX, index);
  319. return mgaread8(mga, ATTRDATA);
  320. }
  321. static uchar
  322. attrset(Mga* mga, int index, uchar set, uchar clr)
  323. {
  324. uchar tmp;
  325. mgawrite8(mga, ATTRIDX, index);
  326. tmp = mgaread8(mga, ATTRDATA);
  327. mgawrite8(mga, ATTRIDX, index);
  328. mgawrite8(mga, ATTRDATA, (tmp & ~clr) | set);
  329. return tmp;
  330. }
  331. static uchar
  332. miscget(Mga* mga)
  333. {
  334. return mgaread8(mga, MISC_R);
  335. }
  336. static uchar
  337. miscset(Mga* mga, uchar set, uchar clr)
  338. {
  339. uchar tmp;
  340. tmp = mgaread8(mga, MISC_R);
  341. mgawrite8(mga, MISC_W, (tmp & ~clr) | set);
  342. return tmp;
  343. }
  344. /* ************************************************************ */
  345. static void
  346. dump_all_regs(Mga* mga)
  347. {
  348. int i;
  349. for (i = 0; i < 25; i++)
  350. trace("crtc[%d] = 0x%x\n", i, crtcget(mga, i));
  351. for (i = 0; i < 9; i++)
  352. trace("crtcext[%d] = 0x%x\n", i, crtcextget(mga, i));
  353. for (i = 0; i < 5; i++)
  354. trace("seq[%d] = 0x%x\n", i, seqget(mga, i));
  355. for (i = 0; i < 9; i++)
  356. trace("gctl[%d] = 0x%x\n", i, gctlget(mga, i));
  357. trace("misc = 0x%x\n", mgaread8(mga, MISC_R));
  358. for (i = 0; i < 0x87; i++)
  359. trace("dac[%d] = 0x%x\n", i, dacget(mga, i));
  360. }
  361. /* ************************************************************ */
  362. static void
  363. dump(Vga* vga, Ctlr* ctlr)
  364. {
  365. dump_all_regs(vga->private);
  366. ctlr->flag |= Fdump;
  367. }
  368. static void
  369. setpalettedepth(int depth)
  370. {
  371. int fd;
  372. char *cmd = strdup("palettedepth X");
  373. if ((depth != 8) && (depth != 6) && (depth != 16))
  374. error("mga: invalid palette depth %d\n", depth);
  375. fd = open("#v/vgactl", OWRITE);
  376. if(fd < 0)
  377. error("mga: can't open vgactl\n");
  378. cmd[13] = '0' + depth;
  379. if(write(fd, cmd, 14) != 14)
  380. error("mga: can't set palette depth to %d\n", depth);
  381. close(fd);
  382. }
  383. static void
  384. mapmga4xx(Vga* vga, Ctlr* ctlr)
  385. {
  386. int f;
  387. long m;
  388. Mga * mga;
  389. if(vga->private == nil)
  390. error("%s: g4xxio: no *mga4xx\n", ctlr->name);
  391. mga = vga->private;
  392. f = open("#v/vgactl", OWRITE);
  393. if(f < 0)
  394. error("%s: can't open vgactl\n", ctlr->name);
  395. if(write(f, "type mga4xx", 11) != 11)
  396. error("%s: can't set mga type\n", ctlr->name);
  397. m = segattach(0, "mga4xxmmio", 0, 16*Kilo);
  398. if(m == -1)
  399. error("%s: can't attach mga4xxmmio segment\n", ctlr->name);
  400. mga->mmio = m;
  401. trace("%s: mmio at 0x%lx\n", ctlr->name, mga->mmio);
  402. m = segattach(0, "mga4xxscreen", 0, 32*Meg);
  403. if(m == -1) {
  404. mga->mgaapsize = 8*Meg;
  405. m = segattach(0, "mga4xxscreen", 0, 8*Meg);
  406. if(m == -1)
  407. error("%s: can't attach mga4xxscreen segment\n", ctlr->name);
  408. } else {
  409. mga->mgaapsize = 32*Meg;
  410. }
  411. mga->mmfb = m;
  412. trace("%s: frame buffer at 0x%lx\n", ctlr->name, mga->mmfb);
  413. close(f);
  414. }
  415. static void
  416. snarf(Vga* vga, Ctlr* ctlr)
  417. {
  418. int i, k, n;
  419. uchar * p;
  420. uchar x[16];
  421. Pcidev * pci;
  422. Mga * mga;
  423. uchar crtcext3;
  424. uchar rid;
  425. trace("%s->snarf\n", ctlr->name);
  426. if(vga->private == nil) {
  427. pci = pcimatch(nil, MATROX, MGA4XX);
  428. if(pci == nil) {
  429. pci = pcimatch(nil, MATROX, MGA200);
  430. if(pci == nil) {
  431. error("%s: no Pcidev with Vid=0x102B, Did=0x052[51]\n", ctlr->name);
  432. }
  433. }
  434. rid = pcicfgr8(pci, PciRID); // PciRID = 0x08
  435. trace("%s: G%d%d0 rev %d\n", ctlr->name, pci->did==0x0521?2:4, rid&0x80?5:0, rid&(~0x80));
  436. i = pcicfgr32(pci, PCfgMgaDevCtrl);
  437. if ((i & 2) != 2)
  438. error("%s: Memory Space not enabled ... Aborting ...\n", ctlr->name);
  439. vga->private = alloc(sizeof(Mga));
  440. mga = (Mga*)vga->private;
  441. mga->devid = pci->did;
  442. mga->revid = rid;
  443. mga->pci = pci;
  444. mapmga4xx(vga, ctlr);
  445. }
  446. else {
  447. mga = (Mga*)vga->private;
  448. }
  449. /* Find out how much memory is here, some multiple of 2Meg */
  450. /* First Set MGA Mode ... */
  451. crtcext3 = crtcextset(mga, 3, 0x80, 0x00);
  452. p = (uchar*)mga->mmfb;
  453. n = (mga->mgaapsize / Meg) / 2;
  454. for (i = 0; i < n; i++) {
  455. k = (2*i+1)*Meg;
  456. p[k] = 0;
  457. p[k] = i+1;
  458. *((uchar*)(mga->mmio + CACHEFLUSH)) = 0;
  459. x[i] = p[k];
  460. trace("x[%d]=%d\n", i, x[i]);
  461. }
  462. for(i = 1; i < n; i++)
  463. if(x[i] != i+1)
  464. break;
  465. vga->vmz = mga->fbsize = 2*i*Meg;
  466. trace("probe found %d megabytes\n", 2*i);
  467. crtcextset(mga, 3, crtcext3, 0xff);
  468. ctlr->flag |= Fsnarf;
  469. }
  470. static void
  471. options(Vga* vga, Ctlr* ctlr)
  472. {
  473. if(vga->virtx & 127)
  474. vga->virtx = (vga->virtx+127)&~127;
  475. ctlr->flag |= Foptions;
  476. }
  477. /* ************************************************************ */
  478. static void
  479. G450ApplyPFactor(Mga*, uchar ucP, ulong *pulFIn)
  480. {
  481. if(!(ucP & 0x40))
  482. {
  483. *pulFIn = *pulFIn / (2L << (ucP & 3));
  484. }
  485. }
  486. static void
  487. G450RemovePFactor(Mga*, uchar ucP, ulong *pulFIn)
  488. {
  489. if(!(ucP & 0x40))
  490. {
  491. *pulFIn = *pulFIn * (2L << (ucP & 3));
  492. }
  493. }
  494. static void
  495. G450CalculVCO(Mga*, ulong ulMNP, ulong *pulF)
  496. {
  497. uchar ucM, ucN;
  498. ucM = (uchar)((ulMNP >> 16) & 0xff);
  499. ucN = (uchar)((ulMNP >> 8) & 0xff);
  500. *pulF = (27000 * (2 * (ucN + 2)) + ((ucM + 1) >> 1)) / (ucM + 1);
  501. trace("G450CalculVCO: ulMNP %lx, pulF %ld\n", ulMNP, *pulF);
  502. }
  503. static void
  504. G450CalculDeltaFreq(Mga*, ulong ulF1, ulong ulF2, ulong *pulDelta)
  505. {
  506. if(ulF2 < ulF1)
  507. {
  508. *pulDelta = ((ulF1 - ulF2) * 1000) / ulF1;
  509. }
  510. else
  511. {
  512. *pulDelta = ((ulF2 - ulF1) * 1000) / ulF1;
  513. }
  514. trace("G450CalculDeltaFreq: ulF1 %ld, ulF2 %ld, pulDelta %ld\n", ulF1, ulF2, *pulDelta);
  515. }
  516. static void
  517. G450FindNextPLLParam(Mga* mga, ulong ulFout, ulong *pulPLLMNP)
  518. {
  519. uchar ucM, ucN, ucP, ucS;
  520. ulong ulVCO, ulVCOMin;
  521. ucM = (uchar)((*pulPLLMNP >> 16) & 0xff);
  522. /* ucN = (uchar)((*pulPLLMNP >> 8) & 0xff); */
  523. ucP = (uchar)(*pulPLLMNP & 0x43);
  524. ulVCOMin = 256000;
  525. if(ulVCOMin >= (255L * 8000))
  526. {
  527. ulVCOMin = 230000;
  528. }
  529. if((ucM == 9) && (ucP & 0x40))
  530. {
  531. *pulPLLMNP = 0xffffffff;
  532. } else if (ucM == 9)
  533. {
  534. if(ucP)
  535. {
  536. ucP--;
  537. }
  538. else
  539. {
  540. ucP = 0x40;
  541. }
  542. ucM = 0;
  543. }
  544. else
  545. {
  546. ucM++;
  547. }
  548. ulVCO = ulFout;
  549. G450RemovePFactor(mga, ucP, &ulVCO);
  550. if(ulVCO < ulVCOMin)
  551. {
  552. *pulPLLMNP = 0xffffffff;
  553. }
  554. if(*pulPLLMNP != 0xffffffff)
  555. {
  556. ucN = (uchar)(((ulVCO * (ucM+1) + 27000)/(27000 * 2)) - 2);
  557. ucS = 5;
  558. if(ulVCO < 1300000) ucS = 4;
  559. if(ulVCO < 1100000) ucS = 3;
  560. if(ulVCO < 900000) ucS = 2;
  561. if(ulVCO < 700000) ucS = 1;
  562. if(ulVCO < 550000) ucS = 0;
  563. ucP |= (uchar)(ucS << 3);
  564. *pulPLLMNP &= 0xff000000;
  565. *pulPLLMNP |= (ulong)ucM << 16;
  566. *pulPLLMNP |= (ulong)ucN << 8;
  567. *pulPLLMNP |= (ulong)ucP;
  568. }
  569. }
  570. static void
  571. G450FindFirstPLLParam(Mga* mga, ulong ulFout, ulong *pulPLLMNP)
  572. {
  573. uchar ucP;
  574. ulong ulVCO;
  575. ulong ulVCOMax;
  576. /* Default value */
  577. ulVCOMax = 1300000;
  578. if(ulFout > (ulVCOMax/2))
  579. {
  580. ucP = 0x40;
  581. ulVCO = ulFout;
  582. }
  583. else
  584. {
  585. ucP = 3;
  586. ulVCO = ulFout;
  587. G450RemovePFactor(mga, ucP, &ulVCO);
  588. while(ucP && (ulVCO > ulVCOMax))
  589. {
  590. ucP--;
  591. ulVCO = ulFout;
  592. G450RemovePFactor(mga, ucP, &ulVCO);
  593. }
  594. }
  595. if(ulVCO > ulVCOMax)
  596. {
  597. *pulPLLMNP = 0xffffffff;
  598. }
  599. else
  600. {
  601. /* Pixel clock: 1 */
  602. *pulPLLMNP = (1 << 24) + 0xff0000 + ucP;
  603. G450FindNextPLLParam(mga, ulFout, pulPLLMNP);
  604. }
  605. }
  606. static void
  607. G450WriteMNP(Mga* mga, ulong ulMNP)
  608. {
  609. if (0) trace("G450WriteMNP : 0x%lx\n", ulMNP);
  610. dacset(mga, Dac_Xpixpllcm, (uchar)(ulMNP >> 16), 0xff);
  611. dacset(mga, Dac_Xpixpllcn, (uchar)(ulMNP >> 8), 0xff);
  612. dacset(mga, Dac_Xpixpllcp, (uchar)ulMNP, 0xff);
  613. }
  614. static void
  615. G450CompareMNP(Mga* mga, ulong ulFout, ulong ulMNP1,
  616. ulong ulMNP2, long *pulResult)
  617. {
  618. ulong ulFreq, ulDelta1, ulDelta2;
  619. G450CalculVCO(mga, ulMNP1, &ulFreq);
  620. G450ApplyPFactor(mga, (uchar) ulMNP1, &ulFreq);
  621. G450CalculDeltaFreq(mga, ulFout, ulFreq, &ulDelta1);
  622. G450CalculVCO(mga, ulMNP2, &ulFreq);
  623. G450ApplyPFactor(mga, (uchar) ulMNP2, &ulFreq);
  624. G450CalculDeltaFreq(mga, ulFout, ulFreq, &ulDelta2);
  625. if(ulDelta1 < ulDelta2)
  626. {
  627. *pulResult = -1;
  628. }
  629. else if(ulDelta1 > ulDelta2)
  630. {
  631. *pulResult = 1;
  632. }
  633. else
  634. {
  635. *pulResult = 0;
  636. }
  637. if((ulDelta1 <= 5) && (ulDelta2 <= 5))
  638. {
  639. if((ulMNP1 & 0xff0000) < (ulMNP2 & 0xff0000))
  640. {
  641. *pulResult = -1;
  642. }
  643. else if((ulMNP1 & 0xff0000) > (ulMNP2 & 0xff0000))
  644. {
  645. *pulResult = 1;
  646. }
  647. }
  648. }
  649. static void
  650. G450IsPllLocked(Mga* mga, int *lpbLocked)
  651. {
  652. ulong ulFallBackCounter, ulLockCount, ulCount;
  653. uchar ucPLLStatus;
  654. /* Pixel PLL */
  655. mgawrite8(mga, 0x3c00, 0x4f);
  656. ulFallBackCounter = 0;
  657. do
  658. {
  659. ucPLLStatus = mgaread8(mga, 0x3c0a);
  660. if (0) trace("ucPLLStatus[1] : 0x%x\n", ucPLLStatus);
  661. ulFallBackCounter++;
  662. } while(!(ucPLLStatus & 0x40) && (ulFallBackCounter < 1000));
  663. ulLockCount = 0;
  664. if(ulFallBackCounter < 1000)
  665. {
  666. for(ulCount = 0; ulCount < 100; ulCount++)
  667. {
  668. ucPLLStatus = mgaread8(mga, 0x3c0a);
  669. if (0) trace("ucPLLStatus[2] : 0x%x\n", ucPLLStatus);
  670. if(ucPLLStatus & 0x40)
  671. {
  672. ulLockCount++;
  673. }
  674. }
  675. }
  676. *lpbLocked = ulLockCount >= 90;
  677. }
  678. static void
  679. G450SetPLLFreq(Mga* mga, long f_out)
  680. {
  681. int bFoundValidPLL;
  682. int bLocked;
  683. ulong ulMaxIndex;
  684. ulong ulMNP;
  685. ulong ulMNPTable[MNP_TABLE_SIZE];
  686. ulong ulIndex;
  687. ulong ulTryMNP;
  688. long lCompareResult;
  689. trace("f_out : %ld\n", f_out);
  690. G450FindFirstPLLParam(mga, f_out, &ulMNP);
  691. ulMNPTable[0] = ulMNP;
  692. G450FindNextPLLParam(mga, f_out, &ulMNP);
  693. ulMaxIndex = 1;
  694. while(ulMNP != 0xffffffff)
  695. {
  696. int ulIndex;
  697. int bSkipValue;
  698. bSkipValue = FALSE;
  699. if(ulMaxIndex == MNP_TABLE_SIZE)
  700. {
  701. G450CompareMNP(mga, f_out, ulMNP, ulMNPTable[MNP_TABLE_SIZE - 1],
  702. &lCompareResult);
  703. if(lCompareResult > 0)
  704. {
  705. bSkipValue = TRUE;
  706. }
  707. else
  708. {
  709. ulMaxIndex--;
  710. }
  711. }
  712. if(!bSkipValue)
  713. {
  714. for(ulIndex = ulMaxIndex; !bSkipValue && (ulIndex > 0); ulIndex--)
  715. {
  716. G450CompareMNP(mga, f_out, ulMNP, ulMNPTable[ulIndex - 1],
  717. &lCompareResult);
  718. if(lCompareResult < 0)
  719. {
  720. ulMNPTable[ulIndex] = ulMNPTable[ulIndex - 1];
  721. }
  722. else
  723. {
  724. break;
  725. }
  726. }
  727. ulMNPTable[ulIndex] = ulMNP;
  728. ulMaxIndex++;
  729. }
  730. G450FindNextPLLParam(mga, f_out, &ulMNP);
  731. }
  732. bFoundValidPLL = FALSE;
  733. ulMNP = 0;
  734. for(ulIndex = 0; !bFoundValidPLL && (ulIndex < ulMaxIndex); ulIndex++)
  735. {
  736. ulTryMNP = ulMNPTable[ulIndex];
  737. {
  738. bLocked = TRUE;
  739. if((ulMNPTable[ulIndex] & 0xff00) < 0x300 ||
  740. (ulMNPTable[ulIndex] & 0xff00) > 0x7a00)
  741. {
  742. bLocked = FALSE;
  743. }
  744. if(bLocked)
  745. {
  746. G450WriteMNP(mga, ulTryMNP - 0x300);
  747. G450IsPllLocked(mga, &bLocked);
  748. }
  749. if(bLocked)
  750. {
  751. G450WriteMNP(mga, ulTryMNP + 0x300);
  752. G450IsPllLocked(mga, &bLocked);
  753. }
  754. if(bLocked)
  755. {
  756. G450WriteMNP(mga, ulTryMNP - 0x200);
  757. G450IsPllLocked(mga, &bLocked);
  758. }
  759. if(bLocked)
  760. {
  761. G450WriteMNP(mga, ulTryMNP + 0x200);
  762. G450IsPllLocked(mga, &bLocked);
  763. }
  764. if(bLocked)
  765. {
  766. G450WriteMNP(mga, ulTryMNP - 0x100);
  767. G450IsPllLocked(mga, &bLocked);
  768. }
  769. if(bLocked)
  770. {
  771. G450WriteMNP(mga, ulTryMNP + 0x100);
  772. G450IsPllLocked(mga, &bLocked);
  773. }
  774. if(bLocked)
  775. {
  776. G450WriteMNP(mga, ulTryMNP);
  777. G450IsPllLocked(mga, &bLocked);
  778. }
  779. else if(!ulMNP)
  780. {
  781. G450WriteMNP(mga, ulTryMNP);
  782. G450IsPllLocked(mga, &bLocked);
  783. if(bLocked)
  784. {
  785. ulMNP = ulMNPTable[ulIndex];
  786. }
  787. bLocked = FALSE;
  788. }
  789. if(bLocked)
  790. {
  791. bFoundValidPLL = TRUE;
  792. }
  793. }
  794. }
  795. if(!bFoundValidPLL)
  796. {
  797. if(ulMNP)
  798. {
  799. G450WriteMNP(mga, ulMNP);
  800. }
  801. else
  802. {
  803. G450WriteMNP(mga, ulMNPTable[0]);
  804. }
  805. }
  806. }
  807. /* ************************************************************ */
  808. /*
  809. calcclock - Calculate the PLL settings (m, n, p, s).
  810. */
  811. static double
  812. g400_calcclock(Mga* mga, long Fneeded)
  813. {
  814. double Fpll;
  815. double Fvco;
  816. double Fref;
  817. int pixpll_m_min;
  818. int pixpll_m_max;
  819. int pixpll_n_min;
  820. int pixpll_n_max;
  821. int pixpll_p_max;
  822. double Ferr, Fcalc;
  823. int m, n, p;
  824. if (mga->devid == 0x0525) {
  825. /* These values are taken from Matrox G400 Specification - p 4-91 */
  826. Fref = 27000000.0;
  827. pixpll_n_min = 7;
  828. pixpll_n_max = 127;
  829. pixpll_m_min = 1;
  830. pixpll_m_max = 31;
  831. pixpll_p_max = 7;
  832. } else { /* 0x0521 */
  833. /* These values are taken from Matrox G200 Specification - p 4-77 */
  834. //Fref = 14318180.0;
  835. Fref = 27050500.0;
  836. pixpll_n_min = 7;
  837. pixpll_n_max = 127;
  838. pixpll_m_min = 1;
  839. pixpll_m_max = 6;
  840. pixpll_p_max = 7;
  841. }
  842. Fvco = ( double ) Fneeded;
  843. for (p = 0; p <= pixpll_p_max && Fvco < mga->maxpclk; p = p * 2 + 1, Fvco *= 2.0)
  844. ;
  845. mga->pixpll_p = p;
  846. Ferr = Fneeded;
  847. for ( m = pixpll_m_min ; m <= pixpll_m_max ; m++ )
  848. for ( n = pixpll_n_min; n <= pixpll_n_max; n++ )
  849. {
  850. Fcalc = Fref * (n + 1) / (m + 1) ;
  851. /*
  852. * Pick the closest frequency.
  853. */
  854. if ( labs(Fcalc - Fvco) < Ferr ) {
  855. Ferr = abs(Fcalc - Fvco);
  856. mga->pixpll_m = m;
  857. mga->pixpll_n = n;
  858. }
  859. }
  860. Fvco = Fref * (mga->pixpll_n + 1) / (mga->pixpll_m + 1);
  861. if (mga->devid == 0x0525) {
  862. if ( (50000000.0 <= Fvco) && (Fvco < 110000000.0) )
  863. mga->pixpll_p |= 0;
  864. if ( (110000000.0 <= Fvco) && (Fvco < 170000000.0) )
  865. mga->pixpll_p |= (1<<3);
  866. if ( (170000000.0 <= Fvco) && (Fvco < 240000000.0) )
  867. mga->pixpll_p |= (2<<3);
  868. if ( (300000000.0 <= Fvco) )
  869. mga->pixpll_p |= (3<<3);
  870. } else {
  871. if ( (50000000.0 <= Fvco) && (Fvco < 100000000.0) )
  872. mga->pixpll_p |= 0;
  873. if ( (100000000.0 <= Fvco) && (Fvco < 140000000.0) )
  874. mga->pixpll_p |= (1<<3);
  875. if ( (140000000.0 <= Fvco) && (Fvco < 180000000.0) )
  876. mga->pixpll_p |= (2<<3);
  877. if ( (250000000.0 <= Fvco) )
  878. mga->pixpll_p |= (3<<3);
  879. }
  880. Fpll = Fvco / (p + 1);
  881. return Fpll;
  882. }
  883. /* ************************************************************ */
  884. static void
  885. init(Vga* vga, Ctlr* ctlr)
  886. {
  887. Mode* mode;
  888. Mga* mga;
  889. double Fpll;
  890. Ctlr* c;
  891. int i;
  892. ulong t;
  893. mga = vga->private;
  894. mode = vga->mode;
  895. trace("mga mmio at 0x%lx\n", mga->mmio);
  896. ctlr->flag |= Ulinear;
  897. if ((mode->z != 32) && (mode->z != 8))
  898. error("depth %d not supported !\n", mode->z);
  899. if (mode->interlace)
  900. error("interlaced mode not supported !\n");
  901. trace("%s: Initializing mode %dx%dx%d on %s\n", ctlr->name, mode->x, mode->y, mode->z, mode->type);
  902. trace("%s: Suggested Dot Clock : %d\n", ctlr->name, mode->frequency);
  903. trace("%s: Horizontal Total = %d\n", ctlr->name, mode->ht);
  904. trace("%s: Start Horizontal Blank = %d\n", ctlr->name, mode->shb);
  905. trace("%s: End Horizontal Blank = %d\n", ctlr->name, mode->ehb);
  906. trace("%s: Vertical Total = %d\n", ctlr->name, mode->vt);
  907. trace("%s: Vertical Retrace Start = %d\n", ctlr->name, mode->vrs);
  908. trace("%s: Vertical Retrace End = %d\n", ctlr->name, mode->vre);
  909. trace("%s: Start Horizontal Sync = %d\n", ctlr->name, mode->shs);
  910. trace("%s: End Horizontal Sync = %d\n", ctlr->name, mode->ehs);
  911. trace("%s: HSync = %c\n", ctlr->name, mode->hsync);
  912. trace("%s: VSync = %c\n", ctlr->name, mode->vsync);
  913. trace("%s: Interlace = %d\n", ctlr->name, mode->interlace);
  914. /* TODO : G400 Max : 360000000 */
  915. if (mga->devid == 0x0525)
  916. mga->maxpclk = 300000000;
  917. else
  918. mga->maxpclk = 250000000;
  919. if (mode->frequency < 50000)
  920. error("mga: Too little Frequency %d : Minimum supported by PLL is %d",
  921. mode->frequency, 50000);
  922. if (mode->frequency > mga->maxpclk)
  923. error("mga: Too big Frequency %d : Maximum supported by PLL is %ld",
  924. mode->frequency, mga->maxpclk);
  925. trace("mga: revision ID is %x\n", mga->revid);
  926. if ((mga->revid == 0x0521) || ((mga->revid & 0x80) == 0x00)) {
  927. /* Is it G200/G400 or G450 ? */
  928. Fpll = g400_calcclock(mga, mode->frequency);
  929. trace("Fpll set to %f\n", Fpll);
  930. trace("pixclks : n = %d m = %d p = %d\n", mga->pixpll_n, mga->pixpll_m, mga->pixpll_p & 0x7);
  931. } else
  932. mga->Fneeded = mode->frequency;
  933. trace("PCI Option1 = 0x%x\n", pcicfgr32(mga->pci, PCfgMgaOption1));
  934. trace("PCI Option2 = 0x%x\n", pcicfgr32(mga->pci, PCfgMgaOption2));
  935. trace("PCI Option3 = 0x%x\n", pcicfgr32(mga->pci, PCfgMgaOption3));
  936. mga->htotal = (mode->ht >> 3) - 5;
  937. mga->hdispend = (mode->x >> 3) - 1;
  938. mga->hblkstr = mga->hdispend; /* (mode->shb >> 3); */
  939. mga->hblkend = mga->htotal + 4; /* (mode->ehb >> 3); */
  940. mga->hsyncstr = (mode->shs >> 3) - 1; // Was (mode->shs >> 3);
  941. mga->hsyncend = (mode->ehs >> 3) - 1; // Was (mode->ehs >> 3);
  942. mga->hsyncdel = 0;
  943. mga->vtotal = mode->vt - 2;
  944. mga->vdispend = mode->y - 1;
  945. mga->vblkstr = mode->y - 1;
  946. mga->vblkend = mode->vt - 1;
  947. mga->vsyncstr = mode->vrs;
  948. mga->vsyncend = mode->vre;
  949. mga->linecomp = mode->y;
  950. mga->hsyncsel = 0; /* Do not double lines ... */
  951. mga->startadd = 0;
  952. mga->offset = (vga->virtx * mode->z) / 128;
  953. /* No Zoom */
  954. mga->maxscan = 0;
  955. /* Not used in Power Graphic mode */
  956. mga->curloc = 0;
  957. mga->prowscan = 0;
  958. mga->currowstr = 0;
  959. mga->currowend = 0;
  960. mga->curoff = 1;
  961. mga->undrow = 0;
  962. mga->curskew = 0;
  963. mga->conv2t4 = 0;
  964. mga->interlace = 0;
  965. mga->hdispskew = 0;
  966. mga->bytepan = 0;
  967. mga->dotclkrt = 0;
  968. mga->dword = 0;
  969. mga->wbmode = 1;
  970. mga->addwrap = 0; /* Not Used ! */
  971. mga->selrowscan = 1;
  972. mga->cms = 1;
  973. mga->csynccen = 0; /* Disable composite sync */
  974. /* VIDRST Pin */
  975. mga->hrsten = 0; // Was 1;
  976. mga->vrsten = 0; // Was 1;
  977. /* vertical interrupt control ... disabled */
  978. mga->vinten = 1;
  979. mga->vintclr = 0;
  980. /* Let [hv]sync run freely */
  981. mga->hsyncoff = 0;
  982. mga->vsyncoff = 0;
  983. mga->crtcrstN = 1;
  984. mga->mgamode = 1;
  985. mga->scale = (mode->z == 8) ? 0 : 3; /* 8 or 32 bits mode */
  986. mga->crtcprotect = 1;
  987. mga->winsize = 0;
  988. mga->winfreq = 0;
  989. if ((mga->htotal == 0)
  990. || (mga->hblkend <= (mga->hblkstr + 1))
  991. || ((mga->htotal - mga->hdispend) == 0)
  992. || ((mga->htotal - mga->bytepan + 2) <= mga->hdispend)
  993. || (mga->hsyncstr <= (mga->hdispend + 2))
  994. || (mga->vtotal == 0))
  995. {
  996. error("Invalid Power Graphic Mode :\n"
  997. "mga->htotal = %ld\n"
  998. "mga->hdispend = %ld\n"
  999. "mga->hblkstr = %ld\n"
  1000. "mga->hblkend = %ld\n"
  1001. "mga->hsyncstr = %ld\n"
  1002. "mga->hsyncend = %ld\n"
  1003. "mga->hsyncdel = %ld\n"
  1004. "mga->vtotal = %ld\n"
  1005. "mga->vdispend = %ld\n"
  1006. "mga->vblkstr = %ld\n"
  1007. "mga->vblkend = %ld\n"
  1008. "mga->vsyncstr = %ld\n"
  1009. "mga->vsyncend = %ld\n"
  1010. "mga->linecomp = %ld\n",
  1011. mga->htotal,
  1012. mga->hdispend,
  1013. mga->hblkstr,
  1014. mga->hblkend,
  1015. mga->hsyncstr,
  1016. mga->hsyncend,
  1017. mga->hsyncdel,
  1018. mga->vtotal,
  1019. mga->vdispend,
  1020. mga->vblkstr,
  1021. mga->vblkend,
  1022. mga->vsyncstr,
  1023. mga->vsyncend,
  1024. mga->linecomp
  1025. );
  1026. }
  1027. mga->hiprilvl = 0;
  1028. mga->maxhipri = 0;
  1029. mga->c2hiprilvl = 0;
  1030. mga->c2maxhipri = 0;
  1031. mga->misc = ((mode->hsync != '-')?0:(1<<6)) | ((mode->vsync != '-')?0:(1<<7));
  1032. trace("mga->htotal = %ld\n"
  1033. "mga->hdispend = %ld\n"
  1034. "mga->hblkstr = %ld\n"
  1035. "mga->hblkend = %ld\n"
  1036. "mga->hsyncstr = %ld\n"
  1037. "mga->hsyncend = %ld\n"
  1038. "mga->hsyncdel = %ld\n"
  1039. "mga->vtotal = %ld\n"
  1040. "mga->vdispend = %ld\n"
  1041. "mga->vblkstr = %ld\n"
  1042. "mga->vblkend = %ld\n"
  1043. "mga->vsyncstr = %ld\n"
  1044. "mga->vsyncend = %ld\n"
  1045. "mga->linecomp = %ld\n",
  1046. mga->htotal,
  1047. mga->hdispend,
  1048. mga->hblkstr,
  1049. mga->hblkend,
  1050. mga->hsyncstr,
  1051. mga->hsyncend,
  1052. mga->hsyncdel,
  1053. mga->vtotal,
  1054. mga->vdispend,
  1055. mga->vblkstr,
  1056. mga->vblkend,
  1057. mga->vsyncstr,
  1058. mga->vsyncend,
  1059. mga->linecomp
  1060. );
  1061. mga->crtc[0x00] = 0xff & mga->htotal;
  1062. mga->crtc[0x01] = 0xff & mga->hdispend;
  1063. mga->crtc[0x02] = 0xff & mga->hblkstr;
  1064. mga->crtc[0x03] = (0x1f & mga->hblkend)
  1065. | ((0x03 & mga->hdispskew) << 5)
  1066. | 0x80 /* cf 3-304 */
  1067. ;
  1068. mga->crtc[0x04] = 0xff & mga->hsyncstr;
  1069. mga->crtc[0x05] = (0x1f & mga->hsyncend)
  1070. | ((0x03 & mga->hsyncdel) << 5)
  1071. | ((0x01 & (mga->hblkend >> 5)) << 7)
  1072. ;
  1073. mga->crtc[0x06] = 0xff & mga->vtotal;
  1074. t = ((0x01 & (mga->vtotal >> 8)) << 0)
  1075. | ((0x01 & (mga->vdispend >> 8)) << 1)
  1076. | ((0x01 & (mga->vsyncstr >> 8)) << 2)
  1077. | ((0x01 & (mga->vblkstr >> 8)) << 3)
  1078. | ((0x01 & (mga->linecomp >> 8)) << 4)
  1079. | ((0x01 & (mga->vtotal >> 9)) << 5)
  1080. | ((0x01 & (mga->vdispend >> 9)) << 6)
  1081. | ((0x01 & (mga->vsyncstr >> 9)) << 7)
  1082. ;
  1083. mga->crtc[0x07] = 0xff & t;
  1084. mga->crtc[0x08] = (0x1f & mga->prowscan)
  1085. | ((0x03 & mga->bytepan) << 5)
  1086. ;
  1087. mga->crtc[0x09] = (0x1f & mga->maxscan)
  1088. | ((0x01 & (mga->vblkstr >> 9)) << 5)
  1089. | ((0x01 & (mga->linecomp >> 9)) << 6)
  1090. | ((0x01 & mga->conv2t4) << 7)
  1091. ;
  1092. mga->crtc[0x0a] = (0x1f & mga->currowstr)
  1093. | ((0x01 & mga->curoff) << 5)
  1094. ;
  1095. mga->crtc[0x0b] = (0x1f & mga->currowend)
  1096. | ((0x03 & mga->curskew) << 5)
  1097. ;
  1098. mga->crtc[0x0c] = 0xff & (mga->startadd >> 8);
  1099. mga->crtc[0x0d] = 0xff & mga->startadd;
  1100. mga->crtc[0x0e] = 0xff & (mga->curloc >> 8);
  1101. mga->crtc[0x0f] = 0xff & mga->curloc;
  1102. mga->crtc[0x10] = 0xff & mga->vsyncstr;
  1103. mga->crtc[0x11] = (0x0f & mga->vsyncend)
  1104. | ((0x01 & mga->vintclr) << 4)
  1105. | ((0x01 & mga->vinten) << 5)
  1106. | ((0x01 & mga->crtcprotect) << 7)
  1107. ;
  1108. mga->crtc[0x12] = 0xff & mga->vdispend;
  1109. mga->crtc[0x13] = 0xff & mga->offset;
  1110. mga->crtc[0x14] = 0x1f & mga->undrow; /* vga only */
  1111. mga->crtc[0x15] = 0xff & mga->vblkstr;
  1112. mga->crtc[0x16] = 0xff & mga->vblkend;
  1113. mga->crtc[0x17] = ((0x01 & mga->cms) << 0)
  1114. | ((0x01 & mga->selrowscan) << 1)
  1115. | ((0x01 & mga->hsyncsel) << 2)
  1116. | ((0x01 & mga->addwrap) << 5)
  1117. | ((0x01 & mga->wbmode) << 6)
  1118. | ((0x01 & mga->crtcrstN) << 7)
  1119. ;
  1120. mga->crtc[0x18] = 0xff & mga->linecomp;
  1121. mga->crtcext[0] = (0x0f & (mga->startadd >> 16))
  1122. | ((0x03 & (mga->offset >> 8)) << 4)
  1123. | ((0x01 & (mga->startadd >> 20)) << 6)
  1124. | ((0x01 & mga->interlace) << 7)
  1125. ;
  1126. mga->crtcext[1] = ((0x01 & (mga->htotal >> 8)) << 0)
  1127. | ((0x01 & (mga->hblkstr >> 8)) << 1)
  1128. | ((0x01 & (mga->hsyncstr >> 8)) << 2)
  1129. | ((0x01 & mga->hrsten) << 3)
  1130. | ((0x01 & mga->hsyncoff) << 4)
  1131. | ((0x01 & mga->vsyncoff) << 5)
  1132. | ((0x01 & (mga->hblkend >> 6)) << 6)
  1133. | ((0x01 & mga->vrsten) << 7)
  1134. ;
  1135. mga->crtcext[2] = ((0x03 & (mga->vtotal >> 10)) << 0)
  1136. | ((0x01 & (mga->vdispend >> 10)) << 2)
  1137. | ((0x03 & (mga->vblkstr >> 10)) << 3)
  1138. | ((0x03 & (mga->vsyncstr >> 10)) << 5)
  1139. | ((0x01 & (mga->linecomp >> 10)) << 7)
  1140. ;
  1141. mga->crtcext[3] = ((0x07 & mga->scale) << 0)
  1142. | ((0x01 & mga->csynccen) << 6)
  1143. | ((0x01 & mga->mgamode) << 7)
  1144. ;
  1145. mga->crtcext[4] = 0; /* memory page ... not used in Power Graphic Mode */
  1146. mga->crtcext[5] = 0; /* Not used in non-interlaced mode */
  1147. mga->crtcext[6] = ((0x07 & mga->hiprilvl) << 0)
  1148. | ((0x07 & mga->maxhipri) << 4)
  1149. ;
  1150. mga->crtcext[7] = ((0x07 & mga->winsize) << 1)
  1151. | ((0x07 & mga->winfreq) << 5)
  1152. ;
  1153. mga->crtcext[8] = (0x01 & (mga->startadd >> 21)) << 0;
  1154. /* Initialize Sequencer */
  1155. mga->sequencer[0] = 0;
  1156. mga->sequencer[1] = 0;
  1157. mga->sequencer[2] = 0x03;
  1158. mga->sequencer[3] = 0;
  1159. mga->sequencer[4] = 0x02;
  1160. /* Graphic Control registers are ignored when not using 0xA0000 aperture */
  1161. for (i = 0; i < 9; i++)
  1162. mga->graphics[i] = 0;
  1163. /* The Attribute Controler is not available in Power Graphics mode */
  1164. for (i = 0; i < 0x15; i++)
  1165. mga->attribute[i] = i;
  1166. /* disable vga load (want to do fields in different order) */
  1167. for(c = vga->link; c; c = c->link)
  1168. if (strncmp(c->name, "vga", 3) == 0)
  1169. c->load = nil;
  1170. }
  1171. static void
  1172. load(Vga* vga, Ctlr* ctlr)
  1173. {
  1174. Mga* mga;
  1175. int i;
  1176. uchar* p;
  1177. Mode* mode;
  1178. uchar cursor;
  1179. mga = vga->private;
  1180. mode = vga->mode;
  1181. trace("mga: Loading ...\n");
  1182. dump_all_regs(mga);
  1183. if (mode->z == 8)
  1184. setpalettedepth(mode->z);
  1185. trace("mga mmio at 0x%lx\n", mga->mmio);
  1186. trace("mga: loading vga registers ...\n" );
  1187. if (ultradebug) Bflush(&stdout);
  1188. /* Initialize Sequencer registers */
  1189. for(i = 0; i < 5; i++)
  1190. seqset(mga, i, mga->sequencer[i], 0xff);
  1191. /* Initialize Attribute register */
  1192. for(i = 0; i < 0x15; i++)
  1193. attrset(mga, i, mga->attribute[i], 0xff);
  1194. /* Initialize Graphic Control registers */
  1195. for(i = 0; i < 9; i++)
  1196. gctlset(mga, i, mga->graphics[i], 0xff);
  1197. /* Wait VSYNC */
  1198. while (mgaread8(mga, STATUS1) & 0x08);
  1199. while (! (mgaread8(mga, STATUS1) & ~0x08));
  1200. /* Turn off the video. */
  1201. seqset(mga, Seq_ClockingMode, Scroff, 0);
  1202. /* Crtc2 Off */
  1203. mgawrite32(mga, C2_CTL, 0);
  1204. /* Disable Cursor */
  1205. cursor = dacset(mga, Dac_Xcurctrl, CursorDis, 0xff);
  1206. /* Pixel Pll UP and set Pixel clock source to Pixel Clock PLL */
  1207. dacset(mga, Dac_Xpixclkctrl, 0x01 | 0x08, 0x0f);
  1208. trace("mga: waiting for the clock source becomes stable ...\n");
  1209. while ((dacget(mga, Dac_Xpixpllstat) & Pixlock) != Pixlock)
  1210. ;
  1211. trace("mga: pixpll locked !\n");
  1212. if (ultradebug) Bflush(&stdout);
  1213. /* Enable LUT, Disable MAFC */
  1214. dacset(mga, Dac_Xmiscctrl, Ramcs | Mfcsel, Vdoutsel);
  1215. /* Disable Dac */
  1216. dacset(mga, Dac_Xmiscctrl, 0, Dacpdn);
  1217. /* Initialize Panel Mode */
  1218. dacset(mga, Dac_Xpanelmode, 0, 0xff);
  1219. /* Disable the PIXCLK and set Pixel clock source to Pixel Clock PLL */
  1220. dacset(mga, Dac_Xpixclkctrl, Pixclkdis | 0x01, 0x3);
  1221. /* Disable mapping of the memory */
  1222. miscset(mga, 0, Misc_rammapen);
  1223. /* Enable 8 bit palette */
  1224. dacset(mga, Dac_Xmiscctrl, Vga8dac, 0);
  1225. /* Select MGA Pixel Clock */
  1226. miscset(mga, Misc_clksel, 0);
  1227. /* Initialize Z Buffer ... (useful?) */
  1228. mgawrite32(mga, Z_DEPTH_ORG, 0);
  1229. /* Wait */
  1230. for (i = 0; i < 50; i++)
  1231. mgaread32(mga, MGA_STATUS);
  1232. if ((mga->devid == 0x0521) || ((mga->revid & 0x80) == 0x00)) {
  1233. dacset(mga, Dac_Xpixpllcm, mga->pixpll_m, 0xff);
  1234. dacset(mga, Dac_Xpixpllcn, mga->pixpll_n, 0xff);
  1235. dacset(mga, Dac_Xpixpllcp, mga->pixpll_p, 0xff);
  1236. /* Wait until new clock becomes stable */
  1237. trace("mga: waiting for the clock source becomes stable ...\n");
  1238. while ((dacget(mga, Dac_Xpixpllstat) & Pixlock) != Pixlock)
  1239. ;
  1240. trace("mga: pixpll locked !\n");
  1241. } else {
  1242. /* Wait until new clock becomes stable */
  1243. trace("mga450: waiting for the clock source becomes stable ...\n");
  1244. while ((dacget(mga, Dac_Xpixpllstat) & Pixlock) != Pixlock)
  1245. ;
  1246. trace("mga: pixpll locked !\n");
  1247. G450SetPLLFreq(mga, (long) mga->Fneeded / 1000);
  1248. }
  1249. /* Enable Pixel Clock Oscillation */
  1250. dacset(mga, Dac_Xpixclkctrl, 0, Pixclkdis);
  1251. if (ultradebug) Bflush(&stdout);
  1252. /* Enable Dac */
  1253. dacset(mga, Dac_Xmiscctrl, Dacpdn, 0);
  1254. /* Set Video Mode */
  1255. switch (mode->z) {
  1256. case 8:
  1257. dacset(mga, Dac_Xmulctrl, _8bitsPerPixel, ColorDepth);
  1258. break;
  1259. case 32:
  1260. dacset(mga, Dac_Xmulctrl, _32bitsPerPixel, ColorDepth);
  1261. break;
  1262. default:
  1263. error("Unsupported depth %d\n", mode->z);
  1264. }
  1265. /* Wait */
  1266. for (i = 0; i < 50; i++)
  1267. mgaread32(mga, MGA_STATUS);
  1268. /* Wait until new clock becomes stable */
  1269. trace("mga: waiting for the clock source becomes stable ...\n");
  1270. if (ultradebug) Bflush(&stdout);
  1271. while ((dacget(mga, Dac_Xpixpllstat) & Pixlock) != Pixlock)
  1272. ;
  1273. trace("mga: pixpll locked !\n");
  1274. if (ultradebug) Bflush(&stdout);
  1275. /* Initialize CRTC registers and remove irq */
  1276. crtcset(mga, 0x11, (1<<4), (1<<5)|0x80);
  1277. for (i = 0; i < 25; i++)
  1278. crtcset(mga, i, mga->crtc[i], 0xff);
  1279. trace("mga: crtc loaded !\n");
  1280. if (ultradebug) Bflush(&stdout);
  1281. /* Initialize CRTC Extension registers */
  1282. for (i = 0; i < 9; i++)
  1283. crtcextset(mga, i, mga->crtcext[i], 0xff);
  1284. trace("mga: ext loaded !\n");
  1285. if (ultradebug) Bflush(&stdout);
  1286. /* Disable Zoom */
  1287. dacset(mga, Dac_Xzoomctrl, 0, 0xff);
  1288. trace("mga: XzoomCtrl Loaded !\n");
  1289. if (ultradebug) Bflush(&stdout);
  1290. /* Enable mga mode again ... Just in case :) */
  1291. crtcextset(mga, CrtcExt_Miscellaneous, Mgamode, 0);
  1292. trace("mga: crtcext MgaMode loaded !\n");
  1293. if (ultradebug) Bflush(&stdout);
  1294. if (mode->z == 32) {
  1295. /* Initialize Big Endian Mode ! */
  1296. mgawrite32(mga, 0x1e54, 0x02 << 16);
  1297. }
  1298. /* Set final misc ... enable mapping ... */
  1299. miscset(mga, mga->misc | Misc_rammapen, 0);
  1300. trace("mga: mapping enabled !\n");
  1301. if (ultradebug) Bflush(&stdout);
  1302. /* Enable Screen */
  1303. seqset(mga, 1, 0, 0xff);
  1304. trace("screen enabled ...\n");
  1305. if (0) {
  1306. p = (uchar*)mga->mmfb;
  1307. for (i = 0; i < mga->fbsize; i++)
  1308. *p++ = (0xff & i);
  1309. }
  1310. trace("mga: Loaded !\n" );
  1311. dump_all_regs(mga);
  1312. if (ultradebug) Bflush(&stdout);
  1313. trace("mga: Loaded [bis]!\n" );
  1314. if (mode->z != 8) {
  1315. /* Initialize Palette */
  1316. mgawrite8(mga, RAMDACIDX, 0);
  1317. for (i = 0; i < 0x100; i++) {
  1318. mgawrite8(mga, RAMDACPALDATA, i);
  1319. mgawrite8(mga, RAMDACPALDATA, i);
  1320. mgawrite8(mga, RAMDACPALDATA, i);
  1321. }
  1322. }
  1323. trace("mga: Palette initialised !\n");
  1324. /* Enable Cursor */
  1325. dacset(mga, Dac_Xcurctrl, cursor, 0xff);
  1326. ctlr->flag |= Fload;
  1327. if (ultradebug) Bflush(&stdout);
  1328. }
  1329. Ctlr mga4xx = {
  1330. "mga4xx", /* name */
  1331. snarf, /* snarf */
  1332. options, /* options */
  1333. init, /* init */
  1334. load, /* load */
  1335. dump, /* dump */
  1336. };
  1337. Ctlr mga4xxhwgc = {
  1338. "mga4xxhwgc", /* name */
  1339. 0, /* snarf */
  1340. 0, /* options */
  1341. 0, /* init */
  1342. 0, /* load */
  1343. dump, /* dump */
  1344. };