s3_driver.c revision 4178061c
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#include "shadowfb.h" 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 OPTION_SHADOW_FB, 162 OPTION_ROTATE 163} S3Opts; 164 165static OptionInfoRec S3Options[] = { 166 { OPTION_NOACCEL, "noaccel", OPTV_BOOLEAN, {0}, FALSE }, 167 { OPTION_HWCURS, "hwcursor", OPTV_BOOLEAN, {0}, FALSE }, 168 { OPTION_SLOW_DRAM_REFRESH, "slow_dram_refresh", OPTV_BOOLEAN, {0}, FALSE }, 169 { OPTION_SLOW_DRAM, "slow_dram", OPTV_BOOLEAN, {0}, FALSE }, 170 { OPTION_SLOW_EDODRAM, "slow_edodram", OPTV_BOOLEAN, {0}, FALSE }, 171 { OPTION_SLOW_VRAM, "slow_vram", OPTV_BOOLEAN, {0}, FALSE }, 172 { OPTION_XVIDEO, "XVideo", OPTV_BOOLEAN, {0}, FALSE }, 173 { OPTION_SHADOW_FB, "ShadowFB", OPTV_BOOLEAN, {0}, FALSE }, 174 { OPTION_ROTATE, "Rotate", OPTV_ANYSTR, {0}, FALSE }, 175 { -1, NULL, OPTV_NONE, {0}, FALSE } 176}; 177 178RamDacSupportedInfoRec S3IBMRamdacs[] = { 179 { IBM524_RAMDAC }, 180 { IBM524A_RAMDAC }, 181 { IBM526_RAMDAC }, 182 { IBM526DB_RAMDAC }, 183 { -1 } 184}; 185 186static int s3AccelLinePitches[] = { 640, 800, 1024, 1280, 1600 }; 187 188#ifdef XFree86LOADER 189 190MODULESETUPPROTO(S3Setup); 191 192static XF86ModuleVersionInfo S3VersRec = { 193 "s3", 194 MODULEVENDORSTRING, 195 MODINFOSTRING1, 196 MODINFOSTRING2, 197 XORG_VERSION_CURRENT, 198 VERSION_MAJOR, VERSION_MINOR, PATCHLEVEL, 199 ABI_CLASS_VIDEODRV, 200 ABI_VIDEODRV_VERSION, 201 MOD_CLASS_VIDEODRV, 202 {0, 0, 0, 0} 203}; 204 205 206_X_EXPORT XF86ModuleData s3ModuleData = { &S3VersRec, S3Setup, NULL }; 207 208pointer S3Setup (pointer module, pointer opts, int *errmaj, int *errmin) 209{ 210 static Bool setupDone = FALSE; 211 212 if (!setupDone) { 213 setupDone = TRUE; 214 xf86AddDriver(&S3, module, 0); 215 return (pointer) 1; 216 } else { 217 if (errmaj) 218 *errmaj = LDR_ONCEONLY; 219 return NULL; 220 } 221} 222 223#endif /* XFree86LOADER */ 224 225 226static Bool S3GetRec(ScrnInfoPtr pScrn) 227{ 228 if (pScrn->driverPrivate) 229 return TRUE; 230 231 pScrn->driverPrivate = xnfcalloc(sizeof(S3Rec), 1); 232 233 return TRUE; 234} 235 236static void S3FreeRec(ScrnInfoPtr pScrn) 237{ 238 if (!pScrn->driverPrivate) 239 return; 240 241 xfree(pScrn->driverPrivate); 242 pScrn->driverPrivate = NULL; 243} 244 245static const OptionInfoRec * S3AvailableOptions(int chipid, int busid) 246{ 247 return S3Options; 248} 249 250static void S3Identify(int flags) 251{ 252 xf86PrintChipsets("S3", "driver (version " DRIVER_VERSION " for S3 chipset", 253 S3Chipsets); 254} 255 256static Bool S3Probe(DriverPtr drv, int flags) 257{ 258 GDevPtr *devSections; 259 int i, *usedChips, numDevSections, numUsed; 260 Bool foundScreen = FALSE; 261 262 /* sanity check */ 263 if ((numDevSections = xf86MatchDevice("s3", &devSections)) <= 0) 264 return FALSE; 265 266 /* XXX do ISA later... some day in the distant future... */ 267 numUsed = xf86MatchPciInstances("s3", PCI_VENDOR_S3, 268 S3Chipsets, S3PciChipsets, 269 devSections, numDevSections, 270 drv, &usedChips); 271 272 xfree(devSections); 273 274 if (numUsed <= 0) 275 return FALSE; 276 277 if (flags & PROBE_DETECT) 278 foundScreen = TRUE; 279 else for (i=0; i<numUsed; i++) { 280 ScrnInfoPtr pScrn = xf86AllocateScreen(drv, 0); 281 282 pScrn->driverVersion = VERSION_MAJOR; 283 pScrn->driverName = DRIVER_NAME; 284 pScrn->name = "s3"; 285 pScrn->Probe = S3Probe; 286 pScrn->PreInit = S3PreInit; 287 pScrn->ScreenInit = S3ScreenInit; 288 pScrn->SwitchMode = S3SwitchMode; 289 pScrn->AdjustFrame = S3AdjustFrame; 290 pScrn->EnterVT = S3EnterVT; 291 pScrn->LeaveVT = S3LeaveVT; 292 pScrn->FreeScreen = S3FreeScreen; 293 294 foundScreen = TRUE; 295 296 xf86ConfigActivePciEntity(pScrn, usedChips[i], S3PciChipsets, 297 NULL, NULL, NULL, NULL, NULL); 298 } 299 300 xfree(usedChips); 301 302 return foundScreen; 303} 304 305static Bool S3PreInit(ScrnInfoPtr pScrn, int flags) 306{ 307 EntityInfoPtr pEnt; 308 S3Ptr pS3; 309 vgaHWPtr hwp; 310 ClockRangePtr clockRanges; 311 rgb zeros = {0, 0, 0}; 312 Gamma gzeros = {0.0, 0.0, 0.0}; 313 int i, vgaCRIndex, vgaCRReg; 314 unsigned char tmp; 315 char *s; 316 317 if (flags & PROBE_DETECT) 318 return FALSE; 319 320 if (!xf86LoadSubModule(pScrn, "vgahw")) 321 return FALSE; 322 323 if (!vgaHWGetHWRec(pScrn)) 324 return FALSE; 325 326 hwp = VGAHWPTR(pScrn); 327 vgaHWGetIOBase(hwp); 328 329 pScrn->monitor = pScrn->confScreen->monitor; 330 331 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support24bppFb | Support32bppFb)) 332 return FALSE; 333 334 switch (pScrn->depth) { 335 case 8: 336 case 15: 337 case 16: 338 case 24: 339 /* OK */ 340 break; 341 default: 342 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 343 "Given depth (%d) is not supported by this driver\n", 344 pScrn->depth); 345 return FALSE; 346 } 347 348 xf86PrintDepthBpp(pScrn); 349 350 if (pScrn->depth > 8) { 351 if (!xf86SetWeight(pScrn, zeros, zeros)) 352 return FALSE; 353 } 354 355 if (!xf86SetDefaultVisual(pScrn, -1)) 356 return FALSE; 357 358 pScrn->progClock = TRUE; 359 360 if (!S3GetRec(pScrn)) 361 return FALSE; 362 363 pS3 = S3PTR(pScrn); 364 365 pS3->s3Bpp = (pScrn->bitsPerPixel >> 3); 366 367 xf86CollectOptions(pScrn, NULL); 368 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, S3Options); 369 370 pS3->XVideo = xf86ReturnOptValBool(S3Options, OPTION_XVIDEO, TRUE); 371 pS3->NoAccel = xf86ReturnOptValBool(S3Options, OPTION_NOACCEL, FALSE); 372 pS3->HWCursor = xf86ReturnOptValBool(S3Options, OPTION_HWCURS, FALSE); 373 pS3->SlowDRAMRefresh = xf86ReturnOptValBool(S3Options, OPTION_SLOW_DRAM_REFRESH, FALSE); 374 pS3->SlowDRAM = xf86ReturnOptValBool(S3Options, OPTION_SLOW_DRAM, FALSE); 375 pS3->SlowEDODRAM = xf86ReturnOptValBool(S3Options, OPTION_SLOW_EDODRAM, FALSE); 376 pS3->SlowVRAM = xf86ReturnOptValBool(S3Options, OPTION_SLOW_VRAM, FALSE); 377 378 379 380 if (xf86GetOptValBool(S3Options, OPTION_SHADOW_FB, &pS3->shadowFB)) 381 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShadowFB %s.\n", 382 pS3->shadowFB ? "enabled" : "disabled"); 383 384 pS3->rotate = 0; 385 if ((s = xf86GetOptValString(S3Options, OPTION_ROTATE))) { 386 if(!xf86NameCmp(s, "CW")) { 387 /* accel is disabled below for shadowFB */ 388 pS3->shadowFB = TRUE; 389 pS3->rotate = 1; 390 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 391 "Rotating screen clockwise - acceleration disabled\n"); 392 } else if(!xf86NameCmp(s, "CCW")) { 393 pS3->shadowFB = TRUE; 394 pS3->rotate = -1; 395 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Rotating screen" 396 "counter clockwise - acceleration disabled\n"); 397 } else { 398 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "\"%s\" is not a valid" 399 "value for Option \"Rotate\"\n", s); 400 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 401 "Valid options are \"CW\" or \"CCW\"\n"); 402 } 403 } 404 405 if(pS3->shadowFB && !pS3->NoAccel) { 406 pS3->NoAccel = TRUE; 407 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 408 "HW acceleration not supported with \"shadowFB\".\n"); 409 } 410 411 412 if (pS3->rotate && pS3->HWCursor) { 413 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 414 "HW cursor not supported with \"rotate\".\n"); 415 pS3->HWCursor = FALSE; 416 } 417 418 419 if (pScrn->numEntities > 1) { 420 S3FreeRec(pScrn); 421 return FALSE; 422 } 423 424 pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 425 if (pEnt->resources) { 426 xfree(pEnt); 427 S3FreeRec(pScrn); 428 return FALSE; 429 } 430 431 if (xf86LoadSubModule(pScrn, "int10")) { 432 pS3->pInt10 = xf86InitInt10(pEnt->index); 433 } 434 435 if (xf86LoadSubModule(pScrn, "vbe")) { 436 pS3->pVBE = VBEInit(pS3->pInt10, pEnt->index); 437 } 438 439 if (pS3->shadowFB) { 440 if (!xf86LoadSubModule(pScrn, "shadowfb")) { 441 S3FreeRec(pScrn); 442 return FALSE; 443 } 444 } 445 446 if (!xf86SetGamma(pScrn, gzeros)) 447 return FALSE; 448 449 pS3->PciInfo = xf86GetPciInfoForEntity(pEnt->index); 450 xf86RegisterResources(pEnt->index, NULL, ResNone); 451 /* don't disable PIO funcs */ 452 xf86SetOperatingState(resVgaMemShared, pEnt->index, ResDisableOpr); 453 454 if (pEnt->device->chipset && *pEnt->device->chipset) { 455 pScrn->chipset = pEnt->device->chipset; 456 pS3->Chipset = xf86StringToToken(S3Chipsets, pScrn->chipset); 457 } else if (pEnt->device->chipID >= 0) { 458 pS3->Chipset = pEnt->device->chipID; 459 pScrn->chipset = (char *)xf86TokenToString(S3Chipsets, 460 pS3->Chipset); 461 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 462 "ChipID override: 0x%04X\n", pS3->Chipset); 463 } else { 464 pS3->Chipset = PCI_DEV_DEVICE_ID(pS3->PciInfo); 465 pScrn->chipset = (char *)xf86TokenToString(S3Chipsets, 466 pS3->Chipset); 467 } 468 if (pEnt->device->chipRev >= 0) { 469 pS3->ChipRev = pEnt->device->chipRev; 470 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 471 pS3->ChipRev); 472 } else 473 pS3->ChipRev = PCI_DEV_REVISION(pS3->PciInfo); 474 475 xfree(pEnt); 476 477 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Chipset: \"%s\"\n", 478 pScrn->chipset); 479 480#ifndef XSERVER_LIBPCIACCESS 481 pS3->PciTag = pciTag(pS3->PciInfo->bus, pS3->PciInfo->device, 482 pS3->PciInfo->func); 483#endif 484 485 switch (pS3->Chipset) { 486 case PCI_CHIP_964_0: 487 case PCI_CHIP_964_1: 488 case PCI_CHIP_TRIO: 489 if (pS3->ChipRev >= 0x40) { /* S3 Trio64V+ has the New MMIO */ 490 pS3->S3NewMMIO = TRUE; 491 break; 492 } 493 case PCI_CHIP_AURORA64VP: /* ??? */ 494 pS3->S3NewMMIO = FALSE; 495 break; 496 case PCI_CHIP_TRIO64V2_DXGX: 497 case PCI_CHIP_TRIO64UVP: 498 case PCI_CHIP_968: 499 pS3->S3NewMMIO = TRUE; 500 break; 501 } 502 503 /* TODO: Streams Processor and Xv for Old MMIO */ 504 505 if (((pS3->Chipset == PCI_CHIP_AURORA64VP) || 506 (pS3->Chipset == PCI_CHIP_TRIO64UVP) || 507 (pS3->Chipset == PCI_CHIP_TRIO64V2_DXGX) || 508 ((pS3->Chipset == PCI_CHIP_TRIO) && (pS3->ChipRev >= 0x40))) 509 && (pS3->S3NewMMIO)) 510 pS3->hasStreams = TRUE; 511 else 512 pS3->hasStreams = FALSE; 513 514 pS3->FBAddress = PCI_REGION_BASE(pS3->PciInfo, 0, REGION_MEM); 515 pScrn->memPhysBase = pS3->FBAddress; 516 pScrn->fbOffset = 0; 517 518 if (pS3->S3NewMMIO) 519 pS3->IOAddress = pS3->FBAddress + S3_NEWMMIO_REGBASE; 520 521 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Framebuffer @ 0x%lx\n", 522 pS3->FBAddress); 523 if (pS3->S3NewMMIO) 524 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "MMIO @ 0x%lx\n", 525 pS3->IOAddress); 526 527 pS3->PCIRetry = FALSE; /* not supported yet */ 528 529 pS3->vgaCRIndex = vgaCRIndex = hwp->IOBase + 4; 530 pS3->vgaCRReg = vgaCRReg = hwp->IOBase + 5; 531 532 /* unlock sys regs */ 533 outb(vgaCRIndex, 0x38); 534 outb(vgaCRReg, 0x48); 535 outb(vgaCRIndex, 0x39); 536 outb(vgaCRReg, 0xa5); 537 538 outb(vgaCRIndex, 0x40); 539 tmp = inb(vgaCRReg) | 0x01; 540 outb(vgaCRReg, tmp); 541 outb(vgaCRIndex, 0x35); 542 tmp = inb(vgaCRReg) & ~0x30; 543 outb(vgaCRReg, tmp); 544 545 outb(0x3c4, 0x08); 546 outb(0x3c5, 0x06); 547 outb(vgaCRIndex, 0x33); 548 tmp = (inb(vgaCRReg) & ~(0x2 | 0x10 | 0x40)) | 0x20; 549 outb(vgaCRReg, tmp); 550 551 /* unprotect CRTC[0-7] */ 552 outb(vgaCRIndex, 0x11); 553 tmp = inb(vgaCRReg) & 0x7f; 554 outb(vgaCRReg, tmp); 555 556 /* wake up */ 557 outb(0x46e8, 0x10); 558 outb(0x102, 0x01); 559 outb(0x46e8, 0x08); 560 561 if (pS3->Chipset == PCI_CHIP_TRIO64V2_DXGX) 562 { 563 /* disable DAC power saving to avoid bright left edge */ 564 outb (0x3d4, 0x86); 565 outb (0x3d5, 0x80); 566 /* disable the stream display fetch length control */ 567 outb (0x3d4, 0x90); 568 outb (0x3d5, 0x00); 569 } 570 571 if (!pScrn->videoRam) { 572 /* probe videoram */ 573 outb(vgaCRIndex, 0x36); 574 tmp = inb(vgaCRReg); 575 576 switch ((tmp & 0xe0) >> 5) { 577 case 0: 578 pScrn->videoRam = 4096; 579 break; 580 case 2: 581 pScrn->videoRam = 3072; 582 break; 583 case 3: 584 pScrn->videoRam = 8192; 585 break; 586 case 4: 587 pScrn->videoRam = 2048; 588 break; 589 case 5: 590 pScrn->videoRam = 6144; 591 break; 592 case 6: 593 pScrn->videoRam = 1024; 594 break; 595 } 596 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, 597 "videoRam = %d Kb\n", pScrn->videoRam); 598 } else { 599 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 600 "videoRam = %d Kb\n", pScrn->videoRam); 601 } 602 603 if (!xf86LoadSubModule(pScrn, "ramdac")) 604 return FALSE; 605 606 pScrn->rgbBits = 8; /* set default */ 607 608 /* probe for dac */ 609 if (S3TiDACProbe(pScrn)) { 610 pS3->DacPreInit = S3TiDAC_PreInit; 611 pS3->DacInit = S3TiDAC_Init; 612 pS3->DacSave = S3TiDAC_Save; 613 pS3->DacRestore = S3TiDAC_Restore; 614#if 0 615 /* FIXME, cursor is drawn in wrong position */ 616 pS3->CursorInit = S3Ti_CursorInit; 617#endif 618 pS3->MaxClock = 135000; 619 pScrn->rgbBits = 8; 620 if (pScrn->bitsPerPixel > 8) 621 pS3->LoadPalette = S3TiLoadPalette; 622 else 623 pS3->LoadPalette = S3GenericLoadPalette; 624 } 625 if (S3ProbeIBMramdac(pScrn)) { 626 pS3->DacPreInit = S3IBMRGB_PreInit; 627 pS3->DacInit = S3IBMRGB_Init; 628 pS3->DacSave = S3IBMRGB_Save; 629 pS3->DacRestore = S3IBMRGB_Restore; 630 pS3->CursorInit = S3IBMRGB_CursorInit; 631 pS3->RamDac->SetBpp = IBMramdac526SetBppWeak(); 632 pS3->MaxClock = 170000; 633 pScrn->rgbBits = 8; 634 pS3->LoadPalette = S3GenericLoadPalette; 635 } 636 if (S3Trio64DACProbe(pScrn)) { 637 pS3->DacPreInit = S3Trio64DAC_PreInit; 638 pS3->DacInit = S3Trio64DAC_Init; 639 pS3->DacSave = S3Trio64DAC_Save; 640 pS3->DacRestore = S3Trio64DAC_Restore; 641#if 0 642 pS3->CursorInit = S3_CursorInit; /* FIXME broken */ 643#endif 644 switch(pScrn->bitsPerPixel) { 645 case 8: 646 if (pS3->Chipset == PCI_CHIP_TRIO64V2_DXGX) 647 pS3->MaxClock = 170000; 648 else 649 pS3->MaxClock = 135000; 650 651 pScrn->rgbBits = 6; 652 break; 653 case 16: 654 pS3->MaxClock = 80000; 655 pScrn->rgbBits = 6; 656 break; 657 case 24: 658 case 32: 659 if (pS3->Chipset == PCI_CHIP_TRIO64V2_DXGX) 660 pS3->MaxClock = 56700; 661 else 662 pS3->MaxClock = 50000; 663 664 pScrn->rgbBits = 8; 665 break; 666 } 667 668 pS3->LoadPalette = S3GenericLoadPalette; 669 } 670 671 if (pS3->RamDac == NULL) { 672 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 673 "Ramdac probe failed\n"); 674 return FALSE; 675 } 676 677 if (!pS3->HWCursor) 678 pS3->CursorInit = NULL; 679 680 pS3->RefClock = S3GetRefClock(pScrn); 681 682 if (pS3->DacPreInit) 683 pS3->DacPreInit(pScrn); 684 685 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "RefClock: %d\n", 686 pS3->RefClock); 687 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Max pixel clock at this depth is %d Mhz\n", 688 pS3->MaxClock / 1000); 689 690 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 691 clockRanges->next = NULL; 692 clockRanges->minClock = 15600; 693 clockRanges->maxClock = pS3->MaxClock; 694 clockRanges->clockIndex = -1; 695 clockRanges->interlaceAllowed = TRUE; /* not yet */ 696 clockRanges->doubleScanAllowed = TRUE; /* not yet */ 697 698 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 699 pScrn->display->modes, clockRanges, 700 pS3->NoAccel ? NULL : s3AccelLinePitches, 701 256, 2048, 702 pScrn->bitsPerPixel, 128, 2048, 703 pScrn->display->virtualX, 704 pScrn->display->virtualY, pScrn->videoRam * 1024, 705 LOOKUP_BEST_REFRESH); 706 707 if (i == -1) { 708 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes left\n"); 709 S3FreeRec(pScrn); 710 return FALSE; 711 } 712 713 xf86PruneDriverModes(pScrn); 714 715 if (i == 0 || pScrn->modes == NULL) { 716 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "no valid modes found\n"); 717 S3FreeRec(pScrn); 718 return FALSE; 719 } 720 721 xf86SetCrtcForModes(pScrn, INTERLACE_HALVE_V); 722 pScrn->currentMode = pScrn->modes; 723 xf86PrintModes(pScrn); 724 xf86SetDpi(pScrn, 0, 0); 725 726 xf86LoadSubModule(pScrn, "fb"); 727 728 if (!xf86LoadSubModule(pScrn, "xaa")) 729 return FALSE; 730 731 return TRUE; 732} 733 734 735static Bool S3ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, 736 char **argv) 737{ 738 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 739 S3Ptr pS3 = S3PTR(pScrn); 740 BoxRec ScreenArea; 741 int width, height, displayWidth; 742 743 if (pS3->rotate) { 744 height = pScrn->virtualX; 745 width = pScrn->virtualY; 746 } else { 747 width = pScrn->virtualX; 748 height = pScrn->virtualY; 749 } 750 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 /* no screen rotation assumed */ 786 if(pS3->shadowFB) { 787 pS3->ShadowPitch = BitmapBytePad(pScrn->bitsPerPixel * width); 788 pS3->ShadowPtr = xalloc(pS3->ShadowPitch * height); 789 displayWidth = pS3->ShadowPitch / (pScrn->bitsPerPixel >> 3); 790 } else { 791 pS3->ShadowPtr = NULL; 792 displayWidth = pScrn->displayWidth; 793 } 794 795 if (!fbScreenInit(pScreen, (pS3->shadowFB ? pS3->ShadowPtr : pS3->FBBase), 796 pScrn->virtualX, 797 pScrn->virtualY, pScrn->xDpi, pScrn->yDpi, 798 pScrn->displayWidth, pScrn->bitsPerPixel)) 799 return FALSE; 800 801 xf86SetBlackWhitePixels(pScreen); 802 803 if (pScrn->bitsPerPixel > 8) { 804 VisualPtr pVis; 805 806 pVis = pScreen->visuals + pScreen->numVisuals; 807 while (--pVis >= pScreen->visuals) { 808 if ((pVis->class | DynamicClass) == DirectColor) { 809 pVis->offsetRed = pScrn->offset.red; 810 pVis->offsetGreen = pScrn->offset.green; 811 pVis->offsetBlue = pScrn->offset.blue; 812 pVis->redMask = pScrn->mask.red; 813 pVis->greenMask = pScrn->mask.green; 814 pVis->blueMask = pScrn->mask.blue; 815 } 816 } 817 } 818 fbPictureInit (pScreen, 0, 0); 819 S3DGAInit(pScreen); 820 821 miInitializeBackingStore(pScreen); 822 xf86SetBackingStore(pScreen); 823 824 /* framebuffer manager setup */ 825 ScreenArea.x1 = 0; 826 ScreenArea.y1 = 0; 827 ScreenArea.x2 = pScrn->displayWidth; 828 ScreenArea.y2 = (pScrn->videoRam * 1024) / pS3->s3BppDisplayWidth; 829 830 if (!xf86InitFBManager(pScreen, &ScreenArea)) { 831 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 832 "Memory manager initialization to (%d,%d) (%d,%d) failed\n", 833 ScreenArea.x1, ScreenArea.y1, 834 ScreenArea.x2, ScreenArea.y2); 835 return FALSE; 836 } else 837 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 838 "Memory manager initialized to (%d,%d) (%d,%d)\n", 839 ScreenArea.x1, ScreenArea.y1, 840 ScreenArea.x2, ScreenArea.y2); 841 842 /* 2D acceleration setup */ 843 844 if (pS3->NoAccel) 845 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 846 "Acceleration disabled (by option)\n"); 847 848 /* It seems that acceleration isn't supported for 24-bit packed 849 colour. So disable it. Using shadowFB is recommended in this mode. */ 850 if (!pS3->NoAccel && (pScrn->bitsPerPixel == 24)) { 851 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "HW acceleration isn't supported for 24 bpp. Disabled.\n"); 852 pS3->NoAccel = TRUE; 853 } 854 855 856 if (!pS3->NoAccel) { 857 if (pS3->S3NewMMIO) 858 if (S3AccelInitNewMMIO(pScreen)) { 859 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 860 "Acceleration enabled\n"); 861 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 862 "Using NewMMIO\n"); 863 } else { 864 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 865 "Acceleration initialization failed\n"); 866 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 867 "Acceleration disabled\n"); 868 } 869 else { 870 if (S3AccelInitPIO(pScreen)) { 871 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 872 "Acceleration enabled\n"); 873 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 874 "Using PIO\n"); 875 } else { 876 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 877 "Acceleration initialization failed\n"); 878 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 879 "Acceleration disabled\n"); 880 } 881 } 882 } 883 884 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 885 886 /* HW cursor setup */ 887 888 if (pS3->CursorInit) { 889 if (pS3->CursorInit(pScreen)) 890 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using HW cursor\n"); 891 else { 892 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "HW cursor initialization failed\n"); 893 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using SW cursor\n"); 894 } 895 } else 896 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using SW cursor\n"); 897 898 899 /* Shadow framebuffer setup */ 900 901 if (pS3->shadowFB) { 902 RefreshAreaFuncPtr refreshArea = S3RefreshArea; 903 904 if (pS3->rotate) { 905 if (!pS3->PointerMoved) { 906 pS3->PointerMoved = pScrn->PointerMoved; 907 pScrn->PointerMoved = S3PointerMoved; 908 } 909 910 switch (pScrn->bitsPerPixel) { 911 case 8: refreshArea = S3RefreshArea8; break; 912 case 16: refreshArea = S3RefreshArea16; break; 913 case 24: refreshArea = S3RefreshArea24; break; 914 case 32: refreshArea = S3RefreshArea32; break; 915 } 916 } 917 918 ShadowFBInit(pScreen, refreshArea); 919 } 920 921 922 923 if (!miCreateDefColormap(pScreen)) 924 return FALSE; 925 926 if (!xf86HandleColormaps(pScreen, 256, pScrn->rgbBits, 927 pS3->LoadPalette, NULL, 928 CMAP_RELOAD_ON_MODE_SWITCH)) 929 return FALSE; 930 931 vgaHWBlankScreen(pScrn, FALSE); 932 933 pScreen->SaveScreen = S3SaveScreen; 934 pS3->CloseScreen = pScreen->CloseScreen; 935 pScreen->CloseScreen = S3CloseScreen; 936 937 xf86DPMSInit(pScreen, S3DisplayPowerManagementSet, 0); 938 939 /* XXX Check if I/O and Mem flags need to be the same. */ 940 pScrn->racIoFlags = pScrn->racMemFlags = RAC_COLORMAP 941 | RAC_FB | RAC_VIEWPORT | RAC_CURSOR; 942 943 if (pS3->SlowEDODRAM) 944 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 945 "SlowEDODRAM: Setting 2-cycle EDO\n"); 946 947 if (pS3->SlowVRAM) 948 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 949 "SlowVRAM: -RAS low time is 4.5 MCLKs\n"); 950 951 if (pS3->SlowDRAM) 952 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 953 "SlowDRAM: -RAS precharge time is 3.5 MCLKs\n"); 954 955 if (pS3->SlowDRAMRefresh) 956 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 957 "SlowDRAMRefresh: three refresh cycles per scanline\n"); 958 959 /* XVideo setup */ 960 961 if (pS3->XVideo) { 962 if (!pS3->hasStreams) { 963 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Overlay video isn't supported by video hardware. Disabled.\n"); 964 pS3->XVideo = FALSE; 965 } else if (pScrn->bitsPerPixel < 16) { 966 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Overlay video isn't supported for %d bpp. Disabled.\n", pScrn->bitsPerPixel); 967 pS3->XVideo = FALSE; 968 } 969 } else 970 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, 971 "Overlay video disabled by option\n"); 972 973 /* At present time we support XV only for chips with New MMIO */ 974 if ((pS3->XVideo) && (pS3->S3NewMMIO)) 975 S3InitVideo(pScreen); 976 977 switch (pScrn->bitsPerPixel) { 978 case 8: 979 pS3->Streams_FIFO = FIFO_PS16_SS8; 980 break; 981 case 15: 982 case 16: 983 pS3->Streams_FIFO = FIFO_PS12_SS12; 984 break; 985 case 24: 986 case 32: 987 pS3->Streams_FIFO = FIFO_PS8_SS16; 988 break; 989 } 990 991 return TRUE; 992} 993 994 995 996 997static void S3Save(ScrnInfoPtr pScrn) 998{ 999 S3Ptr pS3 = S3PTR(pScrn); 1000 S3RegPtr save = &pS3->SavedRegs; 1001 vgaHWPtr hwp = VGAHWPTR(pScrn); 1002 vgaRegPtr pVga = &hwp->SavedReg; 1003 int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 1004 int i; 1005 unsigned char cr5c = 0; 1006 1007 S3BankZero(pScrn); 1008 1009 save->clock = inb(0x3cc); 1010 1011 vgaHWSave(pScrn, pVga, VGA_SR_ALL); 1012 1013 if (pS3->RamDac->RamDacType == TI3025_RAMDAC) { 1014 outb(vgaCRIndex, 0x5c); 1015 cr5c = inb(vgaCRReg); 1016 } 1017 1018 pS3->DacSave(pScrn); 1019 1020 for(i=0; i<5; i++) { 1021 outb(vgaCRIndex, 0x30 + i); 1022 save->s3save[i] = inb(vgaCRReg); 1023 outb(vgaCRIndex, 0x38 + i); 1024 save->s3save[5 + i] = inb(vgaCRReg); 1025 } 1026 1027 for (i=0; i<16; i++) { 1028 outb(vgaCRIndex, 0x40 + i); 1029 save->s3syssave[i] = inb(vgaCRReg); 1030 } 1031 1032 outb(vgaCRIndex, 0x45); 1033 inb(vgaCRReg); 1034 outb(vgaCRIndex, 0x4a); 1035 for(i=0; i<4; i++) { 1036 save->color_stack[i] = inb(vgaCRReg); 1037 outb(vgaCRReg, save->color_stack[i]); 1038 } 1039 1040 outb(vgaCRIndex, 0x45); 1041 inb(vgaCRReg); 1042 outb(vgaCRIndex, 0x4b); 1043 for(i=4; i<8; i++) { 1044 save->color_stack[i] = inb(vgaCRReg); 1045 outb(vgaCRReg, save->color_stack[i]); 1046 } 1047 1048 for(i=0; i<16; i++) { 1049 for (i=0; i<16; i++) { 1050 if (!((1 << i) & 0x673b)) 1051 continue; 1052 outb(vgaCRIndex, 0x50 + i); 1053 save->s3syssave[i + 16] = inb(vgaCRReg); 1054 } 1055 } 1056 1057 if (pS3->RamDac->RamDacType == TI3025_RAMDAC) 1058 save->s3syssave[0x0c + 16] = cr5c; 1059 1060 for(i=32; i<46; i++) { 1061 outb(vgaCRIndex, 0x40 + i); 1062 save->s3syssave[i] = inb(vgaCRReg); 1063 } 1064} 1065 1066 1067Bool S3SaveScreen(ScreenPtr pScreen, int mode) 1068{ 1069 return vgaHWSaveScreen(pScreen, mode); 1070} 1071 1072 1073static void S3FreeScreen(int scrnIndex, int flags) 1074{ 1075 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1076 1077 vgaHWFreeHWRec(pScrn); 1078 1079 S3FreeRec(pScrn); 1080} 1081 1082 1083Bool S3CloseScreen(int scrnIndex, ScreenPtr pScreen) 1084{ 1085 ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; 1086 S3Ptr pS3 = S3PTR(pScrn); 1087 vgaHWPtr hwp = VGAHWPTR(pScrn); 1088 1089 if (pScrn->vtSema) { 1090 vgaHWUnlock(hwp); 1091 S3Restore(pScrn); 1092 vgaHWLock(hwp); 1093 S3UnmapMem(pScrn); 1094 } 1095 1096 if (pS3->DGAModes) 1097 xfree(pS3->DGAModes); 1098 pS3->DGAModes = NULL; 1099 1100 pScrn->vtSema = FALSE; 1101 pScreen->CloseScreen = pS3->CloseScreen; 1102 1103 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 1104} 1105 1106 1107Bool S3SwitchMode(int scrnIndex, DisplayModePtr mode, int flags) 1108{ 1109 return S3ModeInit(xf86Screens[scrnIndex], mode); 1110 1111} 1112 1113 1114static void S3GenericLoadPalette(ScrnInfoPtr pScrn, int numColors, 1115 int *indicies, LOCO *colors, 1116 VisualPtr pVisual) 1117{ 1118 int i, index; 1119 1120 for (i=0; i<numColors; i++) { 1121 index = indicies[i]; 1122 outb(0x3c8, index); 1123 outb(0x3c9, colors[index].red); 1124 outb(0x3c9, colors[index].green); 1125 outb(0x3c9, colors[index].blue); 1126 } 1127} 1128 1129 1130static Bool S3MapMem(ScrnInfoPtr pScrn) 1131{ 1132 S3Ptr pS3 = S3PTR(pScrn); 1133 1134 if (pS3->S3NewMMIO) { 1135 1136 1137#ifndef XSERVER_LIBPCIACCESS 1138 pS3->MMIOBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_MMIO, 1139 pS3->PciTag, pS3->IOAddress, 1140 S3_NEWMMIO_REGSIZE); 1141#else 1142 { 1143 void** result = (void**)&pS3->MMIOBase; 1144 int err = pci_device_map_range(pS3->PciInfo, 1145 pS3->IOAddress, 1146 S3_NEWMMIO_REGSIZE, 1147 PCI_DEV_MAP_FLAG_WRITABLE, 1148 result); 1149 1150 if (err) 1151 return FALSE; 1152 } 1153#endif 1154 if (!pS3->MMIOBase) { 1155 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1156 "Could not map MMIO\n"); 1157 return FALSE; 1158 } 1159 } 1160 1161#ifndef XSERVER_LIBPCIACCESS 1162 pS3->FBBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 1163 pS3->PciTag, pS3->FBAddress, 1164 pScrn->videoRam * 1024); 1165 1166#else 1167 { 1168 void** result = (void**)&pS3->FBBase; 1169 int err = pci_device_map_range(pS3->PciInfo, 1170 pS3->FBAddress, 1171 pScrn->videoRam * 1024, 1172 PCI_DEV_MAP_FLAG_WRITABLE | 1173 PCI_DEV_MAP_FLAG_WRITE_COMBINE, 1174 result); 1175 1176 if (err) 1177 return FALSE; 1178 } 1179#endif 1180 if (!pS3->FBBase) { 1181 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1182 "Could not map framebuffer\n"); 1183 return FALSE; 1184 } 1185 1186 pS3->FBCursorOffset = pScrn->videoRam - 1; 1187 1188 return TRUE; 1189} 1190 1191 1192static void S3UnmapMem(ScrnInfoPtr pScrn) 1193{ 1194 S3Ptr pS3 = S3PTR(pScrn); 1195 1196 if (pS3->S3NewMMIO) { 1197#ifndef XSERVER_LIBPCIACCESS 1198 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pS3->MMIOBase, 1199 S3_NEWMMIO_REGSIZE); 1200#else 1201 pci_device_unmap_range(pS3->PciInfo, pS3->MMIOBase, S3_NEWMMIO_REGSIZE); 1202#endif 1203 } 1204 1205#ifndef XSERVER_LIBPCIACCESS 1206 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pS3->FBBase, 1207 pScrn->videoRam * 1024); 1208#else 1209 pci_device_unmap_range(pS3->PciInfo, pS3->FBBase, pScrn->videoRam * 1024); 1210#endif 1211 1212 return; 1213} 1214 1215 1216static int S3GetPixMuxShift(ScrnInfoPtr pScrn) 1217{ 1218 S3Ptr pS3 = S3PTR(pScrn); 1219 int shift = 0; 1220 1221 if (pS3->Chipset == PCI_CHIP_968) 1222 shift = 1; /* XXX IBMRGB */ 1223 else if (pS3->Chipset == PCI_CHIP_TRIO || 1224 pS3->Chipset == PCI_CHIP_TRIO64UVP || 1225 pS3->Chipset == PCI_CHIP_TRIO64V2_DXGX) { 1226 if (pS3->s3Bpp == 2) 1227 shift = -1; 1228 else 1229 shift = 0; 1230 } 1231 1232 return shift; 1233} 1234 1235static Bool S3ModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 1236{ 1237 S3Ptr pS3 = S3PTR(pScrn); 1238 S3RegPtr new = &pS3->ModeRegs; 1239 vgaHWPtr hwp = VGAHWPTR(pScrn); 1240 vgaRegPtr pVga = &hwp->ModeReg; 1241 int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 1242 int vgaIOBase = hwp->IOBase; 1243 int r, n, m; 1244 unsigned char tmp; 1245 1246 pS3->pixMuxShift = S3GetPixMuxShift(pScrn); 1247 1248 pS3->s3BppDisplayWidth = pScrn->displayWidth * pS3->s3Bpp; 1249 pS3->hwCursor = (mode->Flags & V_DBLSCAN) ? FALSE : TRUE; 1250 pS3->HDisplay = mode->HDisplay; 1251 1252 pS3->s3ScissB = ((pScrn->videoRam * 1024) / pS3->s3BppDisplayWidth) - 1; 1253 pS3->s3ScissR = pScrn->displayWidth - 1; 1254 1255 /* 1256 Set correct blanking for S3 Trio64V2. It's also needed 1257 to clear cr33_5. 1258 */ 1259 if (pS3->Chipset == PCI_CHIP_TRIO64V2_DXGX) 1260 mode->CrtcHBlankStart = mode->CrtcHDisplay + 8; 1261 1262 if ((mode->HTotal == mode->CrtcHTotal) && (pS3->pixMuxShift != 0)) { 1263 if (pS3->pixMuxShift > 0) { 1264 mode->CrtcHTotal >>= pS3->pixMuxShift; 1265 mode->CrtcHDisplay >>= pS3->pixMuxShift; 1266 mode->CrtcHBlankStart >>= pS3->pixMuxShift; 1267 mode->CrtcHBlankEnd >>= pS3->pixMuxShift; 1268 mode->CrtcHSyncStart >>= pS3->pixMuxShift; 1269 mode->CrtcHSyncEnd >>= pS3->pixMuxShift; 1270 mode->CrtcHSkew >>= pS3->pixMuxShift; 1271 } else if (pS3->pixMuxShift < 0) { 1272 mode->CrtcHTotal <<= -pS3->pixMuxShift; 1273 mode->CrtcHDisplay <<= -pS3->pixMuxShift; 1274 mode->CrtcHBlankStart <<= -pS3->pixMuxShift; 1275 mode->CrtcHBlankEnd <<= -pS3->pixMuxShift; 1276 mode->CrtcHSyncStart <<= -pS3->pixMuxShift; 1277 mode->CrtcHSyncEnd <<= -pS3->pixMuxShift; 1278 mode->CrtcHSkew <<= -pS3->pixMuxShift; 1279 } 1280 } 1281 1282 if (!vgaHWInit(pScrn, mode)) 1283 return FALSE; 1284 1285 1286 1287 pVga->MiscOutReg |= 0x0c; 1288 pVga->Sequencer[0] = 0x03; 1289 pVga->CRTC[19] = pS3->s3BppDisplayWidth >> 3; 1290 pVga->CRTC[23] = 0xe3; 1291 pVga->Attribute[0x11] = 0xff; 1292 1293 if (vgaIOBase == 0x3b0) 1294 pVga->MiscOutReg &= 0xfe; 1295 else 1296 pVga->MiscOutReg |= 0x01; 1297 1298 /* ok i give up also, i'm writing in here */ 1299 1300 vgaHWProtect(pScrn, TRUE); 1301 1302 1303 if (pS3->RamDac->RamDacType == TI3025_RAMDAC) { 1304 outb(vgaCRIndex, 0x5c); 1305 tmp = inb(vgaCRReg); 1306 outb(vgaCRReg, tmp & 0xdf); 1307 1308 S3OutTiIndReg(pScrn, TIDAC_ind_curs_ctrl, 0x7f, 0x00); 1309 } 1310 1311 pS3->DacInit(pScrn, mode); 1312 1313 outb(0x3c2, pVga->MiscOutReg); 1314 1315 for(r=1; r<5; r++) { 1316 outw(0x3c4, (pVga->Sequencer[r] << 8) | r); 1317 } 1318 1319 /* We need to set this first - S3 *is* broken */ 1320 outw(vgaCRIndex, (pVga->CRTC[17] << 8) | 17); 1321 for(r=0; r<25; r++) 1322 outw(vgaCRIndex, (pVga->CRTC[r] << 8) | r); 1323 1324 for(r=0; r<9; r++) 1325 outw(0x3ce, (pVga->Graphics[r] << 8) | r); 1326 1327 inb(vgaIOBase + 0x0a); 1328 1329 for(r=0; r<16; r++) { 1330 outb(0x3c0, r); 1331 outb(0x3c0, pVga->Attribute[r]); 1332 } 1333 for(r=16; r<21; r++) { 1334 outb(0x3c0, r | 0x20); 1335 outb(0x3c0, pVga->Attribute[r]); 1336 } 1337 1338 1339 new->cr31 = 0x8d; 1340 outb(vgaCRIndex, 0x31); 1341 outb(vgaCRReg, new->cr31); 1342 1343 new->cr32 = 0x00; 1344 outb(vgaCRIndex, 0x32); 1345 outb(vgaCRReg, new->cr32); 1346 1347 outb(vgaCRIndex, 0x33); 1348 new->cr33 = inb(vgaCRReg) | 0x20; 1349 if ((pS3->Chipset == PCI_CHIP_964_0) || 1350 (pS3->Chipset == PCI_CHIP_964_1)) 1351 new->cr33 = 0x20; 1352 else if (pS3->Chipset == PCI_CHIP_TRIO64V2_DXGX) 1353 new->cr33 &= ~0x20; 1354 outb(vgaCRReg, new->cr33); 1355 1356 new->cr34 = 0x10; 1357 outb(vgaCRIndex, 0x34); 1358 outb(vgaCRReg, new->cr34); 1359 1360 if (pS3->Chipset != PCI_CHIP_AURORA64VP) { 1361 new->cr3b = (pVga->CRTC[0] + pVga->CRTC[4] + 1) / 2; 1362 outb(vgaCRIndex, 0x3b); 1363 outb(vgaCRReg, new->cr3b); 1364 } 1365 1366 new->cr3c = pVga->CRTC[0] / 2; 1367 outb(vgaCRIndex, 0x3c); 1368 outb(vgaCRReg, new->cr3c); 1369 1370 outb(vgaCRIndex, 0x40); 1371 tmp = inb(vgaCRReg); 1372 new->cr40 = (tmp & 0xf2) | 0x05; 1373 outb(vgaCRReg, new->cr40); 1374 1375 outb(vgaCRIndex, 0x43); 1376 switch (pScrn->bitsPerPixel) { 1377 case 24: 1378 case 32: 1379 new->cr43 = inb(vgaCRReg); 1380 break; 1381 case 15: 1382 case 16: 1383 if ((pS3->RamDac->RamDacType == IBM524_RAMDAC) || 1384 (pS3->RamDac->RamDacType == IBM524A_RAMDAC) || 1385 (pS3->RamDac->RamDacType == TI3025_RAMDAC)) 1386 new->cr43 = 0x10; 1387 else if (pS3->RamDac->RamDacType == TRIO64_RAMDAC) 1388 new->cr43 = 0x09; 1389 break; 1390 case 8: 1391 default: 1392 new->cr43 = 0x00; 1393 break; 1394 } 1395 outb(vgaCRReg, new->cr43); 1396 1397 new->cr44 = 0x00; 1398 outb(vgaCRIndex, 0x44); 1399 outb(vgaCRReg, new->cr44); 1400 1401 outb(vgaCRIndex, 0x45); 1402 new->cr45 = inb(vgaCRReg) & 0xf2; 1403 outb(vgaCRReg, new->cr45); 1404 1405 outb(vgaCRIndex, 0x50); 1406 tmp = inb(vgaCRReg) & ~0xf1; 1407 switch (pScrn->bitsPerPixel) { 1408 case 8: 1409 break; 1410 case 16: 1411 tmp |= 0x10; 1412 break; 1413 case 24: 1414 tmp |= 0x20; /* there is no such value in spec s3.txt */ 1415 break; 1416 case 32: 1417 tmp |= 0x30; 1418 break; 1419 } 1420 1421 switch (pScrn->displayWidth) { 1422 case 640: 1423 tmp |= 0x40; 1424 break; 1425 case 800: 1426 tmp |= 0x80; 1427 break; 1428 case 1152: 1429 tmp |= 0x01; 1430 break; 1431 case 1280: 1432 tmp |= 0xc0; 1433 break; 1434 case 1600: 1435 tmp |= 0x81; 1436 break; 1437 } 1438 new->cr50 = tmp; 1439 outb(vgaCRReg, new->cr50); 1440 1441 1442 outb(vgaCRIndex, 0x51); 1443 new->cr51 = (inb(vgaCRReg) & 0xc0) | 1444 ((pS3->s3BppDisplayWidth >> 7) & 0x30); 1445 outb(vgaCRReg, new->cr51); 1446 1447 outb(vgaCRIndex, 0x53); 1448 new->cr53 = inb(vgaCRReg); 1449 if (pS3->S3NewMMIO) 1450 new->cr53 |= 0x18; 1451 else 1452 new->cr53 &= ~0x18; 1453 outb(vgaCRReg, new->cr53); 1454 1455 n = 255; 1456 outb(vgaCRIndex, 0x54); 1457 { 1458 int clock2, mclk; 1459 1460 clock2 = mode->Clock * pS3->s3Bpp; 1461 if (pScrn->videoRam < 2048) 1462 clock2 *= 2; 1463 mclk = pS3->mclk; 1464 m = (int)((mclk/1000.0*.72+16.867)*89.736/(clock2/1000.0+39)-21.1543); 1465 if (pScrn->videoRam < 2048) 1466 m /= 2; 1467 if (m >31) 1468 m = 31; 1469 else if (m < 0) { 1470 m = 0; 1471 n = 16; 1472 } 1473 } 1474 new->cr54 = m << 3; 1475 outb(vgaCRReg, new->cr54); 1476 1477 if (n < 0) 1478 n = 0; 1479 else if (n > 255) 1480 n = 255; 1481 outb(vgaCRIndex, 0x60); 1482 new->cr60 = n; 1483 outb(vgaCRReg, new->cr60); 1484 1485 if (pS3->hasStreams) { 1486 new->cr60 = 255; 1487 outb(vgaCRIndex, 0x60); 1488 outb(vgaCRReg, new->cr60); 1489 1490 new->cr54 = 31 << 3; 1491 outb(vgaCRIndex, 0x54); 1492 outb(vgaCRReg, new->cr54); 1493 } 1494 1495 outb(vgaCRIndex, 0x55); 1496 new->cr55 = (inb(vgaCRReg) & 0x08) | 0x40; 1497 outb(vgaCRReg, new->cr55); 1498 1499 outb(vgaCRIndex, 0x5e); 1500 new->cr5e = (((mode->CrtcVTotal - 2) & 0x400) >> 10) | 1501 (((mode->CrtcVDisplay - 1) & 0x400) >> 9) | 1502 (((mode->CrtcVSyncStart) & 0x400) >> 8) | 1503 (((mode->CrtcVSyncStart) & 0x400) >> 6) | 0x40; 1504 outb(vgaCRReg, new->cr5e); 1505 1506 { 1507 int i; 1508 unsigned int j; 1509 1510 i = ((((mode->CrtcHTotal >> 3) - 5) & 0x100) >> 8) | 1511 ((((mode->CrtcHDisplay >> 3) - 1) & 0x100) >> 7) | 1512 ((((mode->CrtcHSyncStart >> 3) - 1) & 0x100) >> 6) | 1513 ((mode->CrtcHSyncStart & 0x800) >> 7); 1514 if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 64) 1515 i |= 0x08; 1516 if ((mode->CrtcHSyncEnd >> 3) - (mode->CrtcHSyncStart >> 3) > 32) 1517 i |= 0x20; 1518 1519 outb(vgaCRIndex, 0x3b); 1520 j = ((pVga->CRTC[0] + ((i & 0x01) << 8) + 1521 pVga->CRTC[4] + ((i & 0x10) << 4) + 1) / 2); 1522 1523 if (j - (pVga->CRTC[4] + ((i & 0x10) << 4)) < 4) { 1524 if (pVga->CRTC[4] + ((i & 0x10) << 4) + 4 <= pVga->CRTC[0] + ((i & 0x01) << 8)) 1525 j = pVga->CRTC[4] + ((i & 0x10) << 4) + 4; 1526 else 1527 j = pVga->CRTC[0] + ((i & 0x01) << 8) + 1; 1528 } 1529 if (pS3->Chipset == PCI_CHIP_AURORA64VP) { 1530 outb(vgaCRReg, 0x00); 1531 i &= ~0x40; 1532 } else { 1533 new->cr3b = j & 0xff; 1534 outb(vgaCRReg, new->cr3b); 1535 i |= (j & 0x100) >> 2; 1536 } 1537 1538 outb(vgaCRIndex, 0x3c); 1539 new->cr3c = (pVga->CRTC[0] + ((i & 0x01) << 8)) / 2; 1540 outb(vgaCRReg, new->cr3c); 1541 1542 outb(vgaCRIndex, 0x5d); 1543 new->cr5d = (inb(vgaCRReg) & 0x80) | i; 1544 outb(vgaCRReg, new->cr5d); 1545 } 1546 1547 { 1548 int i; 1549 1550 if (pScrn->videoRam > 1024) 1551 i = mode->HDisplay * pS3->s3Bpp / 8 + 1; 1552 else 1553 i = mode->HDisplay * pS3->s3Bpp / 4 + 1; 1554 1555 outb(vgaCRIndex, 0x61); 1556 tmp = 0x80 | (inb(vgaCRReg) & 0x60) | (i >> 8); 1557 new->cr61 = tmp; 1558 outb(vgaCRReg, new->cr61); 1559 outb(vgaCRIndex, 0x62); 1560 new->cr62 = i & 0xff; 1561 outb(vgaCRReg, new->cr62); 1562 } 1563 1564 if (mode->Flags & V_INTERLACE) { 1565 outb(vgaCRIndex, 0x42); 1566 new->cr42 = inb(vgaCRReg) | 0x20; 1567 outb(vgaCRReg, new->cr42); 1568 } else { 1569 outb(vgaCRIndex, 0x42); 1570 new->cr42 = inb(vgaCRReg) & ~0x20; 1571 outb(vgaCRReg, new->cr42); 1572 } 1573 1574 if (pS3->hasStreams) { 1575 unsigned char a; 1576 1577 outb(vgaCRIndex, 0x67); 1578 a = inb(vgaCRReg) & 0xfe; 1579 1580 switch (pScrn->depth) { 1581 case 8: 1582 break; 1583 case 15: 1584 a |= (3 << 4); 1585 break; 1586 case 16: 1587 a |= (5 << 4); 1588 break; 1589 case 24: 1590 a |= (13 << 4); 1591 break; 1592 } 1593 1594 if (pS3->hasStreams) 1595 a |= (3 << 2); 1596 1597 WaitVSync(); /* Wait for VSync before setting mode */ 1598 outb(vgaCRReg, a); 1599 } 1600 1601 if (pS3->Chipset == PCI_CHIP_968) { 1602 unsigned char a; 1603 1604 outb(vgaCRIndex, 0x67); 1605 a = inb(vgaCRReg) & 0xfe; 1606#if 0 1607 switch (pScrn->depth) { 1608 case 8: 1609 break; 1610 case 15: 1611 a |= (3 << 4); 1612 break; 1613 case 16: 1614 a |= (5 << 4); 1615 a |= (3 << 2); /* streams */ 1616 break; 1617 case 24: 1618 a |= (13 << 4); 1619 a |= (3 << 2); /* streams */ 1620 break; 1621 } 1622#endif 1623 outb(vgaCRReg, a); 1624 1625 outb(vgaCRIndex, 0x6d); 1626 outb(vgaCRReg, 0x00); 1627 } 1628 1629 if ((pS3->Chipset == PCI_CHIP_964_0) || 1630 (pS3->Chipset == PCI_CHIP_964_1)) { 1631 unsigned char bdelay; 1632 1633 outb(vgaCRIndex, 0x6d); 1634 bdelay = inb(vgaCRReg); 1635 1636 if (pS3->RamDac->RamDacType == TI3025_RAMDAC) { 1637 if (pS3->s3Bpp == 1) { 1638 if (mode->Clock > 80000) 1639 bdelay = 0x02; 1640 else 1641 bdelay = 0x03; 1642 } else if (pS3->s3Bpp == 2) { 1643 if (mode->Clock > 80000) 1644 bdelay = 0x00; 1645 else 1646 bdelay = 0x01; 1647 } else 1648 bdelay = 0x00; 1649 } 1650 1651 outb(vgaCRReg, bdelay); 1652 } 1653 1654 outb(vgaCRIndex, 0x66); 1655 new->cr66 = inb(vgaCRReg); 1656 if (pS3->S3NewMMIO) 1657 new->cr66 |= 0x88; 1658 else 1659 new->cr66 |= 0x80; 1660 outb(vgaCRReg, new->cr66); 1661 1662 1663 if (pS3->SlowDRAMRefresh) 1664 new->cr3a = 0xb7; 1665 else 1666 new->cr3a = 0xb5; 1667 outb(vgaCRIndex, 0x3a); 1668 outb(vgaCRReg, new->cr3a); 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 int j; 1937 1938 for(j=0; j<0x100; j++) { 1939 outb(vgaCRIndex, j); 1940 ErrorF("CRTC 0x%x = 0x%x\n", j, inb(vgaCRReg)); 1941 } 1942 } 1943#if 0 1944 ErrorF("DAC regs\n"); 1945 1946 { 1947 int j; 1948 1949 for(j=0; j<0x100; j++) 1950 ErrorF("0x%x = 0x%x\n", j, S3InTiIndReg(pScrn, j)); 1951#if 0 1952 outb(vgaCRIndex, 0x22); 1953 ErrorF("cr22 = 0x%x\n", inb(vgaCRReg)); 1954#endif 1955 } 1956#endif 1957} 1958 1959 1960void S3BankZero(ScrnInfoPtr pScrn) 1961{ 1962 S3Ptr pS3 = S3PTR(pScrn); 1963 unsigned char tmp; 1964 int vgaCRIndex = pS3->vgaCRIndex, vgaCRReg = pS3->vgaCRReg; 1965 1966 outb(vgaCRIndex, 0x35); 1967 tmp = inb(vgaCRReg) & 0xf0; 1968 outb(vgaCRReg, tmp); 1969 1970 outb(vgaCRIndex, 0x51); 1971 tmp = inb(vgaCRReg) & 0xf3; 1972 outb(vgaCRReg, tmp); 1973} 1974 1975static void 1976S3DisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 1977 int flags) 1978{ 1979 S3Ptr pS3 = S3PTR(pScrn); 1980 switch (pS3->Chipset) { 1981 case PCI_CHIP_TRIO64V2_DXGX: 1982 case PCI_CHIP_TRIO: 1983 case PCI_CHIP_AURORA64VP: 1984 case PCI_CHIP_TRIO64UVP: 1985 { 1986 int srd; 1987 1988 outb(0x3c4, 0x08); 1989 outb(0x3c5, 0x06); /* unlock extended sequence registers */ 1990 1991 outb(0x3c4, 0x0d); 1992 srd = inb(0x3c5) & 0xf; /* clear the sync control bits */ 1993 1994 switch (PowerManagementMode) { 1995 case DPMSModeOn: 1996 /* Screen: On; HSync: On, VSync: On */ 1997 break; 1998 case DPMSModeStandby: 1999 /* Screen: Off; HSync: Off, VSync: On */ 2000 srd |= 0x10; 2001 break; 2002 case DPMSModeSuspend: 2003 /* Screen: Off; HSync: On, VSync: Off */ 2004 srd |= 0x40; 2005 break; 2006 case DPMSModeOff: 2007 /* Screen: Off; HSync: Off, VSync: Off */ 2008 srd |= 0x50; 2009 break; 2010 } 2011 outb(0x3c4, 0x0d); 2012 outb(0x3c5, srd); 2013 break; 2014 } 2015 default: 2016 vgaHWDPMSSet(pScrn, PowerManagementMode, flags); 2017 } 2018} 2019