1 /*
2  * VGAlib version 1.2 - (c) 1993 Tommy Frandsen
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it without any restrictions. This library is distributed
6  * in the hope that it will be useful, but without any warranty.
7  *
8  * Multi-chipset support Copyright (C) 1993 Harm Hanemaayer
9  * S3 805,868 support Copyright (C) 1995 Stephen Lee
10  */
11 
12 /*
13  * Mar 1999 (Eduardo ...)
14  * Recognizes Trio3D as Trio64
15  *
16  * Sep 1997 (Greg Alexander):
17  * Recognizes S3Trio64V2/DX cards as Trio64's.
18  *
19  * Feb 1996 (Stephen Lee):
20  * 968/IBMRGB support.  Only 256 colors for now.
21  * can now save more than 10 DAC registers (IBMRGB has 256!)
22  * Trio64 patch from Moto Kawamura <kawamura@mmp.cl.nec.co.jp>.
23  * Changed handling of CR34 for VGA modes at Andreas' suggestion.
24  * Changes to s3_saveregs() and s3_setregs() to make them more safe against
25  *   lockups.
26  * 16 color mode should work on the 868/SDAC.
27  * SDAC 4/8bpp doesn't seem to do pixel multiplexing.
28  *
29  * Dec 1995 (Stephen Lee):
30  * Fixed color problem with 868 (CR43 again!).  Could somebody find the
31  * value that works with Trio64?
32  *
33  * Nov 1995 (Stephen Lee):
34  * Linear addressing mode partially works (but is very alpha).
35  * Merged in Andreas Arens' <ari@av.rwth-aachen.de> patch for the 928.
36  *
37  * Sep 1995 (Stephen Lee):
38  * 16 Colors works on my 805, should work on other cards too.
39  *
40  * Alternate banking scheme for 864+.  If you have problems, try undefining
41  * S3_LINEAR_MODE_BANKING_864.
42  *
43  * 8 bit color *really* works.  Took me 3 months to bag this sucker.
44  *
45  * SVGA 8 bit color modes works.  320x200x256 is not really 'packed-pixel',
46  * it occupies 256K per page.  There is no SVGA 320x200x256 mode; I cannot
47  * get the display (timing?) right.
48  *
49  * Aug 1995 (Stephen Lee):
50  * Added "Dacspeed" parsing.
51  * Added support for CLUT8_8 on ATT20C490/498.
52  * Improved support for S3-801/805.
53  * 15/16/24 bit colors works on the 805 + ATT20C490 I tested.
54  * Newer chipsets are recognized (but no support coded in yet).
55  * Should recognize memory size correctly on S3-924.
56  *
57  * Dec 1994 (Harm Hanemaayer):
58  * Partially rewritten using new SVGA-abstracted interface.
59  * Based on XFree86 code (accel/s3/s3.c and s3init.c).
60  * Goal is to have support for the S3-864 + S3-SDAC (which I can test).
61  * 80x with GENDAC might also be supported.
62  * Also, 640x480x256 should work on cards that have standard 25 and 28 MHz
63  * clocks.
64  *
65  * XFree86-equivalent clock select is now supported plus some
66  * industry-standard RAMDACs.
67  *
68  * Remaining problems:
69  * * Okay, okay, so 256 color still isn't fully working on the 805.  I'm
70  *   trying to get a fix for it.
71  *
72  * * The DCLK limit for 864/868 is a bit too relaxed.  If you see noise at
73  *   the highest resolutions when the screen is drawing it is possibly due
74  *   to this.  (How about changing MCLK?)
75  *
76  * * Horizontal Total is limited to 4088 which makes some modes unavailable
77  *   (e.g. 800x600x16M with HTotal > 1022).  Should experiment with
78  *   CR43.7?
79  *
80  * * Some 864 problems are now fixed -- XF86_S3 seems to program the
81  *   linewidth in bytes doubled for the S3-864 with > 1024K, which
82  *   caused problems for this driver. There's still interference
83  *   though when writing to video memory in the higher resolutions.
84  *
85  * * XXXX results of malloc() are not checked: should fix sometime.
86  */
87 
88 #include <stdlib.h>
89 #include <stdarg.h>
90 #include <stdio.h>
91 #include <string.h>
92 #include <unistd.h>		/* iopl() */
93 #include "vga.h"
94 #include "libvga.h"
95 #include "driver.h"
96 #include "timing.h"
97 #include "ramdac/ramdac.h"
98 #include "clockchip/clockchip.h"
99 #include "vgaregs.h"
100 #include "interface.h"
101 #include "8514a.h"
102 #include "vgapci.h"
103 
104 /* no acceleration as of now. */
105 #undef S3_USE_GRAPHIC_ENGINE
106 
107 /* kludge packed pixel for 320x200x256 */
108 /* XXXX doesn't really work */
109 #undef S3_KLUDGE_PAGE_MODE
110 
111 /* use alternate 'linear' banking method for 864+ */
112 #undef S3_LINEAR_MODE_BANKING_864
113 
114 #ifdef __alpha__		/* no good for alpha's */
115 #undef S3_LINEAR_MODE_BANKING_864
116 #endif
117 
118 /*
119  * supports linear buffer.
120  *
121  * XXXX does not work with console switching and might be incompatible with
122  *      S3_LINEAR_MODE_BANKING_864.
123  */
124 #define S3_LINEAR_SUPPORT
125 
126 /* supports 16 colors */
127 #define S3_16_COLORS
128 
129 /*
130  * zero wait state + (ramdac?) FIFO for 864 & 805,
131  * twice as fast but might not work on some cards.
132  */
133 #undef S3_0_WAIT_805_864
134 
135 enum {
136     S3_911, S3_924, S3_801, S3_805, S3_928, S3_864, S3_964, S3_TRIO32,
137     S3_TRIO64, S3_866, S3_868, S3_968, S3_765
138 };
139 
140 static const char *s3_chipname[] =
141 {"911", "924", "801", "805", "928",
142  "864", "964", "Trio32", "Trio64", "866", "868", "968", "Trio64V+"};
143 
144 #define S3_CR(n)	(EXT + (0x##n) - 0x30)
145 
146 #define S3_CR30		S3_CR(30)
147 #define S3_CR31		S3_CR(31)
148 #define S3_CR32		S3_CR(32)
149 #define S3_CR33		S3_CR(33)
150 #define S3_CR34		S3_CR(34)
151 #define S3_CR35		S3_CR(35)
152 #define S3_CR3A		S3_CR(3A)
153 #define S3_CR3B		S3_CR(3B)
154 #define S3_CR3C		S3_CR(3C)
155 #define S3_CR40		S3_CR(40)
156 #define S3_CR42		S3_CR(42)
157 #define S3_CR43		S3_CR(43)
158 #define S3_CR44		S3_CR(44)
159 #define S3_CR50		S3_CR(50)	/* 801+ */
160 #define S3_CR51		S3_CR(51)
161 #define S3_CR53		S3_CR(53)
162 #define S3_CR54		S3_CR(54)
163 #define S3_CR55		S3_CR(55)
164 #define S3_CR58		S3_CR(58)
165 #define S3_CR59		S3_CR(59)
166 #define S3_CR5A		S3_CR(5A)
167 #define S3_CR5D		S3_CR(5D)
168 #define S3_CR5E		S3_CR(5E)
169 #define S3_CR60		S3_CR(60)
170 #define S3_CR61		S3_CR(61)
171 #define S3_CR62		S3_CR(62)
172 #define S3_CR67		S3_CR(67)
173 #define S3_CR6A		S3_CR(6A)
174 #define S3_CR6D		S3_CR(6D)
175 
176 /* For debugging, these (non-)registers are read also (but never written). */
177 
178 #define S3_CR36		S3_CR(36)
179 #define S3_CR37		S3_CR(37)
180 #define S3_CR38		S3_CR(38)
181 #define S3_CR39		S3_CR(39)
182 #define S3_CR3D		S3_CR(3D)
183 #define S3_CR3E		S3_CR(3E)
184 #define S3_CR3F		S3_CR(3F)
185 #define S3_CR45		S3_CR(45)
186 #define S3_CR46		S3_CR(46)
187 #define S3_CR47		S3_CR(47)
188 #define S3_CR48		S3_CR(48)
189 #define S3_CR49		S3_CR(49)
190 #define S3_CR4A		S3_CR(4A)
191 #define S3_CR4B		S3_CR(4B)
192 #define S3_CR4C		S3_CR(4C)
193 #define S3_CR4D		S3_CR(4D)
194 #define S3_CR4E		S3_CR(4E)
195 #define S3_CR4F		S3_CR(4F)
196 #define S3_CR52		S3_CR(52)
197 #define S3_CR56		S3_CR(56)
198 #define S3_CR57		S3_CR(57)
199 #define S3_CR5B		S3_CR(5B)
200 #define S3_CR5C		S3_CR(5C)
201 #define S3_CR5F		S3_CR(5F)
202 #define S3_CR63		S3_CR(63)
203 #define S3_CR64		S3_CR(64)
204 #define S3_CR65		S3_CR(65)
205 #define S3_CR66		S3_CR(66)
206 #define S3_CR6E		S3_CR(6E)
207 #define S3_CR6F		S3_CR(6F)
208 
209 /* Trio extended SR registers */
210 
211 #define S3_SR(n)	(S3_CR6F + 1 + (0x##n) - 0x08)
212 
213 #define S3_SR08		S3_SR(08)
214 #define S3_SR09		S3_SR(09)
215 #define S3_SR0A		S3_SR(0A)
216 #define S3_SR0D		S3_SR(0D)
217 #define S3_SR10		S3_SR(10)
218 #define S3_SR11		S3_SR(11)
219 #define S3_SR12		S3_SR(12)
220 #define S3_SR13		S3_SR(13)
221 #define S3_SR15		S3_SR(15)
222 #define S3_SR18		S3_SR(18)
223 #define S3_SR1D		S3_SR(1D)
224 
225 #define S3_8514_OFFSET	(S3_SR1D + 1)
226 
227 #define S3_8514_COUNT	(1)	/* number of 2-byte words */
228 
229 #define S3_DAC_OFFSET	(S3_8514_OFFSET + (S3_8514_COUNT * 2))
230 
231 #define S3_TOTAL_REGS	(S3_DAC_OFFSET + MAX_DAC_STATE)
232 
233 /* 8514 regs */
234 #define S3_ADVFUNC_CNTL	0
235 
236 static unsigned short s3_8514regs[S3_8514_COUNT] =
237 {
238     /* default assuming text mode */
239     0x0000U
240 };
241 
242 /* flags used by this driver */
243 #define S3_LOCALBUS		0x01
244 #define S3_CLUT8_8		0x02
245 #define S3_OLD_STEPPING		0x04
246 
247 static int s3_flags = 0;
248 
249 static int s3_chiptype;
250 static int s3_memory;
251 static CardSpecs *cardspecs;
252 static DacMethods *dac_used;
253 static ClockChipMethods *clk_used;
254 static int dac_speed = 0;
255 
256 int s3Mclk = 0;
257 
258 /* forward declaration. */
259 extern DriverSpecs __svgalib_s3_driverspecs;
260 
261 static int s3_init(int, int, int);
262 static void s3_setpage(int page);
263 #ifdef S3_LINEAR_MODE_BANKING_864
264 static void s3_setpage864(int page);
265 #endif
266 
267 #ifdef S3_LINEAR_SUPPORT
268 static int s3_cr40;
269 static int s3_cr54;
270 static int s3_cr58;
271 static int s3_cr59;
272 static int s3_cr5A;
273 static int s3_linear_opt = 0;
274 static int s3_linear_addr = 0;
275 static int s3_linear_base = 0;
276 static void s3_linear_enable(void);
277 static void s3_linear_disable(void);
278 #endif
279 
nothing(void)280 static void nothing(void)
281 {
282 }
283 
284 /*
285  * Lock S3's registers.
286  * There are more locks, but this should suffice.
287  *
288  * ARI: More complete Extended VGA Register Lock Documentation, as of Ferraro:
289  *
290  * Register     Bit     Controls Access To:             Function
291  * CR33         1       CR7 bits 1 and 6                1=disable write protect
292  *                                                        setting of CR11 bit 7
293  * CR33         4       Ramdac Register                 1=disable writes
294  * CR33         6       Palette/Overscan Registers      1=lock
295  * CR34         5       Memory Configuration bit 5      1=lock
296  * CR34         7       Misc Register bit 3-2 (Clock)   1=lock
297  * CR35         4       Vertical Timing Registers       1=lock
298  * CR35         5       Horizontal Timing Registers     1=lock
299  *
300  * XXXX mostly, need to lock the enhanced command regs on the 805 (and
301  * probably below) to avoid display corruption.
302  */
s3_lock(void)303 static void s3_lock(void)
304 {
305     __svgalib_outCR(0x39, 0x00);		/* Lock system control regs. */
306     __svgalib_outCR(0x38, 0x00);		/* Lock special regs. */
307 }
308 
s3_lock_enh(void)309 static void s3_lock_enh(void)
310 {
311     if (s3_chiptype > S3_911)
312 	__svgalib_outCR(0x40, __svgalib_inCR(0x40) & ~0x01);    /* Lock enhanced command regs. */
313     s3_lock();
314 }
315 
316 /*
317  * Unlock S3's registers.
318  * There are more locks, but this should suffice.
319  */
s3_unlock(void)320 static void s3_unlock(void)
321 {
322     __svgalib_outCR(0x38, 0x48);		/* Unlock special regs. */
323     __svgalib_outCR(0x39, 0xA5);		/* Unlock system control regs. */
324 }
325 
s3_unlock_enh(void)326 static void s3_unlock_enh(void)
327 {
328     s3_unlock();
329     if (s3_chiptype > S3_911)
330 	__svgalib_outCR(0x40, __svgalib_inCR(0x40) | 0x01);     /* Unlock enhanced command regs. */
331 }
332 
333 /*
334  * Adjust the display width.  This is necessary for the graphics
335  * engine if acceleration is used.  However it will require more
336  * memory making some modes unavailable.
337  */
s3_adjlinewidth(int oldwidth)338 static int s3_adjlinewidth(int oldwidth)
339 {
340     if (s3_chiptype < S3_801)
341 	return 1024;
342 #ifdef S3_USE_GRAPHIC_ENGINE
343     if (oldwidth <= 640)
344 	return 640;
345     if (oldwidth <= 800)
346 	return 800;
347     if (oldwidth <= 1024)
348 	return 1024;
349     if (!(s3_flags & S3_OLD_STEPPING))
350 	if (oldwidth <= 1152)
351 	    return 1152;
352     if (oldwidth <= 1280)
353 	return 1280;
354     if (oldwidth <= 1600 && s3_chiptype >= S3_864)
355 	return 1600;
356 
357     return 2048;
358 #else
359     return oldwidth;
360 #endif
361 }
362 
363 /* Fill in chipset specific mode information */
364 
s3_getmodeinfo(int mode,vga_modeinfo * modeinfo)365 static void s3_getmodeinfo(int mode, vga_modeinfo * modeinfo)
366 {
367     switch (modeinfo->colors) {
368     case 16:			/* 4-plane 16 color mode */
369 	modeinfo->maxpixels = s3_memory * 1024 * 2;
370 	break;
371     default:
372 	modeinfo->maxpixels = s3_memory * 1024 /
373 	    modeinfo->bytesperpixel;
374     }
375 
376     /* Adjust line width (only for SVGA modes) */
377     if (!(mode < G640x480x256 || mode == G720x348x2))
378 	modeinfo->linewidth = s3_adjlinewidth(modeinfo->linewidth);
379 
380     modeinfo->maxlogicalwidth = 8184;
381     if (s3_chiptype >= S3_801)
382 	modeinfo->startaddressrange = 0x3fffff;
383     else
384 	modeinfo->startaddressrange = 0xfffff;
385 
386 #ifdef S3_KLUDGE_PAGE_MODE
387     if (mode == G320x200x256) {
388 	/* set page size to 256k. */
389 	modeinfo->startaddressrange /= 4;
390 	modeinfo->maxpixels /= 4;
391     }
392 #else
393     if (mode == G320x200x256) {
394 	/* disable page flipping. */
395 	/* modeinfo->startaddressrange = 0xffff; */
396 	modeinfo->startaddressrange = 0;
397 	modeinfo->maxpixels = 65536;
398     }
399 #endif
400 
401     modeinfo->haveblit = 0;
402     modeinfo->flags &= ~HAVE_RWPAGE;
403     modeinfo->flags |= HAVE_EXT_SET;
404 #ifdef S3_LINEAR_SUPPORT
405     if (modeinfo->bytesperpixel >= 1) {
406     	modeinfo->flags |= CAPABLE_LINEAR;
407     	if (s3_linear_addr)
408 	    modeinfo->flags |= IS_LINEAR;
409     }
410 #endif
411 
412     modeinfo->memory = s3_memory;
413     modeinfo->chiptype = s3_chiptype;
414 }
415 
416 /*
417  * XXX Part of this function should be implemented in ramdac.c,
418  * but we just kludge it here for now.
419  */
s3_ext_set(unsigned what,va_list params)420 static int s3_ext_set(unsigned what, va_list params)
421 {
422     int param2, old_values;
423     unsigned char regs[10];
424 
425     /* only know this, for now */
426     if (dac_used->id != ATT20C490 && dac_used->id != ATT20C498 &&
427 	dac_used->id != SIERRA_15025)
428 	return 0;
429 
430     param2 = va_arg(params, int);
431     old_values = (s3_flags & S3_CLUT8_8) ? VGA_CLUT8 : 0;
432 
433     switch (what) {
434     case VGA_EXT_AVAILABLE:
435 	switch (param2) {
436 	case VGA_AVAIL_SET:
437 	    return VGA_EXT_AVAILABLE | VGA_EXT_SET | VGA_EXT_CLEAR | VGA_EXT_RESET;
438 	case VGA_AVAIL_ACCEL:
439 	    return 0;
440 	case VGA_AVAIL_FLAGS:
441 	    return VGA_CLUT8;
442 	}
443 	break;
444 
445     case VGA_EXT_SET:
446 	if (param2 & VGA_CLUT8)
447 	    goto setclut8;
448 
449     case VGA_EXT_CLEAR:
450 	if (param2 & VGA_CLUT8)
451 	    goto clearclut8;
452 
453     case VGA_EXT_RESET:
454 	if (param2 & VGA_CLUT8) {
455 	  setclut8:
456 	    dac_used->saveState(regs);
457 	    if (regs[0] == 0x00) {	/* 8bpp, 6 bits/color */
458 		s3_flags |= S3_CLUT8_8;
459 		if (dac_used->id == SIERRA_15025)
460 		    regs[1] = 1;
461 		regs[0] = 0x02;
462 	    }
463 	    dac_used->restoreState(regs);
464 	    return old_values;
465 	} else {
466 	  clearclut8:
467 	    dac_used->saveState(regs);
468 	    if (regs[0] == 0x02) {	/* 8bpp, 8 bits/color */
469 		s3_flags &= ~S3_CLUT8_8;
470 		if (dac_used->id == SIERRA_15025)
471 		    regs[1] = 0;
472 		regs[0] = 0x00;
473 	    }
474 	    dac_used->restoreState(regs);
475 	    return old_values;
476 	}
477     }
478     return 0;
479 }
480 
481 /* Return non-zero if mode is available */
482 
s3_modeavailable(int mode)483 static int s3_modeavailable(int mode)
484 {
485     struct info *info;
486     ModeInfo *modeinfo;
487     ModeTiming *modetiming;
488 
489     if (mode < G640x480x256 || mode == G720x348x2)
490 	return __svgalib_vga_driverspecs.modeavailable(mode);
491 
492     /* Enough memory? */
493     info = &__svgalib_infotable[mode];
494     if (s3_memory * 1024 < info->ydim * s3_adjlinewidth(info->xbytes))
495 	return 0;
496 
497     modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
498 
499     modetiming = malloc(sizeof(ModeTiming));
500     if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {
501 	free(modetiming);
502 	free(modeinfo);
503 	return 0;
504     }
505     free(modetiming);
506     free(modeinfo);
507 
508     return SVGADRV;
509 }
510 
511 /*
512  * save S3 registers.  Lock registers receive special treatment
513  * so dumpreg will work under X.
514  */
s3_saveregs(unsigned char regs[])515 static int s3_saveregs(unsigned char regs[])
516 {
517     unsigned char b, bmax;
518     unsigned char cr38, cr39, cr40;
519 
520     cr38 = __svgalib_inCR(0x38);
521     __svgalib_outCR(0x38, 0x48);		/* unlock S3 VGA regs (CR30-CR3B) */
522 
523     cr39 = __svgalib_inCR(0x39);
524     __svgalib_outCR(0x39, 0xA5);		/* unlock S3 system control (CR40-CR4F) */
525     /* and extended regs (CR50-CR6D) */
526 
527     cr40 = __svgalib_inCR(0x40);		/* unlock enhanced regs */
528     __svgalib_outCR(0x40, cr40 | 0x01);
529 
530     /* retrieve values from private copy */
531     memcpy(regs + S3_8514_OFFSET, s3_8514regs, S3_8514_COUNT * 2);
532 
533     /* get S3 VGA/Ext registers */
534     bmax = 0x4F;
535     if (s3_chiptype >= S3_801)
536 	bmax = 0x66;
537     if (s3_chiptype >= S3_864)
538 	bmax = 0x6D;
539     for (b = 0x30; b <= bmax; b++)
540 	regs[EXT + b - 0x30] = __svgalib_inCR(b);
541 
542     /* get S3 ext. SR registers */
543     /* if (s3_chiptype >= S3_864) { */
544     if (s3_chiptype == S3_TRIO32 || s3_chiptype == S3_TRIO64
545     	|| s3_chiptype == S3_765) {/* SL: actually Trio32/64/V+ */
546 	regs[S3_SR08] = __svgalib_inSR(0x08);
547 	__svgalib_outSR(0x08, 0x06);	/* unlock extended seq regs */
548 	regs[S3_SR09] = __svgalib_inSR(0x09);
549 	regs[S3_SR0A] = __svgalib_inSR(0x0A);
550 	regs[S3_SR0D] = __svgalib_inSR(0x0D);
551 	regs[S3_SR10] = __svgalib_inSR(0x10);
552 	regs[S3_SR11] = __svgalib_inSR(0x11);
553 	regs[S3_SR12] = __svgalib_inSR(0x12);
554 	regs[S3_SR13] = __svgalib_inSR(0x13);
555 	regs[S3_SR15] = __svgalib_inSR(0x15);
556 	regs[S3_SR18] = __svgalib_inSR(0x18);
557 	__svgalib_outSR(0x08, regs[S3_SR08]);
558     }
559 
560     dac_used->saveState(regs + S3_DAC_OFFSET);
561 
562     /* leave the locks the way we found it */
563     __svgalib_outCR(0x40, regs[EXT + 0x40 - 0x30] = cr40);
564     __svgalib_outCR(0x39, regs[EXT + 0x39 - 0x30] = cr39);
565     __svgalib_outCR(0x38, regs[EXT + 0x38 - 0x30] = cr38);
566 #if 0
567 #include "ramdac/IBMRGB52x.h"
568 
569     do {
570 	unsigned char m, n, df;
571 
572 	printf("pix_fmt = 0x%02X, 8bpp = 0x%02X, 16bpp = 0x%02X, 24bpp = 0x%02X, 32bpp = 0x%02X,\n"
573 	  "CR58 = 0x%02X, CR66 = 0x%02X, CR67 = 0x%02X, CR6D = 0x%02X\n",
574 	       regs[S3_DAC_OFFSET + IBMRGB_pix_fmt],
575 	       regs[S3_DAC_OFFSET + IBMRGB_8bpp],
576 	       regs[S3_DAC_OFFSET + IBMRGB_16bpp],
577 	       regs[S3_DAC_OFFSET + IBMRGB_24bpp],
578 	       regs[S3_DAC_OFFSET + IBMRGB_32bpp],
579 	       regs[S3_CR58],
580 	       regs[S3_CR66],
581 	       regs[S3_CR67],
582 	       regs[S3_CR6D]);
583 
584 	m = regs[S3_DAC_OFFSET + IBMRGB_m0 + 4];
585 	n = regs[S3_DAC_OFFSET + IBMRGB_n0 + 4];
586 	df = m >> 6;
587 	m &= ~0xC0;
588 
589 	printf("m = 0x%02X %d, n = 0x%02X %d, df = 0x%02X %d, freq = %.3f\n",
590 	       m, m, n, n, df, df, ((m + 65.0) / n) / (8 >> df) * 16.0);
591     } while (0);
592 #endif
593     return S3_DAC_OFFSET - VGA_TOTAL_REGS + dac_used->stateSize;
594 }
595 
596 /* Set chipset-specific registers */
s3_setregs(const unsigned char regs[],int mode)597 static void s3_setregs(const unsigned char regs[], int mode)
598 {
599     unsigned char b, bmax;
600     /*
601      * Right now, anything != 0x00 gets written in s3_setregs.
602      * May change this into a bitmask later.
603      */
604     static unsigned char s3_regmask[] =
605     {
606 	0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x00, 0x00,		/* CR30-CR37 */
607 	0x00, 0x00, 0x3A, 0x3B, 0x3C, 0x00, 0x00, 0x00,		/* CR38-CR3F */
608 	0x00, 0x00, 0x42, 0x43, 0x44, 0x00, 0x00, 0x00,		/* CR40-CR47 */
609 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,		/* CR48-CR4F */
610 	0x50, 0x51, 0x00, 0x00, 0x54, 0x55, 0x00, 0x00,		/* CR50-CR57 */
611 	0x58, 0x59, 0x5A, 0x00, 0x00, 0x5D, 0x5E, 0x00,		/* CR58-CR5F */
612 	0x60, 0x61, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00,		/* CR60-CR67 */
613 	0x00, 0x00, 0x6A, 0x00, 0x00, 0x00			/* CR68-CR6D */
614     };
615 
616     s3_unlock_enh();
617 
618     /* save a private copy */
619     memcpy(s3_8514regs, regs + S3_8514_OFFSET, S3_8514_COUNT * 2);
620     /*
621      * set this first, so if we segfault on this (e.g. we didn't do a iopl(3))
622      * we don't get a screwed up display
623      */
624     outw(ADVFUNC_CNTL, s3_8514regs[S3_ADVFUNC_CNTL]);
625 
626     /* get S3 VGA/Ext registers */
627     bmax = 0x4F;
628     if (s3_chiptype >= S3_801)
629 	bmax = 0x66;
630     if (s3_chiptype >= S3_864)
631 	bmax = 0x6D;
632     for (b = 0x30; b <= bmax; b++) {
633 	if (s3_regmask[b - 0x30])
634 	    __svgalib_outCR(b, regs[EXT + b - 0x30]);
635     }
636 
637     if (dac_used->id != NORMAL_DAC) {
638 	unsigned char CR1;
639 	/* Blank the screen. */
640 	CR1 = __svgalib_inCR(0x01);
641 	__svgalib_outCR(0x01, CR1 | 0x20);
642 
643 	__svgalib_outbCR(0x55, __svgalib_inCR(0x55) | 1);
644 	__svgalib_outCR(0x66, regs[S3_CR66]);
645 	__svgalib_outCR(0x67, regs[S3_CR67]);	/* S3 pixmux. */
646 
647 	dac_used->restoreState(regs + S3_DAC_OFFSET);
648 
649 	__svgalib_outCR(0x6D, regs[S3_CR6D]);
650 	__svgalib_outbCR(0x55, __svgalib_inCR(0x55) & ~1);
651 
652 	__svgalib_outCR(0x01, CR1);	/* Unblank screen. */
653     }
654 #ifdef S3_LINEAR_SUPPORT
655     if (mode == TEXT && s3_linear_addr)
656 	s3_linear_disable();	/* make sure linear is off */
657 #endif
658 
659     /* restore CR38/39 (may lock other regs) */
660     if (mode == TEXT) {
661 	/* restore lock registers as well */
662 	__svgalib_outCR(0x40, regs[S3_CR40]);
663 	__svgalib_outCR(0x39, regs[S3_CR39]);
664 	__svgalib_outCR(0x38, regs[S3_CR38]);
665     } else
666 	s3_lock_enh();
667 }
668 
669 /*
670  * Initialize register state for a mode.
671  */
672 
s3_initializemode(unsigned char * moderegs,ModeTiming * modetiming,ModeInfo * modeinfo)673 static void s3_initializemode(unsigned char *moderegs,
674 			    ModeTiming * modetiming, ModeInfo * modeinfo)
675 {
676     /* Get current values. */
677     s3_saveregs(moderegs);
678 
679     /* Set up the standard VGA registers for a generic SVGA. */
680     __svgalib_setup_VGA_registers(moderegs, modetiming, modeinfo);
681 
682     /* Set up the extended register values, including modifications */
683     /* of standard VGA registers. */
684 
685     moderegs[VGA_SR0] = 0x03;
686     moderegs[VGA_CR13] = modeinfo->lineWidth >> 3;
687     moderegs[VGA_CR17] = 0xE3;
688 
689     if (modeinfo->lineWidth / modeinfo->bytesPerPixel == 2048)
690 	moderegs[S3_CR31] = 0x8F;
691     else
692 	moderegs[S3_CR31] = 0x8D;
693 #ifdef S3_LINEAR_MODE_BANKING_864
694     if (s3_chiptype >= S3_864) {
695 	/* moderegs[S3_ENHANCEDMODE] |= 0x01; */
696 	/* Enable enhanced memory mode. */
697 	moderegs[S3_CR31] |= 0x04;
698 	/* Enable banking via CR6A in linear mode. */
699 	moderegs[S3_CR31] |= 0x01;
700     }
701 #endif
702     moderegs[S3_CR32] = 0;
703     moderegs[S3_CR33] = 0x20;
704     moderegs[S3_CR34] = 0x10;	/* 1024 */
705     moderegs[S3_CR35] = 0;
706     /* Call cebank() here when setting registers. */
707     if (modeinfo->bitsPerPixel >= 8) {
708 	moderegs[S3_CR3A] = 0xB5;
709 	if (s3_chiptype == S3_928)
710 	    /* ARI: Turn on CHAIN4 for 928, since __svgalib_setup_VGA_registers
711 							 initializes ModeX */
712 	    moderegs[VGA_CR14] = 0x60;
713     } else {
714 	/* 16 color mode */
715 	moderegs[VGA_CR13] = modeinfo->lineWidth >> 1;
716 	moderegs[VGA_GR0] = 0x0F;
717 	moderegs[VGA_GR1] = 0x0F;
718 	moderegs[VGA_GR5] = 0x00;	/* write mode 0 */
719 	moderegs[VGA_AR11] = 0x00;
720 	moderegs[S3_CR3A] = 0x85;
721     }
722 
723     moderegs[S3_CR3B] = (moderegs[VGA_CR0] + moderegs[VGA_CR4] + 1) / 2;
724     moderegs[S3_CR3C] = moderegs[VGA_CR0] / 2;
725     if (s3_chiptype == S3_911) {
726 	moderegs[S3_CR40] &= 0xF2;
727 	moderegs[S3_CR40] |= 0x09;
728     } else if (s3_flags & S3_LOCALBUS) {
729 	moderegs[S3_CR40] &= 0xF2;
730 	/* Pegasus wants 0x01 for zero wait states. */
731 #ifdef S3_0_WAIT_805_864
732 	moderegs[S3_CR40] |= 0x09;	/* use fifo + 0 wait state */
733 #else
734 	moderegs[S3_CR40] |= 0x05;
735 #endif
736     } else {
737 	moderegs[S3_CR40] &= 0xF6;
738 	moderegs[S3_CR40] |= 0x01;
739     }
740 
741     if (modeinfo->bitsPerPixel >= 24) {
742 	/* 24/32 bit color */
743 	if (s3_chiptype == S3_864 || s3_chiptype == S3_964)
744 	    moderegs[S3_CR43] = 0x08;
745 	else if (s3_chiptype == S3_928 && dac_used->id == SIERRA_15025)
746 	    moderegs[S3_CR43] = 0x01;	/* ELSA Winner 1000 */
747     } else if (modeinfo->bitsPerPixel >= 15) {
748 	/* 15/16 bit color */
749 	if (s3_chiptype <= S3_864 || s3_chiptype >= S3_866) {	/* XXXX Trio? */
750 	    moderegs[S3_CR43] = 0x08;
751 	    if (dac_used->id == IBMRGB52x)
752 		moderegs[S3_CR43] = 0x10;
753 	    else if (s3_chiptype == S3_928 && dac_used->id == SIERRA_15025)
754 		moderegs[S3_CR43] = 0x01;
755 	    if (s3_chiptype <= S3_924 && dac_used->id != NORMAL_DAC)
756 		moderegs[S3_CR43] = 0x01;
757 
758 	} else
759 	    /* XXXX some DAC might need this; XF86 source says... */
760 	    moderegs[S3_CR43] = 0x09;
761     } else {
762 	/* 4/8 bit color */
763 	moderegs[S3_CR43] = 0x00;
764     }
765 
766     if (s3_chiptype >= S3_924 && s3_chiptype <= S3_928) {	/* different for 864+ */
767 	s3_8514regs[S3_ADVFUNC_CNTL] = 0x0002;
768 	if ((s3_chiptype == S3_928 && modeinfo->bitsPerPixel != 4) || !(s3_flags & S3_OLD_STEPPING))
769 	    s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0001;
770 	if (modeinfo->bitsPerPixel == 4)
771 	    s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0004;
772 #if 0
773 	/* 864 databook says it is for enhanced 4bpp */
774 	if (modeinfo->lineWidth > 640)
775 	    s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0004;
776 #endif
777     } else if (s3_chiptype == S3_968) {
778 	s3_8514regs[S3_ADVFUNC_CNTL] = 0x0002;
779 	if (modeinfo->bitsPerPixel == 4)
780 	    s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0004;
781 #ifdef PIXEL_MULTIPLEXING
782 	else
783 	    s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0001;
784 #endif
785     } else if (modeinfo->lineWidth / modeinfo->bytesPerPixel == 1024)
786     	s3_8514regs[S3_ADVFUNC_CNTL] = 0x0007;
787     else
788     	s3_8514regs[S3_ADVFUNC_CNTL] = 0x0003;
789 
790     moderegs[S3_CR44] = 0;
791     /* Skip CR45, 'hi/truecolor cursor color enable'. */
792 
793     if (s3_chiptype >= S3_801) {
794 	int m, n;		/* for FIFO balancing */
795 
796 	/* XXXX Not all chips support all widths. */
797 	moderegs[S3_CR50] &= ~0xF1;
798 	switch (modeinfo->bitsPerPixel) {
799 	case 16:
800 	    moderegs[S3_CR50] |= 0x10;
801 	    break;
802 	case 24:		/* XXXX 868/968 only */
803 	    if (s3_chiptype >= S3_868)
804 		moderegs[S3_CR50] |= 0x20;
805 	    break;
806 	case 32:
807 	    moderegs[S3_CR50] |= 0x30;
808 	    break;
809 	}
810 
811 	switch (modeinfo->lineWidth / modeinfo->bytesPerPixel) {
812 	case 640:
813 	    moderegs[S3_CR50] |= 0x40;
814 	    break;
815 	case 800:
816 	    moderegs[S3_CR50] |= 0x80;
817 	    break;
818 	case 1152:
819 	    if (!(s3_flags & S3_OLD_STEPPING)) {
820 		moderegs[S3_CR50] |= 0x01;
821 		break;
822 	    }			/* else fall through */
823 	case 1280:
824 	    moderegs[S3_CR50] |= 0xC0;
825 	    break;
826 	case 1600:
827 	    moderegs[S3_CR50] |= 0x81;
828 	    break;
829 	    /* 1024/2048 no change. */
830 	}
831 
832 	moderegs[S3_CR51] &= 0xC0;
833 	moderegs[S3_CR51] |= (modeinfo->lineWidth >> 7) & 0x30;
834 
835 	/* moderegs[S3_CR53] |= 0x10; *//* Enable MMIO. */
836 	/* moderegs[S3_CR53] |= 0x20; *//* DRAM interleaving for S3_805i with 2MB */
837 
838 	n = 0xFF;
839 	if (s3_chiptype >= S3_864 ||
840 	    s3_chiptype == S3_801 || s3_chiptype == S3_805) {
841 	    /*
842 	     * CRT FIFO balancing for DRAM cards and 964/968
843 	     * in VGA mode.
844 	     */
845 	    int clock, mclk;
846 	    if (modeinfo->bitsPerPixel < 8) {
847 		clock = modetiming->pixelClock;
848 	    } else {
849 		clock = modetiming->pixelClock *
850 		    modeinfo->bytesPerPixel;
851 	    }
852 	    if (s3_memory < 2048 || s3_chiptype == S3_TRIO32)
853 		clock *= 2;
854 	    if (s3Mclk > 0)
855 	    	mclk = s3Mclk;
856 	    else if (s3_chiptype == S3_801 || s3_chiptype == S3_805)
857 		mclk = 50000;	/* Assumption. */
858 	    else
859 		mclk = 60000;	/* Assumption. */
860 	    m = (int) ((mclk / 1000.0 * .72 + 16.867) * 89.736 / (clock / 1000.0 + 39) - 21.1543);
861 	    if (s3_memory < 2048 || s3_chiptype == S3_TRIO32)
862 		m /= 2;
863 	    if (m > 31)
864 		m = 31;
865 	    else if (m < 0) {
866 		m = 0;
867 		n = 16;
868 	    }
869 	} else if (s3_memory == 512 || modetiming->HDisplay > 1200)
870 	    m = 0;
871 	else if (s3_memory == 1024)
872 	    m = 2;
873 	else
874 	    m = 20;
875 
876 	moderegs[S3_CR54] = m << 3;
877 	moderegs[S3_CR60] = n;
878 
879 	moderegs[S3_CR55] &= 0x08;
880 	moderegs[S3_CR55] |= 0x40;
881 
882 #ifdef S3_LINEAR_MODE_BANKING_864
883 	if (s3_chiptype >= S3_864) {
884 	    if (modeinfo->bitsPerPixel >= 8) {
885 		/* Enable linear addressing. */
886 		moderegs[S3_CR58] |= 0x10;
887 		/* Set window size to 64K. */
888 		moderegs[S3_CR58] &= ~0x03;
889 		/* Assume CR59/5A are correctly set up for 0xA0000. */
890 		/* Set CR6A linear bank to zero. */
891 		moderegs[S3_CR6A] &= ~0x3F;
892 		/* use alternate __svgalib_setpage() function */
893 		__svgalib_s3_driverspecs.__svgalib_setpage = s3_setpage864;
894 	    } else {
895 		/* doesn't work for 4bpp. */
896 		__svgalib_s3_driverspecs.__svgalib_setpage = s3_setpage;
897 	    }
898 	}
899 #endif
900 #ifdef S3_LINEAR_SUPPORT
901 	moderegs[S3_CR59] = s3_cr59;
902 	moderegs[S3_CR5A] = s3_cr5A;
903 #endif
904 
905 	/* Extended CRTC timing. */
906 	moderegs[S3_CR5E] =
907 	    (((modetiming->CrtcVTotal - 2) & 0x400) >> 10) |
908 	    (((modetiming->CrtcVDisplay - 1) & 0x400) >> 9) |
909 	    (((modetiming->CrtcVSyncStart) & 0x400) >> 8) |
910 	    (((modetiming->CrtcVSyncStart) & 0x400) >> 6) | 0x40;
911 
912 	{
913 	    int i, j;
914 	    i = ((((modetiming->CrtcHTotal >> 3) - 5) & 0x100) >> 8) |
915 		((((modetiming->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) |
916 		((((modetiming->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) |
917 		((modetiming->CrtcHSyncStart & 0x800) >> 7);
918 	    if ((modetiming->CrtcHSyncEnd >> 3) - (modetiming->CrtcHSyncStart >> 3) > 64)
919 	    	i |= 0x08;
920 	    if ((modetiming->CrtcHSyncEnd >> 3) - (modetiming->CrtcHSyncStart >> 3) > 32)
921 	    	i |= 0x20;
922 	    j = ((moderegs[VGA_CR0] + ((i & 0x01) << 8) +
923 		  moderegs[VGA_CR4] + ((i & 0x10) << 4) + 1) / 2);
924 	    if (j - (moderegs[VGA_CR4] + ((i & 0x10) << 4)) < 4) {
925 	    	if (moderegs[VGA_CR4] + ((i & 0x10) << 4) + 4 <= moderegs[VGA_CR0] + ((i & 0x01) << 8))
926 	    	    j = moderegs[VGA_CR4] + ((i & 0x10) << 4) + 4;
927 	    	else
928 	    	    j = moderegs[VGA_CR0] + ((i & 0x01) << 8) + 1;
929 	    }
930 
931 	    moderegs[S3_CR3B] = j & 0xFF;
932 	    i |= (j & 0x100) >> 2;
933 	    /* Interlace mode frame offset. */
934 	    moderegs[S3_CR3C] = (moderegs[VGA_CR0] + ((i & 0x01) << 8)) / 2;
935 	    moderegs[S3_CR5D] = (moderegs[S3_CR5D] & 0x80) | i;
936 	}
937 
938 	{
939 	    int i;
940 
941 	    if (modeinfo->bitsPerPixel < 8)
942 		i = modetiming->HDisplay / 4 + 1;
943 	    else
944 		i = modetiming->HDisplay *
945 		    modeinfo->bytesPerPixel / 4 + 1;
946 
947 	    moderegs[S3_CR61] = (i >> 8) | 0x80;
948 	    moderegs[S3_CR62] = i & 0xFF;
949 	}
950     }				/* 801+ */
951     if (modetiming->flags & INTERLACED)
952 	moderegs[S3_CR42] |= 0x20;
953 
954     /*
955      * Clock select works as follows:
956      * Clocks 0 and 1 (VGA 25 and 28 MHz) can be selected via the
957      * two VGA MiscOutput clock select bits.
958      * If 0x3 is written to these bits, the selected clock index
959      * is taken from the S3 clock select register at CR42. Clock
960      * indices 0 and 1 should correspond to the VGA ones above,
961      * and 3 is often 0 MHz, followed by extended clocks for a
962      * total of mostly 16.
963      */
964 
965     if (modetiming->flags & USEPROGRCLOCK)
966 	moderegs[VGA_MISCOUTPUT] |= 0x0C;	/* External clock select. */
967     else if (modetiming->selectedClockNo < 2) {
968 	/* Program clock select bits 0 and 1. */
969 	moderegs[VGA_MISCOUTPUT] &= ~0x0C;
970 	moderegs[VGA_MISCOUTPUT] |=
971 	    (modetiming->selectedClockNo & 3) << 2;
972     } else if (modetiming->selectedClockNo >= 2) {
973 	moderegs[VGA_MISCOUTPUT] |= 0x0C;
974 	/* Program S3 clock select bits. */
975 	moderegs[S3_CR42] &= ~0x1F;
976 	moderegs[S3_CR42] |=
977 	    modetiming->selectedClockNo;
978     }
979     if (s3_chiptype == S3_TRIO64 || s3_chiptype == S3_765) {
980 	moderegs[S3_CR33] &= ~0x08;
981 	if (modeinfo->bitsPerPixel == 16)
982 	    moderegs[S3_CR33] |= 0x08;
983 	/*
984 	 * The rest of the DAC/clocking is setup by the
985 	 * Trio64 code in the RAMDAC interface (ramdac.c).
986 	 */
987     }
988     if (dac_used->id != NORMAL_DAC) {
989 	int colormode;
990 	colormode = __svgalib_colorbits_to_colormode(modeinfo->bitsPerPixel,
991 					   modeinfo->colorBits);
992 	dac_used->initializeState(&moderegs[S3_DAC_OFFSET],
993 				  modeinfo->bitsPerPixel, colormode,
994 				  modetiming->pixelClock);
995 
996 	if (dac_used->id == ATT20C490) {
997 	    int pixmux, invert_vclk, blank_delay;
998 	    pixmux = 0;
999 	    invert_vclk = 0;
1000 	    blank_delay = 2;
1001 	    if (colormode == CLUT8_6
1002 		&& modetiming->pixelClock >= 67500) {
1003 		pixmux = 0x00;
1004 		invert_vclk = 1;
1005 	    } else if (colormode == CLUT8_8)
1006 		pixmux = 0x02;
1007 	    else if (colormode == RGB16_555)
1008 		pixmux = 0xa0;
1009 	    else if (colormode == RGB16_565)
1010 		pixmux = 0xc0;
1011 	    else if (colormode == RGB24_888_B)
1012 		pixmux = 0xe0;
1013 	    moderegs[S3_CR67] = pixmux | invert_vclk;
1014 	    moderegs[S3_CR6D] = blank_delay;
1015 	}
1016 	if (dac_used->id == S3_SDAC) {
1017 	    int pixmux, invert_vclk, blank_delay;
1018 	    pixmux = 0;
1019 	    invert_vclk = 0;
1020 	    blank_delay = 0;
1021 	    if (colormode == CLUT8_6
1022 		&& modetiming->pixelClock >= 67500) {
1023 #ifdef SDAC_8BPP_PIXMUX
1024 		/* x64 8bpp pixel multiplexing? */
1025 		pixmux = 0x10;
1026 		if (s3_chiptype != S3_866 && s3_chiptype != S3_868)
1027 		    invert_vclk = 1;
1028 		blank_delay = 2;
1029 #endif
1030 	    } else if (colormode == RGB16_555) {
1031 		pixmux = 0x30;
1032 		blank_delay = 2;
1033 	    } else if (colormode == RGB16_565) {
1034 		pixmux = 0x50;
1035 		blank_delay = 2;
1036 	    } else if (colormode == RGB24_888_B) {	/* XXXX 868/968 only */
1037 		pixmux = 0x90;
1038 		blank_delay = 2;
1039 	    } else if (colormode == RGB32_888_B) {
1040 		pixmux = 0x70;
1041 		blank_delay = 2;
1042 	    }
1043 	    moderegs[S3_CR67] = pixmux | invert_vclk;
1044 	    moderegs[S3_CR6D] = blank_delay;
1045 	    /* Clock select. */
1046 	    moderegs[S3_CR42] &= ~0x0F;
1047 	    moderegs[S3_CR42] |= 0x02;
1048 	}
1049 	if (dac_used->id == IBMRGB52x) {
1050 	    unsigned char pixmux, blank_delay, tmp;
1051 	    tmp = 0;
1052 	    pixmux = 0x11;
1053 	    blank_delay = 0;
1054 	    if (modeinfo->bitsPerPixel < 8 || colormode == RGB32_888_B)
1055 		pixmux = 0x00;
1056 	    moderegs[S3_CR58] |= 0x40;
1057 	    moderegs[S3_CR65] = 0;
1058 	    moderegs[S3_CR66] &= 0xf8;
1059 	    moderegs[S3_CR66] |= tmp;
1060 #ifdef PIXEL_MULTIPLEXING
1061 	    moderegs[S3_CR67] = pixmux;
1062 #endif
1063 	    moderegs[S3_CR6D] = blank_delay;
1064 	    /* Clock select. */
1065 	    moderegs[S3_CR42] &= ~0x0F;
1066 	    moderegs[S3_CR42] |= 0x02;
1067 	}
1068     }
1069 #ifdef S3_LINEAR_SUPPORT
1070     s3_cr58 = moderegs[S3_CR58];
1071     s3_cr40 = moderegs[S3_CR40];
1072     s3_cr54 = moderegs[S3_CR54];
1073 #endif
1074     if (clk_used == &__svgalib_I2061A_clockchip_methods &&
1075 	(modetiming->flags & USEPROGRCLOCK)) {
1076 	/* Clock select. */
1077 	moderegs[S3_CR42] &= ~0x0F;
1078 	moderegs[S3_CR42] |= 0x02;
1079     }
1080     /* update the 8514 regs */
1081     memcpy(moderegs + S3_8514_OFFSET, s3_8514regs, S3_8514_COUNT * 2);
1082 }
1083 
1084 
1085 /* Set a mode */
1086 
s3_setmode(int mode,int prv_mode)1087 static int s3_setmode(int mode, int prv_mode)
1088 {
1089     ModeInfo *modeinfo;
1090     ModeTiming *modetiming;
1091     unsigned char moderegs[S3_TOTAL_REGS];
1092     int res;
1093 
1094     if (mode < G640x480x256 || mode == G720x348x2) {
1095 	/* Let the standard VGA driver set standard VGA modes. */
1096 	res = __svgalib_vga_driverspecs.setmode(mode, prv_mode);
1097 	if (res == 0) {
1098 	    /*
1099 	     * ARI: Turn off virtual size of 1024 - this fixes all problems
1100 	     *      with standard modes, including 320x200x256.
1101 	     *
1102 	     * SL:  Is this for 928 only?  Doesn't matter for 805.
1103              *
1104              * MZ:  Affects 765 as well, so I assume it is good for all chipsets.
1105 	     */
1106 	    s3_unlock();
1107 	    __svgalib_outCR(0x34, __svgalib_inCR(0x34) & ~0x10);
1108 	    s3_lock();
1109 	}
1110 	return res;
1111     }
1112     if (!s3_modeavailable(mode))
1113 	return 1;
1114 
1115     modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
1116 
1117     modetiming = malloc(sizeof(ModeTiming));
1118     if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {
1119 	free(modetiming);
1120 	free(modeinfo);
1121 	return 1;
1122     }
1123     /* Adjust the display width. */
1124     modeinfo->lineWidth = s3_adjlinewidth(modeinfo->lineWidth);
1125     CI.xbytes = modeinfo->lineWidth;
1126 
1127     s3_initializemode(moderegs, modetiming, modeinfo);
1128     free(modeinfo);
1129     free(modetiming);
1130 
1131     __svgalib_setregs(moderegs);	/* Set standard regs. */
1132     s3_setregs(moderegs, mode);	/* Set extended regs. */
1133     return 0;
1134 }
1135 
1136 
1137 /* Indentify chipset; return non-zero if detected */
1138 
1139 /* Some port I/O functions: */
rdinx(int port,unsigned char index)1140 static unsigned char rdinx(int port, unsigned char index)
1141 {
1142     outb(port, index);
1143     return inb(port + 1);
1144 }
1145 
wrinx(int port,unsigned char index,unsigned char val)1146 static void wrinx(int port, unsigned char index, unsigned char val)
1147 {
1148     outb(port, index);
1149     outb(port + 1, val);
1150 }
1151 
1152 /*
1153  * Returns true iff the bits in 'mask' of register 'port', index 'index'
1154  * are read/write.
1155  */
testinx2(int port,unsigned char index,unsigned char mask)1156 static int testinx2(int port, unsigned char index, unsigned char mask)
1157 {
1158     unsigned char old, new1, new2;
1159 
1160     old = rdinx(port, index);
1161     wrinx(port, index, (old & ~mask));
1162     new1 = rdinx(port, index) & mask;
1163     wrinx(port, index, (old | mask));
1164     new2 = rdinx(port, index) & mask;
1165     wrinx(port, index, old);
1166     return (new1 == 0) && (new2 == mask);
1167 }
1168 
s3_test(void)1169 static int s3_test(void)
1170 {
1171     int vgaIOBase, vgaCRIndex, vgaCRReg;
1172 
1173     vgaIOBase = (inb(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;
1174     vgaCRIndex = vgaIOBase + 4;
1175     vgaCRReg = vgaIOBase + 5;
1176 
1177     outb(vgaCRIndex, 0x11);	/* for register CR11, (Vertical Retrace End) */
1178     outb(vgaCRReg, 0x00);	/* set to 0 */
1179 
1180     outb(vgaCRIndex, 0x38);	/* check if we have an S3 */
1181     outb(vgaCRReg, 0x00);
1182 
1183     /* Make sure we can't write when locked */
1184 
1185     if (testinx2(vgaCRIndex, 0x35, 0x0f))
1186 	return 0;
1187 
1188     outb(vgaCRIndex, 0x38);	/* for register CR38, (REG_LOCK1) */
1189     outb(vgaCRReg, 0x48);	/* unlock S3 register set for read/write */
1190 
1191     /* Make sure we can write when unlocked */
1192 
1193     if (!testinx2(vgaCRIndex, 0x35, 0x0f))
1194 	return 0;
1195 
1196     if (s3_init(0, 0, 0))	/* type not OK */
1197 	return 0;
1198     return 1;
1199 }
1200 
1201 /*
1202  * Bank switching function - set 64K bank number
1203  *
1204  * XXXX locking and unlocking might hurt performance but is safer.
1205  */
s3_setpage(int page)1206 static void s3_setpage(int page)
1207 {
1208 #ifdef S3_16_COLORS
1209     /*
1210      * XXXX adjust the parameter for 4bpp (1bpp is ignored).  Shouldn't
1211      * need this, but either me or the drawing functions are making bad
1212      * assumptions about 4bpp.
1213      */
1214     if (infotable[CM].bytesperpixel == 0)
1215 	page *= 4;
1216 #endif
1217 #ifdef S3_KLUDGE_PAGE_MODE
1218     /* adjust to use 256K pages */
1219     if (CM == G320x200x256)
1220 	page *= 4;
1221 #endif
1222     s3_unlock();
1223     outb(CRT_IC, 0x35);
1224     outb(CRT_DC, (inb(CRT_DC) & 0xF0) | (page & 0x0F));
1225     if (s3_chiptype >= S3_801) {
1226 	outb(CRT_IC, 0x51);
1227 	outb(CRT_DC, (inb(CRT_DC) & ~0x0C) | ((page & 0x30) >> 2));
1228     }
1229     inb(CRT_DC);			/* ARI: Ferraro says: required for first generation 911 only */
1230     s3_lock();
1231 }
1232 
1233 /*
1234  * Bank switching function - set 64K bank number for 864+
1235  * (not for 4bpp)
1236  *
1237  * XXXX locking and unlocking might hurt performance
1238  * (864 shouldn't need it).
1239  */
1240 #ifdef S3_LINEAR_MODE_BANKING_864
s3_setpage864(int page)1241 static void s3_setpage864(int page)
1242 {
1243     s3_unlock();
1244     /* "Linear" mode banking. */
1245     outb(CRT_IC, 0x6A);
1246     outb(CRT_DC, (inb(CRT_DC) & ~0x3F) | page);
1247     s3_lock();
1248 }
1249 
1250 #endif
1251 
1252 /*
1253  * Set display start address (not for 16 color modes).
1254  *
1255  * This works up to 4Mb (should be able to go higher).
1256  *
1257  * XXXX locking and unlocking might hurt performance but is safer.
1258  */
s3_setdisplaystart(int address)1259 static void s3_setdisplaystart(int address)
1260 {
1261 #ifdef S3_KLUDGE_PAGE_MODE
1262     /* adjust to use 256K pages */
1263     if (CM == G320x200x256)
1264 	address *= 4;
1265 #endif
1266     s3_unlock();
1267     outw(CRT_IC, 0x0d | ((address << 6) & 0xff00));	/* sa2-sa9 */
1268     outw(CRT_IC, 0x0c | ((address >> 2) & 0xff00));	/* sa10-sa17 */
1269     inb(0x3da);			/* set ATC to addressing mode */
1270     outb(ATT_IW, 0x13 + 0x20);	/* select ATC reg 0x13 */
1271     outb(ATT_IW, (inb(ATT_R) & 0xf0) | ((address & 3) << 1));
1272     /* write sa0-1 to bits 1-2 */
1273 
1274     outb(CRT_IC, 0x31);
1275     outb(CRT_DC, (inb(CRT_DC) & ~0x30) | ((address & 0xc0000) >> 14));
1276     if (s3_chiptype >= S3_801) {
1277 	outb(CRT_IC, 0x51);
1278 	outb(CRT_DC, (inb(CRT_DC) & ~0x03) | ((address & 0x300000) >> 20));
1279     }
1280     s3_lock();
1281 }
1282 
1283 /*
1284  * Set logical scanline length (Multiples of 8 to 8184).
1285  * CR43.2 should be 0 for this.
1286  */
s3_setlogicalwidth(int width)1287 static void s3_setlogicalwidth(int width)
1288 {
1289     __svgalib_outCR(0x13, (width >> 3));	/* lw3-lw11 */
1290     __svgalib_outCR(0x51, (width & 0x300) >> 4);	/* lw12-lw13 */
1291 }
1292 
1293 #ifdef S3_LINEAR_SUPPORT
s3_linear_enable(void)1294 static void s3_linear_enable(void)
1295 {
1296     s3_unlock();
1297 
1298     if (s3_chiptype > S3_924) {
1299     	int i;
1300     	outb (CRT_IC, 0x40);
1301     	i = (s3_cr40 & 0xf6) | 0x0a;
1302     	outb (CRT_DC, (unsigned char) i);
1303     	outb (CRT_IC, 0x58);
1304     	outb (CRT_DC, s3_linear_opt | s3_cr58);
1305     	if (s3_chiptype > S3_928) {
1306     	    outb (CRT_IC, 0x54);
1307     	    outb (CRT_DC, (s3_cr54 + 0x07));
1308     	}
1309     }
1310 
1311     s3_lock();
1312 }
1313 
s3_linear_disable(void)1314 static void s3_linear_disable(void)
1315 {
1316     s3_unlock();
1317 
1318     if (s3_chiptype > S3_924) {
1319     	if (s3_chiptype > S3_928) {
1320     	    outb (CRT_IC, 0x54);
1321     	    outb (CRT_DC, s3_cr54);
1322     	}
1323     	outb (CRT_IC, 0x58);
1324     	outb (CRT_DC, s3_cr58);
1325     	outb (CRT_IC, 0x40);
1326     	outb (CRT_DC, s3_cr40);
1327     }
1328 
1329     s3_lock();
1330 }
1331 
1332 /* Set linear addressing mode */
1333 
s3_linear(int op,int param)1334 static int s3_linear(int op, int param)
1335 {
1336     if (op == LINEAR_QUERY_BASE)
1337     	return s3_linear_base;
1338     if (op == LINEAR_QUERY_GRANULARITY) {
1339 	switch (s3_memory) {
1340 	case 4096:
1341 	case 2048:
1342 	case 1024:
1343 	    return s3_memory * 1024;
1344 	default:
1345 	    return 1024 * 1024;
1346 	}
1347     } else if (op == LINEAR_QUERY_RANGE)
1348 	return 256;
1349     else if (op == LINEAR_ENABLE) {
1350 	s3_setpage(0);
1351 	s3_linear_enable();
1352 	s3_linear_addr = param;
1353 	return 0;
1354     } else if (op == LINEAR_DISABLE) {
1355 	s3_setpage(0);
1356 	s3_linear_disable();
1357 	s3_linear_addr = 0;
1358 	return 0;
1359     } else
1360 	return -1;
1361 }
1362 
1363 #define S3_LINEAR_FUNC s3_linear
1364 #else
1365 #define S3_LINEAR_FUNC 0
1366 #endif				/* S3_LINEAR_SUPPORT */
1367 
1368 /* Function table (exported) */
1369 
1370 DriverSpecs __svgalib_s3_driverspecs =
1371 {
1372     s3_saveregs,		/* saveregs */
1373     s3_setregs,			/* setregs */
1374     (void (*)(void)) nothing,	/* unlock */
1375     (void (*)(void)) nothing,	/* lock */
1376     s3_test,
1377     s3_init,
1378     s3_setpage,
1379     (void (*)(int)) nothing,
1380     (void (*)(int)) nothing,
1381     s3_setmode,
1382     s3_modeavailable,
1383     s3_setdisplaystart,
1384     s3_setlogicalwidth,
1385     s3_getmodeinfo,
1386     0,				/* bitblt */
1387     0,				/* imageblt */
1388     0,				/* fillblt */
1389     0,				/* hlinelistblt */
1390     0,				/* bltwait */
1391     s3_ext_set,			/* extset */
1392     0,				/* accel */
1393     S3_LINEAR_FUNC,		/* linear */
1394     NULL,                       /* Accelspecs */
1395     NULL,                       /* Emulation */
1396 };
1397 
1398 
1399 /* S3-specific config file options. */
1400 
1401 /*
1402  * Currently this only handles Clocks. It would a good idea to have
1403  * higher-level code process options like Clocks that are valid for
1404  * more than one driver driver (with better error detection etc.).
1405  */
1406 
1407 static char *s3_config_options[] =
1408 {
1409     "clocks", "ramdac", "dacspeed", "clockchip", NULL
1410 };
1411 
s3_process_option(int option,int mode)1412 static char *s3_process_option(int option, int mode)
1413 {
1414 /*
1415  * option is the number of the option string in s3_config_options,
1416  * mode seems to be a 'hardness' indicator for security.
1417  */
1418     if (option == 0) {		/* "Clocks" */
1419 	/* Process at most 16 specified clocks. */
1420 	cardspecs->clocks = malloc(sizeof(int) * 16);
1421 	/* cardspecs->nClocks should be already be 0. */
1422 	for (;;) {
1423 	    char *ptr;
1424 	    int freq;
1425 	    ptr = strtok(NULL, " ");
1426 	    if (ptr == NULL)
1427 		break;
1428 	    /*
1429 	     * This doesn't protect against bad characters
1430 	     * (atof() doesn't detect errors).
1431 	     */
1432 	    freq = atof(ptr) * 1000;
1433 	    cardspecs->clocks[cardspecs->nClocks] = freq;
1434 	    cardspecs->nClocks++;
1435 	    if (cardspecs->nClocks == 16)
1436 		break;
1437 	}
1438     }
1439     if (option == 1) {		/* "Ramdac" */
1440 	char *ptr;
1441 	ptr = strtok(NULL, " ");
1442 #ifdef INCLUDE_IBMRGB52x_DAC
1443 	if (strcasecmp(ptr, "IBMRGB52x") == 0)
1444 	    dac_used = &__svgalib_IBMRGB52x_methods;
1445 #endif
1446 #ifdef INCLUDE_SIERRA_DAC
1447 	if (strcasecmp(ptr, "Sierra32K") == 0)
1448 	    dac_used = &__svgalib_Sierra_32K_methods;
1449 #endif
1450 #ifdef INCLUDE_SC15025_DAC
1451 	if (strcasecmp(ptr, "SC15025") == 0)
1452 	    dac_used = &__svgalib_SC15025_methods;
1453 #endif
1454 #ifdef INCLUDE_S3_SDAC_DAC
1455 	if (strcasecmp(ptr, "SDAC") == 0)
1456 	    dac_used = &__svgalib_S3_SDAC_methods;
1457 #endif
1458 #ifdef INCLUDE_S3_GENDAC_DAC
1459 	if (strcasecmp(ptr, "GenDAC") == 0)
1460 	    dac_used = &__svgalib_S3_GENDAC_methods;
1461 #endif
1462 #ifdef INCLUDE_ATT20C490_DAC
1463 	if (strcasecmp(ptr, "ATT20C490") == 0)
1464 	    dac_used = &__svgalib_ATT20C490_methods;
1465 #endif
1466 #ifdef INCLUDE_ATT20C498_DAC
1467 	if (strcasecmp(ptr, "ATT20C498") == 0)
1468 	    dac_used = &__svgalib_ATT20C498_methods;
1469 #endif
1470 #ifdef INCLUDE_NORMAL_DAC
1471 	if (strcasecmp(ptr, "Normal") == 0)	/* force normal VGA dac */
1472 	    dac_used = &__svgalib_normal_dac_methods;
1473 #endif
1474 
1475 	if (clk_used)
1476 	    clk_used->initialize(cardspecs, dac_used);
1477     }
1478     if (option == 2) {		/* "Dacspeed" */
1479 	char *ptr;
1480 	ptr = strtok(NULL, " ");
1481 	/*
1482 	 * This doesn't protect against bad characters
1483 	 * (atoi() doesn't detect errors).
1484 	 */
1485 	dac_speed = atoi(ptr) * 1000;
1486     }
1487     if (option == 3) {		/* "ClockChip" */
1488 	char *ptr;
1489 	long freq;
1490 	ptr = strtok(NULL, " \t");
1491 	if (strcasecmp(ptr, "ICD2061A") == 0 ||
1492 	    strcasecmp(ptr, "DCS2824") == 0)	/* Diamond, compatible to icd2061a */
1493 	    clk_used = &__svgalib_I2061A_clockchip_methods;
1494 	clk_used->initialize(cardspecs, dac_used);
1495 	ptr = strtok(NULL, " \t");
1496 	if (ptr != NULL) {
1497 	    freq = atof(ptr) * 1000L;
1498 	    if (freq) {
1499 		clk_used->TextFrequency = freq;
1500 		ptr = strtok(NULL, " \t");
1501 	    }
1502 	}
1503 	return ptr;
1504     }
1505     return strtok(NULL, " ");
1506 }
1507 
1508 
1509 /* Initialize driver (called after detection) */
1510 /* Derived from XFree86 SuperProbe and s3 driver. */
1511 
1512 static DacMethods *dacs_to_probe[] =
1513 {
1514 #ifdef INCLUDE_S3_SDAC_DAC_TEST
1515     &__svgalib_S3_SDAC_methods,
1516 #endif
1517 #ifdef INCLUDE_S3_GENDAC_DAC_TEST
1518     &__svgalib_S3_GENDAC_methods,
1519 #endif
1520 #ifdef INCLUDE_ATT20C490_DAC_TEST
1521     &__svgalib_ATT20C490_methods,
1522 #endif
1523 #ifdef INCLUDE_SC15025_DAC_TEST
1524     &__svgalib_SC15025_methods,
1525 #endif
1526 #ifdef INCLUDE_SC1148X_DAC_TEST
1527     &__svgalib_SC1148X_methods,
1528 #endif
1529 #ifdef INCLUDE_IBMRGB52x_DAC_TEST
1530     &__svgalib_IBMRGB52x_methods,
1531 #endif
1532     NULL};
1533 
s3_init(int force,int par1,int par2)1534 static int s3_init(int force, int par1, int par2)
1535 {
1536     int id, rev, config;
1537 
1538     s3_unlock();
1539 
1540     s3_flags = 0;		/* initialize */
1541     id = __svgalib_inCR(0x30);		/* Get chip id. */
1542     rev = id & 0x0F;
1543     if (id >= 0xE0) {
1544 	id |= __svgalib_inCR(0x2E) << 8;
1545 	rev |= __svgalib_inCR(0x2F) << 4;
1546     }
1547     if (force) {
1548 	s3_chiptype = par1;	/* we already know the type */
1549 	s3_memory = par2;
1550 	/* ARI: can we really trust the user's specification, or should we ignore
1551 	   it and probe ourselves ? */
1552 	if (s3_chiptype == S3_801 || s3_chiptype == S3_805) {
1553 	    if ((rev & 0x0F) < 2)
1554 		s3_flags |= S3_OLD_STEPPING;	/* can't handle 1152 width */
1555 	} else if (s3_chiptype == S3_928) {
1556 	    if ((rev & 0x0F) < 4)	/* ARI: Stepping D or below */
1557 		s3_flags |= S3_OLD_STEPPING;	/* can't handle 1152 width */
1558 	}
1559     } else {
1560 	s3_chiptype = -1;
1561 	config = __svgalib_inCR(0x36);	/* get configuration info */
1562 	switch (id & 0xf0) {
1563 	case 0x80:
1564 	    if (rev == 1) {
1565 		s3_chiptype = S3_911;
1566 		break;
1567 	    }
1568 	    if (rev == 2) {
1569 		s3_chiptype = S3_924;
1570 		break;
1571 	    }
1572 	    break;
1573 	case 0xa0:
1574 	    switch (config & 0x03) {
1575 	    case 0x00:
1576 	    case 0x01:
1577 		/* EISA or VLB - 805 */
1578 		s3_chiptype = S3_805;
1579 		/* ARI: Test stepping: 0:B, 1:unknown, 2,3,4:C, 8:I, >=5:D */
1580 		if ((rev & 0x0F) < 2)
1581 		    s3_flags |= S3_OLD_STEPPING;	/* can't handle 1152 width */
1582 		break;
1583 	    case 0x03:
1584 		/* ISA - 801 */
1585 		s3_chiptype = S3_801;
1586 		/* Stepping same as 805, just ISA */
1587 		if ((rev & 0x0F) < 2)
1588 		    s3_flags |= S3_OLD_STEPPING;	/* can't handle 1152 width */
1589 		break;
1590 	    }
1591 	    break;
1592 	case 0x90:
1593 	    s3_chiptype = S3_928;
1594 	    if ((rev & 0x0F) < 4)	/* ARI: Stepping D or below */
1595 		s3_flags |= S3_OLD_STEPPING;	/* can't handle 1152 width */
1596 	    break;
1597 	case 0xB0:
1598 	    /* 928P */
1599 	    s3_chiptype = S3_928;
1600 	    break;
1601 	case 0xC0:
1602 	    s3_chiptype = S3_864;
1603 	    break;
1604 	case 0xD0:
1605 	    s3_chiptype = S3_964;
1606 	    break;
1607 	case 0xE0:
1608 	    switch (id & 0xFFF0) {
1609 	    case 0x10E0:
1610 		s3_chiptype = S3_TRIO32;
1611 		break;
1612 	    case 0x3DE0: /* ViRGE/VX ID */
1613 	    case 0x31E0: /* ViRGE ID */
1614 	    case 0x01E0: /* S3Trio64V2/DX ... any others? */
1615             case 0x04E0:
1616 	    case 0x11E0:
1617 		if (rev & 0x0400)
1618 		    s3_chiptype = S3_765;
1619 		else
1620 		    s3_chiptype = S3_TRIO64;
1621 		break;
1622 	    case 0x80E0:
1623 		s3_chiptype = S3_866;
1624 		break;
1625 	    case 0x90E0:
1626 		s3_chiptype = S3_868;
1627 		break;
1628 	    case 0xF0E0:	/* XXXX From data book; XF86 says 0xB0E0? */
1629 		s3_chiptype = S3_968;
1630 		break;
1631 	    }
1632 	}
1633 	if (s3_chiptype == -1) {
1634 	    printf("svgalib: S3: Unknown chip id %02x\n",
1635 		   id);
1636 	    return -1;
1637 	}
1638 	if (s3_chiptype <= S3_924) {
1639 	    if ((config & 0x20) != 0)
1640 		s3_memory = 512;
1641 	    else
1642 		s3_memory = 1024;
1643 	} else {
1644 	    /* look at bits 5, 6 and 7 */
1645 	    switch ((config & 0xE0) >> 5) {
1646 	    case 0:
1647 		s3_memory = 4096;
1648 		break;
1649 	    case 2:
1650 		s3_memory = 3072;
1651 		break;
1652 	    case 3:
1653 		s3_memory = 8192;
1654 		break;
1655 	    case 4:
1656 		s3_memory = 2048;
1657 		break;
1658 	    case 5:
1659 		s3_memory = 6144;
1660 		break;
1661 	    case 6:
1662 		s3_memory = 1024;
1663 		break;
1664 	    case 7:
1665 		s3_memory = 512;
1666 		break;		/* Trio32 */
1667 	    }
1668 	}
1669 
1670 	if ((config & 0x03) < 3)	/* XXXX 928P is ignored */
1671 	    s3_flags |= S3_LOCALBUS;
1672     }
1673 
1674     if (__svgalib_driver_report) {
1675 	printf("svgalib: Using S3 driver (%s, %dK).\n", s3_chipname[s3_chiptype],
1676 	       s3_memory);
1677 	if (s3_flags & S3_OLD_STEPPING)
1678 	    printf("svgalib: Chip revision cannot handle modes with width 1152.\n");
1679 	if (s3_chiptype > S3_TRIO64) {
1680 	    printf("svgalib: s3: chipsets newer than S3 Trio64 is not supported well yet.\n");
1681 	}
1682     }
1683 /* begin: Initialize cardspecs. */
1684     /* If IOPERM is set, assume permissions have already been set by Olaf Titz' */
1685     /* ioperm(1). */
1686     if (getenv("IOPERM") == NULL) {
1687 	if (0 > iopl(3))
1688 	    printf("svgalib: s3: cannot get I/O permissions for 8514.");
1689     }
1690 #ifdef S3_LINEAR_SUPPORT
1691     if (s3_chiptype > S3_805) {
1692     	int found_pciconfig;
1693     	unsigned long pci_conf[64];
1694 
1695     	found_pciconfig = __svgalib_pci_find_vendor_vga(0x5333, pci_conf, 0);
1696     	if (!found_pciconfig)
1697     	    s3_linear_base = pci_conf[4] & 0xFF800000;
1698     }
1699 
1700     s3_cr59 = s3_linear_base >> 24;
1701     s3_cr5A = (s3_linear_base >> 16);
1702     if (! (s3_cr59 | s3_cr5A)) {
1703     	s3_cr59 = __svgalib_inCR(0x59);
1704     	s3_cr5A = __svgalib_inCR(0x5A);
1705     	if (!s3_cr59) {
1706     	    s3_cr59 =  0xF3000000 >> 24;
1707     	    s3_cr5A = (0xF3000000 >> 16);
1708     	}
1709     	s3_linear_base = (s3_cr59 << 24) | (s3_cr5A << 16);
1710     }
1711     s3_linear_opt |= 0x10;
1712     switch (s3_memory) {
1713     	case 512 :
1714     	case 1024 :
1715     	    s3_linear_opt |= 0x01;
1716     	    break;
1717     	case 2048 :
1718     	    s3_linear_opt |= 0x02;
1719     	    break;
1720     	case 3072 :
1721     	case 4096 :
1722     	case 6144 :
1723     	case 8192 :
1724     	    s3_linear_opt |= 0x03;
1725     	    break;
1726     	default :
1727     	    s3_linear_opt = 0x14;	/* like XFree */
1728     }
1729 #endif
1730 
1731     cardspecs = malloc(sizeof(CardSpecs));
1732     cardspecs->videoMemory = s3_memory;
1733     cardspecs->nClocks = 0;
1734     /* cardspecs->maxHorizontalCrtc = 2040; SL: kills 800x600x32k and above */
1735     cardspecs->maxHorizontalCrtc = 4088;
1736     cardspecs->flags = INTERLACE_DIVIDE_VERT;
1737 
1738     /* Process S3-specific config file options. */
1739     __svgalib_read_options(s3_config_options, s3_process_option);
1740 
1741 #ifdef INCLUDE_S3_TRIO64_DAC
1742     if ((s3_chiptype == S3_TRIO64 || s3_chiptype == S3_765) && dac_used == NULL)
1743 	dac_used = &__svgalib_Trio64_methods;
1744 #endif
1745 
1746     if (dac_used == NULL)
1747 	dac_used = __svgalib_probeDacs(dacs_to_probe);
1748     else
1749 	dac_used->initialize();
1750 
1751 
1752     if (dac_used == NULL) {
1753 	/* Not supported. */
1754 	printf("svgalib: s3: Assuming normal VGA DAC.\n");
1755 #ifdef INCLUDE_NORMAL_DAC
1756 	dac_used = &__svgalib_normal_dac_methods;
1757 	dac_used->initialize();
1758 #else
1759 	printf("svgalib: Alas, normal VGA DAC support is not compiled in, goodbye.\n");
1760 	return 1;
1761 #endif
1762     }
1763     if (clk_used)
1764 	clk_used->initialize(cardspecs, dac_used);
1765 
1766     dac_used->qualifyCardSpecs(cardspecs, dac_speed);
1767 
1768     /* Initialize standard clocks for unknown DAC. */
1769     if ((!(cardspecs->flags & CLOCK_PROGRAMMABLE))
1770 	&& cardspecs->nClocks == 0) {
1771 	/*
1772 	 * Almost all cards have 25 and 28 MHz on VGA clocks 0 and 1,
1773 	 * so use these for an unknown DAC, yielding 640x480x256.
1774 	 */
1775 	cardspecs->nClocks = 2;
1776 	cardspecs->clocks = malloc(sizeof(int) * 2);
1777 	cardspecs->clocks[0] = 25175;
1778 	cardspecs->clocks[1] = 28322;
1779     }
1780     /* Limit pixel clocks according to chip specifications. */
1781     if (s3_chiptype == S3_864 || s3_chiptype == S3_868) {
1782 	/* Limit max clocks according to 95 MHz DCLK spec. */
1783 	/* SL: might just be 95000 for 4/8bpp since no pixmux'ing */
1784 	LIMIT(cardspecs->maxPixelClock4bpp, 95000 * 2);
1785 	LIMIT(cardspecs->maxPixelClock8bpp, 95000 * 2);
1786 	LIMIT(cardspecs->maxPixelClock16bpp, 95000);
1787 	/* see explanation below */
1788 	LIMIT(cardspecs->maxPixelClock24bpp, 36000);
1789 	/*
1790 	 * The official 32bpp limit is 47500, but we allow
1791 	 * 50 MHz for VESA 800x600 timing (actually the
1792 	 * S3-864 doesn't have the horizontal timing range
1793 	 * to run unmodified VESA 800x600 72 Hz timings).
1794 	 */
1795 	LIMIT(cardspecs->maxPixelClock32bpp, 50000);
1796     }
1797 #ifndef S3_16_COLORS
1798     cardspecs->maxPixelClock4bpp = 0;	/* 16-color doesn't work. */
1799 #endif
1800 
1801 /* end: Initialize cardspecs. */
1802 
1803     __svgalib_driverspecs = &__svgalib_s3_driverspecs;
1804 
1805     __svgalib_banked_mem_base=0xa0000;
1806     __svgalib_banked_mem_size=0x10000;
1807 #ifdef S3_LINEAR_SUPPORT
1808     __svgalib_linear_mem_base=s3_linear_base;
1809     __svgalib_linear_mem_size=s3_memory*0x400;
1810 #endif
1811 
1812     return 0;
1813 }
1814