Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
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
};