Subversion Repositories shark

Rev

Rev 3 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1063 tullio 1
 
2
/*
3
 * This program is free software; you can redistribute it and/or modify
4
 * it under the terms of the GNU General Public License as published by
5
 * the Free Software Foundation; either version 2 of the License, or
6
 * (at your option) any later version.
7
 *
8
 * This program is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
 * GNU General Public License for more details.
12
 *
13
 * You should have received a copy of the GNU General Public License
14
 * along with this program; if not, write to the Free Software
15
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
 *
17
 */
18
 
2 pj 19
#include <ll/i386/hw-data.h>
20
#include <ll/i386/mem.h>
21
/*
22
#include <ll/i386/x-dos.h>
23
#include <ll/i386/x-dosmem.h>
24
*/
25
#include <ll/i386/cons.h>
26
#include <ll/sys/ll/ll-func.h>
27
 
28
#include "s3.h"
29
#include "chips.h"
30
 
31
 
32
enum {
33
    S3_911, S3_924, S3_801, S3_805, S3_928, S3_864, S3_964, S3_TRIO32,
34
    S3_TRIO64, S3_866, S3_868, S3_968, S3_765, S3_VIRGE, S3_VIRGE_VX,
35
    S3_UNKNOWN
36
};
37
 
38
static const char *s3_chipname[] =
39
{"911", "924", "801", "805", "928",
40
 "864", "964", "Trio32", "Trio64",
41
 "866", "868", "968", "Trio64V+",
42
 "ViRGE", "ViRGE VX",
43
 "Unknown S3 chip"};
44
 
45
 
46
 
47
 
48
#define CRT_IC  0x3D4           /* CRT Controller Index - color emulation */
49
#define CRT_DC  0x3D5           /* CRT Controller Data Register - color emulation */
50
 
51
/* flags used by this driver */
52
#define S3_LOCALBUS             0x01
53
#define S3_CLUT8_8              0x02
54
#define S3_OLD_STEPPING         0x04
55
 
56
DWORD s3_linear_addr = 0;
57
 
58
int s3_chiptype;
59
int s3_flags;
60
int s3_memory;
61
 
62
/*      S3 specific Graphic drivers...  */
63
 
64
static void s3_lock(void)
65
{
66
    outp(0x3d4, 0x39);
67
    outp(0x3d5, 0x00);
68
    outp(0x3d4, 0x38);
69
    outp(0x3d5, 0x00);
70
}
71
 
72
static void s3_lock_enh(void)
73
{
74
    BYTE tmp;
75
 
76
    if (s3_chiptype > S3_911) {
77
        outp(0x3d4, 40);
78
        tmp = inp(0x3d5);
79
        outp(0x3d5, tmp & ~0x01);
80
    }
81
    s3_lock();
82
}
83
 
84
 
85
static void s3_unlock(void)
86
{
87
    outp(0x3d4, 0x38);
88
    outp(0x3d5, 0x48);
89
    outp(0x3d4, 0x39);
90
    outp(0x3d5, 0xA5);
91
}
92
 
93
static void s3_unlock_enh(void)
94
{
95
    BYTE tmp;
96
 
97
    s3_unlock();
98
    if (s3_chiptype > S3_911) {
99
        outp(0x3d4, 0x40);
100
        tmp = inp(0x3d5);
101
        outp(0x3d5, tmp | 0x01);
102
    }
103
}
104
 
105
static int s3_init(int par1, int par2)
106
{
107
    int id, rev;
108
    BYTE config;
109
 
110
    s3_unlock();
111
 
112
    s3_flags = 0;               /* initialize */
113
    outp(0x3d4, 0x30);  /* Get chip id. */
114
    id = inp(0x3d5);
115
    rev = id & 0x0F;
116
    if (id >= 0xE0) {
117
        outp(0x3d4, 0x2D);
118
        id = inp(0x3d5) << 8;
119
        outp(0x3d4, 0x2E);
120
        id |= inp(0x3d5);
121
        outp(0x3d4, 0x2F);
122
        rev = inp(0x3d5);
123
    }
124
    s3_chiptype = -1;
125
    outp(0x3d4, 0x36);  /* Get config info */
126
    config = inp(0x3d5);
127
    switch (id & 0xf0) {
128
        case 0x80:
129
            if (rev == 1) {
130
                s3_chiptype = S3_911;
131
                break;
132
            }
133
            if (rev == 2) {
134
                s3_chiptype = S3_924;
135
                break;
136
            }
137
            break;
138
        case 0xa0:
139
            switch (config & 0x03) {
140
                case 0x00:
141
                case 0x01:
142
                    /* EISA or VLB - 805 */
143
                    s3_chiptype = S3_805;
144
                    /* ARI: Test stepping: 0:B, 1:unknown, 2,3,4:C, 8:I, >=5:D */
145
                    if ((rev & 0x0F) < 2)
146
                        s3_flags |= S3_OLD_STEPPING;        /* can't handle 1152 width */
147
                    break;
148
                case 0x03:
149
                    /* ISA - 801 */
150
                    s3_chiptype = S3_801;
151
                    /* Stepping same as 805, just ISA */
152
                    if ((rev & 0x0F) < 2)
153
                        s3_flags |= S3_OLD_STEPPING;        /* can't handle 1152 width */
154
                    break;
155
            }
156
            break;
157
        case 0x90:
158
            s3_chiptype = S3_928;
159
            if ((rev & 0x0F) < 4)       /* ARI: Stepping D or below */
160
                s3_flags |= S3_OLD_STEPPING;    /* can't handle 1152 width */
161
            break;
162
        case 0xB0:
163
            /* 928P */
164
            s3_chiptype = S3_928;
165
            break;
166
        case 0xC0:
167
            s3_chiptype = S3_864;
168
            break;
169
        case 0xD0:
170
            s3_chiptype = S3_964;
171
            break;
172
        default:
173
            switch (id) {
174
                case 0x8811:
175
                    switch (id & 0xFFF0) {
176
                        case 0x10E0:
177
                            s3_chiptype = S3_TRIO32;
178
                            break;
179
                        case 0x01E0: /* S3Trio64V2/DX ... any others? */
180
                        case 0x11E0:
181
                            if (rev & 0x0400)
182
                                s3_chiptype = S3_765;
183
                            else
184
                                s3_chiptype = S3_TRIO64;
185
                            break;
186
                    }
187
                case 0x883d:  /*ME*/
188
                    s3_chiptype = S3_VIRGE_VX;
189
                    break;
190
                case 0x5631: /* ViRGE ID */
191
                    s3_chiptype = S3_VIRGE;
192
                    break;
193
                case 0x8901:  /*ME*/
194
                    s3_chiptype = S3_765;
195
                    break;
196
                case 0x80E0:
197
                    s3_chiptype = S3_866;       /* Not Ok... */
198
                    break;
199
                case 0x8880:
200
                    s3_chiptype = S3_868;
201
                break;
202
                case 0x88f0:        /* XXXX From data book; XF86 says 0xB0E0? */
203
                    s3_chiptype = S3_968;
204
                    break;
205
                default:
206
                    s3_chiptype = S3_UNKNOWN;
207
                    break;
208
            }
209
    }
210
/*      s3_lock();*/
211
    if (s3_chiptype == -1) {
212
        return -1;
213
    }
214
    if (s3_chiptype == S3_UNKNOWN) {
215
        cprintf("svgalib: S3: Unknown chip id %02x\n", id);
216
        return -1;
217
    }
218
    if (s3_chiptype <= S3_924) {
219
        if ((config & 0x20) != 0) {
220
            s3_memory = 512;
221
        } else {
222
            s3_memory = 1024;
223
        }
224
    } else {
225
        if (s3_chiptype == S3_VIRGE_VX) {
226
            BYTE config2;
227
            int m1;
228
 
229
            outp(0x3d4, 0x37);
230
            config2 = inp(0x3d5);
231
            switch ((config & 0x60) >> 5) {
232
                case 0:
233
                    s3_memory = 2 * 1024;
234
                    break;
235
                case 1:
236
                    s3_memory = 4 * 1024;
237
                    break;
238
                case 2:
239
                    s3_memory = 6 * 1024;
240
                    break;
241
                case 3:
242
                    s3_memory = 8 * 1024;
243
                    break;
244
            }
245
            m1 = 0;
246
            switch ((config2 & 0x60) >> 5) {
247
                case 0:
248
                    m1 = 4 * 1024;
249
                    break;
250
                case 2:
251
                    m1 = 2 * 1024;
252
                    break;
253
            }
254
            cprintf("M1: %d        M2: %d\n", s3_memory, m1);
255
            s3_memory -= m1;
256
        } else {
257
            /* look at bits 5, 6 and 7 */
258
            switch ((config & 0xE0) >> 5) {
259
                case 0:
260
                    s3_memory = 4096;
261
                    break;
262
                case 2:
263
                    s3_memory = 3072;
264
                    break;
265
                case 3:
266
                    s3_memory = 8192;
267
                    break;
268
                case 4:
269
                    s3_memory = 2048;
270
                    break;
271
                case 5:
272
                    s3_memory = 6144;
273
                    break;
274
                case 6:
275
                    s3_memory = 1024;
276
                    break;
277
                case 7:
278
                    s3_memory = 512;
279
                    break;          /* Trio32 */
280
            }
281
        }
282
    }
283
    if ((config & 0x03) < 3)        /* XXXX 928P is ignored */
284
    s3_flags |= S3_LOCALBUS;
285
 
286
    cprintf("svgalib: Using S3 driver (%s, %dK).\n", s3_chipname[s3_chiptype],
287
               s3_memory);
288
    if (s3_flags & S3_OLD_STEPPING)
289
        cprintf("svgalib: Chip revision cannot handle modes with width 1152.\n");
290
    if (s3_chiptype > S3_864) {
291
        cprintf("svgalib: s3: chipsets newer than S3-864 is not supported well yet.\n");
292
    }
293
 
294
#ifdef DAC
295
    cardspecs = malloc(sizeof(CardSpecs));
296
    cardspecs->videoMemory = s3_memory;
297
    cardspecs->nClocks = 0;
298
    /* cardspecs->maxHorizontalCrtc = 2040; SL: kills 800x600x32k and above */
299
    cardspecs->maxHorizontalCrtc = 4088;
300
    cardspecs->flags = INTERLACE_DIVIDE_VERT;
301
 
302
    /* Process S3-specific config file options. */
303
    __svgalib_read_options(s3_config_options, s3_process_option);
304
 
305
#ifdef INCLUDE_S3_TRIO64_DAC
306
    if ((s3_chiptype == S3_TRIO64 || s3_chiptype == S3_765) && dac_used == NULL)        dac_used = &__svgalib_Trio64_methods;
307
#endif
308
 
309
    if (dac_used == NULL)
310
        dac_used = __svgalib_probeDacs(dacs_to_probe);
311
    else
312
        dac_used->initialize();
313
 
314
 
315
    if (dac_used == NULL) {
316
        /* Not supported. */
317
        cprintf("svgalib: s3: Assuming normal VGA DAC.\n");
318
 
319
#ifdef INCLUDE_NORMAL_DAC
320
        dac_used = &__svgalib_normal_dac_methods;
321
        dac_used->initialize();
322
#else
323
        cprintf("svgalib: Alas, normal VGA DAC support is not compiled in, goodbye.\n");
324
        return 1;
325
#endif
326
    }
327
    if (clk_used)
328
        clk_used->initialize(cardspecs, dac_used);
329
 
330
    dac_used->qualifyCardSpecs(cardspecs, dac_speed);
331
 
332
    /* Initialize standard clocks for unknown DAC. */
333
    if ((!(cardspecs->flags & CLOCK_PROGRAMMABLE))
334
        && cardspecs->nClocks == 0) {
335
        /*
336
         * Almost all cards have 25 and 28 MHz on VGA clocks 0 and 1,
337
         * so use these for an unknown DAC, yielding 640x480x256.
338
         */
339
        cardspecs->nClocks = 2;
340
        cardspecs->clocks = malloc(sizeof(int) * 2);
341
        cardspecs->clocks[0] = 25175;
342
 
343
        cardspecs->clocks[1] = 28322;
344
    }
345
    /* Limit pixel clocks according to chip specifications. */
346
    if (s3_chiptype == S3_864 || s3_chiptype == S3_868) {
347
        /* Limit max clocks according to 95 MHz DCLK spec. */
348
        /* SL: might just be 95000 for 4/8bpp since no pixmux'ing */
349
        LIMIT(cardspecs->maxPixelClock4bpp, 95000 * 2);
350
        LIMIT(cardspecs->maxPixelClock8bpp, 95000 * 2);
351
        LIMIT(cardspecs->maxPixelClock16bpp, 95000);
352
        /* see explanation below */
353
        LIMIT(cardspecs->maxPixelClock24bpp, 36000);
354
        /*
355
         * The official 32bpp limit is 47500, but we allow
356
         * 50 MHz for VESA 800x600 timing (actually the
357
         * S3-864 doesn't have the horizontal timing range
358
         * to run unmodified VESA 800x600 72 Hz timings).
359
         */
360
        LIMIT(cardspecs->maxPixelClock32bpp, 50000);
361
    }
362
    __svgalib_driverspecs = &__svgalib_s3_driverspecs;
363
#endif          /*      DAC & c.        */
364
    s3_lock();
365
    return 0;
366
}
367
 
368
int s3_test(void)
369
{
370
    BYTE new_val1, new_val2;
371
 
372
    s3_unlock();
373
    outp(0x3d4, 0x47);
374
    outp(0x3d5, 0xff);
375
    new_val1 = inp(0x3d5);
376
    outp(0x3d5, 0x00);
377
    new_val2 = inp(0x3d5);
378
    s3_lock();
379
 
380
    if ((new_val1 == 0xff) && (new_val2 == 0x00)) {
381
        if (s3_init(0, 0))       /* type not OK */
382
            return 0;
383
        return 1;
384
    }
385
    cprintf("V1: %x         V2: %x\n", new_val1, new_val2);
386
    return 0;
387
}
388
 
389
DWORD s3_getmem(void)
390
{
391
    return s3_memory * 1024;
392
}
393
 
394
void s3_showinfo(void)
395
{
396
    cprintf("\t Using S3 driver (%s, %dK).\n", s3_chipname[s3_chiptype],
397
               s3_memory);
398
    if (s3_flags & S3_OLD_STEPPING) {
399
        cprintf("\t Chip revision cannot handle modes with width 1152.\n");
400
    }
401
    if (s3_chiptype > S3_864) {
402
        cprintf("\t s3: chipsets newer than S3-864 is not supported well yet.\n");
403
    }
404
    cprintf ("\t s3: Frame Linear Buffer @ %lx (%ld)\n", s3_linear_addr, s3_linear_addr);
405
}
406
 
407
/*      These are important!!!  */
408
void s3_setpage(int page)
409
{
410
    s3_unlock();
411
    outp(0x3d4, 0x35);
412
    outp(0x3d5, (inp(0x3d5) & 0xF0) | (page & 0x0F));
413
/*      is it important???
414
    if (s3_chiptype >= S3_801) {
415
        outb(0x3d4, 0x51);
416
        outb(0x3d5, (inb(0x3d5) & ~0x0C) | ((page & 0x30) >> 2));
417
    }
418
*/
419
    inp(0x3d5);                 /* ARI: Ferraro says: required for first generation 911 only */
420
    s3_lock();
421
}
422
 
423
void s3_setpage864(int page)
424
{
425
    /* Let's try this... */
426
    s3_unlock();
427
    /* "Linear" mode banking. */
428
    outp(0x3d4, 0x6A);
429
    outp(0x3d5, (inp(0x3d5) & ~0x3F) | page);
430
    s3_lock();
431
}
432
 
433
void s3_linear(DWORD l_a)
434
{
435
    BYTE r59, r5A, tmp, linopt;
436
    BYTE i3;
437
 
438
    s3_setpage(0);
439
    r59 = l_a >> 24;
440
    r5A = (l_a >> 16) & 0x08;
441
    if (s3_memory <= 1024) {
442
        linopt = 0x15;
443
    } else if (s3_memory <= 2048) {
444
        linopt = 0x16;
445
    } else {
446
        linopt = 0x17;
447
    }
448
 
449
    s3_unlock();
450
 
451
/*#ifdef OLD*/
452
/*      4 805...        */
453
      outp(0x3d4, 0x40);
454
      i3 = inp(0x3d5);
455
      i3 = (i3 & 0xf6) | 0x0a;/* enable fast write buffer and disable
456
                                 * 8514/a mode */
457
      outp(0x3d4, i3);
458
/*      DISABLE_MMIO;*/
459
      { unsigned char tmp;
460
      outp(0x3d4, 0x53);
461
      tmp = inp(0x3d5);
462
      outp(0x3d5, tmp & 0xEF); }
463
/*      outb (vgaCRReg, s3LinApOpt | s3SAM256);
464
      if (!S3_x64_SERIES(s3ChipId)) {
465
         outb (vgaCRIndex, 0x54);
466
         outb (vgaCRReg, (s3Port54 + 07));
467
      }
468
*/
469
/*#endif*/
470
 
471
    outp(0x3d4, 0x58);
472
    tmp = inp(0x3d5) /*& 0x80*/;
473
/*    outp(0x3d5, linopt & ~0x04 | tmp);*/
474
    outp(0x3d5, linopt | tmp);
475
 
476
    outp(0x3d4, 0x59);
477
    outp(0x3d5, r59);
478
    outp(0x3d4, 0x5A);
479
    outp(0x3d5, r5A);
480
 
481
    s3_lock();
482
}