xref: /netbsd-src/sys/arch/bebox/stand/boot/vreset.c (revision c2f76ff004a2cb67efe5b12d97bd3ef7fe89e18d)
1 /*	$NetBSD: vreset.c,v 1.13 2010/10/15 20:01:03 he Exp $	*/
2 
3 /*
4  * Copyright (C) 1995-1997 Gary Thomas (gdt@linuxppc.org)
5  * All rights reserved.
6  *
7  * Initialize the VGA control registers to 80x25 text mode.
8  *
9  * Adapted from a program by:
10  *                                      Steve Sellgren
11  *                                      San Francisco Indigo Company
12  *                                      sfindigo!sellgren@uunet.uu.net
13  * Adapted for Moto boxes by:
14  *                                      Pat Kane & Mark Scott, 1996
15  * Fixed for IBM/PowerStack II          Pat Kane 1997
16  *
17  * Redistribution and use in source and binary forms, with or without
18  * modification, are permitted provided that the following conditions
19  * are met:
20  * 1. Redistributions of source code must retain the above copyright
21  *    notice, this list of conditions and the following disclaimer.
22  * 2. Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the
24  *    documentation and/or other materials provided with the distribution.
25  * 3. All advertising materials mentioning features or use of this software
26  *    must display the following acknowledgement:
27  *      This product includes software developed by Gary Thomas.
28  * 4. The name of the author may not be used to endorse or promote products
29  *    derived from this software without specific prior written permission.
30  *
31  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
32  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
33  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
34  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
35  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
36  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
37  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
38  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
39  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
40  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
41  */
42 
43 #ifdef CONS_VGA
44 #include <lib/libsa/stand.h>
45 #include "boot.h"
46 #include "iso_font.h"
47 
48 /*
49  * VGA Register
50  */
51 struct VgaRegs
52 {
53 	u_short io_port;
54 	u_char io_index;
55 	u_char io_value;
56 };
57 
58 /*
59  * Default console text mode registers  used to reset
60  * graphics adapter.
61  */
62 #define NREGS 54
63 #define ENDMK  0xFFFF  /* End marker */
64 
65 #define S3Vendor	0x5333
66 #define CirrusVendor	0x1013
67 #define DiamondVendor	0x100E
68 #define MatroxVendor	0x102B
69 
70 struct VgaRegs GenVgaTextRegs[NREGS+1] = {
71 /*      port    index   value */
72 	/* SR Regs */
73         { 0x3c4, 0x1, 0x0 },
74         { 0x3c4, 0x2, 0x3 },
75         { 0x3c4, 0x3, 0x0 },
76         { 0x3c4, 0x4, 0x2 },
77 	/* CR Regs */
78         { 0x3d4, 0x0, 0x5f },
79         { 0x3d4, 0x1, 0x4f },
80         { 0x3d4, 0x2, 0x50 },
81         { 0x3d4, 0x3, 0x82 },
82         { 0x3d4, 0x4, 0x55 },
83         { 0x3d4, 0x5, 0x81 },
84         { 0x3d4, 0x6, 0xbf },
85         { 0x3d4, 0x7, 0x1f },
86         { 0x3d4, 0x8, 0x00 },
87         { 0x3d4, 0x9, 0x4f },
88         { 0x3d4, 0xa, 0x0d },
89         { 0x3d4, 0xb, 0x0e },
90         { 0x3d4, 0xc, 0x00 },
91         { 0x3d4, 0xd, 0x00 },
92         { 0x3d4, 0xe, 0x00 },
93         { 0x3d4, 0xf, 0x00 },
94         { 0x3d4, 0x10, 0x9c },
95         { 0x3d4, 0x11, 0x8e },
96         { 0x3d4, 0x12, 0x8f },
97         { 0x3d4, 0x13, 0x28 },
98         { 0x3d4, 0x14, 0x1f },
99         { 0x3d4, 0x15, 0x96 },
100         { 0x3d4, 0x16, 0xb9 },
101         { 0x3d4, 0x17, 0xa3 },
102 	/* GR Regs */
103         { 0x3ce, 0x0, 0x0 },
104         { 0x3ce, 0x1, 0x0 },
105         { 0x3ce, 0x2, 0x0 },
106         { 0x3ce, 0x3, 0x0 },
107         { 0x3ce, 0x4, 0x0 },
108         { 0x3ce, 0x5, 0x10 },
109         { 0x3ce, 0x6, 0xe },
110         { 0x3ce, 0x7, 0x0 },
111         { 0x3ce, 0x8, 0xff },
112         { ENDMK },
113 };
114 
115 struct VgaRegs S3TextRegs[NREGS+1] = {
116 /*	port	index	value */
117 	/* SR Regs */
118 	{ 0x3c4, 0x1, 0x0 },
119 	{ 0x3c4, 0x2, 0x3 },
120 	{ 0x3c4, 0x3, 0x0 },
121 	{ 0x3c4, 0x4, 0x2 },
122 	/* CR Regs */
123 	{ 0x3d4, 0x0, 0x5f },
124 	{ 0x3d4, 0x1, 0x4f },
125 	{ 0x3d4, 0x2, 0x50 },
126 	{ 0x3d4, 0x3, 0x82 },
127 	{ 0x3d4, 0x4, 0x55 },
128 	{ 0x3d4, 0x5, 0x81 },
129 	{ 0x3d4, 0x6, 0xbf },
130 	{ 0x3d4, 0x7, 0x1f },
131 	{ 0x3d4, 0x8, 0x00 },
132 	{ 0x3d4, 0x9, 0x4f },
133 	{ 0x3d4, 0xa, 0x0d },
134 	{ 0x3d4, 0xb, 0x0e },
135 	{ 0x3d4, 0xc, 0x00 },
136 	{ 0x3d4, 0xd, 0x00 },
137 	{ 0x3d4, 0xe, 0x00 },
138 	{ 0x3d4, 0xf, 0x00 },
139 	{ 0x3d4, 0x10, 0x9c },
140 	{ 0x3d4, 0x11, 0x8e },
141 	{ 0x3d4, 0x12, 0x8f },
142 	{ 0x3d4, 0x13, 0x28 },
143 	{ 0x3d4, 0x14, 0x1f },
144 	{ 0x3d4, 0x15, 0x96 },
145 	{ 0x3d4, 0x16, 0xb9 },
146 	{ 0x3d4, 0x17, 0xa3 },
147 	/* GR Regs */
148 	{ 0x3ce, 0x0, 0x0 },
149 	{ 0x3ce, 0x1, 0x0 },
150 	{ 0x3ce, 0x2, 0x0 },
151 	{ 0x3ce, 0x3, 0x0 },
152 	{ 0x3ce, 0x4, 0x0 },
153 	{ 0x3ce, 0x5, 0x10 },
154 	{ 0x3ce, 0x6, 0xe },
155 	{ 0x3ce, 0x7, 0x0 },
156 	{ 0x3ce, 0x8, 0xff },
157         { ENDMK }
158 };
159 
160 struct RGBColors {
161 	u_char r, g, b;
162 };
163 
164 /*
165  * Default console text mode color table.
166  * These values were obtained by booting Linux with
167  * text mode firmware & then dumping the registers.
168  */
169 struct RGBColors TextCLUT[256] = {
170 /*	red	green	blue */
171 	{ 0x0,	0x0,	0x0 },
172 	{ 0x0,	0x0,	0x2a },
173 	{ 0x0,	0x2a,	0x0 },
174 	{ 0x0,	0x2a,	0x2a },
175 	{ 0x2a,	0x0,	0x0 },
176 	{ 0x2a,	0x0,	0x2a },
177 	{ 0x2a,	0x2a,	0x0 },
178 	{ 0x2a,	0x2a,	0x2a },
179 	{ 0x0,	0x0,	0x15 },
180 	{ 0x0,	0x0,	0x3f },
181 	{ 0x0,	0x2a,	0x15 },
182 	{ 0x0,	0x2a,	0x3f },
183 	{ 0x2a,	0x0,	0x15 },
184 	{ 0x2a,	0x0,	0x3f },
185 	{ 0x2a,	0x2a,	0x15 },
186 	{ 0x2a,	0x2a,	0x3f },
187 	{ 0x0,	0x15,	0x0 },
188 	{ 0x0,	0x15,	0x2a },
189 	{ 0x0,	0x3f,	0x0 },
190 	{ 0x0,	0x3f,	0x2a },
191 	{ 0x2a,	0x15,	0x0 },
192 	{ 0x2a,	0x15,	0x2a },
193 	{ 0x2a,	0x3f,	0x0 },
194 	{ 0x2a,	0x3f,	0x2a },
195 	{ 0x0,	0x15,	0x15 },
196 	{ 0x0,	0x15,	0x3f },
197 	{ 0x0,	0x3f,	0x15 },
198 	{ 0x0,	0x3f,	0x3f },
199 	{ 0x2a,	0x15,	0x15 },
200 	{ 0x2a,	0x15,	0x3f },
201 	{ 0x2a,	0x3f,	0x15 },
202 	{ 0x2a,	0x3f,	0x3f },
203 	{ 0x15,	0x0,	0x0 },
204 	{ 0x15,	0x0,	0x2a },
205 	{ 0x15,	0x2a,	0x0 },
206 	{ 0x15,	0x2a,	0x2a },
207 	{ 0x3f,	0x0,	0x0 },
208 	{ 0x3f,	0x0,	0x2a },
209 	{ 0x3f,	0x2a,	0x0 },
210 	{ 0x3f,	0x2a,	0x2a },
211 	{ 0x15,	0x0,	0x15 },
212 	{ 0x15,	0x0,	0x3f },
213 	{ 0x15,	0x2a,	0x15 },
214 	{ 0x15,	0x2a,	0x3f },
215 	{ 0x3f,	0x0,	0x15 },
216 	{ 0x3f,	0x0,	0x3f },
217 	{ 0x3f,	0x2a,	0x15 },
218 	{ 0x3f,	0x2a,	0x3f },
219 	{ 0x15,	0x15,	0x0 },
220 	{ 0x15,	0x15,	0x2a },
221 	{ 0x15,	0x3f,	0x0 },
222 	{ 0x15,	0x3f,	0x2a },
223 	{ 0x3f,	0x15,	0x0 },
224 	{ 0x3f,	0x15,	0x2a },
225 	{ 0x3f,	0x3f,	0x0 },
226 	{ 0x3f,	0x3f,	0x2a },
227 	{ 0x15,	0x15,	0x15 },
228 	{ 0x15,	0x15,	0x3f },
229 	{ 0x15,	0x3f,	0x15 },
230 	{ 0x15,	0x3f,	0x3f },
231 	{ 0x3f,	0x15,	0x15 },
232 	{ 0x3f,	0x15,	0x3f },
233 	{ 0x3f,	0x3f,	0x15 },
234 	{ 0x3f,	0x3f,	0x3f },
235 	{ 0x39,	0xc,	0x5 },
236 	{ 0x15,	0x2c,	0xf },
237 	{ 0x26,	0x10,	0x3d },
238 	{ 0x29,	0x29,	0x38 },
239 	{ 0x4,	0x1a,	0xe },
240 	{ 0x2,	0x1e,	0x3a },
241 	{ 0x3c,	0x25,	0x33 },
242 	{ 0x3c,	0xc,	0x2c },
243 	{ 0x3f,	0x3,	0x2b },
244 	{ 0x1c,	0x9,	0x13 },
245 	{ 0x25,	0x2a,	0x35 },
246 	{ 0x1e,	0xa,	0x38 },
247 	{ 0x24,	0x8,	0x3 },
248 	{ 0x3,	0xe,	0x36 },
249 	{ 0xc,	0x6,	0x2a },
250 	{ 0x26,	0x3,	0x32 },
251 	{ 0x5,	0x2f,	0x33 },
252 	{ 0x3c,	0x35,	0x2f },
253 	{ 0x2d,	0x26,	0x3e },
254 	{ 0xd,	0xa,	0x10 },
255 	{ 0x25,	0x3c,	0x11 },
256 	{ 0xd,	0x4,	0x2e },
257 	{ 0x5,	0x19,	0x3e },
258 	{ 0xc,	0x13,	0x34 },
259 	{ 0x2b,	0x6,	0x24 },
260 	{ 0x4,	0x3,	0xd },
261 	{ 0x2f,	0x3c,	0xc },
262 	{ 0x2a,	0x37,	0x1f },
263 	{ 0xf,	0x12,	0x38 },
264 	{ 0x38,	0xe,	0x2a },
265 	{ 0x12,	0x2f,	0x19 },
266 	{ 0x29,	0x2e,	0x31 },
267 	{ 0x25,	0x13,	0x3e },
268 	{ 0x33,	0x3e,	0x33 },
269 	{ 0x1d,	0x2c,	0x25 },
270 	{ 0x15,	0x15,	0x5 },
271 	{ 0x32,	0x25,	0x39 },
272 	{ 0x1a,	0x7,	0x1f },
273 	{ 0x13,	0xe,	0x1d },
274 	{ 0x36,	0x17,	0x34 },
275 	{ 0xf,	0x15,	0x23 },
276 	{ 0x2,	0x35,	0xd },
277 	{ 0x15,	0x3f,	0xc },
278 	{ 0x14,	0x2f,	0xf },
279 	{ 0x19,	0x21,	0x3e },
280 	{ 0x27,	0x11,	0x2f },
281 	{ 0x38,	0x3f,	0x3c },
282 	{ 0x36,	0x2d,	0x15 },
283 	{ 0x16,	0x17,	0x2 },
284 	{ 0x1,	0xa,	0x3d },
285 	{ 0x1b,	0x11,	0x3f },
286 	{ 0x21,	0x3c,	0xd },
287 	{ 0x1a,	0x39,	0x3d },
288 	{ 0x8,	0xe,	0xe },
289 	{ 0x22,	0x21,	0x23 },
290 	{ 0x1e,	0x30,	0x5 },
291 	{ 0x1f,	0x22,	0x3d },
292 	{ 0x1e,	0x2f,	0xa },
293 	{ 0x0,	0x1c,	0xe },
294 	{ 0x0,	0x1c,	0x15 },
295 	{ 0x0,	0x1c,	0x1c },
296 	{ 0x0,	0x15,	0x1c },
297 	{ 0x0,	0xe,	0x1c },
298 	{ 0x0,	0x7,	0x1c },
299 	{ 0xe,	0xe,	0x1c },
300 	{ 0x11,	0xe,	0x1c },
301 	{ 0x15,	0xe,	0x1c },
302 	{ 0x18,	0xe,	0x1c },
303 	{ 0x1c,	0xe,	0x1c },
304 	{ 0x1c,	0xe,	0x18 },
305 	{ 0x1c,	0xe,	0x15 },
306 	{ 0x1c,	0xe,	0x11 },
307 	{ 0x1c,	0xe,	0xe },
308 	{ 0x1c,	0x11,	0xe },
309 	{ 0x1c,	0x15,	0xe },
310 	{ 0x1c,	0x18,	0xe },
311 	{ 0x1c,	0x1c,	0xe },
312 	{ 0x18,	0x1c,	0xe },
313 	{ 0x15,	0x1c,	0xe },
314 	{ 0x11,	0x1c,	0xe },
315 	{ 0xe,	0x1c,	0xe },
316 	{ 0xe,	0x1c,	0x11 },
317 	{ 0xe,	0x1c,	0x15 },
318 	{ 0xe,	0x1c,	0x18 },
319 	{ 0xe,	0x1c,	0x1c },
320 	{ 0xe,	0x18,	0x1c },
321 	{ 0xe,	0x15,	0x1c },
322 	{ 0xe,	0x11,	0x1c },
323 	{ 0x14,	0x14,	0x1c },
324 	{ 0x16,	0x14,	0x1c },
325 	{ 0x18,	0x14,	0x1c },
326 	{ 0x1a,	0x14,	0x1c },
327 	{ 0x1c,	0x14,	0x1c },
328 	{ 0x1c,	0x14,	0x1a },
329 	{ 0x1c,	0x14,	0x18 },
330 	{ 0x1c,	0x14,	0x16 },
331 	{ 0x1c,	0x14,	0x14 },
332 	{ 0x1c,	0x16,	0x14 },
333 	{ 0x1c,	0x18,	0x14 },
334 	{ 0x1c,	0x1a,	0x14 },
335 	{ 0x1c,	0x1c,	0x14 },
336 	{ 0x1a,	0x1c,	0x14 },
337 	{ 0x18,	0x1c,	0x14 },
338 	{ 0x16,	0x1c,	0x14 },
339 	{ 0x14,	0x1c,	0x14 },
340 	{ 0x14,	0x1c,	0x16 },
341 	{ 0x14,	0x1c,	0x18 },
342 	{ 0x14,	0x1c,	0x1a },
343 	{ 0x14,	0x1c,	0x1c },
344 	{ 0x14,	0x1a,	0x1c },
345 	{ 0x14,	0x18,	0x1c },
346 	{ 0x14,	0x16,	0x1c },
347 	{ 0x0,	0x0,	0x10 },
348 	{ 0x4,	0x0,	0x10 },
349 	{ 0x8,	0x0,	0x10 },
350 	{ 0xc,	0x0,	0x10 },
351 	{ 0x10,	0x0,	0x10 },
352 	{ 0x10,	0x0,	0xc },
353 	{ 0x10,	0x0,	0x8 },
354 	{ 0x10,	0x0,	0x4 },
355 	{ 0x10,	0x0,	0x0 },
356 	{ 0x10,	0x4,	0x0 },
357 	{ 0x10,	0x8,	0x0 },
358 	{ 0x10,	0xc,	0x0 },
359 	{ 0x10,	0x10,	0x0 },
360 	{ 0xc,	0x10,	0x0 },
361 	{ 0x8,	0x10,	0x0 },
362 	{ 0x4,	0x10,	0x0 },
363 	{ 0x0,	0x10,	0x0 },
364 	{ 0x0,	0x10,	0x4 },
365 	{ 0x0,	0x10,	0x8 },
366 	{ 0x0,	0x10,	0xc },
367 	{ 0x0,	0x10,	0x10 },
368 	{ 0x0,	0xc,	0x10 },
369 	{ 0x0,	0x8,	0x10 },
370 	{ 0x0,	0x4,	0x10 },
371 	{ 0x8,	0x8,	0x10 },
372 	{ 0xa,	0x8,	0x10 },
373 	{ 0xc,	0x8,	0x10 },
374 	{ 0xe,	0x8,	0x10 },
375 	{ 0x10,	0x8,	0x10 },
376 	{ 0x10,	0x8,	0xe },
377 	{ 0x10,	0x8,	0xc },
378 	{ 0x10,	0x8,	0xa },
379 	{ 0x10,	0x8,	0x8 },
380 	{ 0x10,	0xa,	0x8 },
381 	{ 0x10,	0xc,	0x8 },
382 	{ 0x10,	0xe,	0x8 },
383 	{ 0x10,	0x10,	0x8 },
384 	{ 0xe,	0x10,	0x8 },
385 	{ 0xc,	0x10,	0x8 },
386 	{ 0xa,	0x10,	0x8 },
387 	{ 0x8,	0x10,	0x8 },
388 	{ 0x8,	0x10,	0xa },
389 	{ 0x8,	0x10,	0xc },
390 	{ 0x8,	0x10,	0xe },
391 	{ 0x8,	0x10,	0x10 },
392 	{ 0x8,	0xe,	0x10 },
393 	{ 0x8,	0xc,	0x10 },
394 	{ 0x8,	0xa,	0x10 },
395 	{ 0xb,	0xb,	0x10 },
396 	{ 0xc,	0xb,	0x10 },
397 	{ 0xd,	0xb,	0x10 },
398 	{ 0xf,	0xb,	0x10 },
399 	{ 0x10,	0xb,	0x10 },
400 	{ 0x10,	0xb,	0xf },
401 	{ 0x10,	0xb,	0xd },
402 	{ 0x10,	0xb,	0xc },
403 	{ 0x10,	0xb,	0xb },
404 	{ 0x10,	0xc,	0xb },
405 	{ 0x10,	0xd,	0xb },
406 	{ 0x10,	0xf,	0xb },
407 	{ 0x10,	0x10,	0xb },
408 	{ 0xf,	0x10,	0xb },
409 	{ 0xd,	0x10,	0xb },
410 	{ 0xc,	0x10,	0xb },
411 	{ 0xb,	0x10,	0xb },
412 	{ 0xb,	0x10,	0xc },
413 	{ 0xb,	0x10,	0xd },
414 	{ 0xb,	0x10,	0xf },
415 	{ 0xb,	0x10,	0x10 },
416 	{ 0xb,	0xf,	0x10 },
417 	{ 0xb,	0xd,	0x10 },
418 	{ 0xb,	0xc,	0x10 },
419 	{ 0x0,	0x0,	0x0 },
420 	{ 0x0,	0x0,	0x0 },
421 	{ 0x0,	0x0,	0x0 },
422 	{ 0x0,	0x0,	0x0 },
423 	{ 0x0,	0x0,	0x0 },
424 	{ 0x0,	0x0,	0x0 },
425 	{ 0x0,	0x0,	0x0 },
426 };
427 
428 u_char AC[21] = {
429 	0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x14, 0x07,
430 	0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
431 	0x0C, 0x00, 0x0F, 0x08, 0x00
432 };
433 
434 
435 static int delayLoop(int);
436 static void writeAttr(u_char, u_char, u_char);
437 static void setTextRegs(struct VgaRegs *);
438 static void setTextCLUT(void);
439 static void loadFont(u_char *);
440 static void unlockS3(void);
441 static void enablePCIvideo(int);
442 
443 void
444 vga_reset(u_char *ISA_mem)
445 {
446 	int slot;
447         struct VgaRegs *VgaTextRegs;
448 
449 	/* See if VGA already in TEXT mode - exit if so! */
450 	outb(0x3CE, 0x06);
451 	if ((inb(0x3CF) & 0x01) == 0)
452 		return;
453 
454 	/* If no VGA responding in text mode, then we have some work to do... */
455 	slot = findPCIVga();		/* find video card in use */
456 	enablePCIvideo(slot);		/* enable I/O to card */
457 
458 	/*
459          * Note: the PCI scanning code does not yet work correctly
460          *       for non-Moto boxes, so the switch below only
461          *       defaults to using an S3 card if it does not
462          *       find a Cirrus card.
463          *
464          *       The only reason we need to scan the bus looking for
465          *       a graphics card is so we could do the "enablePCIvideo(slot)"
466          *       call above; it is needed because Moto's OpenFirmware
467          *       disables I/O to the graphics adapter before it gives
468          *       us control.                                       PEK'97
469          */
470 
471 	switch (PCIVendor(slot)) {
472 	default:			       /* Assume S3 */
473 #if 0
474 	case S3Vendor:
475 #endif
476 		unlockS3();
477 		VgaTextRegs = S3TextRegs;
478 		outw(0x3C4, 0x0120);           /* disable video              */
479 		setTextRegs(VgaTextRegs);      /* initial register setup     */
480 		setTextCLUT();                 /* load color lookup table    */
481 		loadFont(ISA_mem);             /* load font                  */
482 		setTextRegs(VgaTextRegs);      /* reload registers           */
483 		outw(0x3C4, 0x0100);           /* re-enable video            */
484 		outb(0x3c2, 0x63);  	       /* MISC */
485 		outb(0x3c2, 0x67);  	       /* MISC */
486 		break;
487 
488 	case CirrusVendor:
489 		VgaTextRegs = GenVgaTextRegs;
490 		outw(0x3C4, 0x0612);	       /* unlock ext regs            */
491 		outw(0x3C4, 0x0700);	       /* reset ext sequence mode    */
492 		outw(0x3C4, 0x0120);           /* disable video              */
493 		setTextRegs(VgaTextRegs);      /* initial register setup     */
494 		setTextCLUT();                 /* load color lookup table    */
495 		loadFont(ISA_mem);             /* load font                  */
496 		setTextRegs(VgaTextRegs);      /* reload registers           */
497 		outw(0x3C4, 0x0100);           /* re-enable video            */
498 		outb(0x3c2, 0x63);  	       /* MISC */
499 		break;
500 
501         case DiamondVendor:
502         case MatroxVendor:
503 	  /*
504            * The following code is almost enuf to get the Matrox
505            * working (on a Moto box) but the video is not stable.
506            * We probably need to tweak the TVP3026 Video PLL regs.   PEK'97
507            */
508 		VgaTextRegs = GenVgaTextRegs;
509 		outw(0x3C4, 0x0120);           /* disable video              */
510 		setTextRegs(VgaTextRegs);      /* initial register setup     */
511 		setTextCLUT();                 /* load color lookup table    */
512 		loadFont(ISA_mem);             /* load font                  */
513 		setTextRegs(VgaTextRegs);      /* reload registers           */
514 		outw(0x3C4, 0x0100);           /* re-enable video            */
515 		outb(0x3c2, 0x63);  	       /* MISC */
516 		delayLoop(1);
517 		break;
518 	};
519 
520 #ifdef DEBUG
521 	printPCIslots();
522 	delayLoop(5);
523 #endif
524 	delayLoop(2);		/* give time for the video monitor to come up */
525 }
526 
527 static int
528 delayLoop(int k)
529 {
530 	volatile int a, b;
531 	volatile int i, j;
532 	a = 0;
533 	do {
534 		for (i = 0; i < 500; i++) {
535 			b = i;
536 			for (j = 0; j < 200; j++) {
537 				a = b+j;
538 			}
539 		}
540 	} while (k--);
541 	return a;
542 }
543 
544 /*
545  * Write to VGA Attribute registers.
546  */
547 static void
548 writeAttr(u_char index, u_char data, u_char videoOn)
549 {
550 	u_char v;
551 	v = inb(0x3da);   /* reset attr. address toggle */
552 	if (videoOn)
553 		outb(0x3c0, (index & 0x1F) | 0x20);
554 	else
555 		outb(0x3c0, (index & 0x1F));
556 	outb(0x3c0, data);
557 }
558 
559 static void
560 setTextRegs(struct VgaRegs *svp)
561 {
562 	int i;
563 
564 	/*
565 	 *  saved settings
566 	 */
567 	while (svp->io_port != ENDMK) {
568 		outb(svp->io_port,   svp->io_index);
569 		outb(svp->io_port+1, svp->io_value);
570 		svp++;
571 	}
572 
573 	outb(0x3c2, 0x67);  /* MISC */
574 	outb(0x3c6, 0xff);  /* MASK */
575 
576 	for (i = 0; i < 0x10; i++)
577 		writeAttr(i, AC[i], 0);	/* pallete */
578 	writeAttr(0x10, 0x0c, 0);	/* text mode */
579 	writeAttr(0x11, 0x00, 0);	/* overscan color (border) */
580 	writeAttr(0x12, 0x0f, 0);	/* plane enable */
581 	writeAttr(0x13, 0x08, 0);	/* pixel panning */
582 	writeAttr(0x14, 0x00, 1);	/* color select; video on */
583 }
584 
585 static void
586 setTextCLUT(void)
587 {
588 	int i;
589 
590 	outb(0x3C6, 0xFF);
591 	i = inb(0x3C7);
592 	outb(0x3C8, 0);
593 	i = inb(0x3C7);
594 
595 	for (i = 0; i < 256; i++) {
596 		outb(0x3C9, TextCLUT[i].r);
597 		outb(0x3C9, TextCLUT[i].g);
598 		outb(0x3C9, TextCLUT[i].b);
599 	}
600 }
601 
602 static void
603 loadFont(u_char *ISA_mem)
604 {
605 	int i, j;
606 	u_char *font_page = (u_char *)&ISA_mem[0xA0000];
607 
608 	outb(0x3C2, 0x67);
609 	/*
610 	 * Load font
611 	 */
612 	i = inb(0x3DA);		/* Reset Attr toggle */
613 
614 	outb(0x3C0, 0x30);
615 	outb(0x3C0, 0x01);	/* graphics mode */
616 
617 	outw(0x3C4, 0x0001);	/* reset sequencer */
618 	outw(0x3C4, 0x0204);	/* write to plane 2 */
619 	outw(0x3C4, 0x0406);	/* enable plane graphics */
620 	outw(0x3C4, 0x0003);	/* reset sequencer */
621 	outw(0x3CE, 0x0402);	/* read plane 2 */
622 	outw(0x3CE, 0x0500);	/* write mode 0, read mode 0 */
623 	outw(0x3CE, 0x0605);	/* set graphics mode */
624 
625 	for (i = 0;  i < sizeof(font);  i += 16) {
626 		for (j = 0;  j < 16;  j++) {
627 			__asm volatile("eieio");
628 			font_page[(2*i)+j] = font[i+j];
629 		}
630 	}
631 }
632 
633 static void
634 unlockS3(void)
635 {
636 	/* From the S3 manual */
637 	outb(0x46E8, 0x10);  /* Put into setup mode */
638 	outb(0x3C3, 0x10);
639 	outb(0x102, 0x01);   /* Enable registers */
640 	outb(0x46E8, 0x08);  /* Enable video */
641 	outb(0x3C3, 0x08);
642 	outb(0x4AE8, 0x00);
643 
644 	outb(0x42E8, 0x80);  /* Reset graphics engine? */
645 
646 	outb(0x3D4, 0x38);  /* Unlock all registers */
647 	outb(0x3D5, 0x48);
648 	outb(0x3D4, 0x39);
649 	outb(0x3D5, 0xA5);
650 	outb(0x3D4, 0x40);
651 	outb(0x3D5, inb(0x3D5)|0x01);
652 	outb(0x3D4, 0x33);
653 	outb(0x3D5, inb(0x3D5)&~0x52);
654 	outb(0x3D4, 0x35);
655 	outb(0x3D5, inb(0x3D5)&~0x30);
656 	outb(0x3D4, 0x3A);
657 	outb(0x3D5, 0x00);
658 	outb(0x3D4, 0x53);
659 	outb(0x3D5, 0x00);
660 	outb(0x3D4, 0x31);
661 	outb(0x3D5, inb(0x3D5)&~0x4B);
662 	outb(0x3D4, 0x58);
663 
664 	outb(0x3D5, 0);
665 
666 	outb(0x3D4, 0x54);
667 	outb(0x3D5, 0x38);
668 	outb(0x3D4, 0x60);
669 	outb(0x3D5, 0x07);
670 	outb(0x3D4, 0x61);
671 	outb(0x3D5, 0x80);
672 	outb(0x3D4, 0x62);
673 	outb(0x3D5, 0xA1);
674 	outb(0x3D4, 0x69);  /* High order bits for cursor address */
675 	outb(0x3D5, 0);
676 
677 	outb(0x3D4, 0x32);
678 	outb(0x3D5, inb(0x3D5)&~0x10);
679 }
680 
681 /*
682  * The following code modifies the PCI Command register
683  * to enable memory and I/O accesses.
684  */
685 static void
686 enablePCIvideo(int slot)
687 {
688 
689 	enablePCI(slot, 1, 1, 0);	/* Enable IO and Memory */
690 
691 	outb(0x3d4, 0x11);
692 	outb(0x3d5, 0x0e);	/* unlock CR0-CR7 */
693 }
694 #endif /* CONS_VGA */
695