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