t2r4.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include "pci.h"
  5. #include "vga.h"
  6. /*
  7. * #9 Ticket to Ride IV.
  8. */
  9. typedef struct {
  10. Pcidev* pci;
  11. ulong io;
  12. ulong mmio;
  13. ulong ioreg[13];
  14. ulong g[25];
  15. ulong w[25];
  16. } T2r4;
  17. enum { /* memory mapped global registers */
  18. IntVcnt = 0x20/4, /* vertical interrupt counter */
  19. IntHcnt = 0x24/4, /* horizontal interrupt counter */
  20. DbAdr = 0x28/4, /* display start address */
  21. DbPtch = 0x2C/4, /* display pitch */
  22. CrtHac = 0x30/4, /* horizontal active line width */
  23. CrtHbl = 0x34/4, /* horizontal blank width */
  24. CrtHfp = 0x38/4, /* horizontal front porch */
  25. CrtHs = 0x3C/4, /* horizontal sync width */
  26. CrtVac = 0x40/4, /* vertical active field width */
  27. CrtVbl = 0x44/4, /* vertical blank width */
  28. CrtVfp = 0x48/4, /* vertical front porch */
  29. CrtVs = 0x4C/4, /* vertical sync width */
  30. CrtLcnt = 0x50/4, /* CRT line counter */
  31. CrtZoom = 0x54/4, /* display zoom factor */
  32. Crt1con = 0x58/4, /* CRT configuration register 1 */
  33. Crt2con = 0x5C/4, /* CRT configuration register 2 */
  34. DbAdr2 = 0x60/4, /* CRT display start address 2 */
  35. };
  36. enum { /* memory windows registers */
  37. Mw0Ctrl = 0x00/4, /* memory window 0 control */
  38. Mw0Ad = 0x04/4, /* memory window 0 address */
  39. Mw0Sz = 0x08/4, /* memory window 0 size */
  40. Mw0Org = 0x10/4, /* memory window 0 origin */
  41. Mw0Mask = 0x24/4, /* Memory window 0 plane mask */
  42. Mw1Ctlr = 0x28/4, /* memory window 1 control */
  43. Mw1Ad = 0x2C/4, /* memory window 1 address */
  44. Mw1Sz = 0x30/4, /* memory window 1 size */
  45. Mw1Org = 0x38/4, /* memory window 1 origin */
  46. Mw1Mask = 0x4C/4, /* Memory window 1 plane mask */
  47. MwcFcnt = 0x50/4, /* memory window cache flush counter */
  48. MwcFlsh = 0x54/4, /* manual cache flush */
  49. YuvLi = 0x58/4, /* YUV LUT index */
  50. YuvLa = 0x5C/4, /* YUV LUT address */
  51. MwCtrl = 0x60/4, /* memory window 0 and 1 control */
  52. };
  53. enum {
  54. IndexLo = 4,
  55. IndexHi = 5,
  56. Data = 6,
  57. IndexCtl = 7,
  58. };
  59. static uchar
  60. _rgb524xi(Vga* vga, int index)
  61. {
  62. ulong *mmio;
  63. mmio = (ulong*)((T2r4*)vga->private)->mmio;
  64. mmio[IndexLo] = index & 0xFF;
  65. mmio[IndexHi] = (index>>8) & 0xFF;
  66. return mmio[Data];
  67. }
  68. static void
  69. _rgb524xo(Vga* vga, int index, uchar data)
  70. {
  71. ulong *mmio;
  72. mmio = (ulong*)((T2r4*)vga->private)->mmio;
  73. mmio[IndexLo] = index & 0xFF;
  74. mmio[IndexHi] = (index>>8) & 0xFF;
  75. mmio[Data] = data;
  76. }
  77. static void
  78. snarf(Vga* vga, Ctlr* ctlr)
  79. {
  80. long m;
  81. int f, i, x;
  82. Pcidev *p;
  83. T2r4 *t2r4;
  84. ulong *rp;
  85. if(vga->private == nil){
  86. vga->private = alloc(sizeof(T2r4));
  87. if((p = pcimatch(0, 0x105D, 0)) == nil)
  88. error("%s: not found\n", ctlr->name);
  89. switch(p->did){
  90. case 0x5348: /* */
  91. break;
  92. default:
  93. error("%s: not found\n", ctlr->name);
  94. }
  95. if((f = open("#v/vgactl", OWRITE)) < 0)
  96. error("%s: can't open vgactl\n", ctlr->name);
  97. if(write(f, "type t2r4", 9) != 9)
  98. error("%s: can't set type\n", ctlr->name);
  99. close(f);
  100. if((m = segattach(0, "t2r4mmio", 0, p->mem[4].size)) == -1)
  101. error("%s: can't attach mmio segment\n", ctlr->name);
  102. t2r4 = vga->private;
  103. t2r4->pci = p;
  104. t2r4->io = p->mem[5].bar & ~0x0F;
  105. t2r4->mmio = m;
  106. }
  107. t2r4 = vga->private;
  108. for(i = 0; i < nelem(t2r4->ioreg); i++)
  109. t2r4->ioreg[i] = inportl(t2r4->io+(i*4));
  110. x = t2r4->ioreg[7] & 0xFF00001F; /* config1 */
  111. outportl(t2r4->io+0x1C, x|0x00331F10);
  112. x = t2r4->ioreg[8] & 0xFF0FFFFF; /* config2 */
  113. outportl(t2r4->io+0x20, x|0x00100000);
  114. x = inportl(t2r4->io+0x30) & 0xFF; /* vgactl */
  115. outportl(t2r4->io+0x30, x|0x82);
  116. rp = (ulong*)t2r4->mmio;
  117. for(i = 0; i < nelem(t2r4->g); i++)
  118. t2r4->g[i] = *rp++;
  119. rp = (ulong*)(t2r4->mmio+8192);
  120. for(i = 0; i < nelem(t2r4->w); i++)
  121. t2r4->w[i] = *rp++;
  122. vga->vma = vga->vmz = t2r4->pci->mem[0].size;
  123. ctlr->flag |= Hlinear;
  124. /*
  125. * Currently, the RGB524 has no need of a snarf
  126. * routine so this will be called before any RGB524 code.
  127. */
  128. if(vga->ramdac && strncmp(vga->ramdac->name, "rgb524mn", 8) == 0){
  129. rgb524mnxi = _rgb524xi;
  130. rgb524mnxo = _rgb524xo;
  131. }
  132. ctlr->flag |= Fsnarf;
  133. }
  134. static void
  135. options(Vga* vga, Ctlr* ctlr)
  136. {
  137. USED(vga);
  138. ctlr->flag |= Foptions;
  139. }
  140. static void
  141. init(Vga* vga, Ctlr* ctlr)
  142. {
  143. char *val;
  144. T2r4 *t2r4;
  145. int crtclocks, zoom;
  146. t2r4 = vga->private;
  147. crtclocks = 64/vga->mode->z;
  148. zoom = 1;
  149. if((val = dbattr(vga->mode->attr, "zoom")) && strtol(val, 0, 0))
  150. zoom = 2;
  151. t2r4->g[DbAdr] = 0;
  152. switch(vga->mode->z){
  153. case 8:
  154. t2r4->g[DbPtch] = vga->mode->x*1;
  155. break;
  156. case 16:
  157. t2r4->g[DbPtch] = vga->mode->x*2;
  158. break;
  159. case 32:
  160. t2r4->g[DbPtch] = vga->mode->x*4;
  161. break;
  162. }
  163. t2r4->g[CrtHac] = vga->mode->x/crtclocks;
  164. t2r4->g[CrtHbl] = (vga->mode->ht-vga->mode->x)/crtclocks;
  165. if(vga->mode->shs == 0)
  166. vga->mode->shs = vga->mode->shb;
  167. t2r4->g[CrtHfp] = (vga->mode->shs-vga->mode->x)/crtclocks;
  168. if(vga->mode->ehs == 0)
  169. vga->mode->ehs = vga->mode->ehb;
  170. t2r4->g[CrtHs] = (vga->mode->ehs-vga->mode->shs)/crtclocks;
  171. t2r4->g[CrtVac] = vga->mode->y * zoom;
  172. t2r4->g[CrtVbl] = (vga->mode->vt-vga->mode->y) * zoom;
  173. t2r4->g[CrtVfp] = (vga->mode->vrs-vga->mode->y) * zoom;
  174. t2r4->g[CrtVs] = (vga->mode->vre-vga->mode->vrs) * zoom;
  175. t2r4->g[CrtZoom] = 0;
  176. /*
  177. * Turn on the syncs and video.
  178. * Bts (bit 0x100) is digital RGB output enable. If there's
  179. * a flat-panel then this is hopefully already set by the BIOS,
  180. * so don't touch it. (It's possible that bit 0 of SoftSw
  181. * indicates flat-panel or CRT).
  182. */
  183. t2r4->g[Crt1con] &= 0x00000100;
  184. t2r4->g[Crt1con] |= 0x70;
  185. t2r4->g[Crt2con] = 0x20000100;
  186. if(zoom == 2)
  187. t2r4->g[CrtZoom] = 1;
  188. t2r4->w[Mw0Ctrl] = 0;
  189. t2r4->w[Mw0Sz] = 0x0D; /* 32MB */
  190. t2r4->w[Mw0Org] = 0;
  191. t2r4->w[Mw0Mask] = 0xFFFFFFFF;
  192. if(vga->linear && (ctlr->flag & Hlinear))
  193. ctlr->flag |= Ulinear;
  194. ctlr->flag |= Finit;
  195. }
  196. static void
  197. load(Vga* vga, Ctlr* ctlr)
  198. {
  199. T2r4 *t2r4;
  200. ulong *g, *w;
  201. t2r4 = vga->private;
  202. g = (ulong*)t2r4->mmio;
  203. g[DbAdr] = t2r4->g[DbAdr];
  204. g[DbPtch] = t2r4->g[DbPtch];
  205. g[CrtHac] = t2r4->g[CrtHac];
  206. g[CrtHbl] = t2r4->g[CrtHbl];
  207. g[CrtHfp] = t2r4->g[CrtHfp];
  208. g[CrtHs] = t2r4->g[CrtHs];
  209. g[CrtVac] = t2r4->g[CrtVac];
  210. g[CrtVbl] = t2r4->g[CrtVbl];
  211. g[CrtVfp] = t2r4->g[CrtVfp];
  212. g[CrtVs] = t2r4->g[CrtVs];
  213. g[Crt1con] = t2r4->g[Crt1con];
  214. g[Crt2con] = t2r4->g[Crt2con];
  215. g[CrtZoom] = t2r4->g[CrtZoom];
  216. w = (ulong*)(t2r4->mmio+8192);
  217. w[Mw0Ctrl] = t2r4->w[Mw0Ctrl];
  218. w[Mw0Sz] = t2r4->w[Mw0Sz];
  219. w[Mw0Org] = t2r4->w[Mw0Org];
  220. w[Mw0Mask] = t2r4->w[Mw0Mask];
  221. if(t2r4->g[CrtZoom])
  222. outportl(t2r4->io+0x30, 0xA2); /* vgactl */
  223. else
  224. outportl(t2r4->io+0x30, 0x82); /* vgactl */
  225. outportl(t2r4->io+0x24, 0x211BF030); /* sgram */
  226. sleep(500);
  227. outportl(t2r4->io+0x24, 0xA11BF030); /* sgram */
  228. ctlr->flag |= Fload;
  229. }
  230. static void
  231. dump(Vga* vga, Ctlr* ctlr)
  232. {
  233. int i;
  234. T2r4 *t2r4;
  235. t2r4 = vga->private;
  236. Bprint(&stdout, "\n");
  237. Bprint(&stdout, "%s ioreg\t\t%8.8luX\n", ctlr->name, t2r4->io);
  238. Bprint(&stdout, "%s rbase_g\t%8.8luX\n", ctlr->name, t2r4->ioreg[0]);
  239. Bprint(&stdout, "%s rbase_w\t%8.8luX\n", ctlr->name, t2r4->ioreg[1]);
  240. Bprint(&stdout, "%s rbase_d\t%8.8luX\n", ctlr->name, t2r4->ioreg[2]);
  241. Bprint(&stdout, "%s rbase_i\t%8.8luX\n", ctlr->name, t2r4->ioreg[4]);
  242. Bprint(&stdout, "%s rbase_e\t%8.8luX\n", ctlr->name, t2r4->ioreg[5]);
  243. Bprint(&stdout, "%s id\t\t\t%8.8luX\n", ctlr->name, t2r4->ioreg[6]);
  244. Bprint(&stdout, "%s config1\t\t%8.8luX\n", ctlr->name, t2r4->ioreg[7]);
  245. Bprint(&stdout, "%s config2\t\t%8.8luX\n", ctlr->name, t2r4->ioreg[8]);
  246. Bprint(&stdout, "%s sgram\t\t%8.8luX\n", ctlr->name, t2r4->ioreg[9]);
  247. Bprint(&stdout, "%s softsw\t\t%8.8luX\n", ctlr->name, t2r4->ioreg[10]);
  248. Bprint(&stdout, "%s ddc\t\t%8.8luX\n", ctlr->name, t2r4->ioreg[11]);
  249. Bprint(&stdout, "%s vgactl\t\t%8.8luX\n", ctlr->name, t2r4->ioreg[12]);
  250. Bprint(&stdout, "\n");
  251. for(i = 0; i < nelem(t2r4->g); i++)
  252. Bprint(&stdout, "%s g reg0x%2.2uX\t\t%8.8luX\n",
  253. ctlr->name, i*4, t2r4->g[i]);
  254. Bprint(&stdout, "\n");
  255. for(i = 0; i < nelem(t2r4->w); i++)
  256. Bprint(&stdout, "%s w reg0x%2.2uX\t\t%8.8luX\n",
  257. ctlr->name, i*4, t2r4->w[i]);
  258. }
  259. Ctlr t2r4 = {
  260. "t2r4", /* name */
  261. snarf, /* snarf */
  262. options, /* options */
  263. init, /* init */
  264. load, /* load */
  265. dump, /* dump */
  266. };
  267. Ctlr t2r4hwgc = {
  268. "t2r4hwgc", /* name */
  269. 0, /* snarf */
  270. 0, /* options */
  271. 0, /* init */
  272. 0, /* load */
  273. 0, /* dump */
  274. };