Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
169 giacomo 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>
93
#include "vga.h"
94
#include "libvga.h"
95
#include "driver.h"
96
#include "timing.h"
97
#include "ramdac.h"
98
#include "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 __svgalib_s3_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
 
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
 */
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
 
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
 */
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
 
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
 */
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
 
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 (!IS_IN_STANDARD_VGA_DRIVER(mode))
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 | LINEAR_MODE;
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
 */
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
    default:
478
        break;
479
    }
480
    return 0;
481
}
482
 
483
/* Return non-zero if mode is available */
484
 
485
static int s3_modeavailable(int mode)
486
{
487
    struct info *info;
488
    ModeInfo *modeinfo;
489
    ModeTiming *modetiming;
490
 
491
    if (IS_IN_STANDARD_VGA_DRIVER(mode))
492
        return __svgalib_vga_driverspecs.modeavailable(mode);
493
 
494
    /* Enough memory? */
495
    info = &__svgalib_infotable[mode];
496
    if (s3_memory * 1024 < info->ydim * s3_adjlinewidth(info->xbytes))
497
        return 0;
498
 
499
    modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
500
 
501
    modetiming = malloc(sizeof(ModeTiming));
502
    if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {
503
        free(modetiming);
504
        free(modeinfo);
505
        return 0;
506
    }
507
    free(modetiming);
508
    free(modeinfo);
509
 
510
    return SVGADRV;
511
}
512
 
513
/*
514
 * save S3 registers.  Lock registers receive special treatment
515
 * so dumpreg will work under X.
516
 */
517
static int s3_saveregs(unsigned char regs[])
518
{
519
    unsigned char b, bmax;
520
    unsigned char cr38, cr39, cr40;
521
 
522
    cr38 = __svgalib_inCR(0x38);
523
    __svgalib_outCR(0x38, 0x48);                /* unlock S3 VGA regs (CR30-CR3B) */
524
 
525
    cr39 = __svgalib_inCR(0x39);
526
    __svgalib_outCR(0x39, 0xA5);                /* unlock S3 system control (CR40-CR4F) */
527
    /* and extended regs (CR50-CR6D) */
528
 
529
    cr40 = __svgalib_inCR(0x40);                /* unlock enhanced regs */
530
    __svgalib_outCR(0x40, cr40 | 0x01);
531
 
532
    /* retrieve values from private copy */
533
    memcpy(regs + S3_8514_OFFSET, s3_8514regs, S3_8514_COUNT * 2);
534
 
535
    /* get S3 VGA/Ext registers */
536
    bmax = 0x4F;
537
    if (s3_chiptype >= S3_801)
538
        bmax = 0x66;
539
    if (s3_chiptype >= S3_864)
540
        bmax = 0x6D;
541
    for (b = 0x30; b <= bmax; b++)
542
        regs[EXT + b - 0x30] = __svgalib_inCR(b);
543
 
544
    /* get S3 ext. SR registers */
545
    /* if (s3_chiptype >= S3_864) { */
546
    if (s3_chiptype == S3_TRIO32 || s3_chiptype == S3_TRIO64
547
        || s3_chiptype == S3_765) {/* SL: actually Trio32/64/V+ */
548
        regs[S3_SR08] = __svgalib_inSR(0x08);
549
        __svgalib_outSR(0x08, 0x06);    /* unlock extended seq regs */
550
        regs[S3_SR09] = __svgalib_inSR(0x09);
551
        regs[S3_SR0A] = __svgalib_inSR(0x0A);
552
        regs[S3_SR0D] = __svgalib_inSR(0x0D);
553
        regs[S3_SR10] = __svgalib_inSR(0x10);
554
        regs[S3_SR11] = __svgalib_inSR(0x11);
555
        regs[S3_SR12] = __svgalib_inSR(0x12);
556
        regs[S3_SR13] = __svgalib_inSR(0x13);
557
        regs[S3_SR15] = __svgalib_inSR(0x15);
558
        regs[S3_SR18] = __svgalib_inSR(0x18);
559
        __svgalib_outSR(0x08, regs[S3_SR08]);
560
    }
561
 
562
    dac_used->saveState(regs + S3_DAC_OFFSET);
563
 
564
    /* leave the locks the way we found it */
565
    __svgalib_outCR(0x40, regs[EXT + 0x40 - 0x30] = cr40);
566
    __svgalib_outCR(0x39, regs[EXT + 0x39 - 0x30] = cr39);
567
    __svgalib_outCR(0x38, regs[EXT + 0x38 - 0x30] = cr38);
568
#if 0
569
#include "ramdac/IBMRGB52x.h"
570
 
571
    do {
572
        unsigned char m, n, df;
573
 
574
        fprintf(stderr,"pix_fmt = 0x%02X, 8bpp = 0x%02X, 16bpp = 0x%02X, 24bpp = 0x%02X, 32bpp = 0x%02X,\n"
575
          "CR58 = 0x%02X, CR66 = 0x%02X, CR67 = 0x%02X, CR6D = 0x%02X\n",
576
               regs[S3_DAC_OFFSET + IBMRGB_pix_fmt],
577
               regs[S3_DAC_OFFSET + IBMRGB_8bpp],
578
               regs[S3_DAC_OFFSET + IBMRGB_16bpp],
579
               regs[S3_DAC_OFFSET + IBMRGB_24bpp],
580
               regs[S3_DAC_OFFSET + IBMRGB_32bpp],
581
               regs[S3_CR58],
582
               regs[S3_CR66],
583
               regs[S3_CR67],
584
               regs[S3_CR6D]);
585
 
586
        m = regs[S3_DAC_OFFSET + IBMRGB_m0 + 4];
587
        n = regs[S3_DAC_OFFSET + IBMRGB_n0 + 4];
588
        df = m >> 6;
589
        m &= ~0xC0;
590
 
591
        fprintf(stderr,"m = 0x%02X %d, n = 0x%02X %d, df = 0x%02X %d, freq = %.3f\n",
592
               m, m, n, n, df, df, ((m + 65.0) / n) / (8 >> df) * 16.0);
593
    } while (0);
594
#endif
595
    return S3_DAC_OFFSET - VGA_TOTAL_REGS + dac_used->stateSize;
596
}
597
 
598
/* Set chipset-specific registers */
599
static void s3_setregs(const unsigned char regs[], int mode)
600
{
601
    unsigned char b, bmax;
602
    /*
603
     * Right now, anything != 0x00 gets written in s3_setregs.
604
     * May change this into a bitmask later.
605
     */
606
    static unsigned char s3_regmask[] =
607
    {
608
        0x00, 0x31, 0x32, 0x33, 0x34, 0x35, 0x00, 0x00,         /* CR30-CR37 */
609
        0x00, 0x00, 0x3A, 0x3B, 0x3C, 0x00, 0x00, 0x00,         /* CR38-CR3F */
610
        0x00, 0x00, 0x42, 0x43, 0x44, 0x00, 0x00, 0x00,         /* CR40-CR47 */
611
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,         /* CR48-CR4F */
612
        0x50, 0x51, 0x00, 0x00, 0x54, 0x55, 0x00, 0x00,         /* CR50-CR57 */
613
        0x58, 0x59, 0x5A, 0x00, 0x00, 0x5D, 0x5E, 0x00,         /* CR58-CR5F */
614
        0x60, 0x61, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00,         /* CR60-CR67 */
615
        0x00, 0x00, 0x6A, 0x00, 0x00, 0x00                      /* CR68-CR6D */
616
    };
617
 
618
    s3_unlock_enh();
619
 
620
    /* save a private copy */
621
    memcpy(s3_8514regs, regs + S3_8514_OFFSET, S3_8514_COUNT * 2);
622
    /*
623
     * set this first, so if we segfault on this
624
     * we don't get a screwed up display
625
     */
626
    outw(ADVFUNC_CNTL, s3_8514regs[S3_ADVFUNC_CNTL]);
627
 
628
    /* get S3 VGA/Ext registers */
629
    bmax = 0x4F;
630
    if (s3_chiptype >= S3_801)
631
        bmax = 0x66;
632
    if (s3_chiptype >= S3_864)
633
        bmax = 0x6D;
634
    for (b = 0x30; b <= bmax; b++) {
635
        if (s3_regmask[b - 0x30])
636
            __svgalib_outCR(b, regs[EXT + b - 0x30]);
637
    }
638
 
639
    if (dac_used->id != NORMAL_DAC) {
640
        unsigned char CR1;
641
        /* Blank the screen. */
642
        CR1 = __svgalib_inCR(0x01);
643
        __svgalib_outCR(0x01, CR1 | 0x20);
644
 
645
        __svgalib_outcrtc(0x55, __svgalib_inCR(0x55) | 1);
646
        __svgalib_outcrtc(0x66, regs[S3_CR66]);
647
        __svgalib_outcrtc(0x67, regs[S3_CR67]); /* S3 pixmux. */
648
 
649
        dac_used->restoreState(regs + S3_DAC_OFFSET);
650
 
651
        __svgalib_outcrtc(0x6D, regs[S3_CR6D]);
652
        __svgalib_outcrtc(0x55, __svgalib_inCR(0x55) & ~1);
653
 
654
        __svgalib_outcrtc(0x01, CR1);   /* Unblank screen. */
655
    }
656
#ifdef S3_LINEAR_SUPPORT
657
    if (mode == TEXT && s3_linear_addr)
658
        s3_linear_disable();    /* make sure linear is off */
659
#endif
660
 
661
    /* restore CR38/39 (may lock other regs) */
662
    if (mode == TEXT) {
663
        /* restore lock registers as well */
664
        __svgalib_outCR(0x40, regs[S3_CR40]);
665
        __svgalib_outCR(0x39, regs[S3_CR39]);
666
        __svgalib_outCR(0x38, regs[S3_CR38]);
667
    } else
668
        s3_lock_enh();
669
}
670
 
671
/*
672
 * Initialize register state for a mode.
673
 */
674
 
675
static void s3_initializemode(unsigned char *moderegs,
676
                            ModeTiming * modetiming, ModeInfo * modeinfo)
677
{
678
    /* Get current values. */
679
    s3_saveregs(moderegs);
680
 
681
    /* Set up the standard VGA registers for a generic SVGA. */
682
    __svgalib_setup_VGA_registers(moderegs, modetiming, modeinfo);
683
 
684
    /* Set up the extended register values, including modifications */
685
    /* of standard VGA registers. */
686
 
687
    moderegs[VGA_SR0] = 0x03;
688
    moderegs[VGA_CR13] = modeinfo->lineWidth >> 3;
689
    moderegs[VGA_CR17] = 0xE3;
690
 
691
    if (modeinfo->lineWidth / modeinfo->bytesPerPixel == 2048)
692
        moderegs[S3_CR31] = 0x8F;
693
    else
694
        moderegs[S3_CR31] = 0x8D;
695
#ifdef S3_LINEAR_MODE_BANKING_864
696
    if (s3_chiptype >= S3_864) {
697
        /* moderegs[S3_ENHANCEDMODE] |= 0x01; */
698
        /* Enable enhanced memory mode. */
699
        moderegs[S3_CR31] |= 0x04;
700
        /* Enable banking via CR6A in linear mode. */
701
        moderegs[S3_CR31] |= 0x01;
702
    }
703
#endif
704
    moderegs[S3_CR32] = 0;
705
    moderegs[S3_CR33] = 0x20;
706
    moderegs[S3_CR34] = 0x10;   /* 1024 */
707
    moderegs[S3_CR35] = 0;
708
    /* Call cebank() here when setting registers. */
709
    if (modeinfo->bitsPerPixel >= 8) {
710
        moderegs[S3_CR3A] = 0xB5;
711
        if (s3_chiptype == S3_928)
712
            /* ARI: Turn on CHAIN4 for 928, since __svgalib_setup_VGA_registers
713
                                                         initializes ModeX */
714
            moderegs[VGA_CR14] = 0x60;
715
    } else {
716
        /* 16 color mode */
717
        moderegs[VGA_CR13] = modeinfo->lineWidth >> 1;
718
        moderegs[VGA_GR0] = 0x0F;
719
        moderegs[VGA_GR1] = 0x0F;
720
        moderegs[VGA_GR5] = 0x00;       /* write mode 0 */
721
        moderegs[VGA_AR11] = 0x00;
722
        moderegs[S3_CR3A] = 0x85;
723
    }
724
 
725
    moderegs[S3_CR3B] = (moderegs[VGA_CR0] + moderegs[VGA_CR4] + 1) / 2;
726
    moderegs[S3_CR3C] = moderegs[VGA_CR0] / 2;
727
    if (s3_chiptype == S3_911) {
728
        moderegs[S3_CR40] &= 0xF2;
729
        moderegs[S3_CR40] |= 0x09;
730
    } else if (s3_flags & S3_LOCALBUS) {
731
        moderegs[S3_CR40] &= 0xF2;
732
        /* Pegasus wants 0x01 for zero wait states. */
733
#ifdef S3_0_WAIT_805_864
734
        moderegs[S3_CR40] |= 0x09;      /* use fifo + 0 wait state */
735
#else
736
        moderegs[S3_CR40] |= 0x05;
737
#endif
738
    } else {
739
        moderegs[S3_CR40] &= 0xF6;
740
        moderegs[S3_CR40] |= 0x01;
741
    }
742
 
743
    if (modeinfo->bitsPerPixel >= 24) {
744
        /* 24/32 bit color */
745
        if (s3_chiptype == S3_864 || s3_chiptype == S3_964)
746
            moderegs[S3_CR43] = 0x08;
747
        else if (s3_chiptype == S3_928 && dac_used->id == SIERRA_15025)
748
            moderegs[S3_CR43] = 0x01;   /* ELSA Winner 1000 */
749
    } else if (modeinfo->bitsPerPixel >= 15) {
750
        /* 15/16 bit color */
751
        if (s3_chiptype <= S3_864 || s3_chiptype >= S3_866) {   /* XXXX Trio? */
752
            moderegs[S3_CR43] = 0x08;
753
            if (dac_used->id == IBMRGB52x)
754
                moderegs[S3_CR43] = 0x10;
755
            else if (s3_chiptype == S3_928 && dac_used->id == SIERRA_15025)
756
                moderegs[S3_CR43] = 0x01;
757
            if (s3_chiptype <= S3_924 && dac_used->id != NORMAL_DAC)
758
                moderegs[S3_CR43] = 0x01;
759
 
760
        } else
761
            /* XXXX some DAC might need this; XF86 source says... */
762
            moderegs[S3_CR43] = 0x09;
763
    } else {
764
        /* 4/8 bit color */
765
        moderegs[S3_CR43] = 0x00;
766
    }
767
 
768
    if (s3_chiptype >= S3_924 && s3_chiptype <= S3_928) {       /* different for 864+ */
769
        s3_8514regs[S3_ADVFUNC_CNTL] = 0x0002;
770
        if ((s3_chiptype == S3_928 && modeinfo->bitsPerPixel != 4) || !(s3_flags & S3_OLD_STEPPING))
771
            s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0001;
772
        if (modeinfo->bitsPerPixel == 4)
773
            s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0004;
774
#if 0
775
        /* 864 databook says it is for enhanced 4bpp */
776
        if (modeinfo->lineWidth > 640)
777
            s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0004;
778
#endif
779
    } else if (s3_chiptype == S3_968) {
780
        s3_8514regs[S3_ADVFUNC_CNTL] = 0x0002;
781
        if (modeinfo->bitsPerPixel == 4)
782
            s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0004;
783
#ifdef PIXEL_MULTIPLEXING
784
        else
785
            s3_8514regs[S3_ADVFUNC_CNTL] |= 0x0001;
786
#endif
787
    } else if (modeinfo->lineWidth / modeinfo->bytesPerPixel == 1024)
788
        s3_8514regs[S3_ADVFUNC_CNTL] = 0x0007;
789
    else
790
        s3_8514regs[S3_ADVFUNC_CNTL] = 0x0003;
791
 
792
    moderegs[S3_CR44] = 0;
793
    /* Skip CR45, 'hi/truecolor cursor color enable'. */
794
 
795
    if (s3_chiptype >= S3_801) {
796
        int m, n;               /* for FIFO balancing */
797
 
798
        /* XXXX Not all chips support all widths. */
799
        moderegs[S3_CR50] &= ~0xF1;
800
        switch (modeinfo->bitsPerPixel) {
801
        case 16:
802
            moderegs[S3_CR50] |= 0x10;
803
            break;
804
        case 24:                /* XXXX 868/968 only */
805
            if (s3_chiptype >= S3_868)
806
                moderegs[S3_CR50] |= 0x20;
807
            break;
808
        case 32:
809
            moderegs[S3_CR50] |= 0x30;
810
            break;
811
        }
812
 
813
        switch (modeinfo->lineWidth / modeinfo->bytesPerPixel) {
814
        case 640:
815
            moderegs[S3_CR50] |= 0x40;
816
            break;
817
        case 800:
818
            moderegs[S3_CR50] |= 0x80;
819
            break;
820
        case 1152:
821
            if (!(s3_flags & S3_OLD_STEPPING)) {
822
                moderegs[S3_CR50] |= 0x01;
823
                break;
824
            }                   /* else fall through */
825
        case 1280:
826
            moderegs[S3_CR50] |= 0xC0;
827
            break;
828
        case 1600:
829
            moderegs[S3_CR50] |= 0x81;
830
            break;
831
            /* 1024/2048 no change. */
832
        }
833
 
834
        moderegs[S3_CR51] &= 0xC0;
835
        moderegs[S3_CR51] |= (modeinfo->lineWidth >> 7) & 0x30;
836
 
837
        /* moderegs[S3_CR53] |= 0x10; *//* Enable MMIO. */
838
        /* moderegs[S3_CR53] |= 0x20; *//* DRAM interleaving for S3_805i with 2MB */
839
 
840
        n = 0xFF;
841
        if (s3_chiptype >= S3_864 ||
842
            s3_chiptype == S3_801 || s3_chiptype == S3_805) {
843
            /*
844
             * CRT FIFO balancing for DRAM cards and 964/968
845
             * in VGA mode.
846
             */
847
            int clock, mclk;
848
            if (modeinfo->bitsPerPixel < 8) {
849
                clock = modetiming->pixelClock;
850
            } else {
851
                clock = modetiming->pixelClock *
852
                    modeinfo->bytesPerPixel;
853
            }
854
            if (s3_memory < 2048 || s3_chiptype == S3_TRIO32)
855
                clock *= 2;
856
            if (__svgalib_s3_s3Mclk > 0)
857
                mclk = __svgalib_s3_s3Mclk;
858
            else if (s3_chiptype == S3_801 || s3_chiptype == S3_805)
859
                mclk = 50000;   /* Assumption. */
860
            else
861
                mclk = 60000;   /* Assumption. */
862
            m = (int) ((mclk / 1000.0 * .72 + 16.867) * 89.736 / (clock / 1000.0 + 39) - 21.1543);
863
            if (s3_memory < 2048 || s3_chiptype == S3_TRIO32)
864
                m /= 2;
865
            if (m > 31)
866
                m = 31;
867
            else if (m < 0) {
868
                m = 0;
869
                n = 16;
870
            }
871
        } else if (s3_memory == 512 || modetiming->HDisplay > 1200)
872
            m = 0;
873
        else if (s3_memory == 1024)
874
            m = 2;
875
        else
876
            m = 20;
877
 
878
        moderegs[S3_CR54] = m << 3;
879
        moderegs[S3_CR60] = n;
880
 
881
        moderegs[S3_CR55] &= 0x08;
882
        moderegs[S3_CR55] |= 0x40;
883
 
884
#ifdef S3_LINEAR_MODE_BANKING_864
885
        if (s3_chiptype >= S3_864) {
886
            if (modeinfo->bitsPerPixel >= 8) {
887
                /* Enable linear addressing. */
888
                moderegs[S3_CR58] |= 0x10;
889
                /* Set window size to 64K. */
890
                moderegs[S3_CR58] &= ~0x03;
891
                /* Assume CR59/5A are correctly set up for 0xA0000. */
892
                /* Set CR6A linear bank to zero. */
893
                moderegs[S3_CR6A] &= ~0x3F;
894
                /* use alternate __svgalib_setpage() function */
895
                __svgalib_s3_driverspecs.__svgalib_setpage = s3_setpage864;
896
            } else {
897
                /* doesn't work for 4bpp. */
898
                __svgalib_s3_driverspecs.__svgalib_setpage = s3_setpage;
899
            }
900
        }
901
#endif
902
#ifdef S3_LINEAR_SUPPORT
903
        moderegs[S3_CR59] = s3_cr59;
904
        moderegs[S3_CR5A] = s3_cr5A;
905
#endif
906
 
907
        /* Extended CRTC timing. */
908
        moderegs[S3_CR5E] =
909
            (((modetiming->CrtcVTotal - 2) & 0x400) >> 10) |
910
            (((modetiming->CrtcVDisplay - 1) & 0x400) >> 9) |
911
            (((modetiming->CrtcVSyncStart) & 0x400) >> 8) |
912
            (((modetiming->CrtcVSyncStart) & 0x400) >> 6) | 0x40;
913
 
914
        {
915
            int i, j;
916
            i = ((((modetiming->CrtcHTotal >> 3) - 5) & 0x100) >> 8) |
917
                ((((modetiming->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) |
918
                ((((modetiming->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) |
919
                ((modetiming->CrtcHSyncStart & 0x800) >> 7);
920
            if ((modetiming->CrtcHSyncEnd >> 3) - (modetiming->CrtcHSyncStart >> 3) > 64)
921
                i |= 0x08;
922
            if ((modetiming->CrtcHSyncEnd >> 3) - (modetiming->CrtcHSyncStart >> 3) > 32)
923
                i |= 0x20;
924
            j = ((moderegs[VGA_CR0] + ((i & 0x01) << 8) +
925
                  moderegs[VGA_CR4] + ((i & 0x10) << 4) + 1) / 2);
926
            if (j - (moderegs[VGA_CR4] + ((i & 0x10) << 4)) < 4) {
927
                if (moderegs[VGA_CR4] + ((i & 0x10) << 4) + 4 <= moderegs[VGA_CR0] + ((i & 0x01) << 8))
928
                    j = moderegs[VGA_CR4] + ((i & 0x10) << 4) + 4;
929
                else
930
                    j = moderegs[VGA_CR0] + ((i & 0x01) << 8) + 1;
931
            }
932
 
933
            moderegs[S3_CR3B] = j & 0xFF;
934
            i |= (j & 0x100) >> 2;
935
            /* Interlace mode frame offset. */
936
            moderegs[S3_CR3C] = (moderegs[VGA_CR0] + ((i & 0x01) << 8)) / 2;
937
            moderegs[S3_CR5D] = (moderegs[S3_CR5D] & 0x80) | i;
938
        }
939
 
940
        {
941
            int i;
942
 
943
            if (modeinfo->bitsPerPixel < 8)
944
                i = modetiming->HDisplay / 4 + 1;
945
            else
946
                i = modetiming->HDisplay *
947
                    modeinfo->bytesPerPixel / 4 + 1;
948
 
949
            moderegs[S3_CR61] = (i >> 8) | 0x80;
950
            moderegs[S3_CR62] = i & 0xFF;
951
        }
952
    }                           /* 801+ */
953
    if (modetiming->flags & INTERLACED)
954
        moderegs[S3_CR42] |= 0x20;
955
 
956
    /*
957
     * Clock select works as follows:
958
     * Clocks 0 and 1 (VGA 25 and 28 MHz) can be selected via the
959
     * two VGA MiscOutput clock select bits.
960
     * If 0x3 is written to these bits, the selected clock index
961
     * is taken from the S3 clock select register at CR42. Clock
962
     * indices 0 and 1 should correspond to the VGA ones above,
963
     * and 3 is often 0 MHz, followed by extended clocks for a
964
     * total of mostly 16.
965
     */
966
 
967
    if (modetiming->flags & USEPROGRCLOCK)
968
        moderegs[VGA_MISCOUTPUT] |= 0x0C;       /* External clock select. */
969
    else if (modetiming->selectedClockNo < 2) {
970
        /* Program clock select bits 0 and 1. */
971
        moderegs[VGA_MISCOUTPUT] &= ~0x0C;
972
        moderegs[VGA_MISCOUTPUT] |=
973
            (modetiming->selectedClockNo & 3) << 2;
974
    } else if (modetiming->selectedClockNo >= 2) {
975
        moderegs[VGA_MISCOUTPUT] |= 0x0C;
976
        /* Program S3 clock select bits. */
977
        moderegs[S3_CR42] &= ~0x1F;
978
        moderegs[S3_CR42] |=
979
            modetiming->selectedClockNo;
980
    }
981
    if (s3_chiptype == S3_TRIO64 || s3_chiptype == S3_765) {
982
        moderegs[S3_CR33] &= ~0x08;
983
        if (modeinfo->bitsPerPixel == 16)
984
            moderegs[S3_CR33] |= 0x08;
985
        /*
986
         * The rest of the DAC/clocking is setup by the
987
         * Trio64 code in the RAMDAC interface (ramdac.c).
988
         */
989
    }
990
    if (dac_used->id != NORMAL_DAC) {
991
        int colormode;
992
        colormode = __svgalib_colorbits_to_colormode(modeinfo->bitsPerPixel,
993
                                           modeinfo->colorBits);
994
        dac_used->initializeState(&moderegs[S3_DAC_OFFSET],
995
                                  modeinfo->bitsPerPixel, colormode,
996
                                  modetiming->pixelClock);
997
 
998
        if (dac_used->id == ATT20C490) {
999
            int pixmux, invert_vclk, blank_delay;
1000
            pixmux = 0;
1001
            invert_vclk = 0;
1002
            blank_delay = 2;
1003
            if (colormode == CLUT8_6
1004
                && modetiming->pixelClock >= 67500) {
1005
                pixmux = 0x00;
1006
                invert_vclk = 1;
1007
            } else if (colormode == CLUT8_8)
1008
                pixmux = 0x02;
1009
            else if (colormode == RGB16_555)
1010
                pixmux = 0xa0;
1011
            else if (colormode == RGB16_565)
1012
                pixmux = 0xc0;
1013
            else if (colormode == RGB24_888_B)
1014
                pixmux = 0xe0;
1015
            moderegs[S3_CR67] = pixmux | invert_vclk;
1016
            moderegs[S3_CR6D] = blank_delay;
1017
        }
1018
        if (dac_used->id == S3_SDAC) {
1019
            int pixmux, invert_vclk, blank_delay;
1020
            pixmux = 0;
1021
            invert_vclk = 0;
1022
            blank_delay = 0;
1023
            if (colormode == CLUT8_6
1024
                && modetiming->pixelClock >= 67500) {
1025
#ifdef SDAC_8BPP_PIXMUX
1026
                /* x64 8bpp pixel multiplexing? */
1027
                pixmux = 0x10;
1028
                if (s3_chiptype != S3_866 && s3_chiptype != S3_868)
1029
                    invert_vclk = 1;
1030
                blank_delay = 2;
1031
#endif
1032
            } else if (colormode == RGB16_555) {
1033
                pixmux = 0x30;
1034
                blank_delay = 2;
1035
            } else if (colormode == RGB16_565) {
1036
                pixmux = 0x50;
1037
                blank_delay = 2;
1038
            } else if (colormode == RGB24_888_B) {      /* XXXX 868/968 only */
1039
                pixmux = 0x90;
1040
                blank_delay = 2;
1041
            } else if (colormode == RGB32_888_B) {
1042
                pixmux = 0x70;
1043
                blank_delay = 2;
1044
            }
1045
            moderegs[S3_CR67] = pixmux | invert_vclk;
1046
            moderegs[S3_CR6D] = blank_delay;
1047
            /* Clock select. */
1048
            moderegs[S3_CR42] &= ~0x0F;
1049
            moderegs[S3_CR42] |= 0x02;
1050
        }
1051
        if (dac_used->id == IBMRGB52x) {
1052
            unsigned char pixmux, blank_delay, tmp;
1053
            tmp = 0;
1054
            pixmux = 0x11;
1055
            blank_delay = 0;
1056
            if (modeinfo->bitsPerPixel < 8 || colormode == RGB32_888_B)
1057
                pixmux = 0x00;
1058
            moderegs[S3_CR58] |= 0x40;
1059
            moderegs[S3_CR65] = 0;
1060
            moderegs[S3_CR66] &= 0xf8;
1061
            moderegs[S3_CR66] |= tmp;
1062
#ifdef PIXEL_MULTIPLEXING
1063
            moderegs[S3_CR67] = pixmux;
1064
#endif
1065
            moderegs[S3_CR6D] = blank_delay;
1066
            /* Clock select. */
1067
            moderegs[S3_CR42] &= ~0x0F;
1068
            moderegs[S3_CR42] |= 0x02;
1069
        }
1070
    }
1071
#ifdef S3_LINEAR_SUPPORT
1072
    s3_cr58 = moderegs[S3_CR58];
1073
    s3_cr40 = moderegs[S3_CR40];
1074
    s3_cr54 = moderegs[S3_CR54];
1075
#endif
1076
    if (clk_used == &__svgalib_I2061A_clockchip_methods &&
1077
        (modetiming->flags & USEPROGRCLOCK)) {
1078
        /* Clock select. */
1079
        moderegs[S3_CR42] &= ~0x0F;
1080
        moderegs[S3_CR42] |= 0x02;
1081
    }
1082
    /* update the 8514 regs */
1083
    memcpy(moderegs + S3_8514_OFFSET, s3_8514regs, S3_8514_COUNT * 2);
1084
}
1085
 
1086
 
1087
/* Set a mode */
1088
 
1089
static int s3_setmode(int mode, int prv_mode)
1090
{
1091
    ModeInfo *modeinfo;
1092
    ModeTiming *modetiming;
1093
    unsigned char moderegs[S3_TOTAL_REGS];
1094
    int res;
1095
 
1096
    if (IS_IN_STANDARD_VGA_DRIVER(mode)) {
1097
        /* Let the standard VGA driver set standard VGA modes. */
1098
        res = __svgalib_vga_driverspecs.setmode(mode, prv_mode);
1099
        if (res == 0) {
1100
            /*
1101
             * ARI: Turn off virtual size of 1024 - this fixes all problems
1102
             *      with standard modes, including 320x200x256.
1103
             *
1104
             * SL:  Is this for 928 only?  Doesn't matter for 805.
1105
             *
1106
             * MZ:  Affects 765 as well, so I assume it is good for all chipsets.
1107
             */
1108
            s3_unlock();
1109
            __svgalib_outCR(0x34, __svgalib_inCR(0x34) & ~0x10);
1110
            s3_lock();
1111
        }
1112
        return res;
1113
    }
1114
    if (!s3_modeavailable(mode))
1115
        return 1;
1116
 
1117
    modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
1118
 
1119
    modetiming = malloc(sizeof(ModeTiming));
1120
    if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {
1121
        free(modetiming);
1122
        free(modeinfo);
1123
        return 1;
1124
    }
1125
    /* Adjust the display width. */
1126
    modeinfo->lineWidth = s3_adjlinewidth(modeinfo->lineWidth);
1127
    CI.xbytes = modeinfo->lineWidth;
1128
 
1129
    s3_initializemode(moderegs, modetiming, modeinfo);
1130
    free(modeinfo);
1131
    free(modetiming);
1132
 
1133
    __svgalib_setregs(moderegs);        /* Set standard regs. */
1134
    s3_setregs(moderegs, mode); /* Set extended regs. */
1135
    return 0;
1136
}
1137
 
1138
 
1139
/* Indentify chipset; return non-zero if detected */
1140
 
1141
/* Some port I/O functions: */
1142
static unsigned char rdinx(int port, unsigned char index)
1143
{
1144
    outb(port, index);
1145
    return port_in(port + 1);
1146
}
1147
 
1148
static void wrinx(int port, unsigned char index, unsigned char val)
1149
{
1150
    outb(port, index);
1151
    outb(port + 1, val);
1152
}
1153
 
1154
/*
1155
 * Returns true iff the bits in 'mask' of register 'port', index 'index'
1156
 * are read/write.
1157
 */
1158
static int testinx2(int port, unsigned char index, unsigned char mask)
1159
{
1160
    unsigned char old, new1, new2;
1161
 
1162
    old = rdinx(port, index);
1163
    wrinx(port, index, (old & ~mask));
1164
    new1 = rdinx(port, index) & mask;
1165
    wrinx(port, index, (old | mask));
1166
    new2 = rdinx(port, index) & mask;
1167
    wrinx(port, index, old);
1168
    return (new1 == 0) && (new2 == mask);
1169
}
1170
 
1171
int s3_test(void)
1172
{
1173
    int vgaIOBase, vgaCRIndex, vgaCRReg;
1174
 
1175
    vgaIOBase = (port_in(0x3CC) & 0x01) ? 0x3D0 : 0x3B0;
1176
    vgaCRIndex = vgaIOBase + 4;
1177
    vgaCRReg = vgaIOBase + 5;
1178
 
1179
    outb(vgaCRIndex, 0x11);     /* for register CR11, (Vertical Retrace End) */
1180
    outb(vgaCRReg, 0x00);       /* set to 0 */
1181
 
1182
    outb(vgaCRIndex, 0x38);     /* check if we have an S3 */
1183
    outb(vgaCRReg, 0x00);
1184
 
1185
    /* Make sure we can't write when locked */
1186
 
1187
    if (testinx2(vgaCRIndex, 0x35, 0x0f))
1188
        return 0;
1189
 
1190
    outb(vgaCRIndex, 0x38);     /* for register CR38, (REG_LOCK1) */
1191
    outb(vgaCRReg, 0x48);       /* unlock S3 register set for read/write */
1192
 
1193
    /* Make sure we can write when unlocked */
1194
 
1195
    if (!testinx2(vgaCRIndex, 0x35, 0x0f))
1196
        return 0;
1197
 
1198
    if (s3_init(0, 0, 0))       /* type not OK */
1199
        return 0;
1200
    return 1;
1201
}
1202
 
1203
/*
1204
 * Bank switching function - set 64K bank number
1205
 *
1206
 * XXXX locking and unlocking might hurt performance but is safer.
1207
 */
1208
static void s3_setpage(int page)
1209
{
1210
#ifdef S3_16_COLORS
1211
    /*
1212
     * XXXX adjust the parameter for 4bpp (1bpp is ignored).  Shouldn't
1213
     * need this, but either me or the drawing functions are making bad
1214
     * assumptions about 4bpp.
1215
     */
1216
    if (infotable[CM].bytesperpixel == 0)
1217
        page *= 4;
1218
#endif
1219
#ifdef S3_KLUDGE_PAGE_MODE
1220
    /* adjust to use 256K pages */
1221
    if (CM == G320x200x256)
1222
        page *= 4;
1223
#endif
1224
    s3_unlock();
1225
    outb(CRT_IC, 0x35);
1226
    outb(CRT_DC, (port_in(CRT_DC) & 0xF0) | (page & 0x0F));
1227
    if (s3_chiptype >= S3_801) {
1228
        outb(CRT_IC, 0x51);
1229
        outb(CRT_DC, (port_in(CRT_DC) & ~0x0C) | ((page & 0x30) >> 2));
1230
    }
1231
    port_in(CRT_DC);                    /* ARI: Ferraro says: required for first generation 911 only */
1232
    s3_lock();
1233
}
1234
 
1235
/*
1236
 * Bank switching function - set 64K bank number for 864+
1237
 * (not for 4bpp)
1238
 *
1239
 * XXXX locking and unlocking might hurt performance
1240
 * (864 shouldn't need it).
1241
 */
1242
#ifdef S3_LINEAR_MODE_BANKING_864
1243
static void s3_setpage864(int page)
1244
{
1245
    s3_unlock();
1246
    /* "Linear" mode banking. */
1247
    outb(CRT_IC, 0x6A);
1248
    outb(CRT_DC, (port_in(CRT_DC) & ~0x3F) | page);
1249
    s3_lock();
1250
}
1251
 
1252
#endif
1253
 
1254
/*
1255
 * Set display start address (not for 16 color modes).
1256
 *
1257
 * This works up to 4Mb (should be able to go higher).
1258
 *
1259
 * XXXX locking and unlocking might hurt performance but is safer.
1260
 */
1261
static void s3_setdisplaystart(int address)
1262
{
1263
#ifdef S3_KLUDGE_PAGE_MODE
1264
    /* adjust to use 256K pages */
1265
    if (CM == G320x200x256)
1266
        address *= 4;
1267
#endif
1268
    s3_unlock();
1269
    outw(CRT_IC, 0x0d | ((address << 6) & 0xff00));     /* sa2-sa9 */
1270
    outw(CRT_IC, 0x0c | ((address >> 2) & 0xff00));     /* sa10-sa17 */
1271
    port_in(0x3da);                     /* set ATC to addressing mode */
1272
    outb(ATT_IW, 0x13 + 0x20);  /* select ATC reg 0x13 */
1273
    outb(ATT_IW, (port_in(ATT_R) & 0xf0) | ((address & 3) << 1));
1274
    /* write sa0-1 to bits 1-2 */
1275
 
1276
    outb(CRT_IC, 0x31);
1277
    outb(CRT_DC, (port_in(CRT_DC) & ~0x30) | ((address & 0xc0000) >> 14));
1278
    if (s3_chiptype >= S3_801) {
1279
        outb(CRT_IC, 0x51);
1280
        outb(CRT_DC, (port_in(CRT_DC) & ~0x03) | ((address & 0x300000) >> 20));
1281
    }
1282
    s3_lock();
1283
}
1284
 
1285
/*
1286
 * Set logical scanline length (Multiples of 8 to 8184).
1287
 * CR43.2 should be 0 for this.
1288
 */
1289
static void s3_setlogicalwidth(int width)
1290
{
1291
    __svgalib_outCR(0x13, (width >> 3));        /* lw3-lw11 */
1292
    __svgalib_outCR(0x51, (width & 0x300) >> 4);        /* lw12-lw13 */
1293
}
1294
 
1295
#ifdef S3_LINEAR_SUPPORT
1296
static void s3_linear_enable(void)
1297
{
1298
    s3_unlock();
1299
 
1300
    if (s3_chiptype > S3_924) {
1301
        int i;
1302
        outb (CRT_IC, 0x40);
1303
        i = (s3_cr40 & 0xf6) | 0x0a;
1304
        outb (CRT_DC, (unsigned char) i);
1305
        outb (CRT_IC, 0x58);
1306
        outb (CRT_DC, s3_linear_opt | s3_cr58);
1307
        if (s3_chiptype > S3_928) {
1308
            outb (CRT_IC, 0x54);
1309
            outb (CRT_DC, (s3_cr54 + 0x07));
1310
        }
1311
    }
1312
 
1313
    s3_lock();
1314
}
1315
 
1316
static void s3_linear_disable(void)
1317
{
1318
    s3_unlock();
1319
 
1320
    if (s3_chiptype > S3_924) {
1321
        if (s3_chiptype > S3_928) {
1322
            outb (CRT_IC, 0x54);
1323
            outb (CRT_DC, s3_cr54);
1324
        }
1325
        outb (CRT_IC, 0x58);
1326
        outb (CRT_DC, s3_cr58);
1327
        outb (CRT_IC, 0x40);
1328
        outb (CRT_DC, s3_cr40);
1329
    }
1330
 
1331
    s3_lock();
1332
}
1333
 
1334
/* Set linear addressing mode */
1335
 
1336
static int s3_linear(int op, int param)
1337
{
1338
    if (op == LINEAR_QUERY_BASE)
1339
        return s3_linear_base;
1340
    if (op == LINEAR_QUERY_GRANULARITY) {
1341
        switch (s3_memory) {
1342
        case 4096:
1343
        case 2048:
1344
        case 1024:
1345
            return s3_memory * 1024;
1346
        default:
1347
            return 1024 * 1024;
1348
        }
1349
    } else if (op == LINEAR_QUERY_RANGE)
1350
        return 256;
1351
    else if (op == LINEAR_ENABLE) {
1352
        s3_setpage(0);
1353
        s3_linear_enable();
1354
        s3_linear_addr = param;
1355
        return 0;
1356
    } else if (op == LINEAR_DISABLE) {
1357
        s3_setpage(0);
1358
        s3_linear_disable();
1359
        s3_linear_addr = 0;
1360
        return 0;
1361
    } else
1362
        return -1;
1363
}
1364
 
1365
#define S3_LINEAR_FUNC s3_linear
1366
#else
1367
#define S3_LINEAR_FUNC 0
1368
#endif                          /* S3_LINEAR_SUPPORT */
1369
 
1370
/* Function table (exported) */
1371
 
1372
DriverSpecs __svgalib_s3_driverspecs =
1373
{
1374
    s3_saveregs,                /* saveregs */
1375
    s3_setregs,                 /* setregs */
1376
    (void (*)(void)) nothing,   /* unlock */
1377
    (void (*)(void)) nothing,   /* lock */
1378
    s3_test,
1379
    s3_init,
1380
    s3_setpage,
1381
    (void (*)(int)) nothing,
1382
    (void (*)(int)) nothing,
1383
    s3_setmode,
1384
    s3_modeavailable,
1385
    s3_setdisplaystart,
1386
    s3_setlogicalwidth,
1387
    s3_getmodeinfo,
1388
    0,                          /* bitblt */
1389
    0,                          /* imageblt */
1390
    0,                          /* fillblt */
1391
    0,                          /* hlinelistblt */
1392
    0,                          /* bltwait */
1393
    s3_ext_set,                 /* extset */
1394
    0,                          /* accel */
1395
    S3_LINEAR_FUNC,             /* linear */
1396
    NULL,                       /* Accelspecs */
1397
    NULL,                       /* Emulation */
1398
};
1399
 
1400
/* Initialize driver (called after detection) */
1401
/* Derived from XFree86 SuperProbe and s3 driver. */
1402
 
1403
static DacMethods *dacs_to_probe[] =
1404
{
1405
#ifdef INCLUDE_S3_SDAC_DAC_TEST
1406
    &__svgalib_S3_SDAC_methods,
1407
#endif
1408
#ifdef INCLUDE_S3_GENDAC_DAC_TEST
1409
    &__svgalib_S3_GENDAC_methods,
1410
#endif
1411
#ifdef INCLUDE_ATT20C490_DAC_TEST
1412
    &__svgalib_ATT20C490_methods,
1413
#endif
1414
#ifdef INCLUDE_SC15025_DAC_TEST
1415
    &__svgalib_SC15025_methods,
1416
#endif
1417
#ifdef INCLUDE_SC1148X_DAC_TEST
1418
    &__svgalib_SC1148X_methods,
1419
#endif
1420
#ifdef INCLUDE_IBMRGB52x_DAC_TEST
1421
    &__svgalib_IBMRGB52x_methods,
1422
#endif
1423
    NULL};
1424
 
1425
static int s3_init(int force, int par1, int par2)
1426
{
1427
    int id, rev, config;
1428
 
1429
    s3_unlock();
1430
 
1431
    s3_flags = 0;               /* initialize */
1432
    id = __svgalib_inCR(0x30);          /* Get chip id. */
1433
    rev = id & 0x0F;
1434
    if (id >= 0xE0) {
1435
        id |= __svgalib_inCR(0x2E) << 8;
1436
        rev |= __svgalib_inCR(0x2F) << 4;
1437
    }
1438
    if (force) {
1439
        s3_chiptype = par1;     /* we already know the type */
1440
        s3_memory = par2;
1441
        /* ARI: can we really trust the user's specification, or should we ignore
1442
           it and probe ourselves ? */
1443
        if (s3_chiptype == S3_801 || s3_chiptype == S3_805) {
1444
            if ((rev & 0x0F) < 2)
1445
                s3_flags |= S3_OLD_STEPPING;    /* can't handle 1152 width */
1446
        } else if (s3_chiptype == S3_928) {
1447
            if ((rev & 0x0F) < 4)       /* ARI: Stepping D or below */
1448
                s3_flags |= S3_OLD_STEPPING;    /* can't handle 1152 width */
1449
        }
1450
    } else {
1451
        s3_chiptype = -1;
1452
        config = __svgalib_inCR(0x36);  /* get configuration info */
1453
        switch (id & 0xf0) {
1454
        case 0x80:
1455
            if (rev == 1) {
1456
                s3_chiptype = S3_911;
1457
                break;
1458
            }
1459
            if (rev == 2) {
1460
                s3_chiptype = S3_924;
1461
                break;
1462
            }
1463
            break;
1464
        case 0xa0:
1465
            switch (config & 0x03) {
1466
            case 0x00:
1467
            case 0x01:
1468
                /* EISA or VLB - 805 */
1469
                s3_chiptype = S3_805;
1470
                /* ARI: Test stepping: 0:B, 1:unknown, 2,3,4:C, 8:I, >=5:D */
1471
                if ((rev & 0x0F) < 2)
1472
                    s3_flags |= S3_OLD_STEPPING;        /* can't handle 1152 width */
1473
                break;
1474
            case 0x03:
1475
                /* ISA - 801 */
1476
                s3_chiptype = S3_801;
1477
                /* Stepping same as 805, just ISA */
1478
                if ((rev & 0x0F) < 2)
1479
                    s3_flags |= S3_OLD_STEPPING;        /* can't handle 1152 width */
1480
                break;
1481
            }
1482
            break;
1483
        case 0x90:
1484
            s3_chiptype = S3_928;
1485
            if ((rev & 0x0F) < 4)       /* ARI: Stepping D or below */
1486
                s3_flags |= S3_OLD_STEPPING;    /* can't handle 1152 width */
1487
            break;
1488
        case 0xB0:
1489
            /* 928P */
1490
            s3_chiptype = S3_928;
1491
            break;
1492
        case 0xC0:
1493
            s3_chiptype = S3_864;
1494
            break;
1495
        case 0xD0:
1496
            s3_chiptype = S3_964;
1497
            break;
1498
        case 0xE0:
1499
            switch (id & 0xFFF0) {
1500
            case 0x10E0:
1501
                s3_chiptype = S3_TRIO32;
1502
                break;
1503
            case 0x3DE0: /* ViRGE/VX ID */
1504
            case 0x31E0: /* ViRGE ID */
1505
            case 0x01E0: /* S3Trio64V2/DX ... any others? */
1506
            case 0x04E0:
1507
            case 0x11E0:
1508
                if (rev & 0x0400)
1509
                    s3_chiptype = S3_765;
1510
                else
1511
                    s3_chiptype = S3_TRIO64;
1512
                break;
1513
            case 0x80E0:
1514
                s3_chiptype = S3_866;
1515
                break;
1516
            case 0x90E0:
1517
                s3_chiptype = S3_868;
1518
                break;
1519
            case 0xF0E0:        /* XXXX From data book; XF86 says 0xB0E0? */
1520
                s3_chiptype = S3_968;
1521
                break;
1522
            }
1523
        }
1524
        if (s3_chiptype == -1) {
1525
            printk(KERN_ERR "svgalib: S3: Unknown chip id %02x\n",
1526
                   id);
1527
            return -1;
1528
        }
1529
        if (s3_chiptype <= S3_924) {
1530
            if ((config & 0x20) != 0)
1531
                s3_memory = 512;
1532
            else
1533
                s3_memory = 1024;
1534
        } else {
1535
            /* look at bits 5, 6 and 7 */
1536
            switch ((config & 0xE0) >> 5) {
1537
            case 0:
1538
                s3_memory = 4096;
1539
                break;
1540
            case 2:
1541
                s3_memory = 3072;
1542
                break;
1543
            case 3:
1544
                s3_memory = 8192;
1545
                break;
1546
            case 4:
1547
                s3_memory = 2048;
1548
                break;
1549
            case 5:
1550
                s3_memory = 6144;
1551
                break;
1552
            case 6:
1553
                s3_memory = 1024;
1554
                break;
1555
            case 7:
1556
                s3_memory = 512;
1557
                break;          /* Trio32 */
1558
            }
1559
        }
1560
 
1561
        if ((config & 0x03) < 3)        /* XXXX 928P is ignored */
1562
            s3_flags |= S3_LOCALBUS;
1563
    }
1564
 
1565
    if (__svgalib_driver_report) {
1566
        printk(KERN_INFO "svgalib: Using S3 driver (%s, %dK).\n", s3_chipname[s3_chiptype],
1567
               s3_memory);
1568
        if (s3_flags & S3_OLD_STEPPING)
1569
            printk(KERN_INFO "svgalib: Chip revision cannot handle modes with width 1152.\n");
1570
        if (s3_chiptype > S3_TRIO64) {
1571
            printk(KERN_INFO "svgalib: s3: chipsets newer than S3 Trio64 is not supported well yet.\n");
1572
        }
1573
 
1574
    }
1575
/* begin: Initialize cardspecs. */
1576
#ifdef S3_LINEAR_SUPPORT
1577
    if (s3_chiptype > S3_805) {
1578
        int found_pciconfig;
1579
        unsigned long pci_conf[64];
1580
 
1581
        found_pciconfig = __svgalib_pci_find_vendor_vga(0x5333, pci_conf, 0);
1582
        if (!found_pciconfig)
1583
            s3_linear_base = pci_conf[4] & 0xFF800000;
1584
    }
1585
 
1586
    s3_cr59 = s3_linear_base >> 24;
1587
    s3_cr5A = (s3_linear_base >> 16);
1588
    if (! (s3_cr59 | s3_cr5A)) {
1589
        s3_cr59 = __svgalib_inCR(0x59);
1590
        s3_cr5A = __svgalib_inCR(0x5A);
1591
        if (!s3_cr59) {
1592
            s3_cr59 =  0xF3000000 >> 24;
1593
            s3_cr5A = (0xF3000000 >> 16);
1594
        }
1595
        s3_linear_base = (s3_cr59 << 24) | (s3_cr5A << 16);
1596
    }
1597
    s3_linear_opt |= 0x10;
1598
    switch (s3_memory) {
1599
        case 512 :
1600
        case 1024 :
1601
            s3_linear_opt |= 0x01;
1602
            break;
1603
        case 2048 :
1604
            s3_linear_opt |= 0x02;
1605
            break;
1606
        case 3072 :
1607
        case 4096 :
1608
        case 6144 :
1609
        case 8192 :
1610
            s3_linear_opt |= 0x03;
1611
            break;
1612
        default :
1613
            s3_linear_opt = 0x14;       /* like XFree */
1614
    }
1615
#endif
1616
 
1617
    cardspecs = malloc(sizeof(CardSpecs));
1618
    cardspecs->videoMemory = s3_memory;
1619
    cardspecs->nClocks = 0;
1620
    /* cardspecs->maxHorizontalCrtc = 2040; SL: kills 800x600x32k and above */
1621
    cardspecs->maxHorizontalCrtc = 4088;
1622
    cardspecs->flags = INTERLACE_DIVIDE_VERT;
1623
 
1624
    dac_used = NULL;
1625
    clk_used = NULL;
1626
 
1627
#ifdef INCLUDE_S3_TRIO64_DAC
1628
    if ((s3_chiptype == S3_TRIO64 || s3_chiptype == S3_765) && dac_used == NULL)
1629
        dac_used = &__svgalib_Trio64_methods;
1630
#endif
1631
 
1632
    if (dac_used == NULL) {
1633
        /* Not supported. */
1634
        printk(KERN_ERR "svgalib: s3: Assuming S3_SDAC.\n");
1635
        dac_used = &__svgalib_S3_SDAC_methods;
1636
        dac_used->initialize();
1637
    }
1638
    if (clk_used)
1639
        clk_used->initialize(cardspecs, dac_used);
1640
 
1641
    dac_used->qualifyCardSpecs(cardspecs, dac_speed);
1642
 
1643
    /* Initialize standard clocks for unknown DAC. */
1644
    if ((!(cardspecs->flags & CLOCK_PROGRAMMABLE))
1645
        && cardspecs->nClocks == 0) {
1646
        /*
1647
         * Almost all cards have 25 and 28 MHz on VGA clocks 0 and 1,
1648
         * so use these for an unknown DAC, yielding 640x480x256.
1649
         */
1650
        cardspecs->nClocks = 2;
1651
        cardspecs->clocks = malloc(sizeof(int) * 2);
1652
        cardspecs->clocks[0] = 25175;
1653
        cardspecs->clocks[1] = 28322;
1654
    }
1655
    /* Limit pixel clocks according to chip specifications. */
1656
    if (s3_chiptype == S3_864 || s3_chiptype == S3_868) {
1657
        /* Limit max clocks according to 95 MHz DCLK spec. */
1658
        /* SL: might just be 95000 for 4/8bpp since no pixmux'ing */
1659
        LIMIT(cardspecs->maxPixelClock4bpp, 95000 * 2);
1660
        LIMIT(cardspecs->maxPixelClock8bpp, 95000 * 2);
1661
        LIMIT(cardspecs->maxPixelClock16bpp, 95000);
1662
        /* see explanation below */
1663
        LIMIT(cardspecs->maxPixelClock24bpp, 36000);
1664
        /*
1665
         * The official 32bpp limit is 47500, but we allow
1666
         * 50 MHz for VESA 800x600 timing (actually the
1667
         * S3-864 doesn't have the horizontal timing range
1668
         * to run unmodified VESA 800x600 72 Hz timings).
1669
         */
1670
        LIMIT(cardspecs->maxPixelClock32bpp, 50000);
1671
    }
1672
#ifndef S3_16_COLORS
1673
    cardspecs->maxPixelClock4bpp = 0;   /* 16-color doesn't work. */
1674
#endif
1675
 
1676
/* end: Initialize cardspecs. */
1677
 
1678
    __svgalib_driverspecs = &__svgalib_s3_driverspecs;
1679
 
1680
    __svgalib_banked_mem_base=0xa0000;
1681
    __svgalib_banked_mem_size=0x10000;
1682
#ifdef S3_LINEAR_SUPPORT
1683
    __svgalib_linear_mem_base=s3_linear_base;
1684
    __svgalib_linear_mem_size=s3_memory*0x400;
1685
#endif
1686
 
1687
    sleep(4);
1688
 
1689
    return 0;
1690
 
1691
}