Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | 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
 * Trident Cyber938x.
10
 */
11
typedef struct {
12
	uchar	old[3];
13
	int	pcr;		/* Pixel Command Register */
14
 
15
	int	x;
16
	int	y;
17
} Cyber938x;
18
 
19
/*
20
 * Access to the DAC Pixel Command Register.
21
 * The access is similar to that used on the old
22
 * SGS-Thompson STG1702 Enhanced True Color Palette-DAC
23
 * and Sierra SC1502[56] HiCOLOR-24 Palette.
24
 */
25
static void
26
pcrrw(void)
27
{
28
	int i;
29
 
30
	inportb(PaddrW);
31
	for(i = 0; i < 4; i++)
32
		inportb(Pixmask);
33
}
34
 
35
static int
36
pcrr(void)
37
{
38
	int pcr;
39
 
40
	pcrrw();
41
	pcr = inportb(Pixmask);
42
	inportb(PaddrW);
43
 
44
	return pcr;
45
}
46
 
47
static void
48
pcrw(int pcr)
49
{
50
	pcrrw();
51
	outportb(Pixmask, pcr);
52
	inportb(PaddrW);
53
}
54
 
55
static void
56
snarf(Vga* vga, Ctlr* ctlr)
57
{
58
	int i;
59
	Cyber938x *cyber;
60
 
61
	if(vga->private == nil)
62
		vga->private = alloc(sizeof(Cyber938x));
63
	cyber = vga->private;
64
 
65
	/*
66
	 * Switch to old mode (write to Seq0B), read the old
67
	 * mode registers (Seq0[CDE]) then switch to new mode
68
	 * (read Seq0B).
69
	 */
70
	vgaxo(Seqx, 0x0B, 0);
71
	cyber->old[0] = vgaxi(Seqx, 0x0C);
72
	cyber->old[1] = vgaxi(Seqx, 0x0D);
73
	cyber->old[2] = vgaxi(Seqx, 0x0E);
74
	vga->sequencer[0x0B] = vgaxi(Seqx, 0x0B);
75
 
76
	cyber->pcr = pcrr();
77
 
78
	for(i = 0x08; i < 0x20; i++){
79
		if(i == 0x0B)
80
			continue;
81
		vga->sequencer[i] = vgaxi(Seqx, i);
82
	}
83
	for(i = 0x19; i < 0x60; i++)
84
		vga->crt[i] = vgaxi(Crtx, i);
85
	vga->crt[0xCF] = vgaxi(Crtx, 0xCF);
86
	for(i = 0x09; i < 0x60; i++)
87
		vga->graphics[i] = vgaxi(Grx, i);
88
 
89
	vga->vma = 4*1024*1024;
90
	switch(vga->crt[0x1F] & 0x07){
91
	case 0:
92
	case 4:
93
		vga->vma = 8*1024*1024;
94
		vga->vmz = 8*1024*1024;
95
		break;
96
	case 1:
97
	case 5:
98
		vga->vmz = 4*1024*1024;
99
		break;
100
	case 2:
101
	case 6:
102
		vga->vmz = 768*1024;
103
		break;
104
	case 7:
105
		vga->vmz = 2*1024*1024;
106
		break;
107
	case 3:
108
	default:
109
		vga->vmz = 1024*1024;
110
		break;
111
	}
112
 
113
	switch((vga->graphics[0x52]>>4) & 0x03){
114
	case 0:
115
		cyber->x = 1280;
116
		cyber->y = 1024;
117
		break;
118
 
119
	case 1:
120
		cyber->x = 640;
121
		cyber->y = 480;
122
		break;
123
 
124
	case 2:
125
		cyber->x = 1024;
126
		cyber->y = 768;
127
		break;
128
 
129
	case 3:
130
		cyber->x = 800;
131
		cyber->y = 600;
132
		break;
133
	}
134
 
135
	ctlr->flag |= Fsnarf;
136
}
137
 
138
static void
139
options(Vga* vga, Ctlr* ctlr)
140
{
141
	USED(vga);
142
	ctlr->flag |= Hlinear|Foptions;
143
}
144
 
145
static void
146
init(Vga* vga, Ctlr* ctlr)
147
{
148
	Cyber938x *cyber;
149
 
150
	cyber = vga->private;
151
 
152
	vga->crt[0x1E] = 0x80;
153
	vga->crt[0x2A] |= 0x40;
154
 
155
	if(vga->linear && (ctlr->flag & Hlinear))
156
		ctlr->flag |= Ulinear;
157
 
158
	vga->graphics[0x31] &= 0x8F;
159
	if(vga->mode->y > 768)
160
		vga->graphics[0x31] |= 0x30;
161
	else if(vga->mode->y > 600)
162
		vga->graphics[0x31] |= 0x20;
163
	else if(vga->mode->y > 480)
164
		vga->graphics[0x31] |= 0x10;
165
 
166
	switch(vga->mode->z){
167
	case 8:
168
		cyber->pcr = 0;		/* DAC Pixel Command Register */
169
		vga->crt[0x38] = 0x00;	/* Pixel Bus Register */
170
		break;
171
	case 16:
172
		cyber->pcr = 0x30;
173
		vga->crt[0x38] = 0x05;
174
		vga->crt[0x29] |= 0x10;	/* RSC: necessary for Versa SX */
175
		break;
176
	case 24:
177
		cyber->pcr = 0xD0;
178
		vga->crt[0x38] = 0x29;
179
		break;
180
	default:
181
		error("depth %d not supported\n", vga->mode->z);
182
	}
183
 
184
 
185
	switch(vga->sequencer[0x09]){
186
 
187
	default:
188
		error("unknown Cyber revision 0x%uX\n", vga->sequencer[0x09]);
189
		break;
190
	case 0x21:				/* ProVidia 9685 */
191
		/*
192
		 * Incomplete - no clock code so only 640x480x8 works.
193
		 */
194
		vga->attribute[0x11] = 0;
195
		vga->graphics[0x0F] |= 0x07;
196
		break;
197
	case 0x42:				/* Cyber9382 */
198
		/*
199
		 * Try a little magic for DSTN displays.
200
		 * May work on other chips too, who knows.
201
		 */
202
		if(!(vga->graphics[0x42] & 0x80)	/* !TFT */
203
		&& (vga->graphics[0x43] & 0x20)){	/* DSTN */
204
			if(vga->mode->x == 640)
205
				vga->graphics[0x30] |= 0x81;
206
			else
207
				vga->graphics[0x30] &= ~0x81;
208
		}
209
		/*FALLTHROUGH*/
210
	case 0x3:					/* Cyber9320 */
211
	case 0x33:				/* Cyber9385 */
212
	case 0x34:				/* Cyber9385 */
213
	case 0x35:				/* Cyber9385 */
214
	case 0x3A:				/* Cyber9385 */
215
		vga->graphics[0x0F] |= 0x07;
216
		break;
217
	case 0x41:				/* Cyber9525/DVD */
218
		vga->graphics[0x0F] |= 0x17;
219
		break;
220
	case 0x4A:				/* Cyber9388 */
221
	case 0x5D:				/* CyberBlade */
222
	case 0x6A:				/* CyberBlade (iTuner) */
223
	case 0x7A:				/* CyberBlade */
224
		vga->crt[0x2F] = 0x3F;
225
		vga->graphics[0x0F] |= 0x17;
226
		if(vga->mode->x == 1024)
227
			vga->graphics[0x30] = 0x18;
228
		break;
229
	}
230
	vga->graphics[0x52] &= ~0x01;
231
	vga->graphics[0x53] &= ~0x01;
232
 
233
	ctlr->flag |= Finit;
234
}
235
 
236
static void
237
load(Vga* vga, Ctlr* ctlr)
238
{
239
	Cyber938x *cyber;
240
 
241
	cyber = vga->private;
242
 
243
	outportw(0x3C4, 0x000B);
244
	outportb(0x3C4, 0x0B);
245
	inportb(0x3C5);
246
 
247
	pcrw(cyber->pcr);
248
 
249
	outportw(0x3C4, (0xC2 << 8) | 0x0E);
250
	vgaxo(Grx, 0x52, vga->graphics[0x52]);
251
	vgaxo(Grx, 0x53, vga->graphics[0x53]);
252
	vgaxo(Grx, 0x30, vga->graphics[0x30]);
253
	vgaxo(Grx, 0x31, vga->graphics[0x31]);
254
 
255
	vgaxo(Crtx, 0x1E, vga->crt[0x1E]);
256
	if(ctlr->flag & Ulinear)
257
		vga->crt[0x21] |= 0x20;
258
	vgaxo(Crtx, 0x21, vga->crt[0x21]);
259
	vgaxo(Crtx, 0x29, vga->crt[0x29]);
260
	vgaxo(Crtx, 0x2A, vga->crt[0x2A]);
261
	vgaxo(Crtx, 0x2F, vga->crt[0x2F]);
262
	vgaxo(Crtx, 0x38, vga->crt[0x38]);
263
 
264
	vgaxo(Grx, 0x0F, vga->graphics[0x0F]);
265
 
266
	ctlr->flag |= Fload;
267
}
268
 
269
static void
270
dump(Vga* vga, Ctlr* ctlr)
271
{
272
	char *name;
273
	Cyber938x *cyber;
274
	int i, k, m, n, vclka, vclkb;
275
 
276
	name = ctlr->name;
277
	cyber = vga->private;
278
	printitem(name, "Seq08");
279
	for(i = 0x08; i < 0x20; i++)
280
		printreg(vga->sequencer[i]);
281
	printitem(name, "Old Seq0C");
282
	for(i = 0; i < 3; i++)
283
		printreg(cyber->old[i]);
284
	printitem(name, "pcr");
285
	printreg(cyber->pcr);
286
	printitem(name, "Crt19");
287
	for(i = 0x19; i < 0x20; i++)
288
		printreg(vga->crt[i]);
289
	printitem(name, "Crt20");
290
	for(i = 0x20; i < 0x60; i++)
291
		printreg(vga->crt[i]);
292
	printitem(name, "CrtCF");
293
	printreg(vga->crt[0xCF]);
294
	printitem(name, "Gr09");
295
	for(i = 0x09; i < 0x10; i++)
296
		printreg(vga->graphics[i]);
297
	printitem(name, "Gr10");
298
	for(i = 0x10; i < 0x60; i++)
299
		printreg(vga->graphics[i]);
300
 
301
	if(vga->sequencer[0x09] >= 0x4A){
302
		vclka = vga->sequencer[0x18];
303
		vclkb = vga->sequencer[0x19];
304
	}
305
	else{
306
		vclka = inportb(0x43C8);
307
		vclkb = inportb(0x43C9);
308
		printitem(name, "mclk");
309
		printreg(inportb(0x43C6));
310
		printreg(inportb(0x43C7));
311
	}
312
	printitem(name, "vclk");
313
	printreg(vclka);
314
	printreg(vclkb);
315
	k = vclkb>>6;
316
	m = vclkb & 0x3F;
317
	n = vclka;
318
 	Bprint(&stdout, "%18d\n", (((n+8)*RefFreq)*(1<<k))/(m+2));
319
 
320
	printitem(name, "lcd size");
321
	Bprint(&stdout, "%9ud %8ud\n", cyber->x, cyber->y);
322
}
323
 
324
Ctlr cyber938x = {
325
	"cyber938x",			/* name */
326
	snarf,				/* snarf */
327
	options,			/* options */
328
	init,				/* init */
329
	load,				/* load */
330
	dump,				/* dump */
331
};
332
 
333
Ctlr cyber938xhwgc = {
334
	"cyber938xhwgc",		/* name */
335
	0,				/* snarf */
336
	0,				/* options */
337
	0,				/* init */
338
	0,				/* load */
339
	0,				/* dump */
340
};