~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/hw/xfree86/drivers/s3/s3_driver.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 *      Copyright 2001  Ani Joshi <ajoshi@unixbox.com>
 
3
 *
 
4
 *      XFree86 4.x driver for S3 chipsets
 
5
 *
 
6
 *
 
7
 * Permission to use, copy, modify, distribute, and sell this software and its
 
8
 * documentation for any purpose is hereby granted without fee, provided that
 
9
 * the above copyright notice appear in all copies and that both that copyright
 
10
 * notice and this permission notice appear in supporting documentation and
 
11
 * that the name of Ani Joshi not be used in advertising or
 
12
 * publicity pertaining to distribution of the software without specific,
 
13
 * written prior permission.  Ani Joshi makes no representations
 
14
 * about the suitability of this software for any purpose.  It is provided
 
15
 * "as-is" without express or implied warranty.
 
16
 *
 
17
 * ANI JOSHI DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
18
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 
19
 * EVENT SHALL ANI JOSHI BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
20
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 
21
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 
22
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 
23
 * PERFORMANCE OF THIS SOFTWARE.
 
24
 *
 
25
 *
 
26
 *      Credits:
 
27
 *              Thomas Roell <roell@informatik.tu-muenchen.de>
 
28
 *              Mark Vojkovich <markv@valinux.com>
 
29
 *              Kevin E. Martin <martin@valinux.com>
 
30
 *                 - and others for their work on the 3.x S3 driver
 
31
 *
 
32
 *              Dominik Behr
 
33
 *                 - for various hardware donations
 
34
 *
 
35
 *
 
36
 */
 
37
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3/s3_driver.c,v 1.12 2003/02/14 18:06:58 dawes Exp $ */
 
38
 
 
39
 
 
40
#include "xf86.h"
 
41
#include "xf86_OSproc.h"
 
42
#include "xf86_ansic.h"
 
43
#include "xf86Pci.h"
 
44
#include "xf86PciInfo.h"
 
45
#include "xf86Version.h"
 
46
#include "xf86Resources.h"
 
47
#include "xf86fbman.h"
 
48
#include "xf86cmap.h"
 
49
#include "xf86RAC.h"
 
50
#include "compiler.h"
 
51
#include "xaa.h"
 
52
#include "mipointer.h"
 
53
#include "micmap.h"
 
54
#include "mibstore.h"
 
55
#include "fb.h"
 
56
 
 
57
#include "IBM.h"
 
58
#include "TI.h"
 
59
 
 
60
#include "s3.h"
 
61
#include "s3_reg.h"
 
62
 
 
63
#define TRIO64_RAMDAC   0x8811
 
64
 
 
65
 
 
66
short s3alu[16] =
 
67
{
 
68
        MIX_0,
 
69
        MIX_AND,
 
70
        MIX_SRC_AND_NOT_DST,
 
71
        MIX_SRC,
 
72
        MIX_NOT_SRC_AND_DST,
 
73
        MIX_DST,
 
74
        MIX_XOR,
 
75
        MIX_OR,
 
76
        MIX_NOR,
 
77
        MIX_XNOR,
 
78
        MIX_NOT_DST,
 
79
        MIX_SRC_OR_NOT_DST,
 
80
        MIX_NOT_SRC,
 
81
        MIX_NOT_SRC_OR_DST,
 
82
        MIX_NAND,
 
83
        MIX_1,
 
84
};
 
85
 
 
86
 
 
87
/*
 
88
 * Prototypes
 
89
 */
 
90
static const OptionInfoRec * S3AvailableOptions(int chipid, int busid);
 
91
static void S3Identify(int flags);
 
92
static Bool S3Probe(DriverPtr drv, int flags);
 
93
static Bool S3PreInit(ScrnInfoPtr pScrn, int flags);
 
94
static Bool S3EnterVT(int scrnIndex, int flags);
 
95
static void S3LeaveVT(int scrnIndex, int flags);
 
96
static void S3Save(ScrnInfoPtr pScrn);
 
97
static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
 
98
                         char **argv);
 
99
static Bool S3MapMem(ScrnInfoPtr pScrn);
 
100
static void S3UnmapMem(ScrnInfoPtr pScrn);
 
101
static Bool S3ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode);
 
102
static void S3AdjustFrame(int scrnIndex, int x, int y, int flags);
 
103
Bool S3CloseScreen(int scrnIndex, ScreenPtr pScreen);
 
104
Bool S3SaveScreen(ScreenPtr pScreen, int mode);
 
105
static void S3FreeScreen(int scrnIndex, int flags);
 
106
static void S3GenericLoadPalette(ScrnInfoPtr pScrn, int numColors,
 
107
                                 int *indicies, LOCO *colors,
 
108
                                 VisualPtr pVisual);
 
109
static void S3Restore(ScrnInfoPtr pScrn);
 
110
void S3BankZero(ScrnInfoPtr pScrn);
 
111
void S3Regdump(ScrnInfoPtr pScrn);
 
112
static void S3DisplayPowerManagementSet(ScrnInfoPtr pScrn,
 
113
                                        int PowerManagementMode, int flags);
 
114
 
 
115
 
 
116
 
 
117
DriverRec S3 =
 
118
{
 
119
        S3_VERSION,
 
120
        DRIVER_NAME,
 
121
        S3Identify,
 
122
        S3Probe,
 
123
        S3AvailableOptions,
 
124
        NULL,
 
125
        0
 
126
};
 
127
 
 
128
/* supported chipsets */
 
129
static SymTabRec S3Chipsets[] = {
 
130
        { PCI_CHIP_964_0,       "964-0"},
 
131
        { PCI_CHIP_964_1,       "964-1"},
 
132
        { PCI_CHIP_968,         "968" },
 
133
        { PCI_CHIP_TRIO,        "Trio32/64" },
 
134
        { PCI_CHIP_AURORA64VP,  "Aurora64V+" },
 
135
        { -1, NULL }
 
136
};
 
137
 
 
138
 
 
139
static PciChipsets S3PciChipsets[] = {
 
140
        { PCI_CHIP_964_0,       PCI_CHIP_964_0,         RES_SHARED_VGA },
 
141
        { PCI_CHIP_964_1,       PCI_CHIP_964_1,         RES_SHARED_VGA },
 
142
        { PCI_CHIP_968,         PCI_CHIP_968,           RES_SHARED_VGA },
 
143
        { PCI_CHIP_TRIO,        PCI_CHIP_TRIO,          RES_SHARED_VGA },
 
144
        { PCI_CHIP_AURORA64VP,  PCI_CHIP_AURORA64VP,    RES_SHARED_VGA },
 
145
        { -1,                   -1,                     RES_UNDEFINED }
 
146
};
 
147
 
 
148
typedef enum {
 
149
        OPTION_NOACCEL,
 
150
        OPTION_SWCURS,
 
151
        OPTION_SLOW_DRAM_REFRESH,
 
152
        OPTION_SLOW_DRAM,
 
153
        OPTION_SLOW_EDODRAM,
 
154
        OPTION_SLOW_VRAM
 
155
} S3Opts;
 
156
 
 
157
static OptionInfoRec S3Options[] = {
 
158
        { OPTION_NOACCEL, "noaccel", OPTV_BOOLEAN, {0}, FALSE },
 
159
        { OPTION_SWCURS, "swcursor", OPTV_BOOLEAN, {0}, FALSE },
 
160
        { OPTION_SLOW_DRAM_REFRESH, "slow_dram_refresh", OPTV_BOOLEAN, {0}, FALSE },
 
161
        { OPTION_SLOW_DRAM, "slow_dram", OPTV_BOOLEAN, {0}, FALSE },
 
162
        { OPTION_SLOW_EDODRAM, "slow_edodram", OPTV_BOOLEAN, {0}, FALSE },
 
163
        { OPTION_SLOW_VRAM, "slow_vram", OPTV_BOOLEAN, {0}, FALSE },
 
164
        { -1, NULL, OPTV_NONE, {0}, FALSE }
 
165
};
 
166
 
 
167
RamDacSupportedInfoRec S3IBMRamdacs[] = {
 
168
        { IBM524_RAMDAC },
 
169
        { IBM524A_RAMDAC },
 
170
        { -1 }
 
171
};
 
172
 
 
173
#define S3_USEFB
 
174
 
 
175
#ifdef S3_USEFB
 
176
static const char *fbSymbols[] = {
 
177
    "fbPictureInit",
 
178
    "fbScreenInit",
 
179
    NULL
 
180
};
 
181
#else
 
182
static const char *cfbSymbols[] = {
 
183
        "cfbScreenInit",
 
184
        "cfb16ScreenInit",
 
185
        "cfb24ScreenInit",
 
186
        "cfb32ScreenInit",
 
187
        NULL
 
188
};
 
189
#endif
 
190
 
 
191
static const char *vgaHWSymbols[] = {
 
192
        "vgaHWGetHWRec",
 
193
        "vgaHWFreeHWRec",
 
194
        "vgaHWGetIOBase",
 
195
        "vgaHWSave",
 
196
        "vgaHWProtect",
 
197
        "vgaHWRestore",
 
198
        "vgaHWMapMem",
 
199
        "vgaHWUnmapMem",
 
200
        "vgaHWSaveScreen",
 
201
        "vgaHWLock",
 
202
        "vgaHWInit",
 
203
        "vgaHWDPMSSet",
 
204
        NULL
 
205
};
 
206
 
 
207
static const char *vbeSymbols[] = {
 
208
        "VBEInit",
 
209
        "vbeDoEDID",
 
210
        "vbeFree",
 
211
        NULL
 
212
};
 
213
 
 
214
static const char *int10Symbols[] = {
 
215
        "xf86ExecX86int10",
 
216
        "xf86FreeInt10",
 
217
        "xf86InitInt10",
 
218
        "xf86Int10AllocPages",
 
219
        "xf86Int10FreePages",
 
220
        NULL
 
221
};
 
222
 
 
223
static const char *ramdacSymbols[] = {
 
224
        "xf86InitCursor",
 
225
        "xf86CreateCursorInfoRec",
 
226
        "RamDacInit",
 
227
        "RamDacCreateInfoRec",
 
228
        "RamDacDestroyInfoRec",
 
229
        "RamDacHelperCreateInfoRec",
 
230
        "RamDacGetHWIndex",
 
231
        "IBMramdacProbe",
 
232
        "IBMramdac526CalculateMNPCForClock",
 
233
        "IBMramdac526SetBpp",
 
234
        NULL
 
235
};
 
236
 
 
237
static const char *xaaSymbols[] = {
 
238
        "XAADestroyInfoRec",
 
239
        "XAACreateInfoRec",
 
240
        "XAAInit",
 
241
        NULL
 
242
};
 
243
 
 
244
 
 
245
#ifdef XFree86LOADER
 
246
 
 
247
MODULESETUPPROTO(S3Setup);
 
248
 
 
249
static XF86ModuleVersionInfo S3VersRec = {
 
250
        "s3",
 
251
        MODULEVENDORSTRING,
 
252
        MODINFOSTRING1,
 
253
        MODINFOSTRING2,
 
254
        XF86_VERSION_CURRENT,
 
255
        VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL,
 
256
        ABI_CLASS_VIDEODRV,
 
257
        ABI_VIDEODRV_VERSION,
 
258
        MOD_CLASS_VIDEODRV,
 
259
        {0, 0, 0, 0}
 
260
};
 
261
 
 
262
 
 
263
XF86ModuleData s3ModuleData = { &S3VersRec, S3Setup, NULL };
 
264
 
 
265
pointer S3Setup (pointer module, pointer opts, int *errmaj, int *errmin)
 
266
{
 
267
        static Bool setupDone = FALSE;
 
268
 
 
269
        if (!setupDone) {  
 
270
                setupDone = TRUE;
 
271
                xf86AddDriver(&S3, module, 0);
 
272
                LoaderRefSymLists(vgaHWSymbols,
 
273
                                  vbeSymbols, int10Symbols, ramdacSymbols,
 
274
#ifdef S3_USEFB
 
275
                                  fbSymbols,
 
276
#else
 
277
                                  cfbSymbols,
 
278
#endif
 
279
                                  xaaSymbols,
 
280
                                  NULL);
 
281
                return (pointer) 1;
 
282
        } else {
 
283
                if (errmaj)  
 
284
                        *errmaj = LDR_ONCEONLY;
 
285
                return NULL;
 
286
        }
 
287
}               
 
288
 
 
289
#endif /* XFree86LOADER */
 
290
 
 
291
 
 
292
static Bool S3GetRec(ScrnInfoPtr pScrn)
 
293
{       
 
294
        if (pScrn->driverPrivate)
 
295
                return TRUE;
 
296
                
 
297
        pScrn->driverPrivate = xnfcalloc(sizeof(S3Rec), 1);
 
298
                
 
299
        return TRUE;
 
300
}
 
301
                        
 
302
static void S3FreeRec(ScrnInfoPtr pScrn)
 
303
{
 
304
        if (!pScrn->driverPrivate)
 
305
                return;
 
306
 
 
307
        xfree(pScrn->driverPrivate);
 
308
        pScrn->driverPrivate = NULL;
 
309
}
 
310
 
 
311
static const OptionInfoRec * S3AvailableOptions(int chipid, int busid)
 
312
{
 
313
        return S3Options;
 
314
}
 
315
                
 
316
static void S3Identify(int flags)
 
317
{
 
318
        xf86PrintChipsets("S3", "driver (version " DRIVER_VERSION " for S3 chipset",
 
319
                          S3Chipsets);  
 
320
}
 
321
 
 
322
static Bool S3Probe(DriverPtr drv, int flags)
 
323
{
 
324
        GDevPtr *devSections;
 
325
        int i, *usedChips, numDevSections, numUsed;
 
326
        Bool foundScreen = FALSE;
 
327
 
 
328
        /* sanity check */
 
329
        if ((numDevSections = xf86MatchDevice("s3", &devSections)) <= 0)
 
330
                return FALSE;
 
331
 
 
332
        /* XXX do ISA later...  some day in the distant future... */
 
333
        numUsed = xf86MatchPciInstances("s3", PCI_VENDOR_S3,
 
334
                                        S3Chipsets, S3PciChipsets,
 
335
                                        devSections, numDevSections,
 
336
                                        drv, &usedChips);
 
337
 
 
338
        xfree(devSections);
 
339
 
 
340
        if (numUsed <= 0)
 
341
                return FALSE;
 
342
 
 
343
        if (flags & PROBE_DETECT)
 
344
                foundScreen = TRUE;
 
345
        else for (i=0; i<numUsed; i++) {
 
346
                ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0);
 
347
 
 
348
                pScrn->driverVersion = VERSION_MAJOR;
 
349
                pScrn->driverName = DRIVER_NAME;
 
350
                pScrn->name = "s3";
 
351
                pScrn->Probe = S3Probe;
 
352
                pScrn->PreInit = S3PreInit;
 
353
                pScrn->ScreenInit = S3ScreenInit;  
 
354
                pScrn->SwitchMode = S3SwitchMode;
 
355
                pScrn->AdjustFrame = S3AdjustFrame;
 
356
                pScrn->EnterVT = S3EnterVT;
 
357
                pScrn->LeaveVT = S3LeaveVT;
 
358
                pScrn->FreeScreen = S3FreeScreen;
 
359
 
 
360
                foundScreen = TRUE;
 
361
 
 
362
                xf86ConfigActivePciEntity(pScrn, usedChips[i], S3PciChipsets,
 
363
                                          NULL, NULL, NULL, NULL, NULL);
 
364
        }
 
365
                
 
366
        xfree(usedChips);
 
367
                
 
368
        return foundScreen;
 
369
}
 
370
 
 
371
static Bool S3PreInit(ScrnInfoPtr pScrn, int flags)
 
372
{
 
373
        EntityInfoPtr pEnt;
 
374
        S3Ptr pS3;
 
375
        vgaHWPtr hwp;
 
376
        ClockRangePtr clockRanges;
 
377
        rgb zeros = {0, 0, 0};
 
378
        Gamma gzeros = {0.0, 0.0, 0.0};
 
379
        int i, vgaCRIndex, vgaCRReg;
 
380
        unsigned char tmp;
 
381
 
 
382
        if (flags & PROBE_DETECT)
 
383
                return FALSE;
 
384
        
 
385
        if (!xf86LoadSubModule(pScrn, "vgahw"))
 
386
                return FALSE;
 
387
        
 
388
        xf86LoaderReqSymLists(vgaHWSymbols, NULL);  
 
389
 
 
390
        if (!vgaHWGetHWRec(pScrn))
 
391
                return FALSE;
 
392
        
 
393
        hwp = VGAHWPTR(pScrn);
 
394
        vgaHWGetIOBase(hwp);
 
395
        
 
396
        pScrn->monitor = pScrn->confScreen->monitor;
 
397
        
 
398
        if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb))
 
399
                return FALSE;
 
400
 
 
401
        switch (pScrn->depth) {
 
402
                case 8:
 
403
                case 15:
 
404
                case 16:
 
405
                case 24:
 
406
                case 32:
 
407
                       /* OK */
 
408
                       break;
 
409
                default:
 
410
                       xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
411
                                  "Given depth (%d) is not  supported by this driver\n",
 
412
                                   pScrn->depth);
 
413
                               return FALSE;
 
414
        }
 
415
 
 
416
        xf86PrintDepthBpp(pScrn);
 
417
        
 
418
        if (pScrn->depth > 8) {
 
419
                if (!xf86SetWeight(pScrn, zeros, zeros))
 
420
                        return FALSE;
 
421
        }
 
422
 
 
423
        if (!xf86SetDefaultVisual(pScrn, -1))
 
424
                return FALSE;
 
425
                                           
 
426
        pScrn->progClock = TRUE;
 
427
                 
 
428
        if (!S3GetRec(pScrn))
 
429
                return FALSE;
 
430
 
 
431
        pS3 = S3PTR(pScrn);
 
432
 
 
433
        pS3->s3Bpp = (pScrn->bitsPerPixel >> 3);
 
434
 
 
435
        xf86CollectOptions(pScrn, NULL);
 
436
        xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, S3Options);
 
437
         
 
438
        if (xf86ReturnOptValBool(S3Options, OPTION_NOACCEL, FALSE)) {
 
439
                pS3->NoAccel = TRUE;
 
440
                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - acceleration disabled\n");
 
441
        } else          
 
442
                pS3->NoAccel = FALSE;
 
443
        if (xf86ReturnOptValBool(S3Options, OPTION_SWCURS, FALSE)) {
 
444
                pS3->SWCursor = TRUE;
 
445
                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: SWCursor - using software cursor\n");
 
446
        } else
 
447
                pS3->SWCursor = FALSE;
 
448
        if (xf86ReturnOptValBool(S3Options, OPTION_SLOW_DRAM_REFRESH, FALSE)) {
 
449
                pS3->SlowDRAMRefresh = TRUE;
 
450
                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Slow DRAM Refresh enabled\n");
 
451
        } else
 
452
                pS3->SlowDRAMRefresh = FALSE;
 
453
        if (xf86ReturnOptValBool(S3Options, OPTION_SLOW_DRAM, FALSE)) {
 
454
                pS3->SlowDRAM = TRUE;
 
455
                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Slow DRAM enabled\n");
 
456
        } else
 
457
                pS3->SlowDRAM = FALSE;
 
458
        if (xf86ReturnOptValBool(S3Options, OPTION_SLOW_EDODRAM, FALSE)) {
 
459
                pS3->SlowEDODRAM = TRUE;
 
460
                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Slow EDO DRAM enabled\n");
 
461
        } else
 
462
                pS3->SlowEDODRAM = FALSE;
 
463
        if (xf86ReturnOptValBool(S3Options, OPTION_SLOW_DRAM, FALSE)) {
 
464
                pS3->SlowVRAM = TRUE;
 
465
                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: Slow VRAM enabled\n");
 
466
        } else
 
467
                pS3->SlowVRAM = FALSE;
 
468
 
 
469
        if (pScrn->numEntities > 1) {      
 
470
                S3FreeRec(pScrn);
 
471
                return FALSE;
 
472
        }
 
473
                
 
474
        pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
 
475
        if (pEnt->resources) {
 
476
                xfree(pEnt);
 
477
                S3FreeRec(pScrn);
 
478
                return FALSE;
 
479
        }
 
480
 
 
481
        if (xf86LoadSubModule(pScrn, "int10")) {
 
482
                xf86LoaderReqSymLists(int10Symbols, NULL);
 
483
                pS3->pInt10 = xf86InitInt10(pEnt->index);
 
484
        }
 
485
 
 
486
        if (xf86LoadSubModule(pScrn, "vbe")) {
 
487
                xf86LoaderReqSymLists(vbeSymbols, NULL);
 
488
                pS3->pVBE = VBEInit(pS3->pInt10, pEnt->index);
 
489
        }
 
490
        
 
491
        if (!xf86SetGamma(pScrn, gzeros))
 
492
                return FALSE;
 
493
 
 
494
        pS3->PciInfo = xf86GetPciInfoForEntity(pEnt->index);
 
495
        xf86RegisterResources(pEnt->index, NULL, ResNone);
 
496
        /* don't disable PIO funcs */
 
497
        xf86SetOperatingState(resVgaMemShared, pEnt->index, ResDisableOpr);
 
498
 
 
499
        if (pEnt->device->chipset && *pEnt->device->chipset) {
 
500
                pScrn->chipset = pEnt->device->chipset;
 
501
                pS3->Chipset = xf86StringToToken(S3Chipsets, pScrn->chipset);
 
502
        } else if (pEnt->device->chipID >= 0) {            
 
503
                pS3->Chipset = pEnt->device->chipID;
 
504
                pScrn->chipset = (char *)xf86TokenToString(S3Chipsets,
 
505
                                                           pS3->Chipset);
 
506
                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
 
507
                           pS3->Chipset);
 
508
        } else {
 
509
                pS3->Chipset = pS3->PciInfo->chipType;   
 
510
                pScrn->chipset = (char *)xf86TokenToString(S3Chipsets,
 
511
                                                           pS3->Chipset);
 
512
        }                                                  
 
513
        if (pEnt->device->chipRev >= 0) {
 
514
                pS3->ChipRev = pEnt->device->chipRev;
 
515
                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
 
516
                           pS3->ChipRev);
 
517
        } else
 
518
                pS3->ChipRev = pS3->PciInfo->chipRev;    
 
519
        
 
520
        xfree(pEnt);
 
521
        
 
522
        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Chipset: \"%s\"\n", pScrn->chipset);
 
523
        
 
524
        pS3->PciTag = pciTag(pS3->PciInfo->bus, pS3->PciInfo->device,
 
525
                             pS3->PciInfo->func);        
 
526
 
 
527
        switch (pS3->Chipset) {
 
528
        case PCI_CHIP_964_0:
 
529
        case PCI_CHIP_964_1:
 
530
        case PCI_CHIP_TRIO:
 
531
        case PCI_CHIP_AURORA64VP:               /* ??? */
 
532
                pS3->S3NewMMIO = FALSE;
 
533
                break;
 
534
        case PCI_CHIP_968:
 
535
                pS3->S3NewMMIO = TRUE;
 
536
                break;
 
537
        }
 
538
 
 
539
        pS3->FBAddress = pS3->PciInfo->memBase[0];
 
540
        if (pS3->S3NewMMIO)
 
541
                pS3->IOAddress = pS3->FBAddress + S3_NEWMMIO_REGBASE;
 
542
 
 
543
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Framebuffer @ 0x%x\n",
 
544
                   pS3->FBAddress);
 
545
        if (pS3->S3NewMMIO)
 
546
                xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MMIO @ 0x%x\n",
 
547
                           pS3->IOAddress);
 
548
 
 
549
        pS3->PCIRetry = FALSE;          /* not supported yet */
 
550
 
 
551
        pS3->vgaCRIndex = vgaCRIndex = hwp->IOBase + 4;
 
552
        pS3->vgaCRReg = vgaCRReg = hwp->IOBase + 5;
 
553
 
 
554
        /* unlock sys regs */
 
555
        outb(vgaCRIndex, 0x38);
 
556
        outb(vgaCRReg, 0x48);
 
557
        outb(vgaCRIndex, 0x39);
 
558
        outb(vgaCRReg, 0xa5);
 
559
 
 
560
        outb(vgaCRIndex, 0x40);
 
561
        tmp = inb(vgaCRReg) | 0x01;
 
562
        outb(vgaCRReg, tmp);
 
563
        outb(vgaCRIndex, 0x35);
 
564
        tmp = inb(vgaCRReg) & ~0x30;
 
565
        outb(vgaCRReg, tmp);
 
566
 
 
567
        outb(0x3c4, 0x08);
 
568
        outb(0x3c5, 0x06);
 
569
        outb(vgaCRIndex, 0x33);
 
570
        tmp = (inb(vgaCRReg) & ~(0x2 | 0x10 | 0x40)) | 0x20;
 
571
        outb(vgaCRReg, tmp);
 
572
 
 
573
        /* unprotect CRTC[0-7] */
 
574
        outb(vgaCRIndex, 0x11);
 
575
        tmp = inb(vgaCRReg) & 0x7f;
 
576
        outb(vgaCRReg, tmp);
 
577
 
 
578
        /* wake up */
 
579
        outb(0x46e8, 0x10);
 
580
        outb(0x102, 0x01);
 
581
        outb(0x46e8, 0x08);
 
582
 
 
583
        if (!pScrn->videoRam) {
 
584
                /* probe videoram */
 
585
                outb(vgaCRIndex, 0x36);
 
586
                tmp = inb(vgaCRReg);
 
587
 
 
588
                switch ((tmp & 0xe0) >> 5) {
 
589
                case 0:
 
590
                        pScrn->videoRam = 4096;
 
591
                        break;
 
592
                case 2:
 
593
                        pScrn->videoRam = 3072;
 
594
                        break;
 
595
                case 3:
 
596
                        pScrn->videoRam = 8192;
 
597
                        break;
 
598
                case 4:
 
599
                        pScrn->videoRam = 2048;
 
600
                        break;
 
601
                case 5:
 
602
                        pScrn->videoRam = 6144;
 
603
                        break;
 
604
                case 6:
 
605
                        pScrn->videoRam = 1024;
 
606
                        break;
 
607
                }
 
608
                xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
 
609
                           "videoRam = %d Kb\n", pScrn->videoRam);
 
610
        } else {
 
611
                xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
 
612
                           "videoRam = %d Kb\n", pScrn->videoRam);
 
613
        }
 
614
 
 
615
        if (!xf86LoadSubModule(pScrn, "ramdac"))
 
616
                return FALSE;
 
617
        xf86LoaderReqSymLists(ramdacSymbols, NULL);
 
618
 
 
619
        pScrn->rgbBits = 8;     /* set default */
 
620
 
 
621
        /* probe for dac */
 
622
        if (S3TiDACProbe(pScrn)) {
 
623
                pS3->DacPreInit = S3TiDAC_PreInit;
 
624
                pS3->DacInit = S3TiDAC_Init;
 
625
                pS3->DacSave = S3TiDAC_Save;
 
626
                pS3->DacRestore = S3TiDAC_Restore;
 
627
#if 0
 
628
                /* FIXME, cursor is drawn in wrong position */
 
629
                pS3->CursorInit = S3Ti_CursorInit;
 
630
#endif
 
631
                pS3->MaxClock = 135000;
 
632
                pScrn->rgbBits = 8;
 
633
                if (pScrn->bitsPerPixel > 8)
 
634
                        pS3->LoadPalette = S3TiLoadPalette;
 
635
                else
 
636
                        pS3->LoadPalette = S3GenericLoadPalette;
 
637
        }
 
638
        if (S3ProbeIBMramdac(pScrn)) {
 
639
                pS3->DacPreInit = S3IBMRGB_PreInit;
 
640
                pS3->DacInit = S3IBMRGB_Init;
 
641
                pS3->DacSave = S3IBMRGB_Save;
 
642
                pS3->DacRestore = S3IBMRGB_Restore;
 
643
                pS3->CursorInit = S3IBMRGB_CursorInit;
 
644
                pS3->RamDac->SetBpp = IBMramdac526SetBpp;
 
645
                pS3->MaxClock = 170000;
 
646
                pScrn->rgbBits = 8;
 
647
                pS3->LoadPalette = S3GenericLoadPalette;
 
648
        }
 
649
        if (S3Trio64DACProbe(pScrn)) {
 
650
                pS3->DacPreInit = S3Trio64DAC_PreInit;
 
651
                pS3->DacInit = S3Trio64DAC_Init;
 
652
                pS3->DacSave = S3Trio64DAC_Save;
 
653
                pS3->DacRestore = S3Trio64DAC_Restore;
 
654
#if 0
 
655
                pS3->CursorInit = S3_CursorInit;        /* FIXME broken */
 
656
#endif
 
657
                switch(pScrn->bitsPerPixel) {
 
658
                case 8:
 
659
                        pS3->MaxClock = 135000;
 
660
                        break;
 
661
                case 16:
 
662
                        pS3->MaxClock = 80000;
 
663
                        break;
 
664
                case 24:
 
665
                case 32:
 
666
                        pS3->MaxClock = 50000;
 
667
                        break;
 
668
                }
 
669
                pScrn->rgbBits = 6;
 
670
                pS3->LoadPalette = S3GenericLoadPalette;
 
671
        }
 
672
 
 
673
        if (pS3->RamDac == NULL) {
 
674
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
675
                           "Ramdac probe failed\n");
 
676
                return FALSE;
 
677
        }
 
678
 
 
679
        if (pS3->SWCursor)
 
680
                pS3->CursorInit = NULL;
 
681
 
 
682
        pS3->RefClock = S3GetRefClock(pScrn);
 
683
 
 
684
        if (pS3->DacPreInit)
 
685
                pS3->DacPreInit(pScrn);
 
686
 
 
687
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RefClock: %d\n",
 
688
                   pS3->RefClock);
 
689
        xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Max pixel clock at this depth is %d Mhz\n",
 
690
                   pS3->MaxClock / 1000);
 
691
 
 
692
        clockRanges = xnfcalloc(sizeof(ClockRange), 1);
 
693
        clockRanges->next = NULL;
 
694
        clockRanges->minClock = 16000;  /* guess */
 
695
        clockRanges->maxClock = pS3->MaxClock;
 
696
        clockRanges->clockIndex = -1;
 
697
        clockRanges->interlaceAllowed = FALSE;  /* not yet */
 
698
        clockRanges->doubleScanAllowed = FALSE; /* not yet */
 
699
 
 
700
        i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
 
701
                              pScrn->display->modes, clockRanges,
 
702
                              NULL, 256, 2048, pScrn->bitsPerPixel,
 
703
                              128, 2048, pScrn->display->virtualX,
 
704
                              pScrn->display->virtualY, pScrn->videoRam * 1024,
 
705
                              LOOKUP_BEST_REFRESH);
 
706
 
 
707
        if (i == -1) {
 
708
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes left\n");
 
709
                S3FreeRec(pScrn);
 
710
                return FALSE; 
 
711
        }
 
712
        
 
713
        xf86PruneDriverModes(pScrn);
 
714
 
 
715
        if (i == 0 || pScrn->modes == NULL) {
 
716
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes found\n");
 
717
                S3FreeRec(pScrn);
 
718
                return FALSE;
 
719
        }
 
720
 
 
721
        xf86SetCrtcForModes(pScrn, 0);
 
722
        pScrn->currentMode = pScrn->modes;
 
723
        xf86PrintModes(pScrn);
 
724
        xf86SetDpi(pScrn, 0, 0);
 
725
 
 
726
#ifdef S3_USEFB
 
727
        xf86LoadSubModule(pScrn, "fb");
 
728
        xf86LoaderReqSymbols("fbScreenInit", NULL);
 
729
#else
 
730
        {
 
731
                switch (pScrn->bitsPerPixel) {
 
732
                case 8:
 
733
                        xf86LoadSubModule(pScrn, "cfb");
 
734
                        xf86LoaderReqSymbols("cfbScreenInit", NULL);
 
735
                        break;
 
736
                case 16:
 
737
                        xf86LoadSubModule(pScrn, "cfb16");
 
738
                        xf86LoaderReqSymbols("cfb16ScreenInit", NULL);
 
739
                        break;
 
740
                case 24:
 
741
                        xf86LoadSubModule(pScrn, "cfb24");
 
742
                        xf86LoaderReqSymbols("cfb24ScreenInit", NULL);
 
743
                        break;
 
744
                case 32:
 
745
                        xf86LoadSubModule(pScrn, "cfb32");
 
746
                        xf86LoaderReqSymbols("cfb32ScreenInit", NULL);
 
747
                        break;
 
748
                }
 
749
        }
 
750
#endif
 
751
 
 
752
        if (!xf86LoadSubModule(pScrn, "xaa"))
 
753
                return FALSE;
 
754
        xf86LoaderReqSymLists(xaaSymbols, NULL);
 
755
 
 
756
        return TRUE;
 
757
}
 
758
 
 
759
 
 
760
static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
 
761
                         char **argv)
 
762
{
 
763
        ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
 
764
        S3Ptr pS3 = S3PTR(pScrn);
 
765
 
 
766
        pScrn->fbOffset = 0;
 
767
 
 
768
        if (!S3MapMem(pScrn)) {
 
769
                S3FreeRec(pScrn);
 
770
                return FALSE;
 
771
        }
 
772
 
 
773
        S3Save(pScrn);
 
774
 
 
775
        vgaHWBlankScreen(pScrn, TRUE);
 
776
 
 
777
        if (!S3ModeInit(pScrn, pScrn->currentMode))
 
778
                return FALSE;
 
779
#if 0
 
780
        S3Regdump(pScrn);
 
781
#endif
 
782
        pScrn->vtSema = TRUE;
 
783
        
 
784
        S3SaveScreen(pScreen, SCREEN_SAVER_ON);
 
785
 
 
786
        miClearVisualTypes();
 
787
        if (pScrn->bitsPerPixel > 8) {
 
788
                if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
 
789
                                      pScrn->rgbBits, pScrn->defaultVisual))
 
790
                        return FALSE;
 
791
        } else {
 
792
                if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
 
793
                                      pScrn->rgbBits, pScrn->defaultVisual))
 
794
                        return FALSE; 
 
795
        }       
 
796
        
 
797
        miSetPixmapDepths ();
 
798
 
 
799
#ifdef S3_USEFB
 
800
        if (!fbScreenInit(pScreen, pS3->FBBase, pScrn->virtualX,
 
801
                          pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
 
802
                          pScrn->displayWidth, pScrn->bitsPerPixel))
 
803
                return FALSE;
 
804
#else
 
805
        {
 
806
                int ret;
 
807
 
 
808
                switch(pScrn->bitsPerPixel) {
 
809
                case 8:
 
810
                        ret = cfbScreenInit(pScreen, pS3->FBBase,
 
811
                                pScrn->virtualX, pScrn->virtualY,
 
812
                                pScrn->xDpi, pScrn->yDpi,
 
813
                                pScrn->displayWidth);
 
814
                        break;
 
815
                case 16:
 
816
                        ret = cfb16ScreenInit(pScreen, pS3->FBBase,
 
817
                                pScrn->virtualX, pScrn->virtualY,
 
818
                                pScrn->xDpi, pScrn->yDpi,
 
819
                                pScrn->displayWidth);
 
820
                        break;
 
821
                case 24:
 
822
                        ret = cfb24ScreenInit(pScreen, pS3->FBBase,
 
823
                                pScrn->virtualX, pScrn->virtualY,
 
824
                                pScrn->xDpi, pScrn->yDpi,
 
825
                                pScrn->displayWidth);
 
826
                        break;
 
827
                case 32:
 
828
                        ret = cfb32ScreenInit(pScreen, pS3->FBBase,
 
829
                                pScrn->virtualX, pScrn->virtualY,
 
830
                                pScrn->xDpi, pScrn->yDpi,
 
831
                                pScrn->displayWidth);
 
832
                        break;
 
833
                }
 
834
                if (!ret)
 
835
                        return FALSE;
 
836
        }
 
837
#endif
 
838
        
 
839
        xf86SetBlackWhitePixels(pScreen);
 
840
                        
 
841
        if (pScrn->bitsPerPixel > 8) {
 
842
                VisualPtr pVis;
 
843
                         
 
844
                pVis = pScreen->visuals + pScreen->numVisuals;
 
845
                while (--pVis >= pScreen->visuals) {
 
846
                        if ((pVis->class | DynamicClass) == DirectColor) {
 
847
                                pVis->offsetRed = pScrn->offset.red;
 
848
                                pVis->offsetGreen = pScrn->offset.green;
 
849
                                pVis->offsetBlue = pScrn->offset.blue;
 
850
                                pVis->redMask = pScrn->mask.red;
 
851
                                pVis->greenMask = pScrn->mask.green;
 
852
                                pVis->blueMask = pScrn->mask.blue;
 
853
                        }
 
854
                } 
 
855
        }
 
856
#ifdef S3_USEFB
 
857
        fbPictureInit (pScreen, 0, 0);
 
858
#endif
 
859
        S3DGAInit(pScreen);
 
860
 
 
861
        miInitializeBackingStore(pScreen);
 
862
        xf86SetBackingStore(pScreen);
 
863
 
 
864
        if (!pS3->NoAccel) {
 
865
                if (pS3->S3NewMMIO) {
 
866
                        if (S3AccelInitNewMMIO(pScreen)) {
 
867
                                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration enabled\n");
 
868
                                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using NewMMIO\n");
 
869
                        } else {
 
870
                                xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Acceleration initialization failed\n");
 
871
                                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n");
 
872
                        }
 
873
                } else {
 
874
                        if (S3AccelInitPIO(pScreen)) {
 
875
                                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration enabled\n");
 
876
                                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using PIO\n");
 
877
                        } else {
 
878
                                xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Acceleration initialization failed\n");
 
879
                                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n");
 
880
                        }
 
881
                }
 
882
        } else {
 
883
                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled by option\n");
 
884
        }
 
885
 
 
886
        miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
 
887
 
 
888
        /* hw cursor setup */
 
889
        if (pS3->CursorInit) {
 
890
                if (pS3->CursorInit(pScreen))
 
891
                        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using HW cursor\n");
 
892
                else {
 
893
                        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "HW cursor initialization failed\n");
 
894
                        xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using SW cursor\n");
 
895
                }
 
896
        } else
 
897
                xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using SW cursor\n");
 
898
 
 
899
 
 
900
 
 
901
 
 
902
        if (!miCreateDefColormap(pScreen))
 
903
                return FALSE;
 
904
 
 
905
        if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,
 
906
                                 pS3->LoadPalette, NULL,
 
907
                                 CMAP_RELOAD_ON_MODE_SWITCH))
 
908
                return FALSE;
 
909
 
 
910
        vgaHWBlankScreen(pScrn, FALSE);
 
911
 
 
912
        pScreen->SaveScreen = S3SaveScreen;
 
913
        pS3->CloseScreen = pScreen->CloseScreen;
 
914
        pScreen->CloseScreen = S3CloseScreen;
 
915
 
 
916
        xf86DPMSInit(pScreen, S3DisplayPowerManagementSet, 0);
 
917
 
 
918
        /* XXX Check if I/O and Mem flags need to be the same. */
 
919
        pScrn->racIoFlags = pScrn->racMemFlags = RAC_COLORMAP
 
920
            | RAC_FB | RAC_VIEWPORT | RAC_CURSOR;
 
921
 
 
922
#if 0
 
923
        S3InitVideo(pScreen);
 
924
#endif
 
925
        
 
926
        return TRUE;
 
927
}                 
 
928
 
 
929
 
 
930
 
 
931
 
 
932
static void S3Save(ScrnInfoPtr pScrn)
 
933
{
 
934
        S3Ptr pS3 = S3PTR(pScrn);
 
935
        S3RegPtr save = &pS3->SavedRegs;
 
936
        vgaHWPtr hwp = VGAHWPTR(pScrn);
 
937
        vgaRegPtr pVga = &hwp->SavedReg;
 
938
        RamDacHWRecPtr pRAMDAC;
 
939
        RamDacRegRecPtr RAMDACreg;
 
940
        int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
 
941
        int i;
 
942
        unsigned char cr5c = 0;
 
943
 
 
944
        pRAMDAC = RAMDACHWPTR(pScrn);
 
945
        RAMDACreg = &pRAMDAC->SavedReg;
 
946
 
 
947
        S3BankZero(pScrn);
 
948
 
 
949
        save->clock = inb(0x3cc);
 
950
 
 
951
        vgaHWSave(pScrn, pVga, VGA_SR_ALL);
 
952
 
 
953
        if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
 
954
                outb(vgaCRIndex, 0x5c);
 
955
                cr5c = inb(vgaCRReg);
 
956
        }
 
957
 
 
958
        pS3->DacSave(pScrn);
 
959
 
 
960
        for(i=0; i<5; i++) {
 
961
                outb(vgaCRIndex, 0x30 + i);
 
962
                save->s3save[i] = inb(vgaCRReg);
 
963
                outb(vgaCRIndex, 0x38 + i);
 
964
                save->s3save[5 + i] = inb(vgaCRReg);
 
965
        }
 
966
 
 
967
        for (i=0; i<16; i++) {
 
968
                outb(vgaCRIndex, 0x40 + i);
 
969
                save->s3syssave[i] = inb(vgaCRReg);
 
970
        }
 
971
 
 
972
        outb(vgaCRIndex, 0x45);
 
973
        inb(vgaCRReg);
 
974
        outb(vgaCRIndex, 0x4a);
 
975
        for(i=0; i<4; i++) {
 
976
                save->color_stack[i] = inb(vgaCRReg);
 
977
                outb(vgaCRReg, save->color_stack[i]);
 
978
        }
 
979
 
 
980
        outb(vgaCRIndex, 0x45);
 
981
        inb(vgaCRReg);
 
982
        outb(vgaCRIndex, 0x4b);
 
983
        for(i=4; i<8; i++) {
 
984
                save->color_stack[i] = inb(vgaCRReg);
 
985
                outb(vgaCRReg, save->color_stack[i]);
 
986
        }
 
987
 
 
988
        for(i=0; i<16; i++) {
 
989
                for (i=0; i<16; i++) {
 
990
                        if (!((1 << i) & 0x673b))
 
991
                                continue;
 
992
                        outb(vgaCRIndex, 0x50 + i);
 
993
                        save->s3syssave[i + 16] = inb(vgaCRReg);
 
994
                }
 
995
        }
 
996
 
 
997
        if (pS3->RamDac->RamDacType == TI3025_RAMDAC)
 
998
                save->s3syssave[0x0c + 16] = cr5c;      
 
999
 
 
1000
        for(i=32; i<46; i++) {
 
1001
                outb(vgaCRIndex, 0x40 + i);
 
1002
                save->s3syssave[i] = inb(vgaCRReg);
 
1003
        }
 
1004
}
 
1005
 
 
1006
 
 
1007
Bool S3SaveScreen(ScreenPtr pScreen, int mode)
 
1008
{
 
1009
        return vgaHWSaveScreen(pScreen, mode);
 
1010
}
 
1011
 
 
1012
 
 
1013
static void S3FreeScreen(int scrnIndex, int flags)
 
1014
{
 
1015
        ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 
1016
                           
 
1017
        vgaHWFreeHWRec(pScrn);
 
1018
        
 
1019
        S3FreeRec(pScrn);
 
1020
}
 
1021
 
 
1022
 
 
1023
Bool S3CloseScreen(int scrnIndex, ScreenPtr pScreen)
 
1024
{
 
1025
        ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 
1026
        S3Ptr pS3 = S3PTR(pScrn);
 
1027
        vgaHWPtr hwp = VGAHWPTR(pScrn);
 
1028
 
 
1029
        if (pScrn->vtSema) {
 
1030
                vgaHWUnlock(hwp);
 
1031
                S3Restore(pScrn);
 
1032
                vgaHWLock(hwp);
 
1033
                S3UnmapMem(pScrn);
 
1034
        }
 
1035
 
 
1036
        if (pS3->DGAModes)
 
1037
                xfree(pS3->DGAModes);
 
1038
        pS3->DGAModes = NULL;
 
1039
 
 
1040
        pScrn->vtSema = FALSE;
 
1041
        pScreen->CloseScreen = pS3->CloseScreen;
 
1042
                
 
1043
        return (*pScreen->CloseScreen)(scrnIndex, pScreen);
 
1044
}
 
1045
 
 
1046
 
 
1047
Bool S3SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
 
1048
{    
 
1049
        return S3ModeInit(xf86Screens[scrnIndex], xf86Screens[scrnIndex]->currentMode);
 
1050
 
 
1051
}
 
1052
 
 
1053
 
 
1054
static void S3GenericLoadPalette(ScrnInfoPtr pScrn, int numColors,
 
1055
                                 int *indicies, LOCO *colors,
 
1056
                                 VisualPtr pVisual)
 
1057
{               
 
1058
        int i, index;
 
1059
        
 
1060
        for (i=0; i<numColors; i++) {
 
1061
                index = indicies[i];
 
1062
                outb(0x3c8, index);
 
1063
                outb(0x3c9, colors[index].red);
 
1064
                outb(0x3c9, colors[index].green);
 
1065
                outb(0x3c9, colors[index].blue);
 
1066
        }
 
1067
}
 
1068
 
 
1069
 
 
1070
static Bool S3MapMem(ScrnInfoPtr pScrn)
 
1071
{
 
1072
        S3Ptr pS3 = S3PTR(pScrn);
 
1073
 
 
1074
        if (pS3->S3NewMMIO) {
 
1075
                pS3->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO,
 
1076
                                              pS3->PciTag, pS3->IOAddress,
 
1077
                                              S3_NEWMMIO_REGSIZE);
 
1078
                if (!pS3->MMIOBase) {
 
1079
                        xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
1080
                                   "Could not map MMIO\n");
 
1081
                        return FALSE;
 
1082
                }
 
1083
        }
 
1084
 
 
1085
        pS3->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
 
1086
                                    pS3->PciTag, pS3->FBAddress,
 
1087
                                    pScrn->videoRam * 1024);
 
1088
        if (!pS3->FBBase) {
 
1089
                xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
 
1090
                           "Could not map framebuffer\n");
 
1091
                return FALSE;
 
1092
        }
 
1093
 
 
1094
        pS3->FBCursorOffset = pScrn->videoRam - 1;
 
1095
 
 
1096
        return TRUE;
 
1097
}
 
1098
 
 
1099
 
 
1100
static void S3UnmapMem(ScrnInfoPtr pScrn)
 
1101
{
 
1102
        S3Ptr pS3 = S3PTR(pScrn);
 
1103
 
 
1104
        if (pS3->S3NewMMIO)
 
1105
                xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pS3->MMIOBase,
 
1106
                                S3_NEWMMIO_REGSIZE);
 
1107
        xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pS3->FBBase,
 
1108
                        pScrn->videoRam * 1024);
 
1109
 
 
1110
        return;
 
1111
}
 
1112
 
 
1113
 
 
1114
static int S3GetPixMuxShift(ScrnInfoPtr pScrn)
 
1115
{
 
1116
        S3Ptr pS3 = S3PTR(pScrn);
 
1117
        int shift = 0;
 
1118
 
 
1119
        if (pS3->Chipset == PCI_CHIP_968)
 
1120
                shift = 1;      /* XXX IBMRGB */
 
1121
        else if (pS3->Chipset == PCI_CHIP_TRIO)
 
1122
                shift = -(pS3->s3Bpp >> 1);
 
1123
 
 
1124
        return shift;
 
1125
}
 
1126
 
 
1127
static Bool S3ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
 
1128
{
 
1129
        S3Ptr pS3 = S3PTR(pScrn);
 
1130
        S3RegPtr new = &pS3->ModeRegs;
 
1131
        vgaHWPtr hwp = VGAHWPTR(pScrn);
 
1132
        vgaRegPtr pVga = &hwp->ModeReg;
 
1133
        int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
 
1134
        int vgaIOBase = hwp->IOBase;
 
1135
        int r, n, m;
 
1136
        unsigned char tmp;
 
1137
 
 
1138
        pS3->pixMuxShift = S3GetPixMuxShift(pScrn);
 
1139
 
 
1140
        pS3->s3BppDisplayWidth = pScrn->displayWidth * pS3->s3Bpp;
 
1141
        pS3->HDisplay = mode->HDisplay;
 
1142
 
 
1143
        pS3->s3ScissB = ((pScrn->videoRam * 1024) / pS3->s3BppDisplayWidth) - 1;
 
1144
        pS3->s3ScissR = pScrn->displayWidth - 1;
 
1145
 
 
1146
        if (mode->HTotal == mode->CrtcHTotal) {
 
1147
                if (pS3->pixMuxShift > 0) {
 
1148
                        /* XXX hack */
 
1149
                        mode->Flags |= V_PIXMUX;        
 
1150
 
 
1151
                        mode->CrtcHTotal >>= pS3->pixMuxShift;
 
1152
                        mode->CrtcHDisplay >>= pS3->pixMuxShift;
 
1153
                        mode->CrtcHSyncStart >>= pS3->pixMuxShift;
 
1154
                        mode->CrtcHSyncEnd >>= pS3->pixMuxShift;
 
1155
                        mode->CrtcHSkew >>= pS3->pixMuxShift;
 
1156
                } else if (pS3->pixMuxShift < 0) {
 
1157
                        mode->Flags |= V_PIXMUX;
 
1158
 
 
1159
                        mode->CrtcHTotal <<= -pS3->pixMuxShift;
 
1160
                        mode->CrtcHDisplay <<= -pS3->pixMuxShift;
 
1161
                        mode->CrtcHSyncStart <<= -pS3->pixMuxShift;
 
1162
                        mode->CrtcHSyncEnd <<= -pS3->pixMuxShift;
 
1163
                        mode->CrtcHSkew <<= -pS3->pixMuxShift;
 
1164
                }
 
1165
        }
 
1166
 
 
1167
        if (!vgaHWInit(pScrn, mode))
 
1168
                return FALSE;
 
1169
 
 
1170
 
 
1171
 
 
1172
        pVga->MiscOutReg |= 0x0c;
 
1173
        pVga->Sequencer[0] = 0x03;
 
1174
        pVga->CRTC[19] = pS3->s3BppDisplayWidth >> 3;
 
1175
        pVga->CRTC[23] = 0xe3;
 
1176
        pVga->Attribute[0x11] = 0xff;
 
1177
 
 
1178
        if (vgaIOBase == 0x3b0)
 
1179
                pVga->MiscOutReg &= 0xfe;
 
1180
        else
 
1181
                pVga->MiscOutReg |= 0x01;
 
1182
 
 
1183
        /* ok i give up also, i'm writing in here */
 
1184
 
 
1185
        vgaHWProtect(pScrn, TRUE);
 
1186
 
 
1187
 
 
1188
        if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
 
1189
                outb(vgaCRIndex, 0x5c);
 
1190
                tmp = inb(vgaCRReg);
 
1191
                outb(vgaCRReg, tmp & 0xdf);
 
1192
 
 
1193
                S3OutTiIndReg(pScrn, TIDAC_ind_curs_ctrl, 0x7f, 0x00);
 
1194
        }
 
1195
 
 
1196
        pS3->DacInit(pScrn, mode);
 
1197
 
 
1198
        outb(0x3c2, pVga->MiscOutReg);
 
1199
 
 
1200
        for(r=1; r<5; r++) {
 
1201
                outw(0x3c4, (pVga->Sequencer[r] << 8) | r);
 
1202
        }
 
1203
 
 
1204
        /* We need to set this first - S3 *is* broken */
 
1205
        outw(vgaCRIndex, (pVga->CRTC[17] << 8) | 17);
 
1206
        for(r=0; r<25; r++)
 
1207
                outw(vgaCRIndex, (pVga->CRTC[r] << 8) | r);
 
1208
 
 
1209
        for(r=0; r<9; r++) {
 
1210
                outw(0x3ce, (pVga->Graphics[r] << 8) | r);
 
1211
        }
 
1212
 
 
1213
        inb(vgaIOBase + 0x0a);
 
1214
 
 
1215
        for(r=0; r<16; r++) {
 
1216
                outb(0x3c0, r);
 
1217
                outb(0x3c0, pVga->Attribute[r]);
 
1218
        }
 
1219
        for(r=16; r<21; r++) {
 
1220
                outb(0x3c0, r | 0x20);
 
1221
                outb(0x3c0, pVga->Attribute[r]);
 
1222
        }
 
1223
 
 
1224
 
 
1225
        new->cr31 = 0x8d;
 
1226
        outb(vgaCRIndex, 0x31);
 
1227
        outb(vgaCRReg, new->cr31);
 
1228
 
 
1229
        new->cr32 = 0x00;
 
1230
        outb(vgaCRIndex, 0x32);
 
1231
        outb(vgaCRReg, new->cr32);
 
1232
 
 
1233
        outb(vgaCRIndex, 0x33);
 
1234
        new->cr33 = inb(vgaCRReg) | 0x20;
 
1235
        if ((pS3->Chipset == PCI_CHIP_964_0) ||
 
1236
            (pS3->Chipset == PCI_CHIP_964_1))
 
1237
                new->cr33 = 0x20;
 
1238
        outb(vgaCRReg, new->cr33);
 
1239
        
 
1240
        new->cr34 = 0x10;
 
1241
        outb(vgaCRIndex, 0x34);
 
1242
        outb(vgaCRReg, new->cr34);
 
1243
 
 
1244
        if (pS3->SlowDRAMRefresh)
 
1245
                new->cr3a = 0xb7;
 
1246
        else
 
1247
                new->cr3a = 0xb5;
 
1248
        outb(vgaCRIndex, 0x3a);
 
1249
        outb(vgaCRReg, new->cr3a);
 
1250
 
 
1251
        if (pS3->Chipset != PCI_CHIP_AURORA64VP) {
 
1252
                new->cr3b = (pVga->CRTC[0] + pVga->CRTC[4] + 1) / 2;
 
1253
                outb(vgaCRIndex, 0x3b);
 
1254
                outb(vgaCRReg, new->cr3b);
 
1255
        }
 
1256
 
 
1257
        new->cr3c = pVga->CRTC[0] / 2;
 
1258
        outb(vgaCRIndex, 0x3c);
 
1259
        outb(vgaCRReg, new->cr3c);
 
1260
 
 
1261
        outb(vgaCRIndex, 0x40);
 
1262
        tmp = inb(vgaCRReg);
 
1263
        new->cr40 = (tmp & 0xf2) | 0x05;
 
1264
        outb(vgaCRReg, new->cr40);
 
1265
 
 
1266
        outb(vgaCRIndex, 0x43);
 
1267
        switch (pScrn->bitsPerPixel) {
 
1268
        case 24:
 
1269
        case 32:
 
1270
                new->cr43 = inb(vgaCRReg);
 
1271
                break;
 
1272
        case 15:
 
1273
        case 16:
 
1274
                if ((pS3->RamDac->RamDacType == IBM524_RAMDAC) ||
 
1275
                    (pS3->RamDac->RamDacType == IBM524A_RAMDAC) ||
 
1276
                    (pS3->RamDac->RamDacType == TI3025_RAMDAC))
 
1277
                        new->cr43 = 0x10;
 
1278
                else if (pS3->RamDac->RamDacType == TRIO64_RAMDAC)
 
1279
                        new->cr43 = 0x09;
 
1280
                break;
 
1281
        case 8:
 
1282
        default:
 
1283
                new->cr43 = 0x00;
 
1284
                break;
 
1285
        }
 
1286
        outb(vgaCRReg, new->cr43);
 
1287
 
 
1288
        new->cr44 = 0x00;
 
1289
        outb(vgaCRIndex, 0x44);
 
1290
        outb(vgaCRReg, new->cr44);
 
1291
 
 
1292
        outb(vgaCRIndex, 0x45);
 
1293
        new->cr45 = inb(vgaCRReg) & 0xf2;
 
1294
        outb(vgaCRReg, new->cr45);
 
1295
 
 
1296
        outb(vgaCRIndex, 0x50);
 
1297
        tmp = inb(vgaCRReg) & ~0xf1;
 
1298
        switch (pScrn->bitsPerPixel) {
 
1299
        case 8:
 
1300
                break;
 
1301
        case 16:
 
1302
                tmp |= 0x10;
 
1303
                break;
 
1304
        case 24:
 
1305
                tmp |= 0x20;
 
1306
                break;
 
1307
        case 32:
 
1308
                tmp |= 0x30;
 
1309
                break;
 
1310
        }
 
1311
 
 
1312
        switch (pScrn->displayWidth) {
 
1313
        case 640:
 
1314
                tmp |= 0x40;
 
1315
                break;
 
1316
        case 800:
 
1317
                tmp |= 0x80;
 
1318
                break;
 
1319
        case 1152:
 
1320
                tmp |= 0x01;
 
1321
                break;
 
1322
        case 1280:
 
1323
                tmp |= 0xc0;
 
1324
                break;
 
1325
        case 1600:
 
1326
                tmp |= 0x81;
 
1327
                break;
 
1328
        }
 
1329
        new->cr50 = tmp;
 
1330
        outb(vgaCRReg, new->cr50);
 
1331
 
 
1332
 
 
1333
        outb(vgaCRIndex, 0x51);
 
1334
        new->cr51 = (inb(vgaCRReg) & 0xc0) |
 
1335
                    ((pS3->s3BppDisplayWidth >> 7) & 0x30);
 
1336
        outb(vgaCRReg, new->cr51);
 
1337
 
 
1338
        outb(vgaCRIndex, 0x53);
 
1339
        new->cr53 = inb(vgaCRReg);
 
1340
        if (pS3->S3NewMMIO)
 
1341
                new->cr53 |= 0x18;
 
1342
        else
 
1343
                new->cr53 &= ~0x18;
 
1344
        outb(vgaCRReg, new->cr53);
 
1345
 
 
1346
        n = 255;
 
1347
        outb(vgaCRIndex, 0x54);
 
1348
        {
 
1349
                int clock2, mclk;
 
1350
 
 
1351
                clock2 = mode->Clock * pS3->s3Bpp;
 
1352
                if (pScrn->videoRam < 2048)
 
1353
                        clock2 *= 2;
 
1354
                mclk = pS3->mclk;
 
1355
                m = (int)((mclk/1000.0*.72+16.867)*89.736/(clock2/1000.0+39)-21.1543);
 
1356
                if (pScrn->videoRam < 2048)
 
1357
                        m /= 2;
 
1358
                if (m >31)
 
1359
                        m = 31;
 
1360
                else if (m < 0) {
 
1361
                        m = 0;
 
1362
                        n = 16;
 
1363
                }
 
1364
        }
 
1365
        new->cr54 = m << 3;
 
1366
        outb(vgaCRReg, new->cr54);
 
1367
 
 
1368
        if (n < 0)
 
1369
                n = 0;
 
1370
        else if (n > 255)
 
1371
                n = 255;
 
1372
        outb(vgaCRIndex, 0x60);
 
1373
        new->cr60 = n;
 
1374
        outb(vgaCRReg, new->cr60);
 
1375
 
 
1376
        outb(vgaCRIndex, 0x55);
 
1377
        new->cr55 = (inb(vgaCRReg) & 0x08) | 0x40;
 
1378
        outb(vgaCRReg, new->cr55);
 
1379
 
 
1380
        outb(vgaCRIndex, 0x5e);
 
1381
        new->cr5e = (((mode->CrtcVTotal - 2) & 0x400) >> 10)    |
 
1382
                    (((mode->CrtcVDisplay - 1) & 0x400) >> 9)   |
 
1383
                    (((mode->CrtcVSyncStart) & 0x400) >> 8)     |
 
1384
                    (((mode->CrtcVSyncStart) & 0x400) >> 6)     | 0x40;
 
1385
        outb(vgaCRReg, new->cr5e);
 
1386
 
 
1387
        {
 
1388
                int i;
 
1389
                unsigned int j;
 
1390
 
 
1391
                i = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8)      |
 
1392
                    ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7)    |
 
1393
                    ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6)  |
 
1394
                    ((mode->CrtcHSyncStart & 0x800) >> 7);
 
1395
                if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 64)
 
1396
                        i |= 0x08;
 
1397
                if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 32)
 
1398
                        i |= 0x20;
 
1399
 
 
1400
                outb(vgaCRIndex, 0x3b);
 
1401
                j = ((pVga->CRTC[0] + ((i & 0x01) << 8) +
 
1402
                      pVga->CRTC[4] + ((i & 0x10) << 4) + 1) / 2);
 
1403
        
 
1404
                if (j - (pVga->CRTC[4] + ((i & 0x10) << 4)) < 4) {
 
1405
                        if (pVga->CRTC[4] + ((i & 0x10) << 4) + 4 <= pVga->CRTC[0] + ((i & 0x01) << 8))
 
1406
                                j = pVga->CRTC[4] + ((i & 0x10) << 4) + 4;
 
1407
                        else
 
1408
                                j = pVga->CRTC[0] + ((i & 0x01) << 8) + 1;
 
1409
                }
 
1410
                if (pS3->Chipset == PCI_CHIP_AURORA64VP) {
 
1411
                        outb(vgaCRReg, 0x00);
 
1412
                        i &= ~0x40;
 
1413
                } else {
 
1414
                        new->cr3b = j & 0xff;
 
1415
                        outb(vgaCRReg, new->cr3b);
 
1416
                        i |= (j & 0x100) >> 2;
 
1417
                }
 
1418
 
 
1419
                outb(vgaCRIndex, 0x3c);
 
1420
                new->cr3c = (pVga->CRTC[0] + ((i & 0x01) << 8)) / 2;
 
1421
                outb(vgaCRReg, new->cr3c);
 
1422
 
 
1423
                outb(vgaCRIndex, 0x5d);
 
1424
                new->cr5d = (inb(vgaCRReg) & 0x80) | i; 
 
1425
                outb(vgaCRReg, new->cr5d);
 
1426
        }
 
1427
 
 
1428
        {
 
1429
                int i;
 
1430
 
 
1431
                if (pScrn->videoRam > 1024)
 
1432
                        i = mode->HDisplay * pS3->s3Bpp / 8 + 1;
 
1433
                else
 
1434
                        i = mode->HDisplay * pS3->s3Bpp / 4 + 1;
 
1435
 
 
1436
                outb(vgaCRIndex, 0x61);
 
1437
                tmp = 0x80 | (inb(vgaCRReg) & 0x60) | (i >> 8);
 
1438
                new->cr61 = tmp;
 
1439
                outb(vgaCRReg, new->cr61);
 
1440
                outb(vgaCRIndex, 0x62);
 
1441
                new->cr62 = i & 0xff;
 
1442
                outb(vgaCRReg, new->cr62);
 
1443
        }
 
1444
 
 
1445
        outb(vgaCRIndex, 0x42);
 
1446
        new->cr42 = inb(vgaCRReg) & ~0x20;
 
1447
        outb(vgaCRReg, new->cr42);
 
1448
 
 
1449
        if (pS3->Chipset == PCI_CHIP_968) {
 
1450
                unsigned char a;
 
1451
 
 
1452
                outb(vgaCRIndex, 0x67);
 
1453
                a = inb(vgaCRReg) & 0xfe;
 
1454
#if 0
 
1455
                switch (pScrn->depth) {
 
1456
                        case 8:
 
1457
                                break;
 
1458
                        case 15:
 
1459
                                a |= (3 << 4);
 
1460
                                break;
 
1461
                        case 16:
 
1462
                                a |= (5 << 4);
 
1463
                                a |= (3 << 2);  /* streams */
 
1464
                                break;
 
1465
                        case 24:
 
1466
                                a |= (13 << 4);
 
1467
                                a |= (3 << 2);  /* streams */
 
1468
                                break;
 
1469
                }
 
1470
#endif
 
1471
                outb(vgaCRReg, a);
 
1472
 
 
1473
                outb(vgaCRIndex, 0x6d);
 
1474
                outb(vgaCRReg, 0x00);
 
1475
        }
 
1476
 
 
1477
        if ((pS3->Chipset == PCI_CHIP_964_0) ||
 
1478
            (pS3->Chipset == PCI_CHIP_964_1)) {
 
1479
                unsigned char bdelay;
 
1480
 
 
1481
                outb(vgaCRIndex, 0x6d);
 
1482
                bdelay = inb(vgaCRReg);
 
1483
 
 
1484
                if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
 
1485
                        if (pS3->s3Bpp == 1) {
 
1486
                                if (mode->Clock > 80000)
 
1487
                                        bdelay = 0x02;
 
1488
                                else
 
1489
                                        bdelay = 0x03;
 
1490
                        } else if (pS3->s3Bpp == 2) {
 
1491
                                if (mode->Clock > 80000)
 
1492
                                        bdelay = 0x00;
 
1493
                                else
 
1494
                                        bdelay = 0x01;
 
1495
                        } else
 
1496
                                bdelay = 0x00;
 
1497
                }
 
1498
 
 
1499
                outb(vgaCRReg, bdelay);
 
1500
        }
 
1501
 
 
1502
        outb(vgaCRIndex, 0x66);
 
1503
        new->cr66 = inb(vgaCRReg);
 
1504
        if (pS3->S3NewMMIO)
 
1505
                new->cr66 |= 0x88;
 
1506
        else
 
1507
                new->cr66 |= 0x80;
 
1508
        outb(vgaCRReg, new->cr66);
 
1509
 
 
1510
        if (pS3->SlowVRAM) {
 
1511
                /*
 
1512
                 * some Diamond Stealth 64 VRAM cards have a problem with
 
1513
                 * VRAM timing, increas -RAS low timing from 3.5 MCLKs
 
1514
                 * to 4.5 MCLKs
 
1515
                 */
 
1516
                outb(vgaCRIndex, 0x39);
 
1517
                outb(vgaCRReg, 0xa5);
 
1518
                outb(vgaCRIndex, 0x68);
 
1519
                tmp = inb(vgaCRReg);
 
1520
                if (tmp & 0x30)                         /* 3.5 MCLKs */
 
1521
                        outb(vgaCRReg, tmp & 0xef);     /* 4.5 MCLKs */
 
1522
        }
 
1523
 
 
1524
        if (pS3->SlowDRAM) {
 
1525
                /*
 
1526
                 * fixes some pixel errors for a SPEA Trio64V+ card
 
1527
                 * increas -RAS precharge timing from 2.5 MCLKs
 
1528
                 * to 3.5 MCLKs
 
1529
                 */
 
1530
                outb(vgaCRIndex, 0x39);
 
1531
                outb(vgaCRReg, 0xa5);
 
1532
                outb(vgaCRIndex, 0x68);
 
1533
                tmp = inb(vgaCRReg) & 0xf7;
 
1534
                outb(vgaCRReg, tmp);                    /* 3.5 MCLKs */
 
1535
        }
 
1536
 
 
1537
        if (pS3->SlowEDODRAM) {
 
1538
                /*
 
1539
                 * fixes some pixel errors for a SPEA Trio64V+ card
 
1540
                 * increas from 1-cycle to 2-cycle EDO mode
 
1541
                 */
 
1542
                outb(vgaCRIndex, 0x39);
 
1543
 
 
1544
                outb(vgaCRReg, 0xa5);
 
1545
                outb(vgaCRIndex, 0x36);
 
1546
                tmp = inb(vgaCRReg);
 
1547
                if (!(tmp & 0x0c))                      /* 1-cycle EDO */
 
1548
                        outb(vgaCRReg, tmp | 0x08);     /* 2-cycle EDO */
 
1549
        }
 
1550
 
 
1551
        if (pS3->Chipset == PCI_CHIP_AURORA64VP) {
 
1552
                outb(0x3c4, 0x08);
 
1553
                outb(0x3c5, 0x06);
 
1554
#if 0
 
1555
                outb(0x3c4, 0x54);
 
1556
                outb(0x3c5, 0x10);
 
1557
                outb(0x3c4, 0x55);
 
1558
                outb(0x3c5, 0x00);
 
1559
                outb(0x3c4, 0x56);
 
1560
                outb(0x3c5, 0x1c);
 
1561
                outb(0x3c4, 0x57);
 
1562
                outb(0x3c5, 0x00);
 
1563
#else
 
1564
                outb(0x3c4, 0x54);
 
1565
                outb(0x3c5, 0x1f);
 
1566
                outb(0x3c4, 0x55);
 
1567
                outb(0x3c5, 0x1f);
 
1568
                outb(0x3c4, 0x56);
 
1569
                outb(0x3c5, 0x1f);
 
1570
                outb(0x3c4, 0x57);
 
1571
                outb(0x3c5, 0x1f);
 
1572
#endif
 
1573
 
 
1574
                outb(0x3c4, 0x08);
 
1575
                outb(0x3c5, 0x00);
 
1576
        }
 
1577
 
 
1578
        pScrn->AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
 
1579
 
 
1580
        vgaHWProtect(pScrn, FALSE);
 
1581
 
 
1582
        if (pScrn->displayWidth == 1024)
 
1583
                outw(ADVFUNC_CNTL, 0x0007);
 
1584
        else
 
1585
                outw(ADVFUNC_CNTL, 0x0003);
 
1586
 
 
1587
        outb(0x3c6, 0x00);
 
1588
 
 
1589
        outw(SUBSYS_CNTL, 0x8000 | 0x1000);
 
1590
        outw(SUBSYS_CNTL, 0x4000 | 0x1000);
 
1591
 
 
1592
        inw(SUBSYS_STAT);
 
1593
 
 
1594
        outw(0xbee8, 0x5000 | 0x0004 | 0x000c); 
 
1595
 
 
1596
        outb(0x3c6, 0xff);
 
1597
 
 
1598
        new->cr59 = pS3->FBAddress >> 24;
 
1599
        new->cr5a = pS3->FBAddress >> 16;
 
1600
 
 
1601
        if (pScrn->videoRam <= 1024)
 
1602
                new->cr58 = 0x15;
 
1603
        else if (pScrn->videoRam <= 2048)
 
1604
                new->cr58 = 0x16;
 
1605
        else
 
1606
                new->cr58 = 0x17;
 
1607
 
 
1608
        if ((pS3->Chipset == PCI_CHIP_968) ||
 
1609
            (pS3->Chipset == PCI_CHIP_964_0) ||
 
1610
            (pS3->Chipset == PCI_CHIP_964_1))
 
1611
                new->cr58 |= 0x40;
 
1612
 
 
1613
        outb(vgaCRIndex, 0x59);
 
1614
        outb(vgaCRReg, new->cr59);
 
1615
        outb(vgaCRIndex, 0x5a);
 
1616
        outb(vgaCRReg, new->cr5a);
 
1617
        outb(vgaCRIndex, 0x58);
 
1618
        outb(vgaCRReg, new->cr58);
 
1619
 
 
1620
        WaitQueue(5);
 
1621
        SET_SCISSORS(0, 0, pS3->s3ScissR, pS3->s3ScissB);
 
1622
 
 
1623
        outb(vgaCRIndex, 0x6f);
 
1624
 
 
1625
#if 0
 
1626
        if (((pScrn->bitsPerPixel == 16) || 
 
1627
             (pScrn->bitsPerPixel == 24)) && (pS3->S3NewMMIO))
 
1628
                S3InitStreams(pScrn, mode);
 
1629
#endif
 
1630
 
 
1631
        return TRUE;
 
1632
}
 
1633
 
 
1634
 
 
1635
static Bool S3EnterVT(int scrnIndex, int flags)
 
1636
{       
 
1637
        ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 
1638
        vgaHWPtr hwp = VGAHWPTR(pScrn);
 
1639
 
 
1640
        vgaHWUnlock(hwp);
 
1641
        if (!S3ModeInit(pScrn, pScrn->currentMode))
 
1642
                return FALSE;
 
1643
        
 
1644
        return TRUE;
 
1645
}               
 
1646
 
 
1647
 
 
1648
static void S3Restore(ScrnInfoPtr pScrn)
 
1649
{
 
1650
        S3Ptr pS3 = S3PTR(pScrn);
 
1651
        S3RegPtr restore = &pS3->SavedRegs;
 
1652
        vgaHWPtr hwp = VGAHWPTR(pScrn);
 
1653
        int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
 
1654
        int i;
 
1655
 
 
1656
        vgaHWProtect(pScrn, TRUE);
 
1657
        WaitQueue(8);
 
1658
 
 
1659
        S3BankZero(pScrn);
 
1660
 
 
1661
        outw(ADVFUNC_CNTL, 0x0000);
 
1662
 
 
1663
        if (pS3->S3NewMMIO) {
 
1664
                outb(vgaCRIndex, 0x53);
 
1665
                outb(vgaCRReg, 0x00);
 
1666
        }
 
1667
 
 
1668
        pS3->DacRestore(pScrn);
 
1669
 
 
1670
        if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
 
1671
                outb(vgaCRIndex, 0x5c);
 
1672
                outb(vgaCRReg, restore->s3syssave[0x0c + 16]);
 
1673
        }
 
1674
 
 
1675
        for(i=32; i<46; i++) {
 
1676
                outb(vgaCRIndex, 0x40 + i);
 
1677
                outb(vgaCRReg, restore->s3syssave[i]);
 
1678
        }
 
1679
 
 
1680
        for(i=0; i<16; i++) {
 
1681
                if (!((1 << i) & 0x673b))
 
1682
                        continue;
 
1683
                outb(vgaCRIndex, 0x50 + i);
 
1684
                outb(vgaCRReg, restore->s3syssave[i+16]);
 
1685
        }
 
1686
 
 
1687
        for(i=0; i<5; i++) {
 
1688
                outb(vgaCRIndex, 0x30 + i);
 
1689
                outb(vgaCRReg, restore->s3save[i]);
 
1690
                outb(vgaCRIndex, 0x38 + i);
 
1691
                outb(vgaCRReg, restore->s3save[i + 5]);
 
1692
        }
 
1693
 
 
1694
        for(i=0; i<16; i++) {
 
1695
                outb(vgaCRIndex, 0x40 + i);
 
1696
                outb(vgaCRReg, restore->s3syssave[i]);
 
1697
        }
 
1698
 
 
1699
        outb(vgaCRIndex, 0x45);
 
1700
        inb(vgaCRReg);
 
1701
        outb(vgaCRIndex, 0x4a);
 
1702
        for(i=0; i<4; i++)
 
1703
                outb(vgaCRReg, restore->color_stack[i]);
 
1704
 
 
1705
        outb(vgaCRIndex, 0x45);
 
1706
        inb(vgaCRReg);
 
1707
        outb(vgaCRIndex, 0x4b);
 
1708
        for(i=4; i<8; i++)
 
1709
                outb(vgaCRReg, restore->color_stack[i]);
 
1710
 
 
1711
        vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_ALL);
 
1712
 
 
1713
        outb(0x3c2, restore->clock);
 
1714
 
 
1715
        vgaHWProtect(pScrn, FALSE);
 
1716
 
 
1717
}
 
1718
 
 
1719
 
 
1720
static void S3LeaveVT(int scrnIndex, int flags)
 
1721
{
 
1722
        ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 
1723
        vgaHWPtr hwp = VGAHWPTR(pScrn);
 
1724
 
 
1725
        S3Restore(pScrn);
 
1726
        vgaHWLock(hwp);
 
1727
 
 
1728
        return;
 
1729
}       
 
1730
 
 
1731
 
 
1732
static void S3AdjustFrame(int scrnIndex, int x, int y, int flags)
 
1733
{
 
1734
        ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
 
1735
        S3Ptr pS3 = S3PTR(pScrn);
 
1736
        S3RegPtr regs = &pS3->ModeRegs;
 
1737
        int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
 
1738
        int base, orig_base;
 
1739
        unsigned char tmp;
 
1740
 
 
1741
        if (x > pScrn->displayWidth - pS3->HDisplay)
 
1742
                x = pScrn->displayWidth - pS3->HDisplay;
 
1743
 
 
1744
        orig_base = (y * pScrn->displayWidth + x) * pS3->s3Bpp;
 
1745
        base = (orig_base >> 2) & ~1;
 
1746
 
 
1747
        /* for IBMRGB and TI only */
 
1748
        if (pS3->RamDac->RamDacType == IBM524A_RAMDAC)
 
1749
        {
 
1750
                int px, py, a;
 
1751
 
 
1752
                miPointerPosition(&px, &py);
 
1753
 
 
1754
                if (pS3->s3Bpp == 1)
 
1755
                        a = 4 - 1;
 
1756
                else
 
1757
                        a = 8 - 1;
 
1758
                if (px-x > pS3->HDisplay/2)
 
1759
                        base = ((orig_base + a*4) >> 2) & ~1;
 
1760
                base &= ~a;
 
1761
        }
 
1762
 
 
1763
        outb(vgaCRIndex, 0x31);
 
1764
        outb(vgaCRReg, ((base & 0x030000) >> 12) | regs->cr31);
 
1765
        regs->cr51 &= ~0x03;
 
1766
        regs->cr51 |= ((base & 0x0c0000) >> 18);
 
1767
        outb(vgaCRIndex, 0x51);
 
1768
        tmp = (inb(vgaCRReg) & ~0x03) | (regs->cr51 & 0x03);
 
1769
        outb(vgaCRReg, tmp);
 
1770
 
 
1771
        outw(vgaCRIndex, (base & 0x00ff00) | 0x0c);
 
1772
        outw(vgaCRIndex, ((base & 0x00ff) << 8) | 0x0d);
 
1773
}
 
1774
 
 
1775
 
 
1776
void S3Regdump(ScrnInfoPtr pScrn)
 
1777
{
 
1778
        S3Ptr pS3 = S3PTR(pScrn);
 
1779
        int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
 
1780
 
 
1781
#if 1
 
1782
        outb(vgaCRIndex, 0x31);
 
1783
        ErrorF("cr31 = 0x%x\n", inb(vgaCRReg));
 
1784
        outb(vgaCRIndex, 0x32);
 
1785
        ErrorF("cr32 = 0x%x\n", inb(vgaCRReg));
 
1786
        outb(vgaCRIndex, 0x33);
 
1787
        ErrorF("cr33 = 0x%x\n", inb(vgaCRReg));
 
1788
        outb(vgaCRIndex, 0x34);
 
1789
        ErrorF("cr34 = 0x%x\n", inb(vgaCRReg));
 
1790
        outb(vgaCRIndex, 0x3a);
 
1791
        ErrorF("cr3a = 0x%x\n", inb(vgaCRReg));
 
1792
        outb(vgaCRIndex, 0x3b);
 
1793
        ErrorF("cr3b = 0x%x\n", inb(vgaCRReg));
 
1794
        outb(vgaCRIndex, 0x3c);
 
1795
        ErrorF("cr3c = 0x%x\n", inb(vgaCRReg));
 
1796
 
 
1797
        outb(vgaCRIndex, 0x40);
 
1798
        ErrorF("cr40 = 0x%x\n", inb(vgaCRReg));
 
1799
        outb(vgaCRIndex, 0x42);
 
1800
        ErrorF("cr42 = 0x%x\n", inb(vgaCRReg));
 
1801
        outb(vgaCRIndex, 0x43);
 
1802
        ErrorF("cr43 = 0x%x\n", inb(vgaCRReg));
 
1803
        outb(vgaCRIndex, 0x44);
 
1804
        ErrorF("cr44 = 0x%x\n", inb(vgaCRReg));
 
1805
        outb(vgaCRIndex, 0x45);
 
1806
        ErrorF("cr45 = 0x%x\n", inb(vgaCRReg));
 
1807
 
 
1808
        outb(vgaCRIndex, 0x50);
 
1809
        ErrorF("cr50 = 0x%x\n", inb(vgaCRReg));
 
1810
        outb(vgaCRIndex, 0x51);
 
1811
        ErrorF("cr51 = 0x%x\n", inb(vgaCRReg));
 
1812
        outb(vgaCRIndex, 0x53);
 
1813
        ErrorF("cr53 = 0x%x\n", inb(vgaCRReg));
 
1814
        outb(vgaCRIndex, 0x54);
 
1815
        ErrorF("cr54 = 0x%x\n", inb(vgaCRReg));
 
1816
        outb(vgaCRIndex, 0x55);
 
1817
        ErrorF("cr55 = 0x%x\n", inb(vgaCRReg));
 
1818
        outb(vgaCRIndex, 0x58);
 
1819
        ErrorF("cr58 = 0x%x\n", inb(vgaCRReg));
 
1820
        outb(vgaCRIndex, 0x59);
 
1821
        ErrorF("cr59 = 0x%x\n", inb(vgaCRReg));
 
1822
        outb(vgaCRIndex, 0x5a);
 
1823
        ErrorF("cr5a = 0x%x\n", inb(vgaCRReg));
 
1824
        outb(vgaCRIndex, 0x5d);
 
1825
        ErrorF("cr5d = 0x%x\n", inb(vgaCRReg));
 
1826
        outb(vgaCRIndex, 0x5e);
 
1827
        ErrorF("cr5e = 0x%x\n", inb(vgaCRReg));
 
1828
        
 
1829
        outb(vgaCRIndex, 0x60);
 
1830
        ErrorF("cr60 = 0x%x\n", inb(vgaCRReg));
 
1831
        outb(vgaCRIndex, 0x61);
 
1832
        ErrorF("cr61 = 0x%x\n", inb(vgaCRReg));
 
1833
        outb(vgaCRIndex, 0x62);
 
1834
        ErrorF("cr62 = 0x%x\n", inb(vgaCRReg));
 
1835
        outb(vgaCRIndex, 0x65);
 
1836
        ErrorF("cr65 = 0x%x\n", inb(vgaCRReg));
 
1837
        outb(vgaCRIndex, 0x66);
 
1838
        ErrorF("cr66 = 0x%x\n", inb(vgaCRReg));
 
1839
        outb(vgaCRIndex, 0x67);
 
1840
        ErrorF("cr67 = 0x%x\n", inb(vgaCRReg));
 
1841
        outb(vgaCRIndex, 0x6d);
 
1842
        ErrorF("cr6d = 0x%x\n", inb(vgaCRReg));
 
1843
 
 
1844
#else
 
1845
        {
 
1846
                int j;
 
1847
 
 
1848
                for(j=0; j<0x100; j++) {
 
1849
                        outb(vgaCRIndex, j);
 
1850
                        ErrorF("CRTC 0x%x = 0x%x\n", j, inb(vgaCRReg));
 
1851
                }
 
1852
        }
 
1853
#endif
 
1854
 
 
1855
#if 0
 
1856
        ErrorF("DAC regs\n");
 
1857
 
 
1858
        {
 
1859
                int j;
 
1860
 
 
1861
                for(j=0; j<0x100; j++)
 
1862
                        ErrorF("0x%x = 0x%x\n", j, S3InTiIndReg(pScrn, j));
 
1863
#if 0
 
1864
                outb(vgaCRIndex, 0x22);
 
1865
                ErrorF("cr22 = 0x%x\n", inb(vgaCRReg));
 
1866
#endif
 
1867
        }
 
1868
#endif
 
1869
}
 
1870
 
 
1871
 
 
1872
void S3BankZero(ScrnInfoPtr pScrn)
 
1873
{
 
1874
        S3Ptr pS3 = S3PTR(pScrn);
 
1875
        unsigned char tmp;
 
1876
        int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
 
1877
 
 
1878
        outb(vgaCRIndex, 0x35);
 
1879
        tmp = inb(vgaCRReg) & 0xf0;
 
1880
        outb(vgaCRReg, tmp);
 
1881
 
 
1882
        outb(vgaCRIndex, 0x51);
 
1883
        tmp = inb(vgaCRReg) & 0xf3;
 
1884
        outb(vgaCRReg, tmp);
 
1885
}
 
1886
 
 
1887
 
 
1888
 
 
1889
static void S3DisplayPowerManagementSet(ScrnInfoPtr pScrn,
 
1890
                                        int PowerManagementMode, int flags)
 
1891
{
 
1892
        vgaHWDPMSSet(pScrn, PowerManagementMode, flags);
 
1893
}
 
1894