Subversion Repositories shark

Rev

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

Rev Author Line No. Line
54 pj 1
/*
2
Savage chipset driver
3
 
4
Written by Matan Ziv-Av (matan@svgalib.org)
5
 
6
Based on XFree 3.3.6 driver by S. Marineau and Tim Roberts.
7
And XFree 4.1.0 driver by Kevin Brosius.
8
 
9
*/
10
 
11
#include <stdlib.h>
12
//#include <stdio.h>            
13
#include <string.h>
14
#include <unistd.h>
15
//#include <sys/mman.h>
16
#include "vga.h"
17
#include "libvga.h"
18
#include "driver.h"
19
#include "timing.h"
20
#include "vgaregs.h"
21
#include "interface.h"
22
#include "vgapci.h"
23
#include "endianess.h"
24
#include "vgammvgaio.h"
25
 
26
#define SAVAGEREG_SAVE(i) (VGA_TOTAL_REGS+i)
27
#define TOTAL_REGS (VGA_TOTAL_REGS + 64)
28
 
29
typedef struct {    
30
 
31
   unsigned char SR08, SR0A, SR0E, SR0F, SR10, SR11, SR12, SR13;
32
   unsigned char SR15, SR18, SR1B, SR29, SR30;
33
   unsigned char SR54, SR55, SR56, SR57;
34
   unsigned char Clock;
35
//   unsigned char s3DacRegs[0x101];
36
   unsigned char CR31, CR33, CR34, CR36, CR3A, CR3B, CR3C;
37
   unsigned char CR40, CR41, CR42, CR43, CR45;
38
   unsigned char CR50, CR51, CR53, CR54, CR55, CR58, CR5B, CR5D, CR5E;
39
   unsigned char CR63, CR65, CR66, CR67, CR68, CR69, CR6D, CR6F; /* Video attrib. */
40
   unsigned char CR7B, CR7D;
41
   unsigned char CR85, CR86, CR87, CR88;
42
   unsigned char CR90, CR91, CR92, CR93, CRB0;
43
} vgaS3VRec, *vgaS3VPtr;
44
 
45
static int savage_init(int, int, int);
46
static void unlock(void);
47
static void lock(void);
48
static int savage_linear(int op, int param);
49
 
50
enum { UNKNOWN, TRIO64, TRIO3D, TRIO3D2X,
51
                VIRGE, VIRGEVX, VIRGEDX, VIRGEGX2, VIRGEMX,
52
                SAVAGE3D, SAVAGEMX, SAVAGE4, SAVAGEPRO, SAVAGE2000 };
53
 
54
static int memory, chipset;
55
static int is_linear, linear_base;
56
 
57
static CardSpecs *cardspecs;
58
 
59
static void savage_setpage(int page)
60
{
61
    __svgalib_outcrtc(0x6a, page);
62
}
63
 
64
static int inlinearmode(void)
65
{
66
return is_linear;
67
}
68
 
69
/* Fill in chipset specific mode information */
70
 
71
static void savage_getmodeinfo(int mode, vga_modeinfo *modeinfo)
72
{
73
 
74
    if(modeinfo->colors==16)return;
75
 
76
    modeinfo->maxpixels = memory*1024/modeinfo->bytesperpixel;
77
    modeinfo->maxlogicalwidth = 4088;
78
    modeinfo->startaddressrange = memory * 1024 - 1;
79
    modeinfo->haveblit = 0;
80
    modeinfo->flags &= ~HAVE_RWPAGE;
81
 
82
    if (modeinfo->bytesperpixel >= 1) {
83
        if(linear_base)modeinfo->flags |= CAPABLE_LINEAR;
84
        if (inlinearmode())
85
            modeinfo->flags |= IS_LINEAR | LINEAR_MODE;
86
    }
87
}
88
 
89
/* Read and save chipset-specific registers */
90
 
91
static int savage_saveregs(unsigned char regs[])
92
{
93
    unsigned char cr3a, cr66;
94
    vgaS3VPtr save = (vgaS3VPtr)(regs+VGA_TOTAL_REGS);
95
 
96
    unlock();          
97
 
98
    cr66 = __svgalib_incrtc(0x66);
99
    __svgalib_outcrtc(0x66, cr66 | 0x80);
100
    cr3a = __svgalib_incrtc(0x3a);
101
    __svgalib_outcrtc(0x3a, cr3a | 0x80);
102
 
103
    cr66 = __svgalib_incrtc(0x66);
104
    __svgalib_outcrtc(0x66, cr66 | 0x80);
105
    cr3a = __svgalib_incrtc(0x3a);
106
    __svgalib_outcrtc(0x3a, cr3a | 0x80);
107
 
108
#if 0
109
   save = (vgaS3VPtr)vgaHWSave((vgaHWPtr)save, sizeof(vgaS3VRec));
110
#endif
111
 
112
    __svgalib_outcrtc(0x66, cr66);
113
    __svgalib_outcrtc(0x3a, cr3a);
114
    __svgalib_outcrtc(0x66, cr66);
115
    __svgalib_outcrtc(0x3a, cr3a);
116
 
117
   /* First unlock extended sequencer regs */
118
    save->SR08 = __svgalib_inseq(0x08);
119
    __svgalib_outseq(0x08, 0x06);
120
 
121
   /* Now we save all the s3 extended regs we need */
122
    save->CR31 = __svgalib_incrtc(0x31);
123
    save->CR34 = __svgalib_incrtc(0x34);
124
    save->CR36 = __svgalib_incrtc(0x36);
125
    save->CR3A = __svgalib_incrtc(0x3a);
126
 
127
    if(chipset>TRIO3D)
128
        save->CR40 = __svgalib_incrtc(0x40);
129
 
130
    if(chipset==VIRGEMX)
131
        save->CR41 = __svgalib_incrtc(0x41);
132
 
133
    save->CR42 = __svgalib_incrtc(0x42);
134
    save->CR45 = __svgalib_incrtc(0x45);
135
 
136
    if(chipset>=SAVAGE3D)
137
        save->CR50 = __svgalib_incrtc(0x50);
138
 
139
    save->CR51 = __svgalib_incrtc(0x51);
140
    save->CR53 = __svgalib_incrtc(0x53);
141
 
142
    if(chipset<SAVAGE3D){
143
        save->CR54 = __svgalib_incrtc(0x54);
144
        save->CR55 = __svgalib_incrtc(0x55);
145
    }
146
 
147
    save->CR58 = __svgalib_incrtc(0x58);
148
 
149
    if(chipset<SAVAGE3D)
150
        save->CR63 = __svgalib_incrtc(0x63);
151
 
152
    save->CR66 = __svgalib_incrtc(0x66);
153
    save->CR67 = __svgalib_incrtc(0x67);
154
    save->CR68 = __svgalib_incrtc(0x68);
155
    save->CR69 = __svgalib_incrtc(0x69);
156
 
157
    if(chipset>=SAVAGE3D)
158
        save->CR6F = __svgalib_incrtc(0x6f);
159
 
160
    save->CR33 = __svgalib_incrtc(0x33);
161
 
162
    if((chipset==TRIO3D2X)||(chipset==VIRGEGX2)||(chipset==VIRGEMX))
163
        save->CR85 = __svgalib_incrtc(0x85);
164
 
165
    if((chipset==VIRGEDX)||(chipset>=SAVAGE3D))
166
        save->CR86 = __svgalib_incrtc(0x86);
167
 
168
    if((chipset==TRIO3D2X)||(chipset==VIRGEGX2)||(chipset==VIRGEMX)) {
169
        save->CR7B = __svgalib_incrtc(0x7b);
170
        save->CR7D = __svgalib_incrtc(0x7d);
171
        save->CR87 = __svgalib_incrtc(0x87);
172
        save->CR92 = __svgalib_incrtc(0x92);
173
        save->CR93 = __svgalib_incrtc(0x93);
174
    }
175
 
176
    if((chipset==TRIO3D2X)||(chipset==VIRGEDX)||(chipset==VIRGEGX2)||
177
       (chipset==VIRGEMX)) {
178
        save->CR90 = __svgalib_incrtc(0x90);
179
        save->CR91 = __svgalib_incrtc(0x91);
180
    }
181
 
182
    if(chipset>=SAVAGE3D) {
183
        save->CR88 = __svgalib_incrtc(0x88);
184
        save->CR90 = __svgalib_incrtc(0x90);
185
        save->CR91 = __svgalib_incrtc(0x91);
186
        save->CRB0 = __svgalib_incrtc(0xb0) | 0x80;
187
    }
188
 
189
    save->CR3B = __svgalib_incrtc(0x3b);
190
    save->CR3C = __svgalib_incrtc(0x3c);
191
    save->CR43 = __svgalib_incrtc(0x43);
192
    save->CR5D = __svgalib_incrtc(0x5d);
193
    save->CR5E = __svgalib_incrtc(0x5e);
194
    save->CR65 = __svgalib_incrtc(0x65);
195
 
196
    if(chipset<SAVAGE3D)
197
        save->CR6D = __svgalib_incrtc(0x6d);
198
 
199
   /* Save sequencer extended regs for DCLK PLL programming */
200
    save->SR0E = __svgalib_inseq(0x0E);
201
    save->SR10 = __svgalib_inseq(0x10);
202
    save->SR11 = __svgalib_inseq(0x11);
203
    save->SR12 = __svgalib_inseq(0x12);
204
    save->SR13 = __svgalib_inseq(0x13);
205
 
206
    if(chipset>=SAVAGE3D)
207
        save->SR29 = __svgalib_inseq(0x29);
208
 
209
    if((chipset==TRIO3D2X)||(chipset==VIRGEGX2)||(chipset==VIRGEMX)) {
210
        save->SR29 = __svgalib_inseq(0x29);
211
        save->SR54 = __svgalib_inseq(0x54);
212
        save->SR55 = __svgalib_inseq(0x55);
213
        save->SR56 = __svgalib_inseq(0x56);
214
        save->SR57 = __svgalib_inseq(0x57);
215
    }
216
 
217
    save->SR15 = __svgalib_inseq(0x15);
218
 
219
        if(chipset>=SAVAGE3D)
220
        save->SR30 = __svgalib_inseq(0x30);
221
 
222
        save->SR18 = __svgalib_inseq(0x18);
223
 
224
        if(chipset>=SAVAGE3D)
225
        save->SR1B = __svgalib_inseq(0x1B);
226
 
227
    if(chipset<=TRIO3D) {
228
        save->SR0A = __svgalib_inseq(0x0a);
229
        save->SR0F = __svgalib_inseq(0x0f);
230
    }
231
 
232
    __svgalib_outcrtc(0x3a, cr3a);
233
    __svgalib_outcrtc(0x66, cr66);
234
 
235
    return TOTAL_REGS - VGA_TOTAL_REGS;
236
}
237
 
238
/* Set chipset-specific registers */
239
 
240
static void savage_setregs(const unsigned char regs[], int mode)
241
{  
242
    int tmp;
243
    vgaS3VPtr restore = (vgaS3VPtr)(regs+VGA_TOTAL_REGS);
244
 
245
    unlock();
246
 
247
#if 0
248
   /* Are we going to reenable STREAMS in this new mode? */
249
   s3vPriv.STREAMSRunning = restore->CR67 & 0x0c;
250
 
251
   /* First reset GE to make sure nothing is going on */
252
   outb(vgaCRIndex, 0x66);
253
   if(port_in(vgaCRReg) & 0x01) S3SAVGEReset(0,__LINE__,__FILE__);
254
#endif
255
 
256
   /* As per databook, always disable STREAMS before changing modes */
257
    __svgalib_outcrtc(0x67, __svgalib_incrtc(0x67)&0xf3);
258
 
259
    if(chipset<SAVAGE3D)
260
        __svgalib_outcrtc(0x63, restore->CR63);
261
 
262
    __svgalib_outcrtc(0x66, restore->CR66);
263
    __svgalib_outcrtc(0x3a, restore->CR3A);
264
    __svgalib_outcrtc(0x31, restore->CR31);
265
    __svgalib_outcrtc(0x58, restore->CR58);
266
 
267
    if(chipset<SAVAGE3D)
268
        __svgalib_outcrtc(0x55, restore->CR55);
269
 
270
#if 0 /* why is it done twice? */
271
    __svgalib_outseq(0x08, 0x06);
272
    __svgalib_outseq(0x12, restore->SR12);    
273
    __svgalib_outseq(0x13, restore->SR13);    
274
    __svgalib_outseq(0x29, restore->SR29);    
275
    __svgalib_outseq(0x15, restore->SR15);
276
#endif
277
 
278
    __svgalib_outcrtc(0x53, restore->CR53);
279
    __svgalib_outcrtc(0x5d, restore->CR5D);
280
    __svgalib_outcrtc(0x5e, restore->CR5E);
281
    __svgalib_outcrtc(0x3b, restore->CR3B);
282
    __svgalib_outcrtc(0x3c, restore->CR3C);
283
    __svgalib_outcrtc(0x43, restore->CR43);
284
    __svgalib_outcrtc(0x65, restore->CR65);
285
 
286
    if(chipset<SAVAGE3D)
287
        __svgalib_outcrtc(0x6d, restore->CR6D);
288
 
289
   /* Restore the desired video mode with CR67 */
290
 
291
    if(chipset<SAVAGE3D)
292
        __svgalib_outcrtc(0x67, 0x50 | (__svgalib_incrtc(0x67)&0x0f));
293
    else
294
        __svgalib_outcrtc(0x67, 0x50 | (__svgalib_incrtc(0x67)&0xf3));
295
 
296
    sleep(1);
297
    __svgalib_outcrtc(0x67, restore->CR67&0xf3);
298
 
299
    __svgalib_outcrtc(0x34, restore->CR34);
300
 
301
    if(chipset>TRIO3D)
302
        __svgalib_outcrtc(0x40, restore->CR40);
303
 
304
    if(chipset==VIRGEMX)
305
        __svgalib_outcrtc(0x41, restore->CR41);
306
 
307
    __svgalib_outcrtc(0x42, restore->CR42);
308
    __svgalib_outcrtc(0x45, restore->CR45);
309
 
310
    if(chipset>=SAVAGE3D)
311
        __svgalib_outcrtc(0x50, restore->CR50);
312
 
313
    __svgalib_outcrtc(0x51, restore->CR51);
314
 
315
    if(chipset<SAVAGE3D)
316
        __svgalib_outcrtc(0x54, restore->CR54);
317
 
318
    __svgalib_outcrtc(0x36, restore->CR36);
319
    __svgalib_outcrtc(0x68, restore->CR68);
320
    __svgalib_outcrtc(0x69, restore->CR69);
321
 
322
    if(chipset>=SAVAGE3D)
323
        __svgalib_outcrtc(0x6f, restore->CR6F);
324
 
325
    __svgalib_outcrtc(0x33, restore->CR33);
326
 
327
    if(chipset>=SAVAGE3D) {
328
        __svgalib_outcrtc(0x86, restore->CR86);
329
        __svgalib_outcrtc(0x88, restore->CR88);
330
        __svgalib_outcrtc(0x90, restore->CR90);
331
        __svgalib_outcrtc(0x91, restore->CR91);
332
        __svgalib_outcrtc(0xb0, restore->CRB0);
333
    }
334
 
335
    if((chipset==TRIO3D2X)||(chipset==VIRGEGX2)||(chipset==VIRGEMX))
336
        __svgalib_outcrtc(0x85, restore->CR85);
337
 
338
    if(chipset==VIRGEDX)
339
        __svgalib_outcrtc(0x86, restore->CR86);
340
 
341
    if(chipset==VIRGEGX2) {
342
        __svgalib_outcrtc(0x7b, restore->CR7B);
343
        __svgalib_outcrtc(0x7d, restore->CR7D);
344
        __svgalib_outcrtc(0x87, restore->CR87);
345
        __svgalib_outcrtc(0x92, restore->CR92);
346
        __svgalib_outcrtc(0x93, restore->CR93);
347
    }
348
 
349
    if((chipset==TRIO3D2X)||(chipset==VIRGEDX)||(chipset==VIRGEGX2)||(chipset==VIRGEMX)) {
350
        __svgalib_outcrtc(0x90, restore->CR90);
351
        __svgalib_outcrtc(0x91, restore->CR91);
352
    }
353
 
354
    __svgalib_outseq(0x08, 0x06);
355
   /* Restore extended sequencer regs for MCLK. SR10 == 255 indicates that
356
    * we should leave the default SR10 and SR11 values there.
357
    */
358
 
359
    if (restore->SR10 != 255) {  
360
        __svgalib_outseq(0x10, restore->SR10);    
361
        __svgalib_outseq(0x11, restore->SR11);    
362
    }
363
 
364
   /* Restore extended sequencer regs for DCLK */
365
 
366
    __svgalib_outseq(0x12, restore->SR12);    
367
    __svgalib_outseq(0x13, restore->SR13);    
368
 
369
    if(chipset>=SAVAGE3D)
370
        __svgalib_outseq(0x29, restore->SR29);    
371
 
372
    if((chipset==TRIO3D2X)||(chipset==VIRGEGX2)||(chipset==VIRGEMX)) {
373
        __svgalib_outseq(0x29, restore->SR29);    
374
        __svgalib_outseq(0x54, restore->SR54);    
375
        __svgalib_outseq(0x55, restore->SR55);    
376
        __svgalib_outseq(0x56, restore->SR56);    
377
        __svgalib_outseq(0x57, restore->SR57);    
378
    }
379
 
380
    __svgalib_outseq(0x18, restore->SR18);
381
 
382
    if(chipset>=SAVAGE3D)
383
        __svgalib_outseq(0x1B, restore->SR1B);
384
 
385
    tmp = __svgalib_inseq(0x15) & ~0x21;
386
    __svgalib_outseq(0x15, tmp | 0x03);
387
    __svgalib_outseq(0x15, tmp | 0x23);
388
    __svgalib_outseq(0x15, tmp | 0x03);
389
    __svgalib_outseq(0x15, restore->SR15);
390
 
391
    sleep(1);
392
 
393
    if(chipset<=TRIO3D) {
394
        __svgalib_outseq(0x0a, restore->SR0A);
395
        __svgalib_outseq(0x0f, restore->SR0F);
396
    } else if (chipset >= SAVAGE3D) {
397
                __svgalib_outseq(0x30, restore->SR30);
398
        }
399
 
400
    __svgalib_outseq(0x08, restore->SR08);
401
 
402
 
403
   /* Now write out CR67 in full, possibly starting STREAMS */
404
 
405
    __svgalib_outcrtc(0x67, 0x50);
406
    sleep(1);
407
    __svgalib_outcrtc(0x67, restore->CR67&0xf3);
408
 
409
    __svgalib_outcrtc(0x53, restore->CR53);
410
    __svgalib_outcrtc(0x66, restore->CR66);
411
    __svgalib_outcrtc(0x3a, restore->CR3A);
412
}
413
 
414
 
415
/* Return nonzero if mode is available */
416
 
417
static int savage_modeavailable(int mode)
418
{
419
    struct info *info;
420
    ModeTiming *modetiming;
421
    ModeInfo *modeinfo;
422
 
423
    if (IS_IN_STANDARD_VGA_DRIVER(mode))
424
        return __svgalib_vga_driverspecs.modeavailable(mode);
425
 
426
    info = &__svgalib_infotable[mode];
427
 
428
    if (memory * 1024 < info->ydim * info->xbytes)
429
        return 0;
430
 
431
    modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
432
 
433
    if(modeinfo->bytesPerPixel==3) return 0;
434
 
435
    modetiming = malloc(sizeof(ModeTiming));
436
 
437
    if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {
438
        free(modetiming);
439
        free(modeinfo);
440
        return 0;
441
    }
442
 
443
    free(modetiming);
444
    free(modeinfo);
445
    return SVGADRV;
446
}
447
 
448
/* Local, called by setmode(). */
449
#define BASE_FREQ 14.31818
450
 
451
static void savageCalcClock(long freq, int min_m, int min_n1, int max_n1, int min_n2, int max_n2,
452
                long freq_min, long freq_max, unsigned int *mdiv, unsigned int *ndiv, unsigned int *r)
453
{
454
   double ffreq, ffreq_min, ffreq_max;
455
   double div, diff, best_diff;
456
   unsigned int m;
457
   unsigned char n1, n2;
458
   unsigned char best_n1=16+2, best_n2=2, best_m=125+2;
459
 
460
   ffreq     = freq     / 1000.0 / BASE_FREQ;
461
   ffreq_min = freq_min / 1000.0 / BASE_FREQ;
462
   ffreq_max = freq_max / 1000.0 / BASE_FREQ;
463
 
464
   if (ffreq < ffreq_min / (1<<max_n2)) {
465
      ffreq = ffreq_min / (1<<max_n2);
466
   }
467
   if (ffreq > ffreq_max / (1<<min_n2)) {
468
      ffreq = ffreq_max / (1<<min_n2);
469
   }
470
 
471
   /* work out suitable timings */
472
 
473
   best_diff = ffreq;
474
 
475
   for (n2=min_n2; n2<=max_n2; n2++) {
476
      for (n1 = min_n1+2; n1 <= max_n1+2; n1++) {
477
         m = (int)(ffreq * n1 * (1<<n2) + 0.5) ;
478
         if (m < min_m+2 || m > 127+2)
479
            continue;
480
         div = (double)(m) / (double)(n1);       
481
         if ((div >= ffreq_min) &&
482
             (div <= ffreq_max)) {
483
            diff = ffreq - div / (1<<n2);
484
            if (diff < 0.0)
485
               diff = -diff;
486
            if (diff < best_diff) {
487
               best_diff = diff;
488
               best_m    = m;
489
               best_n1   = n1;
490
               best_n2   = n2;
491
            }
492
         }
493
      }
494
   }
495
 
496
   *ndiv = best_n1 - 2;
497
   *r = best_n2;
498
   *mdiv = best_m - 2;
499
}
500
 
501
 
502
static void savage_initializemode(unsigned char *moderegs,
503
                            ModeTiming * modetiming, ModeInfo * modeinfo, int mode)
85 giacomo 504
{
505
#ifdef NL
506
#undef NL
507
#endif  
54 pj 508
#define NL (1<<30)
509
    int i, j, dclk, width, tmp;
510
    int clocklimits[14][2]={
511
        {},
512
        {86000,0}, /* Trio 64 - Guess */
513
        {115000,115000}, /* Trio 3D */
514
        {NL,0}, /* Trio 3D2X */
515
        {80000,0}, /* Virge */
516
        {110000,110000}, /* Virge VX */
517
        {80000,0}, /* Virge DX */
518
        {NL,0}, /* Virge GX2 */
519
        {NL,0}, /* Virge MX */
520
        {NL,NL}, /* Savage 3D */
521
        {0,0}, /* Savage MX */
522
        {NL,NL}, /* Savage 4 */
523
        {NL,NL}, /* Savage Pro */
524
        {230000,230000}, /* Savage 2000 */
525
    };
526
    int cargs[14][4]= {
527
        {},
528
        {31,  0, 3, 86000}, /* Trio 64 - Guess */
529
        {31,  0, 4, 230000},
530
        {31,  0, 4, 170000},
531
        {31,  0, 3, 135000},
532
        {31,  0, 4, 220000},
533
        {31,  0, 3, 135000},
534
        {31,  0, 4, 170000},
535
        {31,  0, 4, 170000},
536
        {127, 0, 4, 180000},
537
        {127, 0, 4, 180000},
538
        {127, 0, 4, 180000},
539
        {127, 0, 4, 180000},
540
        {127, 0, 4, 180000},
541
    };
542
#undef NL
543
 
544
    vgaS3VPtr new = (vgaS3VPtr)(moderegs+VGA_TOTAL_REGS);
545
 
546
    if(modeinfo->bitsPerPixel==16) {
547
        if((chipset==VIRGE)|| (chipset==TRIO64)) {
548
            modetiming->HDisplay *=2;
549
            modetiming->HSyncStart *=2;
550
            modetiming->HSyncEnd *=2;
551
            modetiming->HTotal *=2;
552
            modetiming->CrtcHDisplay =modetiming->HDisplay;
553
            modetiming->CrtcHSyncStart =modetiming->HSyncStart;
554
            modetiming->CrtcHSyncEnd =modetiming->HSyncEnd;
555
            modetiming->CrtcHTotal =modetiming->HTotal;
556
        }
557
    }
558
 
559
    __svgalib_setup_VGA_registers(moderegs, modetiming, modeinfo);
560
 
561
    tmp = __svgalib_incrtc(0x3a);
562
    if((chipset==TRIO3D2X)||(chipset==VIRGEGX2)||(chipset==VIRGEMX)) {
563
        if(0) new->CR3A = tmp | 0x90;                   /* ENH 256, no PCI burst! */
564
            else new->CR3A = (tmp & 0x38) | 0x10;       /* ENH 256, PCI burst */
565
    } else {
566
        if(0) new->CR3A = tmp | 0x95;                   /* ENH 256, no PCI burst! */
567
            else new->CR3A = (tmp & 0x7f) | 0x15;       /* ENH 256, PCI burst */
568
    }
569
 
570
    new->CR53 |= 0x08;          /* Disables MMIO */
571
    new->CR31 = 0x09;           /* Enable 64k window */
572
 
573
    if(chipset==VIRGEVX) {
574
        new->CR66 = 0x90;
575
        new->CR63 = 0x09;
576
        new->CR58 = 0x40;
577
    } else {
578
        if((chipset==TRIO3D2X)||(chipset==VIRGEGX2)||(chipset==VIRGEMX)) {
579
            new->CR63 = 0x08;
580
        } else {
581
            new->CR63 = 0x00;
582
        }
583
        new->CR66 = 0x89;
584
        new->CR58 = 0;
585
    }
586
 
587
/* Now do clock PLL programming. Use the s3gendac function to get m,n */
588
/* Also determine if we need doubling etc. */
589
 
590
    dclk = modetiming->pixelClock;
591
    new->CR67 = 0x00;             /* Defaults */
592
    if(chipset > TRIO3D) {
593
        new->SR15 = 0x03 | 0x80;
594
        if(chipset==VIRGE)
595
           new->SR15 = (__svgalib_inseq(0x15) & 0x80) | 3;
596
    } else {
597
        new->SR15 = (__svgalib_inseq(0x15) & 0x80) | 3;
598
        new->SR0A = __svgalib_inseq(0x0a);
599
    }
600
    new->SR18 = 0x00;
601
    new->CR43 = 0x00;
602
    new->CR45 = 0x00;
603
    new->CR65 = 0x00;
604
    new->CR54 = 0x00;
605
 
606
    if(chipset > TRIO3D)
607
        new->CR40 = __svgalib_incrtc(0x40) & 0xfe ;
608
 
609
    new->SR10 = 255; /* This is a reserved value, so we use as flag */
610
    new->SR11 = 255;
611
 
612
        new->SR1B = 0;
613
        new->SR30 = __svgalib_inseq(0x30);
614
 
615
    switch( modeinfo->colorBits ) {
616
        case 8:
617
            new->CR67 = 0x00;   /* 8bpp, 1 pixel/clock */
618
            if(dclk >= clocklimits[chipset][0]) new->CR67 |= 0x10;
619
            break;
620
        case 15:
621
            new->CR67 = 0x20;
622
            if(dclk >= clocklimits[chipset][1]) new->CR67 |= 0x10;
623
            break;
624
        case 16:
625
            new->CR67 = 0x40;
626
            if(dclk >= clocklimits[chipset][1]) new->CR67 |= 0x10;
627
            break;
628
        case 24:
629
            new->CR67 = 0xd0;
630
            break;
631
    }
632
 
633
    /* Now the special cases */
634
    if(chipset==VIRGE) {
635
        if(new->CR67 == 0x10) {
636
            new->SR15 |= 0x10;
637
            new->SR18 =  0x80;
638
        }
639
    }
640
 
641
    {
642
        unsigned int m, n, r;
643
 
644
        savageCalcClock(dclk, 1, 1, cargs[chipset][0], cargs[chipset][1],
645
          cargs[chipset][2], cargs[chipset][3], cargs[chipset][3]*2,
646
          &m, &n, &r);
647
        if(chipset < SAVAGE3D)
648
            new->SR12 = (r << 5) | (n & 0x1F);
649
            else new->SR12 = (r << 6) | (n & 0x3F);
650
        new->SR13 = m & 0xFF;
651
        new->SR29 = (r & 4) | (m & 0x100) >> 5 | (n & 0x40) >> 2;
652
    }
653
 
654
 
655
   /* If we have an interlace mode, set the interlace bit. Note that mode
656
    * vertical timings are already adjusted by the standard VGA code
657
    */
658
    if (modetiming->flags & INTERLACED) {
659
        new->CR42 = 0x20; /* Set interlace mode */
660
    } else {
661
        new->CR42 = 0x00;
662
    }
663
 
664
    /* Set display fifo */
665
    if((chipset==TRIO3D2X)||(chipset==VIRGEGX2)||(chipset==VIRGEMX)) {
666
        new->CR34 = 0;
667
    } else {
668
        new->CR34 = 0x10;
669
    }
670
 
671
    /* Now we adjust registers for extended mode timings */
672
    /* This is taken without change from the accel/s3_virge code */
673
 
674
    i = ((((modetiming->CrtcHTotal >> 3) - 5) & 0x100) >> 8) |
675
        ((((modetiming->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) |
676
        ((((modetiming->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) |
677
        ((modetiming->CrtcHSyncStart & 0x800) >> 7);
678
 
679
    if ((modetiming->CrtcHSyncEnd >> 3) - (modetiming->CrtcHSyncStart >> 3) > 64)
680
        i |= 0x08;   /* add another 64 DCLKs to blank pulse width */
681
 
682
    if ((modetiming->CrtcHSyncEnd >> 3) - (modetiming->CrtcHSyncStart >> 3) > 32)
683
        i |= 0x20;   /* add another 32 DCLKs to hsync pulse width */
684
 
685
    j = (  moderegs[0] + ((i&0x01)<<8)
686
         + moderegs[4] + ((i&0x10)<<4) + 1) / 2;
687
 
688
    if (j-(moderegs[4] + ((i&0x10)<<4)) < 4) {
689
        if (moderegs[4] + ((i&0x10)<<4) + 4 <= moderegs[0]+ ((i&0x01)<<8))
690
            j = moderegs[4] + ((i&0x10)<<4) + 4;
691
        else
692
            j = moderegs[0]+ ((i&0x01)<<8) + 1;
693
    }
694
 
695
    new->CR3B = j & 0xFF;
696
    i |= (j & 0x100) >> 2;
697
    new->CR3C = (moderegs[0] + ((i&0x01)<<8))/2;
698
 
699
    new->CR5D = i;
700
 
701
    new->CR5E = (((modetiming->CrtcVTotal - 2) & 0x400) >> 10)  |
702
                (((modetiming->CrtcVDisplay - 1) & 0x400) >> 9) |
703
                (((modetiming->CrtcVSyncStart) & 0x400) >> 8)   |
704
                (((modetiming->CrtcVSyncStart) & 0x400) >> 6)   | 0x40;
705
 
706
    width = modeinfo->lineWidth >> 3;
707
    moderegs[19] = 0xFF & width;
708
    new->CR51 = (0x300 & width) >> 4; /* Extension bits */
709
 
710
    /* And finally, select clock source 2 for programmable PLL */
711
    moderegs[VGA_MISCOUTPUT] |= 0x0c;      
712
 
713
    if(chipset>=SAVAGE3D) {
714
        /* Set frame buffer description */
715
        if (modeinfo->colorBits <= 8) {
716
            new->CR50 = 0;
717
        } else {
718
            if (modeinfo->colorBits <= 16) {
719
                new->CR50 = 0x10;
720
            } else {
721
                new->CR50 = 0x30;
722
            }
723
        }
724
 
725
        if (modeinfo->width == 640)
726
            new->CR50 |= 0x40;
727
        else if (modeinfo->width == 800)
728
            new->CR50 |= 0x80;
729
        else if (modeinfo->width == 1024);
730
        else if (modeinfo->width == 1152)
731
            new->CR50 |= 0x01;
732
        else if (modeinfo->width == 1280)
733
            new->CR50 |= 0x41;
734
        else if (modeinfo->width == 2048 && new->CR31 & 2);
735
        else if (modeinfo->width == 1600)
736
            new->CR50 |= 0x81; /* TODO: need to consider bpp=4 */
737
        else
738
            new->CR50 |= 0xC1; /* default to use GlobalBD */
739
 
740
        new->CR33 = 0x08;
741
        new->CR6F = __svgalib_incrtc(0x6f);
742
        new->CR86 = __svgalib_incrtc(0x86);
743
        new->CR88 = __svgalib_incrtc(0x88);
744
        new->CRB0 = __svgalib_incrtc(0xb0) | 0x80;
745
    } else /* trio, virge */ {
746
        new->CR33 = 0x20;
747
        if((chipset==VIRGEDX)||(chipset<=TRIO3D)) {
748
            new->CR86 = 0x80;
749
        }
750
 
751
        if((chipset!=VIRGEVX)&&(chipset!=VIRGE)) {
752
            new->CR91 = (modeinfo->lineWidth+7) >> 3;
753
            new->CR90 = 0x80 | ((modeinfo->lineWidth+7) >> 11);
754
        }    
755
 
756
        if(chipset == VIRGEVX) {
757
            if(modeinfo->colorBits>16) new->CR6D = 0x51 ; else new->CR6D=0;
758
        } else {
759
            new->CR6D = __svgalib_incrtc(0x6d);
760
            new->CR65 &= ~0x38;
761
            switch(modeinfo->colorBits) {
762
                case 8:
763
                    break;
764
                case 15:
765
                case 16:
766
                    new->CR65 |= 2<<3;
767
                    break;
768
                default:
769
                    new->CR65 |= 4<<3;
770
                    break;
771
            }
772
        }
773
 
774
        if(chipset == VIRGEMX) {
775
            new->SR54=0x10;
776
            new->SR55=0x80;
777
            new->SR56=0x10;
778
            new->SR57=0x80;
779
        } else {
780
            new->SR54=0x1f;
781
            new->SR55=0x9f;
782
            new->SR56=0x1f;
783
            new->SR57=0x9f;
784
        }
785
    }
786
 
787
   /* Now we handle various XConfig memory options and others */
788
 
789
    new->CR36 = __svgalib_incrtc(0x36);
790
 
791
#if 0
792
   if (mode->Private) {
793
      new->CR67 &= ~1;
794
      if(
795
        (s3vPriv.chip != S3_SAVAGE2000) &&
796
        (mode->Private[0] & (1 << S3_INVERT_VCLK)) &&
797
        (mode->Private[S3_INVERT_VCLK])
798
      )
799
         new->CR67 |= 1;
800
 
801
      if (mode->Private[0] & (1 << S3_BLANK_DELAY)) {
802
         new->CR65 = (new->CR65 & ~0x38)
803
            | (mode->Private[S3_BLANK_DELAY] & 0x07) << 3;
804
      }
805
   }
806
#endif
807
 
808
    if(__svgalib_emulatepage || is_linear) new->CR58 |= 0x13;
809
    new->CR68 = __svgalib_incrtc(0x68);
810
    new->CR69 = 0;
811
 
812
    return ;
813
}
814
 
815
 
816
static int savage_setmode(int mode, int prv_mode)
817
{
818
    unsigned char *moderegs;
819
    ModeTiming *modetiming;
820
    ModeInfo *modeinfo;
821
 
822
    if (IS_IN_STANDARD_VGA_DRIVER(mode)) {
823
        __svgalib_outcrtc(0x34, 0);
824
        return __svgalib_vga_driverspecs.setmode(mode, prv_mode);
825
    }
826
    if (!savage_modeavailable(mode))
827
        return 1;
828
 
829
    modeinfo = __svgalib_createModeInfoStructureForSvgalibMode(mode);
830
 
831
    modetiming = malloc(sizeof(ModeTiming));
832
    if (__svgalib_getmodetiming(modetiming, modeinfo, cardspecs)) {
833
        free(modetiming);
834
        free(modeinfo);
835
        return 1;
836
    }
837
 
838
    moderegs = malloc(TOTAL_REGS);
839
 
840
    savage_initializemode(moderegs, modetiming, modeinfo, mode);
841
    free(modetiming);
842
 
843
    __svgalib_setregs(moderegs);        /* Set standard regs. */
844
    savage_setregs(moderegs, mode);             /* Set extended regs. */
845
    free(moderegs);
846
 
847
    free(modeinfo);
848
 
849
    return 0;
850
}
851
 
852
 
853
/* Unlock chipset-specific registers */
854
 
855
static void unlock(void)
856
{
857
    __svgalib_outcrtc(0x11,__svgalib_incrtc(0x11)&0x7f);
858
    __svgalib_outcrtc(0x38, 0x48);
859
    __svgalib_outcrtc(0x39, 0xa5);
860
    __svgalib_outcrtc(0x40,__svgalib_incrtc(0x40)&0xfe);  
861
}
862
 
863
static void lock(void)
864
{
865
}
866
 
867
 
868
#define VENDOR_ID 0x5333
869
 
870
/* Indentify chipset, initialize and return non-zero if detected */
871
 
872
int savage_test(void)
873
{
874
    int found;
875
    int id;
876
    unsigned long buf[64];
877
 
878
    found=__svgalib_pci_find_vendor_vga(VENDOR_ID,buf,0);
879
    id=(buf[0]>>16)&0xffff;
880
    if(found)return 0;
881
    switch(id) {
882
        case 0x8811:
883
        case 0x8903:
884
        case 0x8904:
885
        case 0x8a13:
886
        case 0x5631:
887
        case 0x883d:
888
        case 0x8a01:
889
        case 0x8a10:
890
        case 0x8c00:
891
        case 0x8c01:
892
        case 0x8c02:
893
        case 0x8c03:
894
        case 0x8a20:
895
        case 0x8a21:
896
        case 0x8a22:
897
        case 0x8a23:
898
        case 0x8c10:
899
        case 0x8c12:
900
        case 0x9102:
901
                case 0x8d03:
902
                case 0x8d04:
903
            savage_init(0,0,0);
904
            return 1;
905
            break;
906
        default:
907
            return 0;
908
    }
909
}
910
 
911
 
912
/* Set display start address (not for 16 color modes) */
913
 
914
static void savage_setdisplaystart(int address)
915
{
916
  address=address >> 2;
917
  __svgalib_outcrtc(0x0d,address&0xff);
918
  __svgalib_outcrtc(0x0c,(address>>8)&0xff);
919
  __svgalib_outcrtc(0x69,(address>>16)&0xff);
920
 
921
}
922
 
923
/* Set logical scanline length (usually multiple of 8) */
924
/* Cirrus supports multiples of 8, up to 4088 */
925
 
926
static void savage_setlogicalwidth(int width)
927
{  
928
    int offset = width >> 3;
929
 
930
    __svgalib_outcrtc(0x13,offset&0xff);
931
}
932
 
933
static int savage_linear(int op, int param)
934
{
935
    if (op==LINEAR_ENABLE){
936
       __svgalib_outcrtc(0x58,__svgalib_incrtc(0x58)|0x13);
937
       is_linear=1;
938
       return 0;
939
    };
940
    if (op==LINEAR_DISABLE) {
941
       __svgalib_outcrtc(0x58,__svgalib_incrtc(0x58)&~0x13);
942
       is_linear=0;
943
       return 0;
944
    };
945
    if (op==LINEAR_QUERY_BASE) return linear_base;
946
    if (op == LINEAR_QUERY_RANGE || op == LINEAR_QUERY_GRANULARITY) return 0;           /* No granularity or range. */
947
        else return -1;         /* Unknown function. */
948
}
949
 
950
static int match_programmable_clock(int clock)
951
{
952
return clock ;
953
}
954
 
955
static int map_clock(int bpp, int clock)
956
{
957
return clock ;
958
}
959
 
960
static int map_horizontal_crtc(int bpp, int pixelclock, int htiming)
961
{
962
return htiming;
963
}
964
 
965
static struct {
966
    unsigned char c8;
967
    unsigned short c15;
968
    unsigned short c16;
969
    unsigned int c32;
970
} cursor_colors[16*2];
971
 
972
static int pal=1, palette[768];
973
 
974
static int findcolor(int rgb) {
975
   int i,j,k,l=0;
976
 
977
   if(pal)vga_getpalvec(0,256,palette);
978
   pal=0;
979
   k=0xffffff;
980
   for(i=0;i<256;i++) {
981
      j=((rgb&0xff)-(palette[i*3+2]<<2))*((rgb&0xff)-(palette[i*3+2]<<2))+
982
        (((rgb>>8)&0xff)-(palette[i*3+1]<<2))*(((rgb>>8)&0xff)-(palette[i*3+1]<<2))+
983
        (((rgb>>16)&0xff)-(palette[i*3]<<2))*(((rgb>>16)&0xff)-(palette[i*3]<<2));
984
      if(j==0) {
985
         return i;
986
      }
987
      if(j<k) {
988
         k=j;
989
         l=i;
990
      }
991
   }
992
   return l;
993
}
994
 
995
static int savage_cursor( int cmd, int p1, int p2, int p3, int p4, void *p5) {
996
    unsigned long *b3;
997
    unsigned char *buf;
998
    int i, j;
999
    unsigned int l1, l2;
1000
 
1001
    switch(cmd){
1002
        case CURSOR_INIT:
1003
            return 1;
1004
        case CURSOR_HIDE:
1005
            __svgalib_outcrtc(0x45,__svgalib_incrtc(0x45)&0xfe);
1006
            break;
1007
        case CURSOR_SHOW:
1008
            __svgalib_outcrtc(0x45,__svgalib_incrtc(0x45)|0x01); /* Windows */
1009
            break;
1010
        case CURSOR_POSITION:
1011
            __svgalib_outcrtc(0x46,p1>>8);
1012
            __svgalib_outcrtc(0x47,p1&0xff);
1013
            __svgalib_outcrtc(0x49,p2&0xff);
1014
            __svgalib_outcrtc(0x4e,0);
1015
            __svgalib_outcrtc(0x4f,0);
1016
            __svgalib_outcrtc(0x48,p2>>8);
1017
            break;
1018
        case CURSOR_SELECT:
1019
            i=memory-(16-p1);
1020
            switch(CI.colors) {
1021
                case 256:
1022
                    __svgalib_incrtc(0x45);
1023
                    __svgalib_outcrtc(0x4b,cursor_colors[p1*2].c8);
1024
                    __svgalib_outcrtc(0x4b,cursor_colors[p1*2].c8);
1025
                    __svgalib_incrtc(0x45);
1026
                    __svgalib_outcrtc(0x4a,cursor_colors[p1*2+1].c8);
1027
                    __svgalib_outcrtc(0x4a,cursor_colors[p1*2+1].c8);
1028
                   break;
1029
                case 32768:
1030
                    __svgalib_incrtc(0x45);
1031
                    __svgalib_outcrtc(0x4b,cursor_colors[p1*2].c15&0xff);
1032
                    __svgalib_outcrtc(0x4b,cursor_colors[p1*2].c15>>8);
1033
                    __svgalib_outcrtc(0x4b,cursor_colors[p1*2].c15&0xff);
1034
                    __svgalib_outcrtc(0x4b,cursor_colors[p1*2].c15>>8);
1035
                    __svgalib_incrtc(0x45);
1036
                    __svgalib_outcrtc(0x4a,cursor_colors[p1*2+1].c15&0xff);
1037
                    __svgalib_outcrtc(0x4a,cursor_colors[p1*2+1].c15>>8);
1038
                    __svgalib_outcrtc(0x4a,cursor_colors[p1*2+1].c15&0xff);
1039
                    __svgalib_outcrtc(0x4a,cursor_colors[p1*2+1].c15>>8);
1040
                   break;
1041
                case 65536:
1042
                    __svgalib_incrtc(0x45);
1043
                    __svgalib_outcrtc(0x4b,cursor_colors[p1*2].c16&0xff);
1044
                    __svgalib_outcrtc(0x4b,cursor_colors[p1*2].c16>>8);
1045
                    __svgalib_outcrtc(0x4b,cursor_colors[p1*2].c16&0xff);
1046
                    __svgalib_outcrtc(0x4b,cursor_colors[p1*2].c16>>8);
1047
                    __svgalib_incrtc(0x45);
1048
                    __svgalib_outcrtc(0x4a,cursor_colors[p1*2+1].c16&0xff);
1049
                    __svgalib_outcrtc(0x4a,cursor_colors[p1*2+1].c16>>8);
1050
                    __svgalib_outcrtc(0x4a,cursor_colors[p1*2+1].c16&0xff);
1051
                    __svgalib_outcrtc(0x4a,cursor_colors[p1*2+1].c16>>8);
1052
                   break;
1053
                case (1<<24):
1054
                    __svgalib_incrtc(0x45);
1055
                    __svgalib_outcrtc(0x4b,cursor_colors[p1*2].c32&0xff);
1056
                    __svgalib_outcrtc(0x4b,(cursor_colors[p1*2].c32>>8)&0xff);
1057
                    __svgalib_outcrtc(0x4b,(cursor_colors[p1*2].c32>>16)&0xff);
1058
                    __svgalib_incrtc(0x45);
1059
                    __svgalib_outcrtc(0x4a,cursor_colors[p1*2+1].c32&0xff);
1060
                    __svgalib_outcrtc(0x4a,(cursor_colors[p1*2+1].c32>>8)&0xff);
1061
                    __svgalib_outcrtc(0x4a,(cursor_colors[p1*2+1].c32>>16)&0xff);
1062
                   break;
1063
            }
1064
            __svgalib_outcrtc(0x4d, i&0xff);
1065
            __svgalib_outcrtc(0x4c, i>>8);
1066
            break;
1067
        case CURSOR_IMAGE:
1068
            buf=malloc(1024);
1069
            cursor_colors[p1*2].c8=findcolor(p3);
1070
            cursor_colors[p1*2].c32=p3;
1071
            cursor_colors[p1*2].c16=((p3&0xf80000)>>8)|((p3&0xfc00)>>5)|((p3&0xf8)>>3);
1072
            cursor_colors[p1*2].c15=((p3&0xf80000)>>9)|((p3&0xf800)>>5)|((p3&0xf8)>>3);
1073
            cursor_colors[p1*2+1].c8=findcolor(p4);
1074
            cursor_colors[p1*2+1].c32=p4;
1075
            cursor_colors[p1*2+1].c16=((p4&0xf80000)>>8)|((p4&0xfc00)>>5)|((p4&0xf8)>>3);
1076
            cursor_colors[p1*2+1].c15=((p4&0xf80000)>>9)|((p4&0xf800)>>5)|((p4&0xf8)>>3);
1077
            i=memory*1024-(16-p1)*1024;
1078
            b3=(unsigned long *)p5;
1079
            switch(p2) {
1080
                case 0:
1081
                    for(j=0;j<32;j++) {
1082
                        l2=*(b3+j);
1083
                        l1=*(b3+32+j);
1084
                        l1=BE32(l1);
1085
                        l2=BE32(l2);
1086
                        l2=l2&l1;
1087
                        l1=~l1;
1088
                        *(unsigned short *)(buf+16*j)=l1&0xffff;
1089
                        *(unsigned short *)(buf+16*j+2)=l2&0xffff;
1090
                        *(unsigned short *)(buf+16*j+4)=(l1>>16)&0xffff;
1091
                        *(unsigned short *)(buf+16*j+6)=(l2>>16)&0xffff;
1092
                        *(unsigned short *)(buf+16*j+8)=0xffff;
1093
                        *(unsigned short *)(buf+16*j+10)=0;
1094
                        *(unsigned short *)(buf+16*j+12)=0xffff;
1095
                        *(unsigned short *)(buf+16*j+14)=0;
1096
                    }
1097
                    for(j=32;j<64;j++) {
1098
                        *(unsigned short *)(buf+16*j)=0xffff;
1099
                        *(unsigned short *)(buf+16*j+2)=0;
1100
                        *(unsigned short *)(buf+16*j+4)=0xffff;
1101
                        *(unsigned short *)(buf+16*j+6)=0;
1102
                        *(unsigned short *)(buf+16*j+8)=0xffff;
1103
                        *(unsigned short *)(buf+16*j+10)=0;
1104
                        *(unsigned short *)(buf+16*j+12)=0xffff;
1105
                        *(unsigned short *)(buf+16*j+14)=0;
1106
                    }
1107
                    break;
1108
            }
1109
            vga_drawscansegment(buf, i/CI.bytesperpixel,0,1024);
1110
            break;
1111
    }
1112
    return 0;
1113
}      
1114
 
1115
/* Function table (exported) */
1116
DriverSpecs __svgalib_savage_driverspecs =
1117
{
1118
    savage_saveregs,
1119
    savage_setregs,
1120
    unlock,
1121
    lock,
1122
    savage_test,
1123
    savage_init,
1124
    savage_setpage,
1125
    NULL,
1126
    NULL,
1127
    savage_setmode,
1128
    savage_modeavailable,
1129
    savage_setdisplaystart,
1130
    savage_setlogicalwidth,
1131
    savage_getmodeinfo,
1132
    0,                          /* old blit funcs */
1133
    0,
1134
    0,
1135
    0,
1136
    0,
1137
    0,                          /* ext_set */
1138
    0,                          /* accel */
1139
    savage_linear,
1140
    0,                          /* accelspecs, filled in during init. */
1141
    NULL,                       /* Emulation */
1142
    savage_cursor,
1143
};
1144
 
1145
/* Initialize chipset (called after detection) */
1146
static int savage_init(int force, int par1, int par2)
1147
{
1148
    unsigned long buf[64];
1149
    unsigned long mmio_base;
1150
    int found=0, config1;
1151
    int mems[8]={2,4,8,12,16,32,64,2};
1152
    char *chipnames[] = {"Unknown", "Trio64", "Trio 3D", "Trio 3d/2X", "Virge", "Virge VX",
1153
                         "Virge DX", "Virge GX2", "Virge MX",
1154
                         "Savage3D", "SavageMX", "Savage4", "SavagePro", "Savage2000"};
1155
    int vmems[9][8]= { {0},
1156
        {0,0,0,1,0,0,1,0},
1157
        {4,0,4,0,2,0,0,0},
1158
        {4,0,4,0,0,0,2,0},
1159
        {4,0,0,0,2,0,1,0},
1160
        {2,4,6,8,2,4,6,8},
1161
        {4,0,0,0,2,0,1,0},
1162
        {0,0,4,4,0,0,2,2},
1163
        {0,0,4,4,0,0,2,2}
1164
    };
1165
    int id;
1166
 
1167
//    unlock();
1168
    if (force) {
1169
        memory = par1;
1170
        chipset = par2;
1171
    } else {
1172
 
1173
    };
1174
 
1175
    found=__svgalib_pci_find_vendor_vga(VENDOR_ID,buf,0);
1176
    if (found) {
1177
      printk("Savage Card Not Found !\n");
1178
      return 0;
1179
    }
1180
 
1181
    id=(buf[0]>>16)&0xffff;
1182
    switch(id) {
1183
        case 0x8811:
1184
            chipset = TRIO64;
1185
            break;
1186
        case 0x8903:
1187
        case 0x8904:
1188
            chipset = TRIO3D;
1189
            break;
1190
        case 0x8a13:
1191
            chipset = TRIO3D2X;
1192
            break;
1193
        case 0x5631:
1194
            chipset = VIRGE;
1195
            break;
1196
        case 0x883d:
1197
            chipset = VIRGEVX;
1198
            break;
1199
        case 0x8a01:
1200
            chipset = VIRGEDX;
1201
            break;
1202
        case 0x8a10:
1203
            chipset = VIRGEGX2;
1204
            break;
1205
        case 0x8c00:
1206
        case 0x8c01:
1207
        case 0x8c02:
1208
        case 0x8c03:
1209
            chipset = VIRGEMX;
1210
            break;
1211
        case 0x8a20:
1212
        case 0x8a21:
1213
            chipset = SAVAGE3D;
1214
            break;
1215
        case 0x8c10:
1216
        case 0x8c12:
1217
            chipset = SAVAGEMX;
1218
            break;
1219
        case 0x8a22:
1220
        case 0x8a23:
1221
        case 0x8d03:
1222
        case 0x8d04:
1223
            chipset = SAVAGE4;
1224
            break;
1225
        case 0x9102:
1226
            chipset = SAVAGE2000;
1227
            break;
1228
        default:
1229
            chipset = UNKNOWN;
1230
    }
1231
 
1232
    if(chipset<SAVAGE3D) {
1233
        linear_base=buf[4]&0xffffff00;
1234
        mmio_base = linear_base + 0x1000000;
1235
#if 1 /* You need to write linear address to CR59 5A, and enable MMIO in CR53 - 
1236
         But how to do it if it's a secondary card??? */
1237
        if(__svgalib_secondary) {
1238
            __svgalib_mmio_base = mmio_base;
1239
            __svgalib_mmio_size = 0x10000;
1240
            map_mmio();
1241
            __svgalib_vgammbase=0x8000;
1242
            __svgalib_mm_io_mapio();
1243
        }
1244
#endif
1245
        unlock();
1246
        config1=__svgalib_incrtc(0x36);
1247
        memory = 1024 * vmems[chipset][(config1&0xe0)>>5];
1248
    } else {
1249
        linear_base=buf[5]&0xffffff00;
1250
        mmio_base  =buf[4]&0xffffff00;
1251
        __svgalib_mmio_base = mmio_base;
1252
        __svgalib_mmio_size = 0x10000;
1253
        map_mmio();
1254
 
1255
        __svgalib_vgammbase=0x8000;
1256
        __svgalib_mm_io_mapio();
1257
        unlock();
1258
 
1259
        config1=__svgalib_incrtc(0x36);
1260
        if(chipset >= SAVAGE4) {
1261
            memory=mems[config1>>5]*1024;
1262
        } else {
1263
            switch(config1>>6) {
1264
                case 0:
1265
                    memory=8192;
1266
                    break;
1267
                case 0x40:
1268
                case 0x80:
1269
                    memory=4096;
1270
                    break;
1271
                case 0xC0:
1272
                    memory=2048;
1273
                    break;
1274
            }
1275
        }
1276
    }
1277
 
1278
    if (__svgalib_driver_report) {
1279
        printk(KERN_INFO "Using SAVAGE driver, %iKB. Chipset: %s\n",memory, chipnames[chipset]);
1280
    };
1281
    cardspecs = malloc(sizeof(CardSpecs));
1282
    cardspecs->videoMemory = memory;
1283
    cardspecs->maxPixelClock4bpp = 0;  
1284
    cardspecs->maxPixelClock8bpp = 250000;     
1285
    cardspecs->maxPixelClock16bpp = 250000;    
1286
    cardspecs->maxPixelClock24bpp = 220000;
1287
    cardspecs->maxPixelClock32bpp = 220000;
1288
    cardspecs->flags = INTERLACE_DIVIDE_VERT | CLOCK_PROGRAMMABLE;
1289
    cardspecs->maxHorizontalCrtc = 4088;
1290
    cardspecs->nClocks = 0;
1291
    cardspecs->mapClock = map_clock;
1292
    cardspecs->mapHorizontalCrtc = map_horizontal_crtc;
1293
    cardspecs->matchProgrammableClock=match_programmable_clock;
1294
    __svgalib_driverspecs = &__svgalib_savage_driverspecs;
1295
    __svgalib_banked_mem_base=0xa0000;
1296
    __svgalib_banked_mem_size=0x10000;
1297
    __svgalib_linear_mem_base=linear_base;
1298
    __svgalib_linear_mem_size=memory*0x400;
1299
 
1300
    sleep(4);
1301
 
1302
    return 0;
1303
 
1304
}