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