1219b2ee8SDavid du Colombier #include <u.h>
2219b2ee8SDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <bio.h>
4219b2ee8SDavid du Colombier
5*9a747e4fSDavid du Colombier #include "pci.h"
6219b2ee8SDavid du Colombier #include "vga.h"
7219b2ee8SDavid du Colombier
8219b2ee8SDavid du Colombier /*
97dd7cddfSDavid du Colombier * S3 Vision864 GUI Accelerator.
10219b2ee8SDavid du Colombier * Pretty much the same as the 86C80[15].
11219b2ee8SDavid du Colombier * First pass, needs tuning.
12219b2ee8SDavid du Colombier */
13219b2ee8SDavid du Colombier static void
snarf(Vga * vga,Ctlr * ctlr)14219b2ee8SDavid du Colombier snarf(Vga* vga, Ctlr* ctlr)
15219b2ee8SDavid du Colombier {
167dd7cddfSDavid du Colombier s3generic.snarf(vga, ctlr);
17219b2ee8SDavid du Colombier }
18219b2ee8SDavid du Colombier
19219b2ee8SDavid du Colombier static void
options(Vga *,Ctlr * ctlr)207dd7cddfSDavid du Colombier options(Vga*, Ctlr* ctlr)
21219b2ee8SDavid du Colombier {
227dd7cddfSDavid du Colombier ctlr->flag |= Hlinear|Hpclk2x8|Henhanced|Foptions;
23219b2ee8SDavid du Colombier }
24219b2ee8SDavid du Colombier
25219b2ee8SDavid du Colombier static void
init(Vga * vga,Ctlr * ctlr)26219b2ee8SDavid du Colombier init(Vga* vga, Ctlr* ctlr)
27219b2ee8SDavid du Colombier {
28219b2ee8SDavid du Colombier ulong x;
297dd7cddfSDavid du Colombier char *val;
30219b2ee8SDavid du Colombier
317dd7cddfSDavid du Colombier s3generic.init(vga, ctlr);
32219b2ee8SDavid du Colombier vga->crt[0x3B] = vga->crt[0]-5;
33219b2ee8SDavid du Colombier
347dd7cddfSDavid du Colombier if(vga->mode->z > 8)
357dd7cddfSDavid du Colombier error("depth %d not supported\n", vga->mode->z);
367dd7cddfSDavid du Colombier
37219b2ee8SDavid du Colombier /*
38219b2ee8SDavid du Colombier * VL-bus crap.
39219b2ee8SDavid du Colombier */
40219b2ee8SDavid du Colombier if((vga->crt[0x36] & 0x03) == 0x01){
41219b2ee8SDavid du Colombier vga->crt[0x40] |= 0x08;
42219b2ee8SDavid du Colombier vga->crt[0x58] &= ~0x88;
43219b2ee8SDavid du Colombier }
44219b2ee8SDavid du Colombier
45219b2ee8SDavid du Colombier /*
46219b2ee8SDavid du Colombier * Display memory access control.
47219b2ee8SDavid du Colombier * Calculation of the M-parameter (Crt54) is
48219b2ee8SDavid du Colombier * memory-system and dot-clock dependent, the
49219b2ee8SDavid du Colombier * values below are guesses from dumping
50219b2ee8SDavid du Colombier * registers.
51219b2ee8SDavid du Colombier */
52219b2ee8SDavid du Colombier vga->crt[0x60] = 0xFF;
53219b2ee8SDavid du Colombier x = vga->mode->x/8;
54219b2ee8SDavid du Colombier vga->crt[0x61] = 0x80|((x>>8) & 0x07);
55219b2ee8SDavid du Colombier vga->crt[0x62] = (x & 0xFF);
56219b2ee8SDavid du Colombier if(vga->mode->x <= 800)
57219b2ee8SDavid du Colombier vga->crt[0x54] = 0x88;
58219b2ee8SDavid du Colombier else if(vga->mode->x <= 1024)
59219b2ee8SDavid du Colombier vga->crt[0x54] = 0xF8;
60219b2ee8SDavid du Colombier else
61219b2ee8SDavid du Colombier vga->crt[0x54] = 0x40;
62219b2ee8SDavid du Colombier
63219b2ee8SDavid du Colombier vga->crt[0x67] &= ~0xF0;
64219b2ee8SDavid du Colombier if(ctlr->flag & Upclk2x8)
65219b2ee8SDavid du Colombier vga->crt[0x67] |= 0x10;
66219b2ee8SDavid du Colombier
677dd7cddfSDavid du Colombier vga->crt[0x69] = 0x00;
687dd7cddfSDavid du Colombier vga->crt[0x6A] = 0x00;
697dd7cddfSDavid du Colombier
70219b2ee8SDavid du Colombier /*
71219b2ee8SDavid du Colombier * Blank adjust.
72219b2ee8SDavid du Colombier * This may not be correct for all monitors.
73219b2ee8SDavid du Colombier */
747dd7cddfSDavid du Colombier vga->crt[0x6D] = 0x00;
757dd7cddfSDavid du Colombier if(val = dbattr(vga->attr, "delaybl"))
767dd7cddfSDavid du Colombier vga->crt[0x6D] |= strtoul(val, 0, 0) & 0x07;
777dd7cddfSDavid du Colombier else
787dd7cddfSDavid du Colombier vga->crt[0x6D] |= 2;
797dd7cddfSDavid du Colombier if(val = dbattr(vga->attr, "delaysc"))
807dd7cddfSDavid du Colombier vga->crt[0x6D] |= (strtoul(val, 0, 0) & 0x07)<<4;
81219b2ee8SDavid du Colombier }
82219b2ee8SDavid du Colombier
83219b2ee8SDavid du Colombier static void
load(Vga * vga,Ctlr * ctlr)84219b2ee8SDavid du Colombier load(Vga* vga, Ctlr* ctlr)
85219b2ee8SDavid du Colombier {
86219b2ee8SDavid du Colombier ushort advfunc;
87219b2ee8SDavid du Colombier
887dd7cddfSDavid du Colombier s3generic.load(vga, ctlr);
89219b2ee8SDavid du Colombier vgaxo(Crtx, 0x60, vga->crt[0x60]);
90219b2ee8SDavid du Colombier vgaxo(Crtx, 0x61, vga->crt[0x61]);
91219b2ee8SDavid du Colombier vgaxo(Crtx, 0x62, vga->crt[0x62]);
92219b2ee8SDavid du Colombier vgaxo(Crtx, 0x67, vga->crt[0x67]);
937dd7cddfSDavid du Colombier vgaxo(Crtx, 0x69, vga->crt[0x69]);
947dd7cddfSDavid du Colombier vgaxo(Crtx, 0x6A, vga->crt[0x6A]);
95219b2ee8SDavid du Colombier vgaxo(Crtx, 0x6D, vga->crt[0x6D]);
96219b2ee8SDavid du Colombier
97219b2ee8SDavid du Colombier advfunc = 0x0000;
98219b2ee8SDavid du Colombier if(ctlr->flag & Uenhanced){
99219b2ee8SDavid du Colombier if(vga->mode->x == 1024 || vga->mode->x == 800)
100219b2ee8SDavid du Colombier advfunc = 0x0057;
101219b2ee8SDavid du Colombier else
102219b2ee8SDavid du Colombier advfunc = 0x0053;
103219b2ee8SDavid du Colombier }
104219b2ee8SDavid du Colombier outportw(0x4AE8, advfunc);
105219b2ee8SDavid du Colombier }
106219b2ee8SDavid du Colombier
107219b2ee8SDavid du Colombier static void
dump(Vga * vga,Ctlr * ctlr)108219b2ee8SDavid du Colombier dump(Vga* vga, Ctlr* ctlr)
109219b2ee8SDavid du Colombier {
1107dd7cddfSDavid du Colombier s3generic.dump(vga, ctlr);
111219b2ee8SDavid du Colombier }
112219b2ee8SDavid du Colombier
113219b2ee8SDavid du Colombier Ctlr vision864 = {
114219b2ee8SDavid du Colombier "vision864", /* name */
115219b2ee8SDavid du Colombier snarf, /* snarf */
116219b2ee8SDavid du Colombier options, /* options */
117219b2ee8SDavid du Colombier init, /* init */
118219b2ee8SDavid du Colombier load, /* load */
119219b2ee8SDavid du Colombier dump, /* dump */
120219b2ee8SDavid du Colombier };
121