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