neomagic.c 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include "pci.h"
  5. #include "vga.h"
  6. typedef struct {
  7. Pcidev* pci;
  8. int x;
  9. int y;
  10. } Neomagic;
  11. enum {
  12. ExtCrtx = 0x19,
  13. MaxCRT=0x85,
  14. MaxGR=0xc7,
  15. };
  16. enum {
  17. GeneralLockReg = 0x0A,
  18. ExtCRTDispAddr = 0x0E,
  19. ExtCRTOffset = 0x0F,
  20. SysIfaceCntl1 = 0x10,
  21. SysIfaceCntl2 = 0x11,
  22. SingleAddrPage = 0x15, /* not changed? */
  23. DualAddrPage = 0x16, /* not changed? */
  24. PanelDispCntlReg1 = 0x20,
  25. PanelDispCntlReg2 = 0x25,
  26. PanelDispCntlReg3 = 0x30,
  27. PanelVertCenterReg1 = 0x28,
  28. PanelVertCenterReg2 = 0x29,
  29. PanelVertCenterReg3 = 0x2A,
  30. PanelVertCenterReg4 = 0x32, /* not 2070 */
  31. PanelHorizCenterReg1 = 0x33,
  32. PanelHorizCenterReg2 = 0x34,
  33. PanelHorizCenterReg3 = 0x35,
  34. PanelHorizCenterReg4 = 0x36, /* 2160, 2200, 2360 */
  35. PanelVertCenterReg5 = 0x37, /* 2200, 2360 */
  36. PanelHorizCenterReg5 = 0x38, /* 2200, 2360 */
  37. ExtColorModeSelect = 0x90,
  38. VerticalExt = 0x70, /* 2200; iobase+4 */
  39. };
  40. static int crts[] = {
  41. 0x1D, 0x1F, 0x21, 0x23, 0x25, 0x2F,
  42. /* also 40-59, 60-69, 70-MaxCRT */
  43. -1
  44. };
  45. /*
  46. * Neomagic driver (fake)
  47. */
  48. static void
  49. snarf(Vga* vga, Ctlr* ctlr)
  50. {
  51. int i;
  52. Pcidev *p;
  53. Neomagic *nm;
  54. generic.snarf(vga, ctlr);
  55. outportw(Grx, 0x2609); /* unlock neo registers */
  56. outportw(Grx, 0x0015); /* reset bank */
  57. for(i=0; crts[i] >= 0; i++)
  58. vga->crt[crts[i]] = vgaxi(Crtx, crts[i]);
  59. for(i=0x40; i <= MaxCRT; i++)
  60. vga->crt[i] = vgaxi(Crtx, i);
  61. for(i=0x08; i<=0x3F; i++)
  62. vga->graphics[i] = vgaxi(Grx, i);
  63. for(i=0x70; i<=MaxGR; i++)
  64. vga->graphics[i] = vgaxi(Grx, i);
  65. if(vga->private == nil){
  66. vga->private = alloc(sizeof(Neomagic));
  67. nm = vga->private;
  68. if((p = pcimatch(0, 0x10C8, 0)) == nil)
  69. error("%s: not found\n", ctlr->name);
  70. switch(p->did){
  71. case 0x0003: /* MagicGraph 128 ZV */
  72. vga->f[1] = 80000000;
  73. vga->vmz = 2048*1024;
  74. vga->apz = 4*1024*1024;
  75. break;
  76. case 0x0083: /* MagicGraph 128 ZV+ */
  77. vga->f[1] = 80000000;
  78. vga->vmz = 2048*1024;
  79. vga->apz = 4*1024*1024;
  80. break;
  81. case 0x0004: /* MagicGraph 128 XD */
  82. vga->f[1] = 90000000;
  83. vga->vmz = 2048*1024;
  84. vga->apz = 16*1024*1024;
  85. break;
  86. case 0x0005: /* MagicMedia 256 AV */
  87. vga->f[1] = 110000000;
  88. vga->vmz = 2560*1024;
  89. vga->apz = 16*1024*1024;
  90. break;
  91. case 0x0006: /* MagicMedia 256 ZX */
  92. vga->f[1] = 110000000;
  93. vga->vmz = 4096*1024;
  94. vga->apz = 16*1024*1024;
  95. break;
  96. case 0x0001: /* MagicGraph 128 */
  97. case 0x0002: /* MagicGraph 128 V */
  98. default:
  99. error("%s: DID %4.4uX unsupported\n",
  100. ctlr->name, p->did);
  101. }
  102. nm->pci = p;
  103. }
  104. ctlr->flag |= Fsnarf;
  105. }
  106. static void
  107. options(Vga*, Ctlr* ctlr)
  108. {
  109. ctlr->flag |= Ulinear|Hlinear|Foptions;
  110. }
  111. static void
  112. init(Vga* vga, Ctlr* ctlr)
  113. {
  114. Neomagic *nm;
  115. int i, h, v, t;
  116. generic.init(vga, ctlr);
  117. nm = vga->private;
  118. switch((vga->graphics[0x20]>>3)&3){
  119. case 0:
  120. nm->x = 640;
  121. nm->y = 480;
  122. break;
  123. case 1:
  124. nm->x = 800;
  125. nm->y = 600;
  126. break;
  127. case 2:
  128. nm->x = 1024;
  129. nm->y = 768;
  130. case 3:
  131. nm->x = 1280;
  132. nm->y = 1024;
  133. break;
  134. }
  135. vga->crt[0x0C] = 0; /* vga starting address (offset) */
  136. vga->crt[0x0D] = 0;
  137. vga->graphics[GeneralLockReg] = 0x01; /* (internal or simultaneous) */
  138. vga->attribute[0x10] &= ~0x40; /* 2x4 mode not right for neomagic */
  139. t = 2; /* LCD only (0x01 for external) */
  140. switch(vga->mode->x){
  141. case 1280:
  142. t |= 0x60;
  143. break;
  144. case 1024:
  145. t |= 0x40;
  146. break;
  147. case 800:
  148. t |= 0x20;
  149. break;
  150. }
  151. if(0 && (nm->pci->did == 0x0005) || (nm->pci->did == 0x0006)){
  152. vga->graphics[PanelDispCntlReg1] &= 0x98;
  153. vga->graphics[PanelDispCntlReg1] |= (t & ~0x98);
  154. }
  155. else{
  156. vga->graphics[PanelDispCntlReg1] &= 0xDC; /* save bits 7:6, 4:2 */
  157. vga->graphics[PanelDispCntlReg1] |= (t & ~0xDC);
  158. }
  159. vga->graphics[PanelDispCntlReg2] &= 0x38;
  160. vga->graphics[PanelDispCntlReg3] &= 0xEF;
  161. vga->graphics[PanelVertCenterReg1] = 0x00;
  162. vga->graphics[PanelVertCenterReg2] = 0x00;
  163. vga->graphics[PanelVertCenterReg3] = 0x00;
  164. vga->graphics[PanelVertCenterReg4] = 0x00;
  165. vga->graphics[PanelVertCenterReg5] = 0x00;
  166. vga->graphics[PanelHorizCenterReg1] = 0x00;
  167. vga->graphics[PanelHorizCenterReg2] = 0x00;
  168. vga->graphics[PanelHorizCenterReg3] = 0x00;
  169. vga->graphics[PanelHorizCenterReg4] = 0x00;
  170. vga->graphics[PanelHorizCenterReg5] = 0x00;
  171. if(vga->mode->x < nm->x){
  172. vga->graphics[PanelDispCntlReg2] |= 0x01;
  173. vga->graphics[PanelDispCntlReg3] |= 0x10;
  174. h = ((nm->x - vga->mode->x) >> 4) - 1;
  175. v = ((nm->y - vga->mode->y) >> 1) - 2;
  176. switch(vga->mode->x){
  177. case 640:
  178. vga->graphics[PanelHorizCenterReg1] = h;
  179. vga->graphics[PanelVertCenterReg3] = v;
  180. break;
  181. case 800:
  182. vga->graphics[PanelHorizCenterReg2] = h;
  183. vga->graphics[PanelVertCenterReg4] = v;
  184. break;
  185. case 1024:
  186. vga->graphics[PanelHorizCenterReg5] = h;
  187. vga->graphics[PanelVertCenterReg5] = v;
  188. break;
  189. }
  190. }
  191. vga->graphics[ExtCRTDispAddr] = 0x10;
  192. vga->graphics[SysIfaceCntl1] &= 0x0F;
  193. vga->graphics[SysIfaceCntl1] |= 0x30;
  194. vga->graphics[SysIfaceCntl2] = 0x40; /* make sure MMIO is enabled */
  195. vga->graphics[SingleAddrPage] = 0x00;
  196. vga->graphics[DualAddrPage] = 0x00;
  197. vga->graphics[ExtCRTOffset] = 0x00;
  198. t = vga->graphics[ExtColorModeSelect] & 0x70; /* colour mode extension */
  199. if(vga->mode->z == 8){
  200. t |= 0x11;
  201. vga->crt[0x13] = vga->mode->x/8;
  202. vga->graphics[ExtCRTOffset] = vga->mode->x>>11;
  203. vga->graphics[0x05] = 0x00; /* linear addressing? */
  204. vga->crt[0x14] = 0x40; /* double word mode but don't count by 4 */
  205. }
  206. else if(vga->mode->z == 16){
  207. t |= 0x13;
  208. vga->crt[0x13] = vga->mode->x/4;
  209. vga->graphics[0x05] = 0x00; /* linear addressing? */
  210. vga->crt[0x14] = 0x40; /* double word mode but don't count by 4 */
  211. vga->graphics[ExtCRTOffset] = vga->mode->x>>10;
  212. for(i = 0; i < Pcolours; i++){
  213. vga->palette[i][Red] = i<<1;
  214. vga->palette[i][Green] = i;
  215. vga->palette[i][Blue] = i<<1;
  216. }
  217. }
  218. else if(vga->mode->z == 24){
  219. t |= 0x14;
  220. vga->crt[0x13] = (vga->mode->x*3)/8;
  221. // vga->graphics[0x05] = 0x00; /* linear addressing? */
  222. vga->crt[0x14] = 0x40; /* double word mode but don't count by 4 */
  223. vga->graphics[ExtCRTOffset] = (vga->mode->x*3)>>11;
  224. for(i = 0; i < Pcolours; i++){
  225. vga->palette[i][Red] = i;
  226. vga->palette[i][Green] = i;
  227. vga->palette[i][Blue] = i;
  228. }
  229. }
  230. else
  231. error("depth %d not supported\n", vga->mode->z);
  232. vga->graphics[ExtColorModeSelect] = t;
  233. vga->misc |= 0x0C;
  234. ctlr->flag |= Finit;
  235. }
  236. static void
  237. load(Vga* vga, Ctlr* ctlr)
  238. {
  239. vgaxo(Grx, GeneralLockReg, vga->graphics[GeneralLockReg]);
  240. vgaxo(Grx, ExtColorModeSelect, vga->graphics[ExtColorModeSelect]);
  241. vgaxo(Grx, PanelDispCntlReg2, vga->graphics[PanelDispCntlReg2] & 0x39);
  242. sleep(200);
  243. generic.load(vga, ctlr);
  244. vgaxo(Grx, ExtCRTDispAddr, vga->graphics[ExtCRTDispAddr]);
  245. vgaxo(Grx, ExtCRTOffset, vga->graphics[ExtCRTOffset] & 0x39);
  246. vgaxo(Grx, SysIfaceCntl1, vga->graphics[SysIfaceCntl1]);
  247. if(ctlr->flag & Ulinear)
  248. vga->graphics[SysIfaceCntl2] |= 0x80;
  249. vgaxo(Grx, SysIfaceCntl2, vga->graphics[SysIfaceCntl2]);
  250. vgaxo(Grx, SingleAddrPage, vga->graphics[SingleAddrPage]);
  251. vgaxo(Grx, DualAddrPage, vga->graphics[DualAddrPage]);
  252. vgaxo(Grx, PanelDispCntlReg1, vga->graphics[PanelDispCntlReg1]);
  253. vgaxo(Grx, PanelDispCntlReg2, vga->graphics[PanelDispCntlReg2]);
  254. vgaxo(Grx, PanelDispCntlReg3, vga->graphics[PanelDispCntlReg3]);
  255. vgaxo(Grx, PanelVertCenterReg1, vga->graphics[PanelVertCenterReg1]);
  256. vgaxo(Grx, PanelVertCenterReg2, vga->graphics[PanelVertCenterReg2]);
  257. vgaxo(Grx, PanelVertCenterReg3, vga->graphics[PanelVertCenterReg3]);
  258. vgaxo(Grx, PanelVertCenterReg4, vga->graphics[PanelVertCenterReg4]);
  259. vgaxo(Grx, PanelHorizCenterReg1, vga->graphics[PanelHorizCenterReg1]);
  260. vgaxo(Grx, PanelHorizCenterReg2, vga->graphics[PanelHorizCenterReg2]);
  261. vgaxo(Grx, PanelHorizCenterReg3, vga->graphics[PanelHorizCenterReg3]);
  262. vgaxo(Grx, PanelHorizCenterReg4, vga->graphics[PanelHorizCenterReg4]);
  263. vgaxo(Grx, PanelVertCenterReg5, vga->graphics[PanelVertCenterReg5]);
  264. vgaxo(Grx, PanelHorizCenterReg5, vga->graphics[PanelHorizCenterReg5]);
  265. if(vga->mode->z != 8)
  266. palette.load(vga, ctlr);
  267. }
  268. static void
  269. dump(Vga* vga, Ctlr* ctlr)
  270. {
  271. int i;
  272. char buf[100];
  273. generic.dump(vga, ctlr);
  274. for(i = 0; crts[i] >= 0; i++){
  275. sprint(buf, "Crt%2.2uX", crts[i]);
  276. printitem(ctlr->name, buf);
  277. printreg(vga->crt[crts[i]]);
  278. }
  279. printitem(ctlr->name, "Crt40");
  280. for(i=0x40; i<=0x59; i++)
  281. printreg(vga->crt[i]);
  282. printitem(ctlr->name, "Crt60");
  283. for(i=0x60; i<=0x69; i++)
  284. printreg(vga->crt[i]);
  285. printitem(ctlr->name, "Crt70");
  286. for (i = 0x70; i <= MaxCRT; i++)
  287. printreg(vga->crt[i]);
  288. printitem(ctlr->name, "Gr08");
  289. for(i=0x08; i<=0x3F; i++)
  290. printreg(vga->graphics[i]);
  291. printitem(ctlr->name, "Gr70");
  292. for(i=0x70; i<=MaxGR; i++)
  293. printreg(vga->graphics[i]);
  294. }
  295. Ctlr neomagic = {
  296. "neomagic", /* name */
  297. snarf, /* snarf */
  298. options, /* options */
  299. init, /* init */
  300. load, /* load */
  301. dump, /* dump */
  302. };
  303. Ctlr neomagichwgc = {
  304. "neomagichwgc", /* name */
  305. 0, /* snarf */
  306. 0, /* options */
  307. 0, /* init */
  308. 0, /* load */
  309. 0, /* dump */
  310. };