2
* Copyright 2001 Ani Joshi <ajoshi@unixbox.com>
4
* XFree86 4.x driver for S3 chipsets
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.
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.
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
33
* - for various hardware donations
37
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/s3/s3_driver.c,v 1.12 2003/02/14 18:06:58 dawes Exp $ */
41
#include "xf86_OSproc.h"
42
#include "xf86_ansic.h"
44
#include "xf86PciInfo.h"
45
#include "xf86Version.h"
46
#include "xf86Resources.h"
47
#include "xf86fbman.h"
52
#include "mipointer.h"
63
#define TRIO64_RAMDAC 0x8811
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,
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,
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);
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+" },
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 }
151
OPTION_SLOW_DRAM_REFRESH,
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 }
167
RamDacSupportedInfoRec S3IBMRamdacs[] = {
176
static const char *fbSymbols[] = {
182
static const char *cfbSymbols[] = {
191
static const char *vgaHWSymbols[] = {
207
static const char *vbeSymbols[] = {
214
static const char *int10Symbols[] = {
218
"xf86Int10AllocPages",
219
"xf86Int10FreePages",
223
static const char *ramdacSymbols[] = {
225
"xf86CreateCursorInfoRec",
227
"RamDacCreateInfoRec",
228
"RamDacDestroyInfoRec",
229
"RamDacHelperCreateInfoRec",
232
"IBMramdac526CalculateMNPCForClock",
233
"IBMramdac526SetBpp",
237
static const char *xaaSymbols[] = {
247
MODULESETUPPROTO(S3Setup);
249
static XF86ModuleVersionInfo S3VersRec = {
254
XF86_VERSION_CURRENT,
255
VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL,
257
ABI_VIDEODRV_VERSION,
263
XF86ModuleData s3ModuleData = { &S3VersRec, S3Setup, NULL };
265
pointer S3Setup (pointer module, pointer opts, int *errmaj, int *errmin)
267
static Bool setupDone = FALSE;
271
xf86AddDriver(&S3, module, 0);
272
LoaderRefSymLists(vgaHWSymbols,
273
vbeSymbols, int10Symbols, ramdacSymbols,
284
*errmaj = LDR_ONCEONLY;
289
#endif /* XFree86LOADER */
292
static Bool S3GetRec(ScrnInfoPtr pScrn)
294
if (pScrn->driverPrivate)
297
pScrn->driverPrivate = xnfcalloc(sizeof(S3Rec), 1);
302
static void S3FreeRec(ScrnInfoPtr pScrn)
304
if (!pScrn->driverPrivate)
307
xfree(pScrn->driverPrivate);
308
pScrn->driverPrivate = NULL;
311
static const OptionInfoRec * S3AvailableOptions(int chipid, int busid)
316
static void S3Identify(int flags)
318
xf86PrintChipsets("S3", "driver (version " DRIVER_VERSION " for S3 chipset",
322
static Bool S3Probe(DriverPtr drv, int flags)
324
GDevPtr *devSections;
325
int i, *usedChips, numDevSections, numUsed;
326
Bool foundScreen = FALSE;
329
if ((numDevSections = xf86MatchDevice("s3", &devSections)) <= 0)
332
/* XXX do ISA later... some day in the distant future... */
333
numUsed = xf86MatchPciInstances("s3", PCI_VENDOR_S3,
334
S3Chipsets, S3PciChipsets,
335
devSections, numDevSections,
343
if (flags & PROBE_DETECT)
345
else for (i=0; i<numUsed; i++) {
346
ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0);
348
pScrn->driverVersion = VERSION_MAJOR;
349
pScrn->driverName = DRIVER_NAME;
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;
362
xf86ConfigActivePciEntity(pScrn, usedChips[i], S3PciChipsets,
363
NULL, NULL, NULL, NULL, NULL);
371
static Bool S3PreInit(ScrnInfoPtr pScrn, int flags)
376
ClockRangePtr clockRanges;
377
rgb zeros = {0, 0, 0};
378
Gamma gzeros = {0.0, 0.0, 0.0};
379
int i, vgaCRIndex, vgaCRReg;
382
if (flags & PROBE_DETECT)
385
if (!xf86LoadSubModule(pScrn, "vgahw"))
388
xf86LoaderReqSymLists(vgaHWSymbols, NULL);
390
if (!vgaHWGetHWRec(pScrn))
393
hwp = VGAHWPTR(pScrn);
396
pScrn->monitor = pScrn->confScreen->monitor;
398
if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support24bppFb | Support32bppFb))
401
switch (pScrn->depth) {
410
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
411
"Given depth (%d) is not supported by this driver\n",
416
xf86PrintDepthBpp(pScrn);
418
if (pScrn->depth > 8) {
419
if (!xf86SetWeight(pScrn, zeros, zeros))
423
if (!xf86SetDefaultVisual(pScrn, -1))
426
pScrn->progClock = TRUE;
428
if (!S3GetRec(pScrn))
433
pS3->s3Bpp = (pScrn->bitsPerPixel >> 3);
435
xf86CollectOptions(pScrn, NULL);
436
xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, S3Options);
438
if (xf86ReturnOptValBool(S3Options, OPTION_NOACCEL, FALSE)) {
440
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Option: NoAccel - acceleration disabled\n");
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");
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");
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");
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");
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");
467
pS3->SlowVRAM = FALSE;
469
if (pScrn->numEntities > 1) {
474
pEnt = xf86GetEntityInfo(pScrn->entityList[0]);
475
if (pEnt->resources) {
481
if (xf86LoadSubModule(pScrn, "int10")) {
482
xf86LoaderReqSymLists(int10Symbols, NULL);
483
pS3->pInt10 = xf86InitInt10(pEnt->index);
486
if (xf86LoadSubModule(pScrn, "vbe")) {
487
xf86LoaderReqSymLists(vbeSymbols, NULL);
488
pS3->pVBE = VBEInit(pS3->pInt10, pEnt->index);
491
if (!xf86SetGamma(pScrn, gzeros))
494
pS3->PciInfo = xf86GetPciInfoForEntity(pEnt->index);
495
xf86RegisterResources(pEnt->index, NULL, ResNone);
496
/* don't disable PIO funcs */
497
xf86SetOperatingState(resVgaMemShared, pEnt->index, ResDisableOpr);
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,
506
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n",
509
pS3->Chipset = pS3->PciInfo->chipType;
510
pScrn->chipset = (char *)xf86TokenToString(S3Chipsets,
513
if (pEnt->device->chipRev >= 0) {
514
pS3->ChipRev = pEnt->device->chipRev;
515
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n",
518
pS3->ChipRev = pS3->PciInfo->chipRev;
522
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Chipset: \"%s\"\n", pScrn->chipset);
524
pS3->PciTag = pciTag(pS3->PciInfo->bus, pS3->PciInfo->device,
527
switch (pS3->Chipset) {
531
case PCI_CHIP_AURORA64VP: /* ??? */
532
pS3->S3NewMMIO = FALSE;
535
pS3->S3NewMMIO = TRUE;
539
pS3->FBAddress = pS3->PciInfo->memBase[0];
541
pS3->IOAddress = pS3->FBAddress + S3_NEWMMIO_REGBASE;
543
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Framebuffer @ 0x%x\n",
546
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MMIO @ 0x%x\n",
549
pS3->PCIRetry = FALSE; /* not supported yet */
551
pS3->vgaCRIndex = vgaCRIndex = hwp->IOBase + 4;
552
pS3->vgaCRReg = vgaCRReg = hwp->IOBase + 5;
554
/* unlock sys regs */
555
outb(vgaCRIndex, 0x38);
556
outb(vgaCRReg, 0x48);
557
outb(vgaCRIndex, 0x39);
558
outb(vgaCRReg, 0xa5);
560
outb(vgaCRIndex, 0x40);
561
tmp = inb(vgaCRReg) | 0x01;
563
outb(vgaCRIndex, 0x35);
564
tmp = inb(vgaCRReg) & ~0x30;
569
outb(vgaCRIndex, 0x33);
570
tmp = (inb(vgaCRReg) & ~(0x2 | 0x10 | 0x40)) | 0x20;
573
/* unprotect CRTC[0-7] */
574
outb(vgaCRIndex, 0x11);
575
tmp = inb(vgaCRReg) & 0x7f;
583
if (!pScrn->videoRam) {
585
outb(vgaCRIndex, 0x36);
588
switch ((tmp & 0xe0) >> 5) {
590
pScrn->videoRam = 4096;
593
pScrn->videoRam = 3072;
596
pScrn->videoRam = 8192;
599
pScrn->videoRam = 2048;
602
pScrn->videoRam = 6144;
605
pScrn->videoRam = 1024;
608
xf86DrvMsg(pScrn->scrnIndex, X_PROBED,
609
"videoRam = %d Kb\n", pScrn->videoRam);
611
xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
612
"videoRam = %d Kb\n", pScrn->videoRam);
615
if (!xf86LoadSubModule(pScrn, "ramdac"))
617
xf86LoaderReqSymLists(ramdacSymbols, NULL);
619
pScrn->rgbBits = 8; /* set default */
622
if (S3TiDACProbe(pScrn)) {
623
pS3->DacPreInit = S3TiDAC_PreInit;
624
pS3->DacInit = S3TiDAC_Init;
625
pS3->DacSave = S3TiDAC_Save;
626
pS3->DacRestore = S3TiDAC_Restore;
628
/* FIXME, cursor is drawn in wrong position */
629
pS3->CursorInit = S3Ti_CursorInit;
631
pS3->MaxClock = 135000;
633
if (pScrn->bitsPerPixel > 8)
634
pS3->LoadPalette = S3TiLoadPalette;
636
pS3->LoadPalette = S3GenericLoadPalette;
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;
647
pS3->LoadPalette = S3GenericLoadPalette;
649
if (S3Trio64DACProbe(pScrn)) {
650
pS3->DacPreInit = S3Trio64DAC_PreInit;
651
pS3->DacInit = S3Trio64DAC_Init;
652
pS3->DacSave = S3Trio64DAC_Save;
653
pS3->DacRestore = S3Trio64DAC_Restore;
655
pS3->CursorInit = S3_CursorInit; /* FIXME broken */
657
switch(pScrn->bitsPerPixel) {
659
pS3->MaxClock = 135000;
662
pS3->MaxClock = 80000;
666
pS3->MaxClock = 50000;
670
pS3->LoadPalette = S3GenericLoadPalette;
673
if (pS3->RamDac == NULL) {
674
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
675
"Ramdac probe failed\n");
680
pS3->CursorInit = NULL;
682
pS3->RefClock = S3GetRefClock(pScrn);
685
pS3->DacPreInit(pScrn);
687
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RefClock: %d\n",
689
xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Max pixel clock at this depth is %d Mhz\n",
690
pS3->MaxClock / 1000);
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 */
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);
708
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes left\n");
713
xf86PruneDriverModes(pScrn);
715
if (i == 0 || pScrn->modes == NULL) {
716
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes found\n");
721
xf86SetCrtcForModes(pScrn, 0);
722
pScrn->currentMode = pScrn->modes;
723
xf86PrintModes(pScrn);
724
xf86SetDpi(pScrn, 0, 0);
727
xf86LoadSubModule(pScrn, "fb");
728
xf86LoaderReqSymbols("fbScreenInit", NULL);
731
switch (pScrn->bitsPerPixel) {
733
xf86LoadSubModule(pScrn, "cfb");
734
xf86LoaderReqSymbols("cfbScreenInit", NULL);
737
xf86LoadSubModule(pScrn, "cfb16");
738
xf86LoaderReqSymbols("cfb16ScreenInit", NULL);
741
xf86LoadSubModule(pScrn, "cfb24");
742
xf86LoaderReqSymbols("cfb24ScreenInit", NULL);
745
xf86LoadSubModule(pScrn, "cfb32");
746
xf86LoaderReqSymbols("cfb32ScreenInit", NULL);
752
if (!xf86LoadSubModule(pScrn, "xaa"))
754
xf86LoaderReqSymLists(xaaSymbols, NULL);
760
static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc,
763
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
764
S3Ptr pS3 = S3PTR(pScrn);
768
if (!S3MapMem(pScrn)) {
775
vgaHWBlankScreen(pScrn, TRUE);
777
if (!S3ModeInit(pScrn, pScrn->currentMode))
782
pScrn->vtSema = TRUE;
784
S3SaveScreen(pScreen, SCREEN_SAVER_ON);
786
miClearVisualTypes();
787
if (pScrn->bitsPerPixel > 8) {
788
if (!miSetVisualTypes(pScrn->depth, TrueColorMask,
789
pScrn->rgbBits, pScrn->defaultVisual))
792
if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth),
793
pScrn->rgbBits, pScrn->defaultVisual))
797
miSetPixmapDepths ();
800
if (!fbScreenInit(pScreen, pS3->FBBase, pScrn->virtualX,
801
pScrn->virtualY, pScrn->xDpi, pScrn->yDpi,
802
pScrn->displayWidth, pScrn->bitsPerPixel))
808
switch(pScrn->bitsPerPixel) {
810
ret = cfbScreenInit(pScreen, pS3->FBBase,
811
pScrn->virtualX, pScrn->virtualY,
812
pScrn->xDpi, pScrn->yDpi,
813
pScrn->displayWidth);
816
ret = cfb16ScreenInit(pScreen, pS3->FBBase,
817
pScrn->virtualX, pScrn->virtualY,
818
pScrn->xDpi, pScrn->yDpi,
819
pScrn->displayWidth);
822
ret = cfb24ScreenInit(pScreen, pS3->FBBase,
823
pScrn->virtualX, pScrn->virtualY,
824
pScrn->xDpi, pScrn->yDpi,
825
pScrn->displayWidth);
828
ret = cfb32ScreenInit(pScreen, pS3->FBBase,
829
pScrn->virtualX, pScrn->virtualY,
830
pScrn->xDpi, pScrn->yDpi,
831
pScrn->displayWidth);
839
xf86SetBlackWhitePixels(pScreen);
841
if (pScrn->bitsPerPixel > 8) {
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;
857
fbPictureInit (pScreen, 0, 0);
861
miInitializeBackingStore(pScreen);
862
xf86SetBackingStore(pScreen);
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");
870
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Acceleration initialization failed\n");
871
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n");
874
if (S3AccelInitPIO(pScreen)) {
875
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration enabled\n");
876
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using PIO\n");
878
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Acceleration initialization failed\n");
879
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled\n");
883
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Acceleration disabled by option\n");
886
miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
888
/* hw cursor setup */
889
if (pS3->CursorInit) {
890
if (pS3->CursorInit(pScreen))
891
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using HW cursor\n");
893
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "HW cursor initialization failed\n");
894
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using SW cursor\n");
897
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using SW cursor\n");
902
if (!miCreateDefColormap(pScreen))
905
if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits,
906
pS3->LoadPalette, NULL,
907
CMAP_RELOAD_ON_MODE_SWITCH))
910
vgaHWBlankScreen(pScrn, FALSE);
912
pScreen->SaveScreen = S3SaveScreen;
913
pS3->CloseScreen = pScreen->CloseScreen;
914
pScreen->CloseScreen = S3CloseScreen;
916
xf86DPMSInit(pScreen, S3DisplayPowerManagementSet, 0);
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;
923
S3InitVideo(pScreen);
932
static void S3Save(ScrnInfoPtr pScrn)
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;
942
unsigned char cr5c = 0;
944
pRAMDAC = RAMDACHWPTR(pScrn);
945
RAMDACreg = &pRAMDAC->SavedReg;
949
save->clock = inb(0x3cc);
951
vgaHWSave(pScrn, pVga, VGA_SR_ALL);
953
if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
954
outb(vgaCRIndex, 0x5c);
955
cr5c = inb(vgaCRReg);
961
outb(vgaCRIndex, 0x30 + i);
962
save->s3save[i] = inb(vgaCRReg);
963
outb(vgaCRIndex, 0x38 + i);
964
save->s3save[5 + i] = inb(vgaCRReg);
967
for (i=0; i<16; i++) {
968
outb(vgaCRIndex, 0x40 + i);
969
save->s3syssave[i] = inb(vgaCRReg);
972
outb(vgaCRIndex, 0x45);
974
outb(vgaCRIndex, 0x4a);
976
save->color_stack[i] = inb(vgaCRReg);
977
outb(vgaCRReg, save->color_stack[i]);
980
outb(vgaCRIndex, 0x45);
982
outb(vgaCRIndex, 0x4b);
984
save->color_stack[i] = inb(vgaCRReg);
985
outb(vgaCRReg, save->color_stack[i]);
988
for(i=0; i<16; i++) {
989
for (i=0; i<16; i++) {
990
if (!((1 << i) & 0x673b))
992
outb(vgaCRIndex, 0x50 + i);
993
save->s3syssave[i + 16] = inb(vgaCRReg);
997
if (pS3->RamDac->RamDacType == TI3025_RAMDAC)
998
save->s3syssave[0x0c + 16] = cr5c;
1000
for(i=32; i<46; i++) {
1001
outb(vgaCRIndex, 0x40 + i);
1002
save->s3syssave[i] = inb(vgaCRReg);
1007
Bool S3SaveScreen(ScreenPtr pScreen, int mode)
1009
return vgaHWSaveScreen(pScreen, mode);
1013
static void S3FreeScreen(int scrnIndex, int flags)
1015
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1017
vgaHWFreeHWRec(pScrn);
1023
Bool S3CloseScreen(int scrnIndex, ScreenPtr pScreen)
1025
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1026
S3Ptr pS3 = S3PTR(pScrn);
1027
vgaHWPtr hwp = VGAHWPTR(pScrn);
1029
if (pScrn->vtSema) {
1037
xfree(pS3->DGAModes);
1038
pS3->DGAModes = NULL;
1040
pScrn->vtSema = FALSE;
1041
pScreen->CloseScreen = pS3->CloseScreen;
1043
return (*pScreen->CloseScreen)(scrnIndex, pScreen);
1047
Bool S3SwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
1049
return S3ModeInit(xf86Screens[scrnIndex], xf86Screens[scrnIndex]->currentMode);
1054
static void S3GenericLoadPalette(ScrnInfoPtr pScrn, int numColors,
1055
int *indicies, LOCO *colors,
1060
for (i=0; i<numColors; i++) {
1061
index = indicies[i];
1063
outb(0x3c9, colors[index].red);
1064
outb(0x3c9, colors[index].green);
1065
outb(0x3c9, colors[index].blue);
1070
static Bool S3MapMem(ScrnInfoPtr pScrn)
1072
S3Ptr pS3 = S3PTR(pScrn);
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");
1085
pS3->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
1086
pS3->PciTag, pS3->FBAddress,
1087
pScrn->videoRam * 1024);
1089
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
1090
"Could not map framebuffer\n");
1094
pS3->FBCursorOffset = pScrn->videoRam - 1;
1100
static void S3UnmapMem(ScrnInfoPtr pScrn)
1102
S3Ptr pS3 = S3PTR(pScrn);
1105
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pS3->MMIOBase,
1106
S3_NEWMMIO_REGSIZE);
1107
xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pS3->FBBase,
1108
pScrn->videoRam * 1024);
1114
static int S3GetPixMuxShift(ScrnInfoPtr pScrn)
1116
S3Ptr pS3 = S3PTR(pScrn);
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);
1127
static Bool S3ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
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;
1138
pS3->pixMuxShift = S3GetPixMuxShift(pScrn);
1140
pS3->s3BppDisplayWidth = pScrn->displayWidth * pS3->s3Bpp;
1141
pS3->HDisplay = mode->HDisplay;
1143
pS3->s3ScissB = ((pScrn->videoRam * 1024) / pS3->s3BppDisplayWidth) - 1;
1144
pS3->s3ScissR = pScrn->displayWidth - 1;
1146
if (mode->HTotal == mode->CrtcHTotal) {
1147
if (pS3->pixMuxShift > 0) {
1149
mode->Flags |= V_PIXMUX;
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;
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;
1167
if (!vgaHWInit(pScrn, mode))
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;
1178
if (vgaIOBase == 0x3b0)
1179
pVga->MiscOutReg &= 0xfe;
1181
pVga->MiscOutReg |= 0x01;
1183
/* ok i give up also, i'm writing in here */
1185
vgaHWProtect(pScrn, TRUE);
1188
if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
1189
outb(vgaCRIndex, 0x5c);
1190
tmp = inb(vgaCRReg);
1191
outb(vgaCRReg, tmp & 0xdf);
1193
S3OutTiIndReg(pScrn, TIDAC_ind_curs_ctrl, 0x7f, 0x00);
1196
pS3->DacInit(pScrn, mode);
1198
outb(0x3c2, pVga->MiscOutReg);
1200
for(r=1; r<5; r++) {
1201
outw(0x3c4, (pVga->Sequencer[r] << 8) | r);
1204
/* We need to set this first - S3 *is* broken */
1205
outw(vgaCRIndex, (pVga->CRTC[17] << 8) | 17);
1207
outw(vgaCRIndex, (pVga->CRTC[r] << 8) | r);
1209
for(r=0; r<9; r++) {
1210
outw(0x3ce, (pVga->Graphics[r] << 8) | r);
1213
inb(vgaIOBase + 0x0a);
1215
for(r=0; r<16; r++) {
1217
outb(0x3c0, pVga->Attribute[r]);
1219
for(r=16; r<21; r++) {
1220
outb(0x3c0, r | 0x20);
1221
outb(0x3c0, pVga->Attribute[r]);
1226
outb(vgaCRIndex, 0x31);
1227
outb(vgaCRReg, new->cr31);
1230
outb(vgaCRIndex, 0x32);
1231
outb(vgaCRReg, new->cr32);
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))
1238
outb(vgaCRReg, new->cr33);
1241
outb(vgaCRIndex, 0x34);
1242
outb(vgaCRReg, new->cr34);
1244
if (pS3->SlowDRAMRefresh)
1248
outb(vgaCRIndex, 0x3a);
1249
outb(vgaCRReg, new->cr3a);
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);
1257
new->cr3c = pVga->CRTC[0] / 2;
1258
outb(vgaCRIndex, 0x3c);
1259
outb(vgaCRReg, new->cr3c);
1261
outb(vgaCRIndex, 0x40);
1262
tmp = inb(vgaCRReg);
1263
new->cr40 = (tmp & 0xf2) | 0x05;
1264
outb(vgaCRReg, new->cr40);
1266
outb(vgaCRIndex, 0x43);
1267
switch (pScrn->bitsPerPixel) {
1270
new->cr43 = inb(vgaCRReg);
1274
if ((pS3->RamDac->RamDacType == IBM524_RAMDAC) ||
1275
(pS3->RamDac->RamDacType == IBM524A_RAMDAC) ||
1276
(pS3->RamDac->RamDacType == TI3025_RAMDAC))
1278
else if (pS3->RamDac->RamDacType == TRIO64_RAMDAC)
1286
outb(vgaCRReg, new->cr43);
1289
outb(vgaCRIndex, 0x44);
1290
outb(vgaCRReg, new->cr44);
1292
outb(vgaCRIndex, 0x45);
1293
new->cr45 = inb(vgaCRReg) & 0xf2;
1294
outb(vgaCRReg, new->cr45);
1296
outb(vgaCRIndex, 0x50);
1297
tmp = inb(vgaCRReg) & ~0xf1;
1298
switch (pScrn->bitsPerPixel) {
1312
switch (pScrn->displayWidth) {
1330
outb(vgaCRReg, new->cr50);
1333
outb(vgaCRIndex, 0x51);
1334
new->cr51 = (inb(vgaCRReg) & 0xc0) |
1335
((pS3->s3BppDisplayWidth >> 7) & 0x30);
1336
outb(vgaCRReg, new->cr51);
1338
outb(vgaCRIndex, 0x53);
1339
new->cr53 = inb(vgaCRReg);
1344
outb(vgaCRReg, new->cr53);
1347
outb(vgaCRIndex, 0x54);
1351
clock2 = mode->Clock * pS3->s3Bpp;
1352
if (pScrn->videoRam < 2048)
1355
m = (int)((mclk/1000.0*.72+16.867)*89.736/(clock2/1000.0+39)-21.1543);
1356
if (pScrn->videoRam < 2048)
1366
outb(vgaCRReg, new->cr54);
1372
outb(vgaCRIndex, 0x60);
1374
outb(vgaCRReg, new->cr60);
1376
outb(vgaCRIndex, 0x55);
1377
new->cr55 = (inb(vgaCRReg) & 0x08) | 0x40;
1378
outb(vgaCRReg, new->cr55);
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);
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)
1397
if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 32)
1400
outb(vgaCRIndex, 0x3b);
1401
j = ((pVga->CRTC[0] + ((i & 0x01) << 8) +
1402
pVga->CRTC[4] + ((i & 0x10) << 4) + 1) / 2);
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;
1408
j = pVga->CRTC[0] + ((i & 0x01) << 8) + 1;
1410
if (pS3->Chipset == PCI_CHIP_AURORA64VP) {
1411
outb(vgaCRReg, 0x00);
1414
new->cr3b = j & 0xff;
1415
outb(vgaCRReg, new->cr3b);
1416
i |= (j & 0x100) >> 2;
1419
outb(vgaCRIndex, 0x3c);
1420
new->cr3c = (pVga->CRTC[0] + ((i & 0x01) << 8)) / 2;
1421
outb(vgaCRReg, new->cr3c);
1423
outb(vgaCRIndex, 0x5d);
1424
new->cr5d = (inb(vgaCRReg) & 0x80) | i;
1425
outb(vgaCRReg, new->cr5d);
1431
if (pScrn->videoRam > 1024)
1432
i = mode->HDisplay * pS3->s3Bpp / 8 + 1;
1434
i = mode->HDisplay * pS3->s3Bpp / 4 + 1;
1436
outb(vgaCRIndex, 0x61);
1437
tmp = 0x80 | (inb(vgaCRReg) & 0x60) | (i >> 8);
1439
outb(vgaCRReg, new->cr61);
1440
outb(vgaCRIndex, 0x62);
1441
new->cr62 = i & 0xff;
1442
outb(vgaCRReg, new->cr62);
1445
outb(vgaCRIndex, 0x42);
1446
new->cr42 = inb(vgaCRReg) & ~0x20;
1447
outb(vgaCRReg, new->cr42);
1449
if (pS3->Chipset == PCI_CHIP_968) {
1452
outb(vgaCRIndex, 0x67);
1453
a = inb(vgaCRReg) & 0xfe;
1455
switch (pScrn->depth) {
1463
a |= (3 << 2); /* streams */
1467
a |= (3 << 2); /* streams */
1473
outb(vgaCRIndex, 0x6d);
1474
outb(vgaCRReg, 0x00);
1477
if ((pS3->Chipset == PCI_CHIP_964_0) ||
1478
(pS3->Chipset == PCI_CHIP_964_1)) {
1479
unsigned char bdelay;
1481
outb(vgaCRIndex, 0x6d);
1482
bdelay = inb(vgaCRReg);
1484
if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
1485
if (pS3->s3Bpp == 1) {
1486
if (mode->Clock > 80000)
1490
} else if (pS3->s3Bpp == 2) {
1491
if (mode->Clock > 80000)
1499
outb(vgaCRReg, bdelay);
1502
outb(vgaCRIndex, 0x66);
1503
new->cr66 = inb(vgaCRReg);
1508
outb(vgaCRReg, new->cr66);
1510
if (pS3->SlowVRAM) {
1512
* some Diamond Stealth 64 VRAM cards have a problem with
1513
* VRAM timing, increas -RAS low timing from 3.5 MCLKs
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 */
1524
if (pS3->SlowDRAM) {
1526
* fixes some pixel errors for a SPEA Trio64V+ card
1527
* increas -RAS precharge timing from 2.5 MCLKs
1530
outb(vgaCRIndex, 0x39);
1531
outb(vgaCRReg, 0xa5);
1532
outb(vgaCRIndex, 0x68);
1533
tmp = inb(vgaCRReg) & 0xf7;
1534
outb(vgaCRReg, tmp); /* 3.5 MCLKs */
1537
if (pS3->SlowEDODRAM) {
1539
* fixes some pixel errors for a SPEA Trio64V+ card
1540
* increas from 1-cycle to 2-cycle EDO mode
1542
outb(vgaCRIndex, 0x39);
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 */
1551
if (pS3->Chipset == PCI_CHIP_AURORA64VP) {
1578
pScrn->AdjustFrame(pScrn->scrnIndex, pScrn->frameX0, pScrn->frameY0, 0);
1580
vgaHWProtect(pScrn, FALSE);
1582
if (pScrn->displayWidth == 1024)
1583
outw(ADVFUNC_CNTL, 0x0007);
1585
outw(ADVFUNC_CNTL, 0x0003);
1589
outw(SUBSYS_CNTL, 0x8000 | 0x1000);
1590
outw(SUBSYS_CNTL, 0x4000 | 0x1000);
1594
outw(0xbee8, 0x5000 | 0x0004 | 0x000c);
1598
new->cr59 = pS3->FBAddress >> 24;
1599
new->cr5a = pS3->FBAddress >> 16;
1601
if (pScrn->videoRam <= 1024)
1603
else if (pScrn->videoRam <= 2048)
1608
if ((pS3->Chipset == PCI_CHIP_968) ||
1609
(pS3->Chipset == PCI_CHIP_964_0) ||
1610
(pS3->Chipset == PCI_CHIP_964_1))
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);
1621
SET_SCISSORS(0, 0, pS3->s3ScissR, pS3->s3ScissB);
1623
outb(vgaCRIndex, 0x6f);
1626
if (((pScrn->bitsPerPixel == 16) ||
1627
(pScrn->bitsPerPixel == 24)) && (pS3->S3NewMMIO))
1628
S3InitStreams(pScrn, mode);
1635
static Bool S3EnterVT(int scrnIndex, int flags)
1637
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1638
vgaHWPtr hwp = VGAHWPTR(pScrn);
1641
if (!S3ModeInit(pScrn, pScrn->currentMode))
1648
static void S3Restore(ScrnInfoPtr pScrn)
1650
S3Ptr pS3 = S3PTR(pScrn);
1651
S3RegPtr restore = &pS3->SavedRegs;
1652
vgaHWPtr hwp = VGAHWPTR(pScrn);
1653
int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
1656
vgaHWProtect(pScrn, TRUE);
1661
outw(ADVFUNC_CNTL, 0x0000);
1663
if (pS3->S3NewMMIO) {
1664
outb(vgaCRIndex, 0x53);
1665
outb(vgaCRReg, 0x00);
1668
pS3->DacRestore(pScrn);
1670
if (pS3->RamDac->RamDacType == TI3025_RAMDAC) {
1671
outb(vgaCRIndex, 0x5c);
1672
outb(vgaCRReg, restore->s3syssave[0x0c + 16]);
1675
for(i=32; i<46; i++) {
1676
outb(vgaCRIndex, 0x40 + i);
1677
outb(vgaCRReg, restore->s3syssave[i]);
1680
for(i=0; i<16; i++) {
1681
if (!((1 << i) & 0x673b))
1683
outb(vgaCRIndex, 0x50 + i);
1684
outb(vgaCRReg, restore->s3syssave[i+16]);
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]);
1694
for(i=0; i<16; i++) {
1695
outb(vgaCRIndex, 0x40 + i);
1696
outb(vgaCRReg, restore->s3syssave[i]);
1699
outb(vgaCRIndex, 0x45);
1701
outb(vgaCRIndex, 0x4a);
1703
outb(vgaCRReg, restore->color_stack[i]);
1705
outb(vgaCRIndex, 0x45);
1707
outb(vgaCRIndex, 0x4b);
1709
outb(vgaCRReg, restore->color_stack[i]);
1711
vgaHWRestore(pScrn, &hwp->SavedReg, VGA_SR_ALL);
1713
outb(0x3c2, restore->clock);
1715
vgaHWProtect(pScrn, FALSE);
1720
static void S3LeaveVT(int scrnIndex, int flags)
1722
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
1723
vgaHWPtr hwp = VGAHWPTR(pScrn);
1732
static void S3AdjustFrame(int scrnIndex, int x, int y, int flags)
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;
1741
if (x > pScrn->displayWidth - pS3->HDisplay)
1742
x = pScrn->displayWidth - pS3->HDisplay;
1744
orig_base = (y * pScrn->displayWidth + x) * pS3->s3Bpp;
1745
base = (orig_base >> 2) & ~1;
1747
/* for IBMRGB and TI only */
1748
if (pS3->RamDac->RamDacType == IBM524A_RAMDAC)
1752
miPointerPosition(&px, &py);
1754
if (pS3->s3Bpp == 1)
1758
if (px-x > pS3->HDisplay/2)
1759
base = ((orig_base + a*4) >> 2) & ~1;
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);
1771
outw(vgaCRIndex, (base & 0x00ff00) | 0x0c);
1772
outw(vgaCRIndex, ((base & 0x00ff) << 8) | 0x0d);
1776
void S3Regdump(ScrnInfoPtr pScrn)
1778
S3Ptr pS3 = S3PTR(pScrn);
1779
int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
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));
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));
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));
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));
1848
for(j=0; j<0x100; j++) {
1849
outb(vgaCRIndex, j);
1850
ErrorF("CRTC 0x%x = 0x%x\n", j, inb(vgaCRReg));
1856
ErrorF("DAC regs\n");
1861
for(j=0; j<0x100; j++)
1862
ErrorF("0x%x = 0x%x\n", j, S3InTiIndReg(pScrn, j));
1864
outb(vgaCRIndex, 0x22);
1865
ErrorF("cr22 = 0x%x\n", inb(vgaCRReg));
1872
void S3BankZero(ScrnInfoPtr pScrn)
1874
S3Ptr pS3 = S3PTR(pScrn);
1876
int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg;
1878
outb(vgaCRIndex, 0x35);
1879
tmp = inb(vgaCRReg) & 0xf0;
1880
outb(vgaCRReg, tmp);
1882
outb(vgaCRIndex, 0x51);
1883
tmp = inb(vgaCRReg) & 0xf3;
1884
outb(vgaCRReg, tmp);
1889
static void S3DisplayPowerManagementSet(ScrnInfoPtr pScrn,
1890
int PowerManagementMode, int flags)
1892
vgaHWDPMSSet(pScrn, PowerManagementMode, flags);