Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_posix/sys/src/cmd/aux/vga/clgd546x.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | 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
 * Laguna Visual Media Accelerators Family CL-GD546x.
10
 */
11
typedef struct {
12
	Pcidev*	pci;
13
	uchar*	mmio;
14
	int	mem;
15
 
16
	int	format;			/* graphics and video format */
17
	int	threshold;		/* display threshold */
18
	int	tilectrl;		/* tiling control */
19
	int	vsc;			/* vendor specific control */
20
	int	control;		/* control */
21
	int	tilectrl2D3D;		/* tiling control 2D3D */
22
} Laguna;
23
 
24
enum {
25
	Format		= 0xC0,		/* graphics and video format */
26
 
27
	Threshold	= 0xEA,		/* Display Threshold */
28
 
29
	TileCtrl	= 0x2C4,
30
 
31
	Vsc		= 0x3FC,	/* Vendor Specific Control (32-bits) */
32
 
33
	Control		= 0x402,	/* 2D Control */
34
	TileCtrl2D3D	= 0x407,	/* (8-bits) */
35
};
36
 
37
static int
38
mmio8r(Laguna* laguna, int offset)
39
{
40
	return *(laguna->mmio+offset) & 0xFF;
41
}
42
 
43
static void
44
mmio8w(Laguna* laguna, int offset, int data)
45
{
46
	*(laguna->mmio+offset) = data;
47
}
48
 
49
static int
50
mmio16r(Laguna* laguna, int offset)
51
{
52
	return *((ushort*)(laguna->mmio+offset)) & 0xFFFF;
53
}
54
 
55
static void
56
mmio16w(Laguna* laguna, int offset, int data)
57
{
58
	*((ushort*)(laguna->mmio+offset)) = data;
59
}
60
 
61
static int
62
mmio32r(Laguna* laguna, int offset)
63
{
64
	return *((ulong*)(laguna->mmio+offset));
65
}
66
 
67
static void
68
mmio32w(Laguna* laguna, int offset, int data)
69
{
70
	*((ulong*)(laguna->mmio+offset)) = data;
71
}
72
 
73
static void
74
snarf(Vga* vga, Ctlr* ctlr)
75
{
76
	int f, i;
77
	uchar *mmio;
78
	Pcidev *p;
79
	Laguna *laguna;
80
 
81
	/*
82
	 * Save all the registers, even though we'll only
83
	 * change a handful.
84
	 */
85
	for(i = 0x06; i < 0x20; i++)
86
		vga->sequencer[i] = vgaxi(Seqx, i);
87
 
88
	for(i = 0x09; i < 0x0C; i++)
89
		vga->graphics[i] = vgaxi(Grx, i);
90
 
91
	for(i = 0x19; i < 0x20; i++)
92
		vga->crt[i] = vgaxi(Crtx, i);
93
 
94
	if(vga->private == nil){
95
		vga->private = alloc(sizeof(Laguna));
96
		if((p = pcimatch(0, 0x1013, 0)) == nil)
97
			error("%s: not found\n", ctlr->name);
98
		switch(p->did){
99
		case 0xD0:			/* CL-GD5462 */
100
			vga->f[1] = 170000000;
101
			break;
102
		case 0xD4:			/* CL-GD5464 */
103
		case 0xD6:			/* CL-GD5465 */
104
			vga->f[1] = 230000000;
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 clgd546x", 13) != 13)
113
			error("%s: can't set type\n", ctlr->name);
114
		close(f);
115
 
116
		mmio = segattach(0, "clgd546xmmio", 0, p->mem[1].size);
117
		if(mmio == (void*)-1)
118
			error("%s: can't attach mmio segment\n", ctlr->name);
119
		laguna = vga->private;
120
		laguna->pci = p;
121
		laguna->mmio = mmio;
122
	}
123
	laguna = vga->private;
124
 
125
	laguna->mem = (vga->sequencer[0x14] & 0x07)+1;
126
 
127
	laguna->format = mmio16r(laguna, Format);
128
	laguna->threshold = mmio16r(laguna, Threshold);
129
	laguna->tilectrl = mmio16r(laguna, TileCtrl);
130
	laguna->vsc = mmio32r(laguna, Vsc);
131
	laguna->control = mmio16r(laguna, Control);
132
	laguna->tilectrl2D3D = mmio8r(laguna, TileCtrl2D3D);
133
 
134
	vga->vma = vga->vmz = laguna->pci->mem[0].size;
135
	ctlr->flag |= Hlinear;
136
 
137
	ctlr->flag |= Fsnarf;
138
}
139
 
140
static void
141
init(Vga* vga, Ctlr* ctlr)
142
{
143
	Mode *mode;
144
	ushort x;
145
	int format, interleave, fetches, nointerleave, notile, pagesize, tiles;
146
	Laguna *laguna;
147
 
148
	nointerleave = 1;
149
	notile = 1;
150
	pagesize = 0;
151
 
152
	mode = vga->mode;
153
 
154
	if(vga->f[0] == 0)
155
		vga->f[0] = vga->mode->frequency;
156
	if(vga->f[0] > vga->f[1])
157
		error("%s: invalid pclk - %lud\n", ctlr->name, vga->f[0]);
158
 
159
	if(mode->z > 8)
160
		error("%s: depth %d not supported\n", ctlr->name, mode->z);
161
 
162
	/*
163
	 * VCLK3
164
	 */
165
	clgd54xxclock(vga, ctlr);
166
	vga->misc |= 0x0C;
167
	vga->sequencer[0x1E] = vga->n[0];
168
	vga->sequencer[0x0E] = (vga->d[0]<<1)|vga->p[0];
169
 
170
	vga->sequencer[0x07] = 0x00;
171
	if(mode->z == 8)
172
		vga->sequencer[0x07] |= 0x01;
173
 
174
	vga->crt[0x14] = 0;
175
	vga->crt[0x17] = 0xC3;
176
 
177
	/*
178
	 * Overflow bits.
179
	 */
180
	vga->crt[0x1A] = 0x00;
181
	x = mode->ehb>>3;
182
	if(x & 0x40)
183
		vga->crt[0x1A] |= 0x10;
184
	if(x & 0x80)
185
		vga->crt[0x1A] |= 0x20;
186
	if(vga->crt[0x16] & 0x100)
187
		vga->crt[0x1A] |= 0x40;
188
	if(vga->crt[0x16] & 0x200)
189
		vga->crt[0x1A] |= 0x80;
190
	vga->crt[0x1B] = 0x22;
191
	if(vga->crt[0x13] & 0x100)
192
		vga->crt[0x1B] |= 0x10;
193
	vga->crt[0x1D] = 0x00;
194
	if(vga->crt[0x13] & 0x200)
195
		vga->crt[0x1D] |= 0x01;
196
	vga->crt[0x1E] = 0x00;
197
	if(vga->crt[0x10] & 0x400)
198
		vga->crt[0x1E] |= 0x01;
199
	if(vga->crt[0x15] & 0x400)
200
		vga->crt[0x1E] |= 0x02;
201
	if(vga->crt[0x12] & 0x400)
202
		vga->crt[0x1E] |= 0x04;
203
	if(vga->crt[0x06] & 0x400)
204
		vga->crt[0x1E] |= 0x08;
205
	if(vga->crt[0x04] & 0x100)
206
		vga->crt[0x1E] |= 0x10;
207
	if(vga->crt[0x02] & 0x100)
208
		vga->crt[0x1E] |= 0x20;
209
	if(vga->crt[0x01] & 0x100)
210
		vga->crt[0x1E] |= 0x40;
211
	if(vga->crt[0x00] & 0x100)
212
		vga->crt[0x1E] |= 0x80;
213
 
214
	vga->graphics[0x0B] = 0x00;
215
	if(vga->vmz > 1024*1024)
216
		vga->graphics[0x0B] |= 0x20;
217
 
218
	if(mode->interlace == 'v'){
219
		vga->crt[0x19] = vga->crt[0x00]/2;
220
		vga->crt[0x1A] |= 0x01;
221
	}
222
 
223
	if(vga->linear && (ctlr->flag & Hlinear))
224
		ctlr->flag |= Ulinear;
225
 
226
	laguna = vga->private;
227
 
228
	/*
229
	 * Ignore wide tiles for now, this simplifies things.
230
	 */
231
	if(mode->x <= 640)
232
		tiles = 5;
233
	else if(mode->x <= 1024)
234
		tiles = 8;
235
	else if(mode->x <= 1280)
236
		tiles = 10;
237
	else if(mode->x <= 1664)
238
		tiles = 13;
239
	else if(mode->x <= 2048)
240
		tiles = 16;
241
	else if(mode->x <= 2560)
242
		tiles = 20;
243
	else if(mode->x <= 3228)
244
		tiles = 26;
245
	else
246
		tiles = 32;
247
	fetches = tiles;		/* -1? */
248
 
249
	if(nointerleave)
250
		interleave = 0;
251
	else switch(laguna->mem){
252
	default:
253
		interleave = 0;
254
		break;
255
	case 2:
256
		interleave = 1;
257
		break;
258
	case 4:
259
	case 8:
260
		interleave = 2;
261
		break;
262
	}
263
 
264
	if(mode->z == 8)
265
		format = 0;
266
	else if(mode->z == 16)
267
		format = (1<<12)|(2<<9);
268
	else if(mode->z == 24)
269
		format = (2<<12)|(2<<9);
270
	else
271
		format = (2<<12)|(2<<9);
272
 
273
	//if(ctlr->flag & Ulinear)
274
	//	laguna->vsc |= 0x10000000;
275
	//else
276
		laguna->vsc &= ~0x10000000;
277
	laguna->format = format;
278
	laguna->threshold = (interleave<<14)|(fetches<<8)|0x14;
279
	laguna->tilectrl &= 0x3F;
280
	laguna->tilectrl |= (interleave<<14)|(tiles<<8);
281
	if(!notile)
282
		laguna->tilectrl |= 0x80;
283
	if(pagesize == 1)
284
		laguna->tilectrl |= 0x10;
285
	laguna->tilectrl2D3D = (interleave<<6)|tiles;
286
	laguna->control = 0;
287
	if(notile)
288
		laguna->control |= 0x1000;
289
	if(pagesize == 1)
290
		laguna->control |= 0x0200;
291
}
292
 
293
static void
294
load(Vga* vga, Ctlr*)
295
{
296
	Laguna *laguna;
297
 
298
	vgaxo(Seqx, 0x0E, vga->sequencer[0x0E]);
299
	vgaxo(Seqx, 0x1E, vga->sequencer[0x1E]);
300
	vgaxo(Seqx, 0x07, vga->sequencer[0x07]);
301
 
302
	if(vga->mode->interlace == 'v')
303
		vgaxo(Crtx, 0x19, vga->crt[0x19]);
304
	vgaxo(Crtx, 0x1A, vga->crt[0x1A]);
305
	vgaxo(Crtx, 0x1B, vga->crt[0x1B]);
306
	vgaxo(Crtx, 0x1D, vga->crt[0x1D]);
307
	vgaxo(Crtx, 0x1E, vga->crt[0x1E]);
308
 
309
	vgaxo(Grx, 0x0B, vga->graphics[0x0B]);
310
 
311
	laguna = vga->private;
312
	mmio16w(laguna, Format, laguna->format);
313
	mmio32w(laguna, Vsc, laguna->vsc);
314
	mmio16w(laguna, Threshold, laguna->threshold);
315
	mmio16w(laguna, TileCtrl, laguna->tilectrl);
316
	mmio8w(laguna, TileCtrl2D3D, laguna->tilectrl2D3D);
317
	mmio16w(laguna, Control, laguna->control);
318
}
319
 
320
static void
321
dump(Vga* vga, Ctlr* ctlr)
322
{
323
	int i;
324
	char *name;
325
	Laguna *laguna;
326
 
327
	name = ctlr->name;
328
 
329
	printitem(name, "Seq06");
330
	for(i = 0x06; i < 0x20; i++)
331
		printreg(vga->sequencer[i]);
332
 
333
	printitem(name, "Crt19");
334
	for(i = 0x19; i < 0x20; i++)
335
		printreg(vga->crt[i]);
336
 
337
	printitem(name, "Gr09");
338
	for(i = 0x09; i < 0x0C; i++)
339
		printreg(vga->graphics[i]);
340
 
341
	laguna = vga->private;
342
	Bprint(&stdout, "\n");
343
	Bprint(&stdout, "%s mem\t\t%d\n", ctlr->name, laguna->mem*1024*1024);
344
	Bprint(&stdout, "%s Format\t\t%uX\n", ctlr->name, laguna->format);
345
	Bprint(&stdout, "%s Threshold\t\t\t%uX\n",
346
		ctlr->name, laguna->threshold);
347
	Bprint(&stdout, "%s TileCtrl\t\t\t%uX\n", ctlr->name, laguna->tilectrl);
348
	Bprint(&stdout, "%s Vsc\t\t%uX\n", ctlr->name, laguna->vsc);
349
	Bprint(&stdout, "%s Control\t\t%uX\n", ctlr->name, laguna->control);
350
	Bprint(&stdout, "%s TileCtrlC2D3D\t\t%uX\n",
351
		ctlr->name, laguna->tilectrl2D3D);
352
}
353
 
354
Ctlr clgd546x = {
355
	"clgd546x",			/* name */
356
	snarf,				/* snarf */
357
	0,				/* options */
358
	init,				/* init */
359
	load,				/* load */
360
	dump,				/* dump */
361
};
362
 
363
Ctlr clgd546xhwgc = {
364
	"clgd546xhwgc",			/* name */
365
	0,				/* snarf */
366
	0,				/* options */
367
	0,				/* init */
368
	0,				/* load */
369
	0,				/* dump */
370
};