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