17dd7cddfSDavid du Colombier #include <u.h>
27dd7cddfSDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
47dd7cddfSDavid du Colombier
5*9a747e4fSDavid du Colombier #include "pci.h"
67dd7cddfSDavid du Colombier #include "vga.h"
77dd7cddfSDavid du Colombier
87dd7cddfSDavid du Colombier /*
97dd7cddfSDavid du Colombier * S3 Vision968 GUI Accelerator.
107dd7cddfSDavid du Colombier */
117dd7cddfSDavid du Colombier static void
snarf(Vga * vga,Ctlr * ctlr)127dd7cddfSDavid du Colombier snarf(Vga* vga, Ctlr* ctlr)
137dd7cddfSDavid du Colombier {
147dd7cddfSDavid du Colombier s3generic.snarf(vga, ctlr);
157dd7cddfSDavid du Colombier
167dd7cddfSDavid du Colombier vga->sequencer[0x09] = vgaxi(Seqx, 0x09);
177dd7cddfSDavid du Colombier vga->sequencer[0x0A] = vgaxi(Seqx, 0x0A);
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier vga->crt[0x22] = vgaxi(Crtx, 0x22);
207dd7cddfSDavid du Colombier vga->crt[0x24] = vgaxi(Crtx, 0x24);
217dd7cddfSDavid du Colombier vga->crt[0x26] = vgaxi(Crtx, 0x26);
227dd7cddfSDavid du Colombier vga->crt[0x2D] = vgaxi(Crtx, 0x2D);
237dd7cddfSDavid du Colombier vga->crt[0x2E] = vgaxi(Crtx, 0x2E);
247dd7cddfSDavid du Colombier vga->crt[0x2F] = vgaxi(Crtx, 0x2F);
257dd7cddfSDavid du Colombier }
267dd7cddfSDavid du Colombier
277dd7cddfSDavid du Colombier static void
options(Vga *,Ctlr * ctlr)287dd7cddfSDavid du Colombier options(Vga*, Ctlr* ctlr)
297dd7cddfSDavid du Colombier {
307dd7cddfSDavid du Colombier ctlr->flag |= Hlinear|Henhanced|Foptions;
317dd7cddfSDavid du Colombier }
327dd7cddfSDavid du Colombier
337dd7cddfSDavid du Colombier static void
init(Vga * vga,Ctlr * ctlr)347dd7cddfSDavid du Colombier init(Vga* vga, Ctlr* ctlr)
357dd7cddfSDavid du Colombier {
367dd7cddfSDavid du Colombier Mode *mode;
377dd7cddfSDavid du Colombier ulong x;
387dd7cddfSDavid du Colombier int sid, dbl, bpp, divide;
397dd7cddfSDavid du Colombier char *val;
407dd7cddfSDavid du Colombier
417dd7cddfSDavid du Colombier if(vga->mode->z > 8)
427dd7cddfSDavid du Colombier error("depth %d not supported\n", vga->mode->z);
437dd7cddfSDavid du Colombier
447dd7cddfSDavid du Colombier mode = vga->mode;
457dd7cddfSDavid du Colombier if(vga->ramdac && (vga->ramdac->flag & Uclk2)){
467dd7cddfSDavid du Colombier resyncinit(vga, ctlr, Uenhanced, 0);
477dd7cddfSDavid du Colombier vga->crt[0x00] = ((mode->ht/2)>>3)-5;
487dd7cddfSDavid du Colombier vga->crt[0x01] = ((mode->x/2)>>3)-1;
497dd7cddfSDavid du Colombier vga->crt[0x02] = ((mode->shb/2)>>3)-1;
507dd7cddfSDavid du Colombier
517dd7cddfSDavid du Colombier x = (mode->ehb/2)>>3;
527dd7cddfSDavid du Colombier vga->crt[0x03] = 0x80|(x & 0x1F);
537dd7cddfSDavid du Colombier vga->crt[0x04] = (mode->shs/2)>>3;
547dd7cddfSDavid du Colombier vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F;
557dd7cddfSDavid du Colombier if(x & 0x20)
567dd7cddfSDavid du Colombier vga->crt[0x05] |= 0x80;
577dd7cddfSDavid du Colombier vga->crt[0x13] = mode->x/8;
587dd7cddfSDavid du Colombier }
597dd7cddfSDavid du Colombier else if(mode->z == 8)
607dd7cddfSDavid du Colombier resyncinit(vga, ctlr, Uenhanced, 0);
617dd7cddfSDavid du Colombier s3generic.init(vga, ctlr);
627dd7cddfSDavid du Colombier /*
637dd7cddfSDavid du Colombier if((ctlr->flag & Uenhanced) == 0)
647dd7cddfSDavid du Colombier vga->crt[0x33] &= ~0x20;
657dd7cddfSDavid du Colombier */
667dd7cddfSDavid du Colombier vga->crt[0x3B] = (vga->crt[0]+vga->crt[4]+1)/2;
677dd7cddfSDavid du Colombier if(vga->crt[0x3B] & 0x100)
687dd7cddfSDavid du Colombier vga->crt[0x5D] |= 0x40;
697dd7cddfSDavid du Colombier vga->crt[0x55] = 0x00;
707dd7cddfSDavid du Colombier
717dd7cddfSDavid du Colombier vga->crt[0x40] &= ~0x10;
727dd7cddfSDavid du Colombier vga->crt[0x53] &= ~0x20;
737dd7cddfSDavid du Colombier vga->crt[0x58] &= ~0x48;
747dd7cddfSDavid du Colombier vga->crt[0x65] = 0x00;
757dd7cddfSDavid du Colombier vga->crt[0x66] &= ~0x07;
767dd7cddfSDavid du Colombier vga->crt[0x67] = 0x00;
777dd7cddfSDavid du Colombier vga->crt[0x6D] = 0x00;
787dd7cddfSDavid du Colombier if(ctlr->flag & Uenhanced){
797dd7cddfSDavid du Colombier if(vga->ramdac && (vga->ramdac->flag & Hextsid)){
807dd7cddfSDavid du Colombier if(vga->ramdac->flag & Hsid32)
817dd7cddfSDavid du Colombier sid = 32;
827dd7cddfSDavid du Colombier else
837dd7cddfSDavid du Colombier sid = 64;
847dd7cddfSDavid du Colombier if(vga->ramdac->flag & Uclk2)
857dd7cddfSDavid du Colombier dbl = 2;
867dd7cddfSDavid du Colombier else
877dd7cddfSDavid du Colombier dbl = 1;
887dd7cddfSDavid du Colombier if(mode->z < 4)
897dd7cddfSDavid du Colombier bpp = 4;
907dd7cddfSDavid du Colombier else
917dd7cddfSDavid du Colombier bpp = mode->z;
927dd7cddfSDavid du Colombier divide = sid/(dbl*bpp);
937dd7cddfSDavid du Colombier switch(divide){
947dd7cddfSDavid du Colombier case 2:
957dd7cddfSDavid du Colombier vga->crt[0x66] |= 0x01;
967dd7cddfSDavid du Colombier break;
977dd7cddfSDavid du Colombier case 4:
987dd7cddfSDavid du Colombier vga->crt[0x66] |= 0x02;
997dd7cddfSDavid du Colombier break;
1007dd7cddfSDavid du Colombier case 8:
1017dd7cddfSDavid du Colombier vga->crt[0x66] |= 0x03;
1027dd7cddfSDavid du Colombier break;
1037dd7cddfSDavid du Colombier case 16:
1047dd7cddfSDavid du Colombier vga->crt[0x66] |= 0x04;
1057dd7cddfSDavid du Colombier break;
1067dd7cddfSDavid du Colombier case 32:
1077dd7cddfSDavid du Colombier vga->crt[0x66] |= 0x05;
1087dd7cddfSDavid du Colombier break;
1097dd7cddfSDavid du Colombier }
1107dd7cddfSDavid du Colombier }
1117dd7cddfSDavid du Colombier
1127dd7cddfSDavid du Colombier vga->crt[0x40] |= 0x10;
1137dd7cddfSDavid du Colombier vga->crt[0x58] |= 0x40;
1147dd7cddfSDavid du Colombier
1157dd7cddfSDavid du Colombier /*
1167dd7cddfSDavid du Colombier * The test against 1376 is necessary for the STB
1177dd7cddfSDavid du Colombier * Velocity 64 Video, no idea if it's relevant to other
1187dd7cddfSDavid du Colombier * cards.
1197dd7cddfSDavid du Colombier * Although not mentioned in the databook, bit 4 of Crt67
1207dd7cddfSDavid du Colombier * needs to be set on the STB Velocity 64 Video too. Gak.
1217dd7cddfSDavid du Colombier */
1227dd7cddfSDavid du Colombier if(dbattr(vga->attr, "disa1sc") && mode->x <= 1376)
1237dd7cddfSDavid du Colombier vga->crt[0x65] |= 0x02;
1247dd7cddfSDavid du Colombier if(vga->ramdac && strncmp(vga->ramdac->name, "tvp3026", 7))
1257dd7cddfSDavid du Colombier vga->crt[0x67] |= 0x10;
1267dd7cddfSDavid du Colombier
1277dd7cddfSDavid du Colombier if(dbattr(vga->attr, "vclkphs"))
1287dd7cddfSDavid du Colombier vga->crt[0x67] |= 0x01;
1297dd7cddfSDavid du Colombier if(val = dbattr(vga->attr, "delaybl"))
1307dd7cddfSDavid du Colombier vga->crt[0x6D] |= strtoul(val, 0, 0) & 0x07;
1317dd7cddfSDavid du Colombier if(val = dbattr(vga->attr, "delaysc"))
1327dd7cddfSDavid du Colombier vga->crt[0x6D] |= (strtoul(val, 0, 0) & 0x07)<<4;
1337dd7cddfSDavid du Colombier }
1347dd7cddfSDavid du Colombier }
1357dd7cddfSDavid du Colombier
1367dd7cddfSDavid du Colombier static void
load(Vga * vga,Ctlr * ctlr)1377dd7cddfSDavid du Colombier load(Vga* vga, Ctlr* ctlr)
1387dd7cddfSDavid du Colombier {
1397dd7cddfSDavid du Colombier ushort advfunc;
1407dd7cddfSDavid du Colombier
1417dd7cddfSDavid du Colombier s3generic.load(vga, ctlr);
1427dd7cddfSDavid du Colombier vgaxo(Crtx, 0x65, vga->crt[0x65]);
1437dd7cddfSDavid du Colombier vgaxo(Crtx, 0x66, vga->crt[0x66]);
1447dd7cddfSDavid du Colombier vgaxo(Crtx, 0x67, vga->crt[0x67]);
1457dd7cddfSDavid du Colombier vgaxo(Crtx, 0x6D, vga->crt[0x6D]);
1467dd7cddfSDavid du Colombier
1477dd7cddfSDavid du Colombier advfunc = 0x0000;
1487dd7cddfSDavid du Colombier if(ctlr->flag & Uenhanced)
1497dd7cddfSDavid du Colombier advfunc = 0x0001;
1507dd7cddfSDavid du Colombier outportw(0x4AE8, advfunc);
1517dd7cddfSDavid du Colombier }
1527dd7cddfSDavid du Colombier
1537dd7cddfSDavid du Colombier static void
dump(Vga * vga,Ctlr * ctlr)1547dd7cddfSDavid du Colombier dump(Vga* vga, Ctlr* ctlr)
1557dd7cddfSDavid du Colombier {
1567dd7cddfSDavid du Colombier s3generic.dump(vga, ctlr);
1577dd7cddfSDavid du Colombier
1587dd7cddfSDavid du Colombier printitem(ctlr->name, "Seq09");
1597dd7cddfSDavid du Colombier printreg(vga->sequencer[0x09]);
1607dd7cddfSDavid du Colombier printreg(vga->sequencer[0x0A]);
1617dd7cddfSDavid du Colombier
1627dd7cddfSDavid du Colombier printitem(ctlr->name, "Crt22");
1637dd7cddfSDavid du Colombier printreg(vga->crt[0x22]);
1647dd7cddfSDavid du Colombier printitem(ctlr->name, "Crt24");
1657dd7cddfSDavid du Colombier printreg(vga->crt[0x24]);
1667dd7cddfSDavid du Colombier printitem(ctlr->name, "Crt26");
1677dd7cddfSDavid du Colombier printreg(vga->crt[0x26]);
1687dd7cddfSDavid du Colombier printitem(ctlr->name, "Crt2D");
1697dd7cddfSDavid du Colombier printreg(vga->crt[0x2D]);
1707dd7cddfSDavid du Colombier printreg(vga->crt[0x2E]);
1717dd7cddfSDavid du Colombier printreg(vga->crt[0x2F]);
1727dd7cddfSDavid du Colombier }
1737dd7cddfSDavid du Colombier
1747dd7cddfSDavid du Colombier Ctlr vision968 = {
1757dd7cddfSDavid du Colombier "vision968", /* name */
1767dd7cddfSDavid du Colombier snarf, /* snarf */
1777dd7cddfSDavid du Colombier options, /* options */
1787dd7cddfSDavid du Colombier init, /* init */
1797dd7cddfSDavid du Colombier load, /* load */
1807dd7cddfSDavid du Colombier dump, /* dump */
1817dd7cddfSDavid du Colombier };
182