Subversion Repositories shark

Rev

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

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