vganvidia.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. #include "u.h"
  2. #include "../port/lib.h"
  3. #include "mem.h"
  4. #include "dat.h"
  5. #include "fns.h"
  6. #include "io.h"
  7. #include "../port/error.h"
  8. #define Image IMAGE
  9. #include <draw.h>
  10. #include <memdraw.h>
  11. #include <cursor.h>
  12. #include "screen.h"
  13. enum {
  14. Pramin = 0x00710000,
  15. Pramdac = 0x00680000,
  16. Fifo = 0x00800000,
  17. Pgraph = 0x00400000
  18. };
  19. enum {
  20. hwCurPos = Pramdac + 0x0300,
  21. hwCurImage = Pramin + (0x00010000 - 0x0800),
  22. };
  23. static ushort nvidiadid[] = {
  24. 0x0020, /* Riva TNT */
  25. 0x0028, /* Riva TNT2 */
  26. 0x0029, /* Riva TNT2 (Ultra)*/
  27. 0x002C, /* Riva TNT2 (Vanta) */
  28. 0x002D, /* Riva TNT2 M64 */
  29. 0x00A0, /* Riva TNT2 (Integrated) */
  30. 0x0100, /* GeForce 256 */
  31. 0x0101, /* GeForce DDR */
  32. 0x0103, /* Quadro */
  33. 0x0110, /* GeForce2 MX */
  34. 0x0111, /* GeForce2 MX DDR */
  35. 0x0112, /* GeForce 2 Go */
  36. 0x0113, /* Quadro 2 MXR */
  37. 0x0150, /* GeForce2 GTS */
  38. 0x0151, /* GeForce2 GTS (rev 1) */
  39. 0x0152, /* GeForce2 Ultra */
  40. 0x0153, /* Quadro 2 Pro */
  41. 0x0200, /* GeForce3 */
  42. 0x0201,
  43. 0x0202,
  44. 0,
  45. };
  46. static Pcidev*
  47. nvidiapci(void)
  48. {
  49. Pcidev *p;
  50. ushort *did;
  51. if((p = pcimatch(nil, 0x10DE, 0)) == nil)
  52. return nil;
  53. for(did = nvidiadid; *did; did++){
  54. if(*did == p->did)
  55. return p;
  56. }
  57. return nil;
  58. }
  59. static ulong
  60. nvidialinear(VGAscr* scr, int* size, int* align)
  61. {
  62. Pcidev *p;
  63. int oapsize, wasupamem;
  64. ulong aperture, oaperture;
  65. oaperture = scr->aperture;
  66. oapsize = scr->apsize;
  67. wasupamem = scr->isupamem;
  68. aperture = 0;
  69. if(p = nvidiapci()){
  70. aperture = p->mem[1].bar & ~0x0F;
  71. *size = p->mem[1].size;
  72. }
  73. if(wasupamem) {
  74. if(oaperture == aperture)
  75. return oaperture;
  76. upafree(oaperture, oapsize);
  77. }
  78. scr->isupamem = 0;
  79. aperture = upamalloc(aperture, *size, *align);
  80. if(aperture == 0){
  81. if(wasupamem && upamalloc(oaperture, oapsize, 0)){
  82. aperture = oaperture;
  83. scr->isupamem = 1;
  84. }
  85. else
  86. scr->isupamem = 0;
  87. }
  88. else
  89. scr->isupamem = 1;
  90. return aperture;
  91. }
  92. static void
  93. nvidiaenable(VGAscr* scr)
  94. {
  95. Pcidev *p;
  96. ulong aperture;
  97. int align, size;
  98. /*
  99. * Only once, can't be disabled for now.
  100. * scr->io holds the physical address of
  101. * the MMIO registers.
  102. */
  103. if(scr->io)
  104. return;
  105. p = nvidiapci();
  106. if(p == nil)
  107. return;
  108. scr->io = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0);
  109. if (scr->io == 0)
  110. return;
  111. addvgaseg("nvidiammio", scr->io, p->mem[0].size);
  112. size = p->mem[1].size;
  113. align = 0;
  114. aperture = nvidialinear(scr, &size, &align);
  115. if(aperture) {
  116. scr->aperture = aperture;
  117. scr->apsize = size;
  118. addvgaseg("nvidiascreen", aperture, size);
  119. }
  120. }
  121. static void
  122. nvidiacurdisable(VGAscr* scr)
  123. {
  124. if(scr->io == 0)
  125. return;
  126. vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
  127. }
  128. static void
  129. nvidiacurload(VGAscr* scr, Cursor* curs)
  130. {
  131. ulong* p;
  132. int i,j;
  133. ushort c,s;
  134. ulong tmp;
  135. if(scr->io == 0)
  136. return;
  137. vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) & ~0x01);
  138. p = KADDR(scr->io + hwCurImage);
  139. for (i=0; i<16; i++) {
  140. c = (curs->clr[2 * i] << 8) | curs->clr[2 * i+1];
  141. s = (curs->set[2 * i] << 8) | curs->set[2 * i+1];
  142. tmp = 0;
  143. for (j=0; j<16; j++) {
  144. if(s&0x8000)
  145. tmp |= 0x80000000;
  146. else if(c&0x8000)
  147. tmp |= 0xFFFF0000;
  148. if (j&0x1) {
  149. *p++ = tmp;
  150. tmp = 0;
  151. } else {
  152. tmp>>=16;
  153. }
  154. c<<=1;
  155. s<<=1;
  156. }
  157. for (j=0; j<8; j++)
  158. *p++ = 0;
  159. }
  160. for (i=0; i<256; i++)
  161. *p++ = 0;
  162. scr->offset = curs->offset;
  163. vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);
  164. return;
  165. }
  166. static int
  167. nvidiacurmove(VGAscr* scr, Point p)
  168. {
  169. ulong* cursorpos;
  170. if(scr->io == 0)
  171. return 1;
  172. cursorpos = KADDR(scr->io + hwCurPos);
  173. *cursorpos = ((p.y+scr->offset.y)<<16)|((p.x+scr->offset.x) & 0xFFFF);
  174. return 0;
  175. }
  176. static void
  177. nvidiacurenable(VGAscr* scr)
  178. {
  179. nvidiaenable(scr);
  180. if(scr->io == 0)
  181. return;
  182. vgaxo(Crtx, 0x1F, 0x57);
  183. nvidiacurload(scr, &arrow);
  184. nvidiacurmove(scr, ZP);
  185. vgaxo(Crtx, 0x31, vgaxi(Crtx, 0x31) | 0x01);
  186. }
  187. enum {
  188. RopFifo = 0x00000000,
  189. ClipFifo = 0x00002000,
  190. PattFifo = 0x00004000,
  191. BltFifo = 0x00008000,
  192. BitmapFifo = 0x0000A000,
  193. };
  194. enum {
  195. RopRop3 = RopFifo + 0x300,
  196. ClipTopLeft = ClipFifo + 0x300,
  197. ClipWidthHeight = ClipFifo + 0x304,
  198. PattShape = PattFifo + 0x0308,
  199. PattColor0 = PattFifo + 0x0310,
  200. PattColor1 = PattFifo + 0x0314,
  201. PattMonochrome0 = PattFifo + 0x0318,
  202. PattMonochrome1 = PattFifo + 0x031C,
  203. BltTopLeftSrc = BltFifo + 0x0300,
  204. BltTopLeftDst = BltFifo + 0x0304,
  205. BltWidthHeight = BltFifo + 0x0308,
  206. BitmapColor1A = BitmapFifo + 0x03FC,
  207. BitmapURect0TopLeft = BitmapFifo + 0x0400,
  208. BitmapURect0WidthHeight = BitmapFifo + 0x0404,
  209. };
  210. static void
  211. waitforidle(VGAscr *scr)
  212. {
  213. ulong* pgraph;
  214. int x;
  215. pgraph = KADDR(scr->io + Pgraph);
  216. x = 0;
  217. while (pgraph[0x00000700/4] & 0x01 && x++ < 1000000)
  218. ;
  219. if(x >= 1000000)
  220. iprint("idle stat %lud scrio %.8lux scr %p pc %luX\n", *pgraph, scr->io, scr, getcallerpc(&scr));
  221. }
  222. static void
  223. waitforfifo(VGAscr *scr, int fifo, int entries)
  224. {
  225. ushort* fifofree;
  226. int x;
  227. x = 0;
  228. fifofree = KADDR(scr->io + Fifo + fifo + 0x10);
  229. while (((*fifofree >> 2) < entries) && x++ < 1000000)
  230. ;
  231. if(x >= 1000000)
  232. iprint("fifo stat %d scrio %.8lux scr %p pc %luX\n", *fifofree, scr->io, scr, getcallerpc(&scr));
  233. }
  234. static int
  235. nvidiahwfill(VGAscr *scr, Rectangle r, ulong sval)
  236. {
  237. ulong* fifo;
  238. fifo = KADDR(scr->io + Fifo);
  239. waitforfifo(scr, BitmapFifo, 1);
  240. fifo[BitmapColor1A/4] = sval;
  241. waitforfifo(scr, BitmapFifo, 2);
  242. fifo[BitmapURect0TopLeft/4] = (r.min.x << 16) | r.min.y;
  243. fifo[BitmapURect0WidthHeight/4] = (Dx(r) << 16) | Dy(r);
  244. waitforidle(scr);
  245. return 1;
  246. }
  247. static int
  248. nvidiahwscroll(VGAscr *scr, Rectangle r, Rectangle sr)
  249. {
  250. ulong* fifo;
  251. fifo = KADDR(scr->io + Fifo);
  252. waitforfifo(scr, BltFifo, 3);
  253. fifo[BltTopLeftSrc/4] = (sr.min.y << 16) | sr.min.x;
  254. fifo[BltTopLeftDst/4] = (r.min.y << 16) | r.min.x;
  255. fifo[BltWidthHeight/4] = (Dy(r) << 16) | Dx(r);
  256. waitforidle(scr);
  257. return 1;
  258. }
  259. void
  260. nvidiablank(VGAscr*, int blank)
  261. {
  262. uchar seq1, crtc1A;
  263. seq1 = vgaxi(Seqx, 1) & ~0x20;
  264. crtc1A = vgaxi(Crtx, 0x1A) & ~0xC0;
  265. if(blank) {
  266. seq1 |= 0x20;
  267. // crtc1A |= 0xC0;
  268. crtc1A |= 0x80;
  269. }
  270. vgaxo(Seqx, 1, seq1);
  271. vgaxo(Crtx, 0x1A, crtc1A);
  272. }
  273. static void
  274. nvidiadrawinit(VGAscr *scr)
  275. {
  276. ulong* fifo;
  277. fifo = KADDR(scr->io + Fifo);
  278. waitforfifo(scr, ClipFifo, 2);
  279. fifo[ClipTopLeft/4] = 0x0;
  280. fifo[ClipWidthHeight/4] = 0x80008000;
  281. waitforfifo(scr, PattFifo, 5);
  282. fifo[PattShape/4] = 0;
  283. fifo[PattColor0/4] = 0xffffffff;
  284. fifo[PattColor1/4] = 0xffffffff;
  285. fifo[PattMonochrome0/4] = 0xffffffff;
  286. fifo[PattMonochrome1/4] = 0xffffffff;
  287. waitforfifo(scr, RopFifo, 1);
  288. fifo[RopRop3/4] = 0xCC;
  289. waitforidle(scr);
  290. scr->blank = nvidiablank;
  291. hwblank = 1;
  292. scr->fill = nvidiahwfill;
  293. scr->scroll = nvidiahwscroll;
  294. }
  295. VGAdev vganvidiadev = {
  296. "nvidia",
  297. nvidiaenable,
  298. nil,
  299. nil,
  300. nvidialinear,
  301. nvidiadrawinit,
  302. };
  303. VGAcur vganvidiacur = {
  304. "nvidiahwgc",
  305. nvidiacurenable,
  306. nvidiacurdisable,
  307. nvidiacurload,
  308. nvidiacurmove,
  309. };