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_tlsv12/sys/src/cmd/aux/vga/ics534x.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
 * ICS534x GENDAC.
10
 * For now assumed to be hooked to either a Tseng Labs ET4000-W32p
11
 * (Hercules Dynamite Power, the Hercules generates RS2 using CLK3)
12
 * or an ARK2000pv (Diamond Stealth64 Graphics 2001).
13
 */
14
static uchar
15
setrs2(Vga* vga, Ctlr* ctlr)
16
{
17
	uchar rs2;
18
 
19
	rs2 = 0;
20
	if(strncmp(vga->ctlr->name, "et4000-w32", 10) == 0){
21
		rs2 = vgaxi(Crtx, 0x31);
22
		vgaxo(Crtx, 0x31, 0x40|rs2);
23
	}
24
	else if(strncmp(vga->ctlr->name, "ark2000pv", 9) == 0){
25
		rs2 = vgaxi(Seqx, 0x1C);
26
		vgaxo(Seqx, 0x1C, 0x80|rs2);
27
	}
28
	else
29
		error("%s: not configured for %s\n", vga->ctlr->name, ctlr->name);
30
 
31
	return rs2;
32
}
33
 
34
static void
35
restorers2(Vga* vga, uchar rs2)
36
{
37
	if(strncmp(vga->ctlr->name, "et4000-w32", 10) == 0)
38
		vgaxo(Crtx, 0x31, rs2);
39
	else if(strncmp(vga->ctlr->name, "ark2000pv", 9) == 0)
40
		vgaxo(Seqx, 0x1C, rs2);
41
}
42
 
43
static void
44
options(Vga*, Ctlr* ctlr)
45
{
46
	ctlr->flag |= Hpclk2x8|Foptions;
47
}
48
 
49
static void
50
clock(Vga* vga, Ctlr* ctlr)
51
{
52
	ulong f, m, n, r;
53
	double fmin, fmax, t, tok;
54
 
55
	/*
56
	 * The PLL frequency is defined by:
57
	 *		    (M+2)
58
	 *	 Fout = ------------ x Fref
59
	 *	        (N+2) x 2**R
60
	 * where M, N and R have the following contraints:
61
	 * 1)	     2MHz < Fref < 32MHz
62
	 * 2)		    Fref
63
	 *         600KHz < ----- <= 8Mhz
64
	 *	            (N+2)
65
	 * 3)		(M+2) x Fref
66
	 *     60MHz <= ------------ <= 270MHz
67
	 *		    (N+2)
68
	 * 4) Fout < 135MHz
69
	 * 5) 1 <= M <= 127, 1 <= N <= 31, 0 <= R <= 3
70
	 *
71
	 * First determine R by finding the highest value
72
	 * for which
73
	 *	      2**R x Fout <= 270Mhz
74
	 * The datasheet says that if the multiplexed 16-bit
75
	 * pseudo-colour mode is used then N2 (vga->r) must
76
	 * be 2.
77
	 */
78
	if(ctlr->flag & Upclk2x8)
79
		vga->r[0] = 2;
80
	else{
81
		vga->r[0] = 4;
82
		for(r = 0; r <= 3; r++){
83
			f = vga->f[0]*(1<<r);
84
			if(60000000 < f && f <= 270000000)
85
				vga->r[0] = r;
86
		}
87
		if(vga->r[0] > 3)
88
			error("%s: pclk %lud out of range\n",
89
				ctlr->name, vga->f[0]);
90
	}
91
 
92
	/*
93
	 * Now find the closest match for M and N.
94
	 * Lower values of M and N give better noise rejection.
95
	 */
96
	fmin = vga->f[0]*0.995;
97
	fmax = vga->f[0]*1.005;
98
	tok = 0.0;
99
	for(n = 31; n >= 1; n--){
100
		t = RefFreq/(n+2);
101
		if(600000 >= t || t > 8000000)
102
			continue;
103
 
104
		t = vga->f[0]*(n+2)*(1<<vga->r[0]);
105
		t /= RefFreq;
106
		m = (t+0.5) - 2;
107
		if(m > 127)
108
			continue;
109
 
110
		t = (m+2)*RefFreq;
111
		t /= (n+2)*(1<<vga->r[0]);
112
 
113
		if(fmin <= t && t < fmax){
114
			vga->m[0] = m;
115
			vga->n[0] = n;
116
			tok = t;
117
		}
118
	}
119
 
120
	if(tok == 0.0)
121
		error("%s: pclk %lud out of range\n", ctlr->name, vga->f[0]);
122
}
123
 
124
static void
125
init(Vga* vga, Ctlr* ctlr)
126
{
127
	ulong pclk;
128
	char *p;
129
 
130
	/*
131
	 * Part comes in -135, -110 and -80MHz speed-grades.
132
	 */
133
	pclk = 80000000;
134
	if(p = strrchr(ctlr->name, '-'))
135
		pclk = strtoul(p+1, 0, 0) * 1000000;
136
 
137
	/*
138
	 * If we don't already have a desired pclk,
139
	 * take it from the mode.
140
	 * Check it's within range.
141
	 */
142
	if(vga->f[0] == 0)
143
		vga->f[0] = vga->mode->frequency;
144
	if(vga->f[0] > pclk)
145
		error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]);
146
 
147
	/*
148
	 * Determine whether to use 2x8-bit mode or not.
149
	 * If yes and the clock has already been initialised,
150
	 * initialise it again.
151
	 */
152
	if(vga->ctlr && (vga->ctlr->flag & Hpclk2x8) && vga->mode->z == 8 && vga->f[0] >= pclk/2){
153
		vga->f[0] /= 2;
154
		resyncinit(vga, ctlr, Upclk2x8, 0);
155
	}
156
 
157
	/*
158
	 * Clock bits. If the desired video clock is
159
	 * one of the two standard VGA clocks it can just be
160
	 * set using bits <3:2> of vga->misc, otherwise we
161
	 * need to programme the DCLK PLL.
162
	 */
163
	vga->misc &= ~0x0C;
164
	if(vga->f[0] == VgaFreq0)
165
		vga->i[0] = 0;
166
	else if(vga->f[0] == VgaFreq1){
167
		vga->misc |= 0x04;
168
		vga->i[0] = 1;
169
	}
170
	else{
171
		/*
172
		 * Initialise the PLL parameters.
173
		 * Use CLK0 f7 internal clock (there are only 3
174
		 * clock-select bits).
175
		 */
176
		clock(vga, ctlr);
177
		vga->i[0] = 0x07;
178
	}
179
 
180
	ctlr->flag |= Finit;
181
}
182
 
183
static void
184
load(Vga* vga, Ctlr* ctlr)
185
{
186
	uchar rs2, mode, pll;
187
 
188
	rs2 = setrs2(vga, ctlr);
189
 
190
	/*
191
	 * Put the chip into snooze mode,
192
	 * colour mode 0.
193
	 */
194
	mode = 0x00;
195
	outportb(Pixmask, 0x01);
196
 
197
	if(ctlr->flag & Upclk2x8)
198
		mode = 0x10;
199
 
200
	/*
201
	 * If necessary, set the PLL parameters for CLK0 f7
202
	 * and make sure the PLL control register selects the
203
	 * correct clock. Preserve the memory clock setting.
204
	 */
205
	outportb(PaddrR, 0x0E);
206
	pll = inportb(Pdata) & 0x10;
207
	if(vga->i[0] == 0x07){
208
		outportb(PaddrW, vga->i[0]);
209
		outportb(Pdata, vga->m[0]);
210
		outportb(Pdata, (vga->r[0]<<5)|vga->n[0]);
211
		pll |= 0x27;
212
	}
213
	outportb(PaddrW, 0x0E);
214
	outportb(Pdata, pll);
215
	outportb(Pixmask, mode);
216
 
217
	restorers2(vga, rs2);
218
	ctlr->flag |= Fload;
219
}
220
 
221
static void
222
dump(Vga* vga, Ctlr* ctlr)
223
{
224
	int i;
225
	uchar rs2, m, n;
226
	char buf[32];
227
	ulong f;
228
 
229
	rs2 = setrs2(vga, ctlr);
230
 
231
	printitem(ctlr->name, "command");
232
	printreg(inportb(Pixmask));
233
 
234
	outportb(PaddrR, 0x00);
235
	for(i = 0; i < 0x0E; i++){
236
		sprint(buf, "f%X m n", i);
237
		printitem(ctlr->name, buf);
238
		m = inportb(Pdata);
239
		printreg(m);
240
		n = inportb(Pdata);
241
		printreg(n);
242
 
243
		f = 14318180*(m+2);
244
		f /= (n & 0x1F)+2;
245
		f /= 1<<((n>>5) & 0x03);
246
		Bprint(&stdout, "%12lud", f);
247
	}
248
	printitem(ctlr->name, "control");
249
	printreg(inportb(Pdata));
250
 
251
	restorers2(vga, rs2);
252
}
253
 
254
Ctlr ics534x = {
255
	"ics534x",			/* name */
256
	0,				/* snarf */
257
	options,			/* options */
258
	init,				/* init */
259
	load,				/* load */
260
	dump,				/* dump */
261
};