tdfx_driver.c revision 880ed95a
1#ifdef HAVE_CONFIG_H 2#include "config.h" 3#endif 4 5#ifdef HAVE_INTTYPES_H 6#include <inttypes.h> 7#endif 8 9#define USE_INT10 1 10#define USE_PCIVGAIO 1 11 12/************************************************************************** 13 14Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 15All Rights Reserved. 16 17Permission is hereby granted, free of charge, to any person obtaining a 18copy of this software and associated documentation files (the 19"Software"), to deal in the Software without restriction, including 20without limitation the rights to use, copy, modify, merge, publish, 21distribute, sub license, and/or sell copies of the Software, and to 22permit persons to whom the Software is furnished to do so, subject to 23the following conditions: 24 25The above copyright notice and this permission notice (including the 26next paragraph) shall be included in all copies or substantial portions 27of the Software. 28 29THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 30OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 31MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 32IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 33ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 34TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 35SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 36 37**************************************************************************/ 38 39/* 40 * Authors: 41 * Daryll Strauss <daryll@precisioninsight.com> 42 * 43 */ 44 45/* 46 * This server does not support these XFree 4.0 features yet 47 * DDC2 (requires I2C) 48 * shadowFb (if requested or acceleration is off) 49 * Overlay planes 50 */ 51 52/* 53 * These are X and server generic header files. 54 */ 55#include "xf86.h" 56#include "xf86_OSproc.h" 57#include "xf86Resources.h" 58#include "xf86RAC.h" 59#include "vbe.h" 60#include "xf86cmap.h" 61 62/* If the driver uses port I/O directly, it needs: */ 63 64#include "compiler.h" 65 66/* Drivers using the mi implementation of backing store need: */ 67 68#include "mibstore.h" 69 70/* All drivers using the vgahw module need this */ 71/* This driver needs to be modified to not use vgaHW for multihead operation */ 72#include "vgaHW.h" 73 74/* Drivers using the mi SW cursor need: */ 75 76#include "mipointer.h" 77 78/* Drivers using the mi colourmap code need: */ 79 80#include "micmap.h" 81 82/* Required for line biases */ 83#include "miline.h" 84 85#include "fb.h" 86 87/* !!! These need to be checked !!! */ 88#if 0 89#define _XF86DGA_SERVER_ 90#include <X11/extensions/xf86dgastr.h> 91#endif 92 93/* The driver's own header file: */ 94 95#include "tdfx.h" 96 97#include "regionstr.h" 98#include "dixstruct.h" 99 100#include "xf86xv.h" 101#include <X11/extensions/Xv.h> 102 103#ifdef XF86DRI 104#include "dri.h" 105#endif 106 107/* Required Functions: */ 108 109static const OptionInfoRec * TDFXAvailableOptions(int chipid, int busid); 110/* Print a driver identifying message. */ 111static void TDFXIdentify(int flags); 112 113/* Identify if there is any hardware present that I know how to drive. */ 114#ifdef XSERVER_LIBPCIACCESS 115static Bool TDFXPciProbe(DriverPtr drv, int entity_num, 116 struct pci_device *dev, intptr_t match_data); 117#else 118static Bool TDFXProbe(DriverPtr drv, int flags); 119#endif 120 121/* Process the config file and see if we have a valid configuration */ 122static Bool TDFXPreInit(ScrnInfoPtr pScrn, int flags); 123 124/* Initialize a screen */ 125static Bool TDFXScreenInit(int Index, ScreenPtr pScreen, int argc, char **argv); 126 127/* Enter from a virtual terminal */ 128static Bool TDFXEnterVT(int scrnIndex, int flags); 129 130/* Leave to a virtual terminal */ 131static void TDFXLeaveVT(int scrnIndex, int flags); 132 133/* Close down each screen we initialized */ 134static Bool TDFXCloseScreen(int scrnIndex, ScreenPtr pScreen); 135 136/* Change screensaver state */ 137static Bool TDFXSaveScreen(ScreenPtr pScreen, int mode); 138 139/* Cleanup server private data */ 140static void TDFXFreeScreen(int scrnIndex, int flags); 141 142/* Check if a mode is valid on the hardware */ 143static ModeStatus TDFXValidMode(int scrnIndex, DisplayModePtr mode, 144 Bool verbose, int flags); 145 146static void TDFXBlockHandler(int, pointer, pointer, pointer); 147 148/* Switch to various Display Power Management System levels */ 149static void TDFXDisplayPowerManagementSet(ScrnInfoPtr pScrn, 150 int PowerManagermentMode, int flags); 151 152#ifdef XSERVER_LIBPCIACCESS 153#define TDFX_DEVICE_MATCH(d, sub, i) \ 154 { 0x121A, (d), PCI_MATCH_ANY, (sub), 0, 0, (i) } 155 156static const struct pci_id_match tdfx_device_match[] = { 157 TDFX_DEVICE_MATCH(PCI_CHIP_BANSHEE, PCI_MATCH_ANY, Banshee), 158 159 /* There are *many* missing PCI IDs here. 160 */ 161 TDFX_DEVICE_MATCH(PCI_CHIP_VOODOO3, 0x0036, Voodoo3_2000), 162 TDFX_DEVICE_MATCH(PCI_CHIP_VOODOO3, 0x003A, Voodoo3_3000), 163 164 TDFX_DEVICE_MATCH(PCI_CHIP_VOODOO3, PCI_MATCH_ANY, Voodoo3_Unknown), 165 TDFX_DEVICE_MATCH(PCI_CHIP_VOODOO5, PCI_MATCH_ANY, Voodoo5), 166 { 0, 0, 0 } 167}; 168 169static const int MaxClocks[MAX_VOODOO_CARDS] = { 170 [Banshee] = 270000, 171 [Voodoo3_2000] = 300000, 172 [Voodoo3_3000] = 350000, 173 [Voodoo3_Unknown] = 300000, 174 [Voodoo5] = 350000 175}; 176#endif 177 178 179_X_EXPORT DriverRec TDFX = { 180 TDFX_VERSION, 181 TDFX_DRIVER_NAME, 182 TDFXIdentify, 183#ifdef XSERVER_LIBPCIACCESS 184 NULL, 185#else 186 TDFXProbe, 187#endif 188 189 TDFXAvailableOptions, 190 NULL, 191 0, 192 NULL, 193 194#ifdef XSERVER_LIBPCIACCESS 195 tdfx_device_match, 196 TDFXPciProbe 197#endif 198}; 199 200/* Chipsets */ 201static SymTabRec TDFXChipsets[] = { 202 { PCI_CHIP_BANSHEE, "3dfx Banshee"}, 203 { PCI_CHIP_VOODOO3, "3dfx Voodoo3"}, 204 { PCI_CHIP_VOODOO5, "3dfx Voodoo5"}, 205 { -1, NULL } 206}; 207 208#ifndef XSERVER_LIBPCIACCESS 209static PciChipsets TDFXPciChipsets[] = { 210 { PCI_CHIP_BANSHEE, PCI_CHIP_BANSHEE, RES_SHARED_VGA }, 211 { PCI_CHIP_VOODOO3, PCI_CHIP_VOODOO3, RES_SHARED_VGA }, 212 { PCI_CHIP_VOODOO5, PCI_CHIP_VOODOO5, RES_SHARED_VGA }, 213 { -1, -1, RES_UNDEFINED } 214}; 215#endif 216 217/* !!! Do we want an option for alternate clocking? !!! */ 218 219typedef enum { 220 OPTION_NOACCEL, 221 OPTION_SW_CURSOR, 222 OPTION_USE_PIO, 223 OPTION_SHOWCACHE, 224 OPTION_VIDEO_KEY, 225 OPTION_NO_SLI, 226 OPTION_TEXTURED_VIDEO, 227 OPTION_DRI 228} TDFXOpts; 229 230static const OptionInfoRec TDFXOptions[] = { 231 { OPTION_NOACCEL, "NoAccel", OPTV_BOOLEAN, {0}, FALSE }, 232 { OPTION_SW_CURSOR, "SWcursor", OPTV_BOOLEAN, {0}, FALSE }, 233 { OPTION_USE_PIO, "UsePIO", OPTV_BOOLEAN, {0}, FALSE}, 234 { OPTION_SHOWCACHE, "ShowCache", OPTV_BOOLEAN, {0}, FALSE}, 235 { OPTION_VIDEO_KEY, "VideoKey", OPTV_INTEGER, {0}, FALSE}, 236 { OPTION_NO_SLI, "NoSLI", OPTV_BOOLEAN, {0}, FALSE}, 237 { OPTION_TEXTURED_VIDEO, "TexturedVideo", OPTV_BOOLEAN, {1}, FALSE}, 238 { OPTION_DRI, "DRI", OPTV_BOOLEAN, {0}, FALSE}, 239 { -1, NULL, OPTV_NONE, {0}, FALSE} 240}; 241 242static const char *vgahwSymbols[] = { 243 "vgaHWEnable", 244 "vgaHWFreeHWRec", 245 "vgaHWGetHWRec", 246 "vgaHWGetIOBase", 247 "vgaHWGetIndex", 248 "vgaHWInit", 249 "vgaHWLock", 250 "vgaHWMapMem", 251 "vgaHWProtect", 252 "vgaHWRestore", 253 "vgaHWSave", 254 "vgaHWSeqReset", 255 "vgaHWUnlock", 256 0 257}; 258 259static const char *ramdacSymbols[] = { 260 "xf86CreateCursorInfoRec", 261 "xf86InitCursor", 262 NULL 263}; 264 265static const char *ddcSymbols[] = { 266 "xf86PrintEDID", 267 "xf86SetDDCproperties", 268 "xf86DoEDID_DDC2", 269 NULL 270}; 271 272static const char *i2cSymbols[] = { 273 "xf86CreateI2CBusRec", 274 "xf86I2CBusInit", 275 NULL 276}; 277 278static const char *fbSymbols[] = { 279 "fbPictureInit", 280 "fbScreenInit", 281 NULL 282}; 283 284static const char *xaaSymbols[] = { 285 "XAACreateInfoRec", 286 "XAADestroyInfoRec", 287 "XAAInit", 288 "XAAReverseBitOrder", 289 NULL 290}; 291 292static const char *vbeSymbols[] = { 293 "VBEInit", 294 "vbeDoEDID", 295 "vbeFree", 296 NULL 297}; 298 299static const char *int10Symbols[] = { 300 "xf86FreeInt10", 301 "xf86InitInt10", 302 NULL 303}; 304 305#ifdef XF86DRI 306static const char *drmSymbols[] = { 307 "drmAddMap", 308 "drmFreeVersion", 309 "drmGetVersion", 310 NULL 311}; 312 313static const char *driSymbols[] = { 314 "DRICloseScreen", 315 "DRICreateInfoRec", 316 "DRIDestroyInfoRec", 317 "DRIFinishScreenInit", 318 "DRIGetSAREAPrivate", 319 "DRILock", 320 "DRIMoveBuffersHelper", 321 "DRIQueryVersion", 322 "DRIScreenInit", 323 "DRIUnlock", 324 "GlxSetVisualConfigs", 325 "DRICreatePCIBusID", 326 NULL 327}; 328 329#endif 330 331#ifdef XFree86LOADER 332 333static MODULESETUPPROTO(tdfxSetup); 334 335static XF86ModuleVersionInfo tdfxVersRec = 336{ 337 "tdfx", 338 MODULEVENDORSTRING, 339 MODINFOSTRING1, 340 MODINFOSTRING2, 341 XORG_VERSION_CURRENT, 342 TDFX_MAJOR_VERSION, TDFX_MINOR_VERSION, TDFX_PATCHLEVEL, 343 ABI_CLASS_VIDEODRV, 344 ABI_VIDEODRV_VERSION, 345 MOD_CLASS_VIDEODRV, 346 {0,0,0,0} 347}; 348 349_X_EXPORT XF86ModuleData tdfxModuleData = {&tdfxVersRec, tdfxSetup, 0}; 350 351static pointer 352tdfxSetup(pointer module, pointer opts, int *errmaj, int *errmin) 353{ 354 static Bool setupDone = FALSE; 355 356 /* This module should be loaded only once, but check to be sure. */ 357 358 if (!setupDone) { 359 setupDone = TRUE; 360 xf86AddDriver(&TDFX, module, 1); 361 362 /* 363 * Modules that this driver always requires may be loaded here 364 * by calling LoadSubModule(). 365 */ 366 367 /* 368 * Tell the loader about symbols from other modules that this module 369 * might refer to. 370 */ 371 LoaderRefSymLists(vgahwSymbols, fbSymbols, xaaSymbols, 372 ramdacSymbols, vbeSymbols, int10Symbols, 373#ifdef XF86DRI 374 drmSymbols, driSymbols, 375#endif 376 NULL); 377 378 /* 379 * The return value must be non-NULL on success even though there 380 * is no TearDownProc. 381 */ 382 return (pointer)1; 383 } else { 384 if (errmaj) *errmaj = LDR_ONCEONLY; 385 return NULL; 386 } 387} 388 389#endif 390 391/* 392 * TDFXGetRec and TDFXFreeRec -- 393 * 394 * Private data for the driver is stored in the screen structure. 395 * These two functions create and destroy that private data. 396 * 397 */ 398static TDFXPtr 399TDFXGetRec(ScrnInfoPtr pScrn) 400{ 401 if (pScrn->driverPrivate == NULL) { 402 pScrn->driverPrivate = xnfcalloc(sizeof(TDFXRec), 1); 403 } 404 405 return (TDFXPtr) pScrn->driverPrivate; 406} 407 408static void 409TDFXFreeRec(ScrnInfoPtr pScrn) { 410 if (!pScrn) return; 411 if (!pScrn->driverPrivate) return; 412 xfree(pScrn->driverPrivate); 413 pScrn->driverPrivate=0; 414} 415 416/* 417 * TDFXIdentify -- 418 * 419 * Returns the string name for the driver based on the chipset. In this 420 * case it will always be an TDFX, so we can return a static string. 421 * 422 */ 423static void 424TDFXIdentify(int flags) { 425 xf86PrintChipsets(TDFX_NAME, "Driver for 3dfx Banshee/Voodoo3 chipsets", TDFXChipsets); 426} 427 428static const OptionInfoRec * 429TDFXAvailableOptions(int chipid, int busid) 430{ 431 return TDFXOptions; 432} 433 434static void 435TDFXProbeDDC(ScrnInfoPtr pScrn, int index) 436{ 437 vbeInfoPtr pVbe; 438 if (xf86LoadSubModule(pScrn, "vbe")) 439 { 440 pVbe = VBEInit(NULL,index); 441 ConfiguredMonitor = vbeDoEDID(pVbe, NULL); 442 vbeFree(pVbe); 443 } 444} 445 446#ifdef XSERVER_LIBPCIACCESS 447/** 448 * TDFXPciProbe 449 * 450 * Look through the PCI bus to find cards that are TDFX boards. 451 * Setup the dispatch table for the rest of the driver functions. 452 */ 453static Bool 454TDFXPciProbe(DriverPtr drv, int entity_num, struct pci_device *dev, 455 intptr_t match_data) 456{ 457 ScrnInfoPtr pScrn; 458 459 TDFXTRACE("TDFXPciProbe start\n"); 460 461 462 /* Allocate new ScrnInfoRec and claim the slot */ 463 pScrn = xf86ConfigPciEntity(NULL, 0, entity_num, NULL, NULL, 464 NULL, NULL, NULL, NULL); 465 if (pScrn != NULL) { 466 TDFXPtr pTDFX; 467 468 pScrn->driverVersion = TDFX_VERSION; 469 pScrn->driverName = TDFX_DRIVER_NAME; 470 pScrn->name = TDFX_NAME; 471 pScrn->Probe = NULL; 472 pScrn->PreInit = TDFXPreInit; 473 pScrn->ScreenInit = TDFXScreenInit; 474 pScrn->SwitchMode = TDFXSwitchMode; 475 pScrn->AdjustFrame = TDFXAdjustFrame; 476 pScrn->EnterVT = TDFXEnterVT; 477 pScrn->LeaveVT = TDFXLeaveVT; 478 pScrn->FreeScreen = TDFXFreeScreen; 479 pScrn->ValidMode = TDFXValidMode; 480 481 /* Allocate driverPrivate */ 482 pTDFX = TDFXGetRec(pScrn); 483 if (pTDFX == NULL) { 484 return FALSE; 485 } 486 487 pTDFX->initDone = FALSE; 488 pTDFX->match_id = (enum tdfx_chips) match_data; 489 pTDFX->pEnt = xf86GetEntityInfo(entity_num); 490 pTDFX->PciInfo[0] = dev; 491 pTDFX->numChips = 1; 492 pTDFX->Primary = xf86IsPrimaryPci(dev); 493 494 pTDFX->PIOBase[0] = dev->regions[2].base_addr; 495 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 496 "PIO base = 0x%lx\n", pTDFX->PIOBase[0]); 497 } 498 499 return (pScrn != NULL); 500} 501#else 502/** 503 * TDFXProbe 504 * 505 * Look through the PCI bus to find cards that are TDFX boards. 506 * Setup the dispatch table for the rest of the driver functions. 507 */ 508static Bool 509TDFXProbe(DriverPtr drv, int flags) 510{ 511 int i, numUsed, numDevSections, *usedChips; 512 GDevPtr *devSections; 513 Bool foundScreen = FALSE; 514 515 TDFXTRACE("TDFXProbe start\n"); 516 /* 517 Find the config file Device sections that match this 518 driver, and return if there are none. 519 */ 520 if ((numDevSections = xf86MatchDevice(TDFX_DRIVER_NAME, &devSections))<=0) { 521 return FALSE; 522 } 523 524 /* 525 Since these Probing is just checking the PCI data the server already 526 collected. 527 */ 528 if (!xf86GetPciVideoInfo()) return FALSE; 529 530 numUsed = xf86MatchPciInstances(TDFX_NAME, PCI_VENDOR_3DFX, 531 TDFXChipsets, TDFXPciChipsets, 532 devSections, numDevSections, 533 drv, &usedChips); 534 535 xfree(devSections); 536 if (numUsed<=0) return FALSE; 537 538 if (flags & PROBE_DETECT) 539 foundScreen = TRUE; 540 else for (i=0; i<numUsed; i++) { 541 ScrnInfoPtr pScrn; 542 543 /* Allocate new ScrnInfoRec and claim the slot */ 544 pScrn = NULL; 545 if ((pScrn = xf86ConfigPciEntity(pScrn, 0, usedChips[i], 546 TDFXPciChipsets, NULL, NULL, NULL, NULL, NULL))) { 547 548 pScrn->driverVersion = TDFX_VERSION; 549 pScrn->driverName = TDFX_DRIVER_NAME; 550 pScrn->name = TDFX_NAME; 551 pScrn->Probe = TDFXProbe; 552 pScrn->PreInit = TDFXPreInit; 553 pScrn->ScreenInit = TDFXScreenInit; 554 pScrn->SwitchMode = TDFXSwitchMode; 555 pScrn->AdjustFrame = TDFXAdjustFrame; 556 pScrn->EnterVT = TDFXEnterVT; 557 pScrn->LeaveVT = TDFXLeaveVT; 558 pScrn->FreeScreen = TDFXFreeScreen; 559 pScrn->ValidMode = TDFXValidMode; 560 foundScreen = TRUE; 561 } 562 } 563 xfree(usedChips); 564 565 return foundScreen; 566} 567#endif 568 569static int 570TDFXCountRam(ScrnInfoPtr pScrn) { 571 TDFXPtr pTDFX; 572 int vmemSize; 573 int vmemType=-1; /* SDRAM or SGRAM */ 574 575 pTDFX = TDFXPTR(pScrn); 576 TDFXTRACE("TDFXCountRam start\n"); 577 vmemSize=0; 578 if (pTDFX->PIOBase[0]) { 579 CARD32 580 partSize, /* size of SGRAM chips in Mbits */ 581 nChips, /* # chips of SDRAM/SGRAM */ 582 banks, /* Number of banks of chips */ 583 dramInit0_strap, 584 dramInit1_strap, 585 dramInit1, 586 miscInit1; 587 588 /* determine memory type: SDRAM or SGRAM */ 589 vmemType = MEM_TYPE_SGRAM; 590 dramInit1_strap = pTDFX->readLong(pTDFX, DRAMINIT1); 591 dramInit1_strap &= SST_MCTL_TYPE_SDRAM; 592 if (dramInit1_strap) vmemType = MEM_TYPE_SDRAM; 593 594 /* set memory interface delay values and enable refresh */ 595 /* these apply to all RAM vendors */ 596 dramInit1 = 0x0; 597 dramInit1 |= 2<<SST_SGRAM_OFLOP_DEL_ADJ_SHIFT; 598 dramInit1 |= SST_SGRAM_CLK_NODELAY; 599 dramInit1 |= SST_DRAM_REFRESH_EN; 600 dramInit1 |= (0x18 << SST_DRAM_REFRESH_VALUE_SHIFT) & SST_DRAM_REFRESH_VALUE; 601 dramInit1 &= ~SST_MCTL_TYPE_SDRAM; 602 dramInit1 |= dramInit1_strap; 603 604 /* Some information about the timing register (for later debugging) */ 605 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 606 "DRAMINIT1 read 0x%x, programming 0x%lx (not Banshee)\n", 607 pTDFX->readLong(pTDFX, DRAMINIT1), (unsigned long)dramInit1); 608 609 /* 610 * Here we don't whack the timing register on the Banshee boards as the 611 * BIOS has done a perfectly good job. As Banshee boards were made by 612 * different manufacturers we don't touch this, but carry on whacking it 613 * for Voodoo3 and Voodoo5 boards, as we've never had a problem with them. 614 * I guess this could be removed for all boards as we probably shouldn't 615 * be doing this to the V3/V5 boards too. 616 */ 617 if (pTDFX->ChipType != PCI_CHIP_BANSHEE) 618 pTDFX->writeLong(pTDFX, DRAMINIT1, dramInit1); 619 620 /* determine memory size from strapping pins (dramInit0 and dramInit1) */ 621 dramInit0_strap = pTDFX->readLong(pTDFX, DRAMINIT0); 622 623 if (pTDFX->ChipType<=PCI_CHIP_VOODOO3) { /* Banshee/V3 */ 624 if (vmemType == MEM_TYPE_SDRAM) { 625 vmemSize = 16; 626 } else { 627 nChips = ((dramInit0_strap & SST_SGRAM_NUM_CHIPSETS) == 0) ? 4 : 8; 628 629 if ( (dramInit0_strap & SST_SGRAM_TYPE) == SST_SGRAM_TYPE_8MBIT ) { 630 partSize = 8; 631 } else if ( (dramInit0_strap & SST_SGRAM_TYPE) == SST_SGRAM_TYPE_16MBIT) { 632 partSize = 16; 633 } else { 634 ErrorF("Invalid sgram type = 0x%lx", 635 (dramInit0_strap & SST_SGRAM_TYPE) << SST_SGRAM_TYPE_SHIFT ); 636 return 0; 637 } 638 vmemSize = (nChips * partSize) / 8; /* in MBytes */ 639 } 640 } else { /* V4, V5 */ 641 nChips = ((dramInit0_strap & SST_SGRAM_NUM_CHIPSETS)==0) ? 4 : 8; 642 partSize=1<<((dramInit0_strap&0x38000000)>>28); 643 banks=((dramInit0_strap&BIT(30))==0) ? 2 : 4; 644 vmemSize=nChips*partSize*banks; 645 } 646 TDFXTRACEREG("dramInit0 = %lx dramInit1 = %lx\n", 647 (unsigned long)dramInit0_strap, (unsigned long)dramInit1_strap); 648 TDFXTRACEREG("MemConfig %d chips %ld size %ld total\n", (int)nChips, 649 (unsigned long)partSize, (unsigned long)vmemSize); 650 651 /* 652 disable block writes for SDRAM 653 */ 654 miscInit1 = pTDFX->readLong(pTDFX, MISCINIT1); 655 if ( vmemType == MEM_TYPE_SDRAM ) { 656 miscInit1 |= SST_DISABLE_2D_BLOCK_WRITE; 657 } 658 miscInit1|=1; 659 pTDFX->writeLong(pTDFX, MISCINIT1, miscInit1); 660 } 661 662 /* return # of KBytes of board memory */ 663 return vmemSize*1024; 664} 665 666#if 0 667static int TDFXCfgToSize(int cfg) 668{ 669 if (cfg<4) return 0x8000000<<cfg; 670 return 0x4000000>>(cfg-4); 671} 672#endif 673 674static int TDFXSizeToCfg(int size) 675{ 676 switch (size) { 677 case 0x40000000: return 3; 678 case 0x20000000: return 2; 679 case 0x10000000: return 1; 680 case 0x08000000: return 0; 681 case 0x04000000: return 4; 682 case 0x02000000: return 5; 683 case 0x01000000: return 6; 684 case 0x00800000: return 7; 685 case 0x00400000: return 8; 686 default: 687 return -1; 688 } 689} 690 691#ifndef XSERVER_LIBPCIACCESS 692static void 693TDFXFindChips(ScrnInfoPtr pScrn, pciVideoPtr match) 694{ 695 TDFXPtr pTDFX; 696 pciVideoPtr *ppPci; 697 698 pTDFX=TDFXPTR(pScrn); 699 pTDFX->numChips=0; 700 pTDFX->ChipType=match->chipType; 701 for (ppPci = xf86GetPciVideoInfo(); *ppPci != NULL; ppPci++) { 702 if ((*ppPci)->bus == match->bus && 703 (*ppPci)->device == match->device) { 704 pTDFX->PciTag[pTDFX->numChips] = pciTag((*ppPci)->bus, 705 (*ppPci)->device, 706 (*ppPci)->func); 707 pTDFX->PIOBase[pTDFX->numChips] = 708 pScrn->domainIOBase + ((*ppPci)->ioBase[2] & 0xFFFFFFFCU); 709 pTDFX->numChips++; 710 } 711 } 712 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 713 "TDFXFindChips: found %d chip(s)\n", pTDFX->numChips); 714 /* Disable the secondary chips for now */ 715 pTDFX->numChips=1; 716} 717#endif 718 719static void 720TDFXInitChips(ScrnInfoPtr pScrn) 721{ 722 TDFXPtr pTDFX = TDFXPTR(pScrn); 723 int i; 724#if 0 725 int v; 726#endif 727 uint32_t cfgbits, initbits; 728 uint32_t mem0base, mem1base, mem0size, mem0bits, mem1size, mem1bits; 729 730 731 PCI_READ_LONG(cfgbits, CFG_PCI_DECODE, 0); 732 PCI_READ_LONG(mem0base, CFG_MEM0BASE, 0); 733 PCI_READ_LONG(mem1base, CFG_MEM1BASE, 0); 734 PCI_READ_LONG(initbits, CFG_INIT_ENABLE, 0); 735 736 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 737 "TDFXInitChips: numchips = %d\n", pTDFX->numChips); 738 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 739 "TDFXInitChips: cfgbits = 0x%08lx, initbits = 0x%08lx\n", 740 cfgbits, initbits); 741 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 742 "TDFXInitChips: mem0base = 0x%08lx, mem1base = 0x%08lx\n", 743 mem0base, mem1base); 744 745 mem0size = 32 * 1024 * 1024; /* Registers are always 32MB */ 746 mem1size = pScrn->videoRam * 1024 * 2; /* Linear mapping is 2x memory */ 747 748 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 749 "TDFXInitChips: mem0size = 0x%08lx, mem1size = 0x%08lx\n", 750 mem0size, mem1size); 751 752 mem0bits = TDFXSizeToCfg(mem0size); 753 mem1bits = TDFXSizeToCfg(mem1size) << 4; 754 755 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 756 "TDFXInitChips: mem0bits = 0x%08lx, mem1bits = 0x%08lx\n", 757 mem0bits, mem1bits); 758 759 cfgbits = (cfgbits & ~(0xFF)) | mem0bits | mem1bits; 760 761 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 762 "TDFXInitChips: cfgbits = 0x%08lx\n", cfgbits); 763 764 for (i = 0; i < pTDFX->numChips; i++) { 765 PCI_WRITE_LONG(initbits | BIT(10), CFG_INIT_ENABLE, i); 766 767#if 0 768 v=pciReadWord(pTDFX->PciTag[i], CFG_PCI_COMMAND); 769 if (!i) 770 pciWriteWord(pTDFX->PciTag[i], CFG_PCI_COMMAND, v | 0x3); 771 else 772 pciWriteWord(pTDFX->PciTag[i], CFG_PCI_COMMAND, v | 0x2); 773#endif 774 775 pTDFX->MMIOAddr[i] = mem0base + (i * mem0size); 776 777 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 778 "TDFXInitChips: MMIOAddr[%d] = 0x%08lx\n", 779 i, pTDFX->MMIOAddr[i]); 780 781 PCI_WRITE_LONG(pTDFX->MMIOAddr[i], CFG_MEM0BASE, i); 782 783 pTDFX->MMIOAddr[i] &= 0xFFFFFF00; 784 pTDFX->LinearAddr[i] = mem1base + (i * mem1size); 785 786 PCI_WRITE_LONG(pTDFX->LinearAddr[i], CFG_MEM1BASE, i); 787 788 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, 3, 789 "TDFXInitChips: LinearAddr[%d] = 0x%08lx\n", 790 i, pTDFX->LinearAddr[i]); 791 pTDFX->LinearAddr[i] &= 0xFFFFFF00; 792 793 PCI_WRITE_LONG(cfgbits, CFG_PCI_DECODE, i); 794 PCI_WRITE_LONG(initbits, CFG_INIT_ENABLE, i); 795 } 796} 797 798void 799TDFXPutBits(I2CBusPtr b, int scl, int sda) 800{ 801 TDFXPtr pTDFX= b->DriverPrivate.ptr; 802 CARD32 reg; 803 804 reg = pTDFX->readLong(pTDFX, VIDSERIALPARALLELPORT); 805 reg = (reg & ~(VSP_SDA0_OUT | VSP_SCL0_OUT)) | 806 (scl ? VSP_SCL0_OUT : 0) | 807 (sda ? VSP_SDA0_OUT : 0); 808 pTDFX->writeLong(pTDFX, VIDSERIALPARALLELPORT, reg); 809} 810 811void 812TDFXGetBits(I2CBusPtr b, int *scl, int *sda) 813{ 814 TDFXPtr pTDFX = b->DriverPrivate.ptr; 815 CARD32 reg; 816 817 reg = pTDFX->readLong(pTDFX, VIDSERIALPARALLELPORT); 818 *sda = (reg & VSP_SDA0_IN) ? 1 : 0; 819 *scl = (reg & VSP_SCL0_IN) ? 1 : 0; 820} 821 822Bool TDFXI2cInit(ScrnInfoPtr pScrn) 823{ 824 TDFXPtr pTDFX = TDFXPTR(pScrn); 825 826 if (!(pTDFX->pI2CBus = xf86CreateI2CBusRec())) 827 { 828 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to allocate I2C Bus record.\n"); 829 return FALSE; 830 } 831 832 /* Fill in generic structure fields */ 833 pTDFX->pI2CBus->BusName = "DDC"; 834 pTDFX->pI2CBus->scrnIndex = pScrn->scrnIndex; 835 pTDFX->pI2CBus->I2CPutBits = TDFXPutBits; 836 pTDFX->pI2CBus->I2CGetBits = TDFXGetBits; 837 pTDFX->pI2CBus->DriverPrivate.ptr = pTDFX; 838 839 /* longer timeouts as per the vesa spec */ 840 pTDFX->pI2CBus->ByteTimeout = 2200; /* VESA DDC spec 3 p. 43 (+10 %) */ 841 pTDFX->pI2CBus->StartTimeout = 550; 842 pTDFX->pI2CBus->BitTimeout = 40; 843 pTDFX->pI2CBus->ByteTimeout = 40; 844 pTDFX->pI2CBus->AcknTimeout = 40; 845 846 if (!xf86I2CBusInit(pTDFX->pI2CBus)) { 847 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Unable to init I2C Bus.\n"); 848 return FALSE; 849 } 850 return TRUE; 851} 852 853static xf86MonPtr doTDFXDDC(ScrnInfoPtr pScrn) 854{ 855 TDFXPtr pTDFX = TDFXPTR(pScrn); 856 I2CBusPtr pI2CBus; 857 xf86MonPtr pMon = NULL; 858 CARD32 reg; 859 860 reg = pTDFX->readLong(pTDFX, VIDSERIALPARALLELPORT); 861 pTDFX->writeLong(pTDFX, VIDSERIALPARALLELPORT, reg | VSP_ENABLE_IIC0); 862 863 pMon = xf86DoEDID_DDC2(pScrn->scrnIndex, pTDFX->pI2CBus); 864 865 if (pMon == NULL) 866 xf86Msg(X_WARNING, "No DDC2 capable monitor found\n"); 867 868 pTDFX->writeLong(pTDFX, VIDSERIALPARALLELPORT, reg); 869 870 return pMon; 871} 872 873/* 874 * TDFXPreInit -- 875 * 876 * Do initial setup of the board before we know what resolution we will 877 * be running at. 878 * 879 */ 880static Bool 881TDFXPreInit(ScrnInfoPtr pScrn, int flags) 882{ 883 TDFXPtr pTDFX; 884 ClockRangePtr clockRanges; 885 xf86MonPtr pMon; 886 int i; 887 MessageType from; 888 int flags24; 889 rgb defaultWeight = {0, 0, 0}; 890#ifdef XSERVER_LIBPCIACCESS 891 struct pci_device *match; 892#else 893 pciVideoPtr match; 894#endif 895 int availableMem; 896 897 TDFXTRACE("TDFXPreInit start\n"); 898 if (pScrn->numEntities != 1) return FALSE; 899 900#ifndef XSERVER_LIBPCIACCESS 901 /* Allocate driverPrivate */ 902 pTDFX = TDFXGetRec(pScrn); 903 if (pTDFX == NULL) { 904 return FALSE; 905 } 906 907 908 pTDFX->initDone=FALSE; 909 pTDFX->pEnt = xf86GetEntityInfo(pScrn->entityList[0]); 910#else 911 pTDFX = TDFXPTR(pScrn); 912#endif 913 914 if (flags & PROBE_DETECT) { 915#if !defined(__powerpc__) 916 TDFXProbeDDC(pScrn, pTDFX->pEnt->index); 917 return TRUE; 918#else 919 return FALSE; 920#endif 921 } 922 923 if (pTDFX->pEnt->location.type != BUS_PCI) return FALSE; 924 925 /* The vgahw module should be loaded here when needed */ 926 if (!xf86LoadSubModule(pScrn, "vgahw")) return FALSE; 927 928 xf86LoaderReqSymLists(vgahwSymbols, NULL); 929 930 /* Allocate a vgaHWRec */ 931 if (!vgaHWGetHWRec(pScrn)) return FALSE; 932 933#if USE_INT10 934#if !defined(__powerpc__) 935 if (xf86LoadSubModule(pScrn, "int10")) { 936 xf86Int10InfoPtr pInt; 937 938 xf86LoaderReqSymLists(int10Symbols, NULL); 939 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 940 "Softbooting the board (through the int10 interface).\n"); 941 pInt = xf86InitInt10(pTDFX->pEnt->index); 942 if (!pInt) 943 { 944 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 945 "Softbooting the board failed.\n"); 946 } 947 else 948 { 949 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 950 "Softbooting the board succeeded.\n"); 951 xf86FreeInt10(pInt); 952 } 953 } 954#endif 955#endif 956 957#ifdef XSERVER_LIBPCIACCESS 958 match = pTDFX->PciInfo[0]; 959 pTDFX->ChipType = DEVICE_ID(match); 960#else 961 match=pTDFX->PciInfo=xf86GetPciInfoForEntity(pTDFX->pEnt->index); 962 TDFXFindChips(pScrn, match); 963 pTDFX->Primary = xf86IsPrimaryPci(pTDFX->PciInfo); 964#endif 965 966 if (xf86RegisterResources(pTDFX->pEnt->index, NULL, ResExclusive)) { 967 TDFXFreeRec(pScrn); 968 return FALSE; 969 } 970 /* 971 * We don't need VGA resources during OPERATING state. However I'm 972 * not sure if they are disabled. 973 */ 974 xf86SetOperatingState(resVgaIo, pTDFX->pEnt->index, ResDisableOpr); 975 976 /* Is VGA memory disabled during OPERATING state? */ 977 xf86SetOperatingState(resVgaMem, pTDFX->pEnt->index, ResUnusedOpr); 978 /* 979 * I'm sure we don't need to set these. All resources 980 * for these operations are exclusive. 981 */ 982 if (pTDFX->usePIO) { 983 pScrn->racMemFlags = 0; 984 pScrn->racIoFlags = RAC_FB | RAC_COLORMAP | RAC_CURSOR | RAC_VIEWPORT; 985 } else 986 pScrn->racMemFlags = 0; 987 988 /* Set pScrn->monitor */ 989 pScrn->monitor = pScrn->confScreen->monitor; 990 991 flags24=Support24bppFb | Support32bppFb | SupportConvert32to24; 992 if (!xf86SetDepthBpp(pScrn, 0, 0, 0, flags24)) { 993 return FALSE; 994 } else { 995 switch (pScrn->depth) { 996 case 8: 997 case 16: 998 case 24: 999 break; 1000 default: 1001 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1002 "Given depth (%d) is not supported by tdfx driver\n", 1003 pScrn->depth); 1004 return FALSE; 1005 } 1006 } 1007 xf86PrintDepthBpp(pScrn); 1008 1009 pScrn->rgbBits=8; 1010 if (pScrn->depth>8) { 1011 if (!xf86SetWeight(pScrn, defaultWeight, defaultWeight)) 1012 return FALSE; 1013 } 1014 1015 if (!xf86SetDefaultVisual(pScrn, -1)) { 1016 return FALSE; 1017 } else { 1018 /* We don't currently support DirectColor at > 8bpp */ 1019 if (pScrn->depth > 8 && pScrn->defaultVisual != TrueColor) { 1020 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Given default visual" 1021 " (%s) is not supported at depth %d\n", 1022 xf86GetVisualName(pScrn->defaultVisual), pScrn->depth); 1023 return FALSE; 1024 } 1025 } 1026 1027 /* We use a programmable clock */ 1028 pScrn->progClock = TRUE; 1029 1030 pTDFX->cpp = pScrn->bitsPerPixel/8; 1031 1032 /* Process the options */ 1033 xf86CollectOptions(pScrn, NULL); 1034 if (!(pTDFX->Options = xalloc(sizeof(TDFXOptions)))) 1035 return FALSE; 1036 memcpy(pTDFX->Options, TDFXOptions, sizeof(TDFXOptions)); 1037 xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, pTDFX->Options); 1038 1039 /* 1040 * Set the Chipset and ChipRev, allowing config file entries to 1041 * override. 1042 */ 1043 if (pTDFX->pEnt->device->chipset && *pTDFX->pEnt->device->chipset) { 1044 pScrn->chipset = pTDFX->pEnt->device->chipset; 1045 from = X_CONFIG; 1046 } else if (pTDFX->pEnt->device->chipID >= 0) { 1047 pScrn->chipset = (char *)xf86TokenToString(TDFXChipsets, pTDFX->pEnt->device->chipID); 1048 from = X_CONFIG; 1049 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipID override: 0x%04X\n", 1050 pTDFX->pEnt->device->chipID); 1051 } else { 1052 from = X_PROBED; 1053 pScrn->chipset = (char *)xf86TokenToString(TDFXChipsets, 1054 DEVICE_ID(match)); 1055 } 1056 if (pTDFX->pEnt->device->chipRev >= 0) { 1057 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ChipRev override: %d\n", 1058 pTDFX->pEnt->device->chipRev); 1059 } 1060 1061 xf86DrvMsg(pScrn->scrnIndex, from, "Chipset: \"%s\"\n", pScrn->chipset); 1062 1063 if (pTDFX->pEnt->device->MemBase != 0) { 1064 pTDFX->LinearAddr[0] = pTDFX->pEnt->device->MemBase; 1065 from = X_CONFIG; 1066 } else { 1067 if (PCI_MEM_BASE(match, 1) != 0) { 1068 pTDFX->LinearAddr[0] = PCI_MEM_BASE(match, 1); 1069 from = X_PROBED; 1070 } else { 1071 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1072 "No valid FB address in PCI config space\n"); 1073 TDFXFreeRec(pScrn); 1074 return FALSE; 1075 } 1076 } 1077 xf86DrvMsg(pScrn->scrnIndex, from, "Linear framebuffer at 0x%lX\n", 1078 (unsigned long)pTDFX->LinearAddr[0]); 1079 1080 if (pTDFX->pEnt->device->IOBase != 0) { 1081 pTDFX->MMIOAddr[0] = pTDFX->pEnt->device->IOBase; 1082 from = X_CONFIG; 1083 } else { 1084 if (PCI_MEM_BASE(match, 0)) { 1085 pTDFX->MMIOAddr[0] = PCI_MEM_BASE(match, 0); 1086 from = X_PROBED; 1087 } else { 1088 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1089 "No valid MMIO address in PCI config space\n"); 1090 TDFXFreeRec(pScrn); 1091 return FALSE; 1092 } 1093 } 1094 xf86DrvMsg(pScrn->scrnIndex, from, "MMIO registers at addr 0x%lX\n", 1095 (unsigned long)pTDFX->MMIOAddr[0]); 1096 1097 if (!PCI_IO_BASE(match, 2)) { 1098 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1099 "No valid PIO address in PCI config space\n"); 1100 TDFXFreeRec(pScrn); 1101 return FALSE; 1102 } 1103 xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "PIO registers at addr 0x%lX\n", 1104 (unsigned long)pTDFX->PIOBase[0]); 1105 1106 /* We have to use PIO to probe, because we haven't mappend yet */ 1107 TDFXSetPIOAccess(pTDFX); 1108 1109 /* Calculate memory */ 1110 pScrn->videoRam = TDFXCountRam(pScrn); 1111 from = X_PROBED; 1112 if (pTDFX->pEnt->device->videoRam) { 1113 pScrn->videoRam = pTDFX->pEnt->device->videoRam; 1114 from = X_CONFIG; 1115 } 1116 1117 TDFXInitChips(pScrn); 1118 1119 /* Multiple by two because tiled access requires more address space */ 1120 pTDFX->FbMapSize = pScrn->videoRam*1024*2; 1121 xf86DrvMsg(pScrn->scrnIndex, from, "VideoRAM: %d kByte Mapping %ld kByte\n", 1122 pScrn->videoRam, pTDFX->FbMapSize/1024); 1123 1124 /* Since we can do gamma correction, we call xf86SetGamma */ 1125 { 1126 Gamma zeros = {0.0, 0.0, 0.0}; 1127 1128 if (!xf86SetGamma(pScrn, zeros)) { 1129 return FALSE; 1130 } 1131 } 1132 1133 pTDFX->MaxClock = 0; 1134 if (pTDFX->pEnt->device->dacSpeeds[0]) { 1135 switch (pScrn->bitsPerPixel) { 1136 case 8: 1137 pTDFX->MaxClock = pTDFX->pEnt->device->dacSpeeds[DAC_BPP8]; 1138 break; 1139 case 16: 1140 pTDFX->MaxClock = pTDFX->pEnt->device->dacSpeeds[DAC_BPP16]; 1141 break; 1142 case 24: 1143 pTDFX->MaxClock = pTDFX->pEnt->device->dacSpeeds[DAC_BPP24]; 1144 break; 1145 case 32: 1146 pTDFX->MaxClock = pTDFX->pEnt->device->dacSpeeds[DAC_BPP32]; 1147 break; 1148 } 1149 if (!pTDFX->MaxClock) 1150 pTDFX->MaxClock = pTDFX->pEnt->device->dacSpeeds[0]; 1151 from = X_CONFIG; 1152 } else { 1153#ifdef XSERVER_LIBPCIACCESS 1154 pTDFX->MaxClock = MaxClocks[pTDFX->match_id]; 1155#else 1156 switch (pTDFX->ChipType) { 1157 case PCI_CHIP_BANSHEE: 1158 pTDFX->MaxClock = 270000; 1159 break; 1160 case PCI_CHIP_VOODOO3: 1161 switch(match->subsysCard) { 1162 case PCI_CARD_VOODOO3_2000: 1163 pTDFX->MaxClock = 300000; 1164 break; 1165 case PCI_CARD_VOODOO3_3000: 1166 pTDFX->MaxClock = 350000; 1167 break; 1168 default: 1169 pTDFX->MaxClock = 300000; 1170 break; 1171 } 1172 break; 1173 case PCI_CHIP_VOODOO5: 1174 pTDFX->MaxClock = 350000; 1175 break; 1176 } 1177#endif 1178 } 1179 clockRanges = xnfcalloc(sizeof(ClockRange), 1); 1180 clockRanges->next=NULL; 1181 clockRanges->minClock= 12000; /* !!! What's the min clock? !!! */ 1182 clockRanges->maxClock=pTDFX->MaxClock; 1183 clockRanges->clockIndex = -1; 1184 switch (pTDFX->ChipType) { 1185 case PCI_CHIP_BANSHEE: 1186 clockRanges->interlaceAllowed = FALSE; 1187 break; 1188 case PCI_CHIP_VOODOO3: 1189 case PCI_CHIP_VOODOO5: 1190 clockRanges->interlaceAllowed = TRUE; 1191 break; 1192 default: 1193 clockRanges->interlaceAllowed = FALSE; 1194 break; 1195 } 1196 clockRanges->doubleScanAllowed = TRUE; 1197 1198 /* 1199 * Max memory available for the framebuffer is the total less the 1200 * HW cursor space and FIFO space. 1201 */ 1202 availableMem = pScrn->videoRam - 4096 - 1203 (((255 <= CMDFIFO_PAGES) ? 255 : CMDFIFO_PAGES) << 12); 1204 1205 if (!xf86LoadSubModule(pScrn, "fb")) { 1206 TDFXFreeRec(pScrn); 1207 return FALSE; 1208 } 1209 xf86LoaderReqSymLists(fbSymbols, NULL); 1210 1211 if (!xf86ReturnOptValBool(pTDFX->Options, OPTION_NOACCEL, FALSE)) { 1212 if (!xf86LoadSubModule(pScrn, "xaa")) { 1213 TDFXFreeRec(pScrn); 1214 return FALSE; 1215 } 1216 xf86LoaderReqSymLists(xaaSymbols, NULL); 1217 } 1218 1219 if (!xf86GetOptValBool(pTDFX->Options, OPTION_SHOWCACHE, &(pTDFX->ShowCache))) { 1220 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "ShowCache %s\n", pTDFX->ShowCache ? "Enabled" : "Disabled"); 1221 } else { 1222 pTDFX->ShowCache = FALSE; 1223 } 1224 1225 if (xf86GetOptValBool(pTDFX->Options, OPTION_TEXTURED_VIDEO, &(pTDFX->TextureXvideo))) { 1226 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Texture Xvideo Adaptor %s\n", pTDFX->TextureXvideo ? "Enabled" : "Disabled"); 1227 } else { 1228 pTDFX->TextureXvideo = FALSE; 1229 } 1230 1231 if (xf86GetOptValInteger(pTDFX->Options, OPTION_VIDEO_KEY, &(pTDFX->videoKey))) { 1232 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key set to 0x%x\n", pTDFX->videoKey); 1233 } else { 1234 xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "video key default 0x%x\n", pTDFX->videoKey = 0x1E); 1235 } 1236 1237 if (!xf86ReturnOptValBool(pTDFX->Options, OPTION_SW_CURSOR, FALSE)) { 1238 if (!xf86LoadSubModule(pScrn, "ramdac")) { 1239 TDFXFreeRec(pScrn); 1240 return FALSE; 1241 } 1242 xf86LoaderReqSymLists(ramdacSymbols, NULL); 1243 } 1244 1245 /* Load DDC and I2C for monitor ID */ 1246 if (!xf86LoadSubModule(pScrn, "i2c")) { 1247 TDFXFreeRec(pScrn); 1248 return FALSE; 1249 } 1250 xf86LoaderReqSymLists(i2cSymbols, NULL); 1251 1252 if (!xf86LoadSubModule(pScrn, "ddc")) { 1253 TDFXFreeRec(pScrn); 1254 return FALSE; 1255 } 1256 xf86LoaderReqSymLists(ddcSymbols, NULL); 1257 1258 /* try to read read DDC2 data */ 1259 if (TDFXI2cInit(pScrn)) { 1260 pMon = doTDFXDDC(pScrn); 1261 if (pMon != NULL) 1262 xf86SetDDCproperties(pScrn,xf86PrintEDID(pMon)); 1263 } else { 1264 /* try to use vbe if we didn't find anything */ 1265#if USE_INT10 1266#if !defined(__powerpc__) 1267 /* Initialize DDC1 if possible */ 1268 if (xf86LoadSubModule(pScrn, "vbe")) { 1269 vbeInfoPtr pVbe = VBEInit(NULL,pTDFX->pEnt->index); 1270 1271 xf86LoaderReqSymLists(vbeSymbols, NULL); 1272 pMon = vbeDoEDID(pVbe, NULL); 1273 vbeFree(pVbe); 1274 xf86SetDDCproperties(pScrn,xf86PrintEDID(pMon)); 1275 } 1276#endif 1277#endif 1278 } 1279 1280 i = xf86ValidateModes(pScrn, pScrn->monitor->Modes, 1281 pScrn->display->modes, clockRanges, 1282 0, 320, 2048, 16*pScrn->bitsPerPixel, 1283 200, 2047, 1284 pScrn->display->virtualX, pScrn->display->virtualY, 1285 availableMem, LOOKUP_BEST_REFRESH); 1286 1287 if (i==-1) { 1288 TDFXFreeRec(pScrn); 1289 return FALSE; 1290 } 1291 1292 xf86PruneDriverModes(pScrn); 1293 1294 if (!i || !pScrn->modes) { 1295 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes found\n"); 1296 TDFXFreeRec(pScrn); 1297 return FALSE; 1298 } 1299 1300 xf86SetCrtcForModes(pScrn, 0); 1301 1302 pScrn->currentMode = pScrn->modes; 1303 1304 xf86PrintModes(pScrn); 1305 1306 xf86SetDpi(pScrn, 0, 0); 1307 1308 if (xf86ReturnOptValBool(pTDFX->Options, OPTION_USE_PIO, FALSE)) { 1309 pTDFX->usePIO=TRUE; 1310 } 1311 1312#if X_BYTE_ORDER == X_BIG_ENDIAN 1313 pTDFX->ModeReg.miscinit0 = pTDFX->readLong(pTDFX, MISCINIT0); 1314 pTDFX->SavedReg.miscinit0 = pTDFX->ModeReg.miscinit0; 1315 1316 switch (pScrn->bitsPerPixel) { 1317 case 8: 1318 pTDFX->writeFifo = TDFXWriteFifo_8; 1319 pTDFX->ModeReg.miscinit0 &= ~BIT(30); /* LFB byte swizzle */ 1320 pTDFX->ModeReg.miscinit0 &= ~BIT(31); /* LFB word swizzle */ 1321 break; 1322 case 15: 1323 case 16: 1324 pTDFX->writeFifo = TDFXWriteFifo_16; 1325 pTDFX->ModeReg.miscinit0 |= BIT(30); /* LFB byte swizzle */ 1326 pTDFX->ModeReg.miscinit0 |= BIT(31); /* LFB word swizzle */ 1327 break; 1328 case 24: 1329 case 32: 1330 pTDFX->writeFifo = TDFXWriteFifo_24; 1331 pTDFX->ModeReg.miscinit0 |= BIT(30); /* LFB byte swizzle */ 1332 pTDFX->ModeReg.miscinit0 &= ~BIT(31); /* LFB word swizzle */ 1333 break; 1334 default: 1335 return FALSE; 1336 break; 1337 } 1338 pTDFX->writeLong(pTDFX, MISCINIT0, pTDFX->ModeReg.miscinit0); 1339#endif 1340 1341#ifdef XF86DRI 1342 /* Load the dri module if requested. */ 1343 if (xf86ReturnOptValBool(pTDFX->Options, OPTION_DRI, FALSE)) { 1344 if (xf86LoadSubModule(pScrn, "dri")) { 1345 xf86LoaderReqSymLists(driSymbols, drmSymbols, NULL); 1346 } 1347 } 1348#endif 1349 return TRUE; 1350} 1351 1352static Bool 1353TDFXMapMem(ScrnInfoPtr pScrn) 1354{ 1355 int i; 1356 TDFXPtr pTDFX = TDFXPTR(pScrn); 1357#ifdef XSERVER_LIBPCIACCESS 1358 int err; 1359#else 1360 const int mmioFlags = VIDMEM_MMIO | VIDMEM_READSIDEEFFECT; 1361#endif 1362 1363 TDFXTRACE("TDFXMapMem start\n"); 1364 1365#ifdef XSERVER_LIBPCIACCESS 1366 /* FIXME: I'm not convinced that this is correct for SLI cards, but I 1367 * FIXME: don't have any such hardware to test. 1368 */ 1369 for (i = 0; i < pTDFX->numChips; i++) { 1370 err = pci_device_map_memory_range(pTDFX->PciInfo[i], 1371 pTDFX->MMIOAddr[i], 1372 TDFXIOMAPSIZE, 1373 TRUE, 1374 & pTDFX->MMIOBase[i]); 1375 if (err) { 1376 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1377 "Unable to map MMIO region for card %u (%d).\n", 1378 i, err); 1379 return FALSE; 1380 } 1381 } 1382 1383 1384 err = pci_device_map_memory_range(pTDFX->PciInfo[0], 1385 pTDFX->LinearAddr[0], 1386 pTDFX->FbMapSize, 1387 TRUE, 1388 & pTDFX->FbBase); 1389 if (err) { 1390 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 1391 "Unable to map framebuffer (%d).\n", err); 1392 return FALSE; 1393 } 1394#else 1395 for (i=0; i<pTDFX->numChips; i++) { 1396 pTDFX->MMIOBase[i] = xf86MapPciMem(pScrn->scrnIndex, mmioFlags, 1397 pTDFX->PciTag[i], 1398 pTDFX->MMIOAddr[i], 1399 TDFXIOMAPSIZE); 1400 1401 if (!pTDFX->MMIOBase[i]) return FALSE; 1402 } 1403 1404 pTDFX->FbBase = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER, 1405 pTDFX->PciTag[0], 1406 pTDFX->LinearAddr[0], 1407 pTDFX->FbMapSize); 1408 if (!pTDFX->FbBase) return FALSE; 1409#endif 1410 1411 return TRUE; 1412} 1413 1414static Bool 1415TDFXUnmapMem(ScrnInfoPtr pScrn) 1416{ 1417 TDFXPtr pTDFX; 1418 int i; 1419 1420 TDFXTRACE("TDFXUnmapMem start\n"); 1421 pTDFX = TDFXPTR(pScrn); 1422 1423#ifdef XSERVER_LIBPCIACCESS 1424 pci_device_unmap_region(pTDFX->PciInfo[0], 0); 1425 pci_device_unmap_region(pTDFX->PciInfo[0], 1); 1426 1427 (void) memset(pTDFX->MMIOBase, 0, sizeof(pTDFX->MMIOBase)); 1428 pTDFX->FbBase = NULL; 1429#else 1430 for (i=0; i<pTDFX->numChips; i++) { 1431 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTDFX->MMIOBase[i], 1432 TDFXIOMAPSIZE); 1433 pTDFX->MMIOBase[i]=0; 1434 } 1435 1436 xf86UnMapVidMem(pScrn->scrnIndex, (pointer)pTDFX->FbBase, pTDFX->FbMapSize); 1437 pTDFX->FbBase = 0; 1438#endif 1439 return TRUE; 1440} 1441 1442static void 1443PrintRegisters(ScrnInfoPtr pScrn, TDFXRegPtr regs) 1444{ 1445#ifdef TRACE 1446 int i; 1447 TDFXPtr pTDFX; 1448 vgaHWPtr pHW = VGAHWPTR(pScrn); 1449 vgaRegPtr pVga = &VGAHWPTR(pScrn)->ModeReg; 1450 1451 1452 pTDFX = TDFXPTR(pScrn); 1453#if 1 1454 ErrorF("VGA Registers\n"); 1455 ErrorF("MiscOutReg = %x versus %x\n", pHW->readMiscOut(pHW), pVga->MiscOutReg); 1456 ErrorF("EnableReg = %x\n", pHW->readEnable(pHW)); 1457 for (i=0; i<25; i++) { 1458 int x; 1459 x = pHW->readCrtc(pHW, i); 1460 ErrorF("CRTC[%d]=%d versus %d\n", i, x, pVga->CRTC[i]); 1461 } 1462 for (i=0; i<21; i++) { 1463 ErrorF("Attribute[%d]=%d versus %d\n", i, pHW->readAttr(pHW, i), pVga->Attribute[i]); 1464 } 1465 for (i=0; i<9; i++) { 1466 ErrorF("Graphics[%d]=%d versus %d\n", i, pHW->readGr(pHW, i), pVga->Graphics[i]); 1467 } 1468 for (i=0; i<5; i++) { 1469 ErrorF("Sequencer[%d]=%d versus %d\n", i, pHW->readSeq(pHW, i), pVga->Sequencer[i]); 1470 } 1471#endif 1472#if 1 1473 ErrorF("Banshee Registers\n"); 1474 ErrorF("VidCfg = %x versus %x\n", pTDFX->readLong(pTDFX, VIDPROCCFG), regs->vidcfg); 1475 ErrorF("DACmode = %x versus %x\n", pTDFX->readLong(pTDFX, DACMODE), regs->dacmode); 1476 ErrorF("Vgainit0 = %x versus %x\n", pTDFX->readLong(pTDFX, VGAINIT0), regs->vgainit0); 1477 ErrorF("Vgainit1 = %x versus %x\n", pTDFX->readLong(pTDFX, VGAINIT1), regs->vgainit1); 1478 ErrorF("Miscinit0 = %x versus %x\n", pTDFX->readLong(pTDFX, MISCINIT0), regs->miscinit0); 1479 ErrorF("Miscinit1 = %x versus %x\n", pTDFX->readLong(pTDFX, MISCINIT1), regs->miscinit1); 1480 ErrorF("DramInit0 = %x\n", pTDFX->readLong(pTDFX, DRAMINIT0)); 1481 ErrorF("DramInit1 = %x\n", pTDFX->readLong(pTDFX, DRAMINIT1)); 1482 ErrorF("VidPLL = %x versus %x\n", pTDFX->readLong(pTDFX, PLLCTRL0), regs->vidpll); 1483 ErrorF("screensize = %x versus %x\n", pTDFX->readLong(pTDFX, VIDSCREENSIZE), regs->screensize); 1484 ErrorF("stride = %x versus %x\n", pTDFX->readLong(pTDFX, VIDDESKTOPOVERLAYSTRIDE), regs->stride); 1485 ErrorF("startaddr = %x versus %x\n", pTDFX->readLong(pTDFX, VIDDESKTOPSTARTADDR), regs->startaddr); 1486 ErrorF("Input Status 0 = %x\n", pTDFX->readLong(pTDFX, 0xc2)); 1487 ErrorF("Input Status 1 = %x\n", pTDFX->readLong(pTDFX, 0xda)); 1488 ErrorF("2D Status = %x\n", pTDFX->readLong(pTDFX, SST_2D_OFFSET)); 1489 ErrorF("3D Status = %x\n", pTDFX->readLong(pTDFX, SST_3D_OFFSET)); 1490#endif 1491#endif 1492} 1493 1494/* 1495 * TDFXSave -- 1496 * 1497 * This function saves the video state. It reads all of the SVGA registers 1498 * into the vgaTDFXRec data structure. There is in general no need to 1499 * mask out bits here - just read the registers. 1500 */ 1501static void 1502DoSave(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, TDFXRegPtr tdfxReg, Bool saveFonts) 1503{ 1504 TDFXPtr pTDFX; 1505 vgaHWPtr hwp; 1506 int i, dummy, count; 1507 1508 TDFXTRACE("TDFXDoSave start\n"); 1509 pTDFX = TDFXPTR(pScrn); 1510 hwp = VGAHWPTR(pScrn); 1511 1512 /* 1513 * This function will handle creating the data structure and filling 1514 * in the generic VGA portion. 1515 */ 1516 if (saveFonts && pTDFX->Primary) { 1517 /* Enable legacy VGA to access font memory. */ 1518 dummy = pTDFX->readLong(pTDFX, VGAINIT0); 1519 pTDFX->writeLong(pTDFX, VGAINIT0, dummy & ~SST_VGA0_LEGACY_DECODE); 1520 vgaHWSave(pScrn, vgaReg, VGA_SR_MODE|VGA_SR_FONTS); 1521 pTDFX->writeLong(pTDFX, VGAINIT0, dummy); 1522 } else 1523 vgaHWSave(pScrn, vgaReg, VGA_SR_MODE); 1524 1525 tdfxReg->ExtVga[0] = hwp->readCrtc(hwp, 0x1a); 1526 tdfxReg->ExtVga[1] = hwp->readCrtc(hwp, 0x1b); 1527 tdfxReg->miscinit1=pTDFX->readLong(pTDFX, MISCINIT1); 1528 tdfxReg->vidcfg=pTDFX->readLong(pTDFX, VIDPROCCFG); 1529 tdfxReg->vidpll=pTDFX->readLong(pTDFX, PLLCTRL0); 1530 tdfxReg->dacmode=pTDFX->readLong(pTDFX, DACMODE); 1531 tdfxReg->screensize=pTDFX->readLong(pTDFX, VIDSCREENSIZE); 1532 tdfxReg->stride=pTDFX->readLong(pTDFX, VIDDESKTOPOVERLAYSTRIDE); 1533 tdfxReg->cursloc=pTDFX->readLong(pTDFX, HWCURPATADDR); 1534 tdfxReg->startaddr=pTDFX->readLong(pTDFX, VIDDESKTOPSTARTADDR); 1535 tdfxReg->clip0min=TDFXReadLongMMIO(pTDFX, SST_2D_CLIP0MIN); 1536 tdfxReg->clip0max=TDFXReadLongMMIO(pTDFX, SST_2D_CLIP0MAX); 1537 tdfxReg->clip1min=TDFXReadLongMMIO(pTDFX, SST_2D_CLIP1MIN); 1538 tdfxReg->clip1max=TDFXReadLongMMIO(pTDFX, SST_2D_CLIP1MAX); 1539 tdfxReg->srcbaseaddr=TDFXReadLongMMIO(pTDFX, SST_2D_SRCBASEADDR); 1540 tdfxReg->dstbaseaddr=TDFXReadLongMMIO(pTDFX, SST_2D_DSTBASEADDR); 1541 for (i=0; i<512; i++) { 1542 count=0; 1543 do { 1544 TDFXWriteLongMMIO(pTDFX, DACADDR, i); 1545 dummy=TDFXReadLongMMIO(pTDFX, DACADDR); 1546 } while (count++<100 && dummy!=i); 1547 tdfxReg->dactable[i]=TDFXReadLongMMIO(pTDFX, DACDATA); 1548 } 1549 PrintRegisters(pScrn, tdfxReg); 1550} 1551 1552static void 1553TDFXSave(ScrnInfoPtr pScrn) 1554{ 1555 vgaHWPtr hwp; 1556 TDFXPtr pTDFX; 1557 1558 TDFXTRACE("TDFXSave start\n"); 1559 hwp = VGAHWPTR(pScrn); 1560 pTDFX = TDFXPTR(pScrn); 1561 /* Make sure VGA functionality is enabled */ 1562 pTDFX->SavedReg.vgainit0=pTDFX->readLong(pTDFX, VGAINIT0); 1563#if 0 1564 pTDFX->SavedReg.vgainit1=pTDFX->readLong(pTDFX, VGAINIT1); 1565#endif 1566 pTDFX->writeLong(pTDFX, VGAINIT0, pTDFX->ModeReg.vgainit0); 1567#if 0 1568 pTDFX->writeLong(pTDFX, VGAINIT1, pTDFX->ModeReg.vgainit1); 1569#endif 1570 vgaHWEnable(hwp); 1571 1572 DoSave(pScrn, &hwp->SavedReg, &pTDFX->SavedReg, TRUE); 1573} 1574 1575static void 1576DoRestore(ScrnInfoPtr pScrn, vgaRegPtr vgaReg, TDFXRegPtr tdfxReg, 1577 Bool restoreFonts) { 1578 TDFXPtr pTDFX; 1579 vgaHWPtr hwp; 1580 int i, dummy, count; 1581 1582 TDFXTRACE("TDFXDoRestore start\n"); 1583 pTDFX = TDFXPTR(pScrn); 1584 hwp = VGAHWPTR(pScrn); 1585 1586 pTDFX->sync(pScrn); 1587 1588 vgaHWProtect(pScrn, TRUE); 1589 1590 if (restoreFonts && pTDFX->Primary) { 1591 /* Enable legacy VGA to access font memory. */ 1592 dummy = pTDFX->readLong(pTDFX, VGAINIT0); 1593 pTDFX->writeLong(pTDFX, VGAINIT0, dummy & ~SST_VGA0_LEGACY_DECODE); 1594 vgaHWRestore(pScrn, vgaReg, VGA_SR_FONTS|VGA_SR_MODE); 1595 pTDFX->writeLong(pTDFX, VGAINIT0, dummy); 1596 } else 1597 vgaHWRestore(pScrn, vgaReg, VGA_SR_MODE); 1598 1599 hwp->writeCrtc(hwp, 0x1a, tdfxReg->ExtVga[0]); 1600 hwp->writeCrtc(hwp, 0x1b, tdfxReg->ExtVga[1]); 1601 pTDFX->writeLong(pTDFX, PLLCTRL0, tdfxReg->vidpll); 1602 pTDFX->writeLong(pTDFX, DACMODE, tdfxReg->dacmode); 1603 pTDFX->writeLong(pTDFX, VIDDESKTOPOVERLAYSTRIDE, tdfxReg->stride); 1604 pTDFX->writeLong(pTDFX, HWCURPATADDR, tdfxReg->cursloc); 1605 pTDFX->writeLong(pTDFX, VIDSCREENSIZE, tdfxReg->screensize); 1606 pTDFX->writeLong(pTDFX, VIDDESKTOPSTARTADDR, tdfxReg->startaddr); 1607 TDFXWriteLongMMIO(pTDFX, SST_2D_CLIP0MIN, tdfxReg->clip0min); 1608 TDFXWriteLongMMIO(pTDFX, SST_2D_CLIP0MAX, tdfxReg->clip0max); 1609 TDFXWriteLongMMIO(pTDFX, SST_2D_CLIP1MIN, tdfxReg->clip1min); 1610 TDFXWriteLongMMIO(pTDFX, SST_2D_CLIP1MAX, tdfxReg->clip1max); 1611#if X_BYTE_ORDER == X_BIG_ENDIAN 1612 pTDFX->writeLong(pTDFX, MISCINIT0, tdfxReg->miscinit0); 1613#endif 1614 pTDFX->writeLong(pTDFX, VIDPROCCFG, tdfxReg->vidcfg); 1615 TDFXWriteLongMMIO(pTDFX, SST_2D_SRCBASEADDR, tdfxReg->srcbaseaddr); 1616 TDFXWriteLongMMIO(pTDFX, SST_2D_DSTBASEADDR, tdfxReg->dstbaseaddr); 1617 for (i=0; i<512; i++) { 1618 count=0; 1619 do { 1620 TDFXWriteLongMMIO(pTDFX, DACADDR, i); 1621 dummy=TDFXReadLongMMIO(pTDFX, DACADDR); 1622 } while (count++<100 && dummy!=i); 1623 count=0; 1624 do { 1625 TDFXWriteLongMMIO(pTDFX, DACDATA, tdfxReg->dactable[i]); 1626 dummy=TDFXReadLongMMIO(pTDFX, DACDATA); 1627 } while (count++<100 && dummy!=tdfxReg->dactable[i]); 1628 } 1629 pTDFX->writeLong(pTDFX, VGAINIT0, tdfxReg->vgainit0); 1630#if 0 1631 pTDFX->writeLong(pTDFX, VGAINIT1, tdfxReg->vgainit1); 1632 pTDFX->writeLong(pTDFX, MISCINIT1, tdfxReg->miscinit1); 1633#endif 1634 vgaHWProtect(pScrn, FALSE); 1635 1636 pTDFX->sync(pScrn); 1637 PrintRegisters(pScrn, tdfxReg); 1638} 1639 1640static void 1641TDFXRestore(ScrnInfoPtr pScrn) { 1642 vgaHWPtr hwp; 1643 TDFXPtr pTDFX; 1644 1645 TDFXTRACE("TDFXRestore start\n"); 1646 hwp = VGAHWPTR(pScrn); 1647 pTDFX = TDFXPTR(pScrn); 1648 1649 DoRestore(pScrn, &hwp->SavedReg, &pTDFX->SavedReg, TRUE); 1650} 1651 1652#define REFFREQ 14318.18 1653 1654static int 1655CalcPLL(int freq, int *f_out, int isBanshee) { 1656 int m, n, k, best_m, best_n, best_k, f_cur, best_error; 1657 int minm, maxm; 1658 1659 TDFXTRACE("CalcPLL start\n"); 1660 best_error=freq; 1661 best_n=best_m=best_k=0; 1662 if (isBanshee) { 1663 minm=24; 1664 maxm=24; 1665 } else { 1666 minm=1; 1667 maxm=57; /* This used to be 64, alas it seems the last 8 (funny that ?) 1668 * values cause jittering at lower resolutions. I've not done 1669 * any calculations to what the adjustment affects clock ranges, 1670 * but I can still run at 1600x1200@75Hz */ 1671 } 1672 for (n=1; n<256; n++) { 1673 f_cur=REFFREQ*(n+2); 1674 if (f_cur<freq) { 1675 f_cur=f_cur/3; 1676 if (freq-f_cur<best_error) { 1677 best_error=freq-f_cur; 1678 best_n=n; 1679 best_m=1; 1680 best_k=0; 1681 continue; 1682 } 1683 } 1684 for (m=minm; m<maxm; m++) { 1685 for (k=0; k<4; k++) { 1686 f_cur=REFFREQ*(n+2)/(m+2)/(1<<k); 1687 if (abs(f_cur-freq)<best_error) { 1688 best_error=abs(f_cur-freq); 1689 best_n=n; 1690 best_m=m; 1691 best_k=k; 1692 } 1693 } 1694 } 1695 } 1696 n=best_n; 1697 m=best_m; 1698 k=best_k; 1699 *f_out=REFFREQ*(n+2)/(m+2)/(1<<k); 1700 return (n<<8)|(m<<2)|k; 1701} 1702 1703static Bool 1704SetupVidPLL(ScrnInfoPtr pScrn, DisplayModePtr mode) { 1705 TDFXPtr pTDFX; 1706 TDFXRegPtr tdfxReg; 1707 int freq, f_out; 1708 1709 TDFXTRACE("SetupVidPLL start\n"); 1710 pTDFX = TDFXPTR(pScrn); 1711 tdfxReg = &pTDFX->ModeReg; 1712 freq=mode->Clock; 1713 tdfxReg->dacmode&=~SST_DAC_MODE_2X; 1714 tdfxReg->vidcfg&=~SST_VIDEO_2X_MODE_EN; 1715 if (freq>TDFX2XCUTOFF) { 1716 if (freq>pTDFX->MaxClock) { 1717 ErrorF("Overclocked PLLs\n"); 1718 freq=pTDFX->MaxClock; 1719 } 1720 tdfxReg->dacmode|=SST_DAC_MODE_2X; 1721 tdfxReg->vidcfg|=SST_VIDEO_2X_MODE_EN; 1722 } 1723 tdfxReg->vidpll=CalcPLL(freq, &f_out, 0); 1724 TDFXTRACEREG("Vid PLL freq=%d f_out=%d reg=%x\n", freq, f_out, 1725 tdfxReg->vidpll); 1726 return TRUE; 1727} 1728 1729#if 0 1730static Bool 1731SetupMemPLL(int freq) { 1732 TDFXPtr pTDFX; 1733 vgaTDFXPtr tdfxReg; 1734 int f_out; 1735 1736 TDFXTRACE("SetupMemPLL start\n"); 1737 pTDFX=TDFXPTR(); 1738 tdfxReg=(vgaTDFXPtr)vgaNewVideoState; 1739 tdfxReg->mempll=CalcPLL(freq, &f_out); 1740 pTDFX->writeLong(pTDFX, PLLCTRL1, tdfxReg->mempll); 1741 TDFXTRACEREG("Mem PLL freq=%d f_out=%d reg=%x\n", freq, f_out, 1742 tdfxReg->mempll); 1743 return TRUE; 1744} 1745 1746static Bool 1747SetupGfxPLL(int freq) { 1748 TDFXPtr pTDFX; 1749 vgaTDFXPtr tdfxReg; 1750 int f_out; 1751 1752 TDFXTRACE("SetupGfxPLL start\n"); 1753 pTDFX=TDFXPTR(); 1754 tdfxReg=(vgaTDFXPtr)vgaNewVideoState; 1755 if (pTDFX->chipType==PCI_CHIP_BANSHEE) 1756 tdfxReg->gfxpll=CalcPLL(freq, &f_out, 1); 1757 else 1758 tdfxReg->gfxpll=CalcPLL(freq, &f_out, 0); 1759 pTDFX->writeLong(pTDFX, PLLCTRL2, tdfxReg->gfxpll); 1760 TDFXTRACEREG("Gfx PLL freq=%d f_out=%d reg=%x\n", freq, f_out, 1761 tdfxReg->gfxpll); 1762 return TRUE; 1763} 1764#endif 1765 1766#if 0 1767static Bool 1768TDFXInitWithBIOSData(ScrnInfoPtr pScrn) 1769{ 1770 TDFXPtr pTDFX; 1771 unsigned char *bios = NULL; 1772 int offset1, offset2; 1773 int i; 1774 CARD32 uint[9]; 1775 1776 pTDFX=TDFXPTR(pScrn); 1777 1778 if (pTDFX->initDone) 1779 return TRUE; 1780 1781 if (pTDFX->Primary) { 1782 uint[0] = pTDFX->readLong(pTDFX, PCIINIT0); 1783 uint[1] = pTDFX->readLong(pTDFX, MISCINIT0); 1784 uint[2] = pTDFX->readLong(pTDFX, MISCINIT1); 1785 uint[3] = pTDFX->readLong(pTDFX, DRAMINIT0); 1786 uint[4] = pTDFX->readLong(pTDFX, DRAMINIT1); 1787 uint[5] = pTDFX->readLong(pTDFX, AGPINIT); 1788 uint[6] = pTDFX->readLong(pTDFX, PLLCTRL1); 1789 uint[7] = pTDFX->readLong(pTDFX, PLLCTRL2); 1790 for (i = 0; i < 8; i++) { 1791 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Primary UINT32[%d] is 0x%08lx\n", i, uint[i]); 1792 } 1793 return TRUE; 1794 } 1795 1796#define T_B_SIZE (64 * 1024) 1797 bios = xcalloc(T_B_SIZE, 1); 1798 if (!bios) 1799 return FALSE; 1800 1801#ifdef XSERVER_LIBPCIACCESS 1802 pci_device_read_rom(pTDFX->PciInfo[0], bios); 1803#else 1804 if (!xf86ReadPciBIOS(0, pTDFX->PciTag[0], 1, bios, T_B_SIZE)) { 1805#if 0 1806 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Bad BIOS read.\n"); 1807 xfree(bios); 1808 return FALSE; 1809#endif 1810 } 1811#endif 1812 1813 if (bios[0] != 0x55 || bios[1] != 0xAA) { 1814 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Bad BIOS signature.\n"); 1815 xfree(bios); 1816 return FALSE; 1817 } 1818 1819 offset1 = bios[0x50] | (bios[0x51] << 8); 1820 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Offset 1 is (0x%04x)\n", offset1); 1821 offset2 = bios[offset1] | (bios[offset1 + 1] << 8); 1822 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Offset 2 is (0x%04x)\n", offset2); 1823 1824 for (i = 0; i < 9; i++) { 1825 int o; 1826 1827 o = offset2 + i * 4; 1828 uint[i] = bios[o] | (bios[o+1] << 8) | (bios[o+2] << 16) | (bios[o+3] << 24); 1829 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "UINT32[%d] is 0x%08lx\n", i, uint[i]); 1830 } 1831 1832#if 1 1833 uint[0] = 0x0584fb04; 1834 uint[1] = 0x00000000; 1835 uint[2] = 0x03000001; 1836 uint[3] = 0x0c17a9e9; 1837 uint[4] = 0x00202031; 1838 uint[5] = 0x8000049e; 1839 uint[6] = 0x00003a05; 1840 uint[7] = 0x00000c00; 1841#endif 1842 1843 pTDFX->writeLong(pTDFX, PCIINIT0, uint[0]); 1844 pTDFX->writeLong(pTDFX, MISCINIT0, uint[1]); 1845 pTDFX->writeLong(pTDFX, MISCINIT1, uint[2]); 1846 pTDFX->writeLong(pTDFX, DRAMINIT0, uint[3]); 1847 pTDFX->writeLong(pTDFX, DRAMINIT1, uint[4]); 1848 pTDFX->writeLong(pTDFX, AGPINIT, uint[5]); 1849 pTDFX->writeLong(pTDFX, PLLCTRL1, uint[6]); 1850 pTDFX->writeLong(pTDFX, PLLCTRL2, uint[7]); 1851#if 0 1852 pTDFX->writeLong(pTDFX, DRAMCOMMAND, uint[8]); 1853#endif 1854 1855 /* reset */ 1856 pTDFX->writeLong(pTDFX, MISCINIT0, 0xF3); 1857 pTDFX->writeLong(pTDFX, MISCINIT0, uint[1]); 1858 1859 xfree(bios); 1860 return TRUE; 1861} 1862#endif 1863 1864 1865static Bool 1866TDFXInitVGA(ScrnInfoPtr pScrn) 1867{ 1868 TDFXPtr pTDFX; 1869 TDFXRegPtr tdfxReg; 1870 1871 TDFXTRACE("TDFXInitVGA start\n"); 1872 pTDFX=TDFXPTR(pScrn); 1873 if (pTDFX->initDone) return TRUE; 1874 pTDFX->initDone=TRUE; 1875 1876 tdfxReg = &pTDFX->ModeReg; 1877 tdfxReg->vgainit0 = 0; 1878 tdfxReg->vgainit0 |= SST_VGA0_EXTENSIONS; 1879 tdfxReg->vgainit0 |= SST_WAKEUP_3C3 << SST_VGA0_WAKEUP_SELECT_SHIFT; 1880#if USE_PCIVGAIO 1881 tdfxReg->vgainit0 |= SST_VGA0_LEGACY_DECODE; 1882#endif 1883 tdfxReg->vgainit0 |= SST_ENABLE_ALT_READBACK << SST_VGA0_CONFIG_READBACK_SHIFT; 1884 tdfxReg->vgainit0 |= SST_CLUT_SELECT_8BIT << SST_VGA0_CLUT_SELECT_SHIFT; 1885 1886 tdfxReg->vgainit0 |= BIT(12); 1887#if 0 1888 tdfxReg->vgainit1 |= 0; 1889 tdfxReg->miscinit1 = 0; 1890#endif 1891 1892 tdfxReg->vidcfg = SST_VIDEO_PROCESSOR_EN | SST_CURSOR_X11 | SST_DESKTOP_EN | 1893 (pTDFX->cpp-1)<<SST_DESKTOP_PIXEL_FORMAT_SHIFT; 1894 1895 /* tdfxReg->vidcfg |= SST_DESKTOP_CLUT_BYPASS; */ 1896 1897 tdfxReg->stride = pTDFX->stride; 1898 1899 tdfxReg->clip0min = tdfxReg->clip1min = 0; 1900 tdfxReg->clip0max = tdfxReg->clip1max = pTDFX->maxClip; 1901 1902 return TRUE; 1903} 1904 1905static Bool 1906TDFXSetMode(ScrnInfoPtr pScrn, DisplayModePtr mode) { 1907 TDFXPtr pTDFX; 1908 TDFXRegPtr tdfxReg; 1909 vgaRegPtr pVga; 1910 int hbs, hbe, vbs, vbe, hse; 1911 int hd, hss, ht, vt, vd; 1912 1913 TDFXTRACE("TDFXSetMode start\n"); 1914 1915 pTDFX = TDFXPTR(pScrn); 1916 tdfxReg = &pTDFX->ModeReg; 1917 pVga = &VGAHWPTR(pScrn)->ModeReg; 1918 1919 /* Tell the board we're using a programmable clock */ 1920 pVga->MiscOutReg |= 0xC; 1921 1922 /* Calculate the CRTC values */ 1923 hd = (mode->CrtcHDisplay>>3)-1; 1924 hss = (mode->CrtcHSyncStart>>3); 1925 hse = (mode->CrtcHSyncEnd>>3); 1926 ht = (mode->CrtcHTotal>>3)-5; 1927 hbs = (mode->CrtcHBlankStart>>3)-1; 1928 hbe = (mode->CrtcHBlankEnd>>3)-1; 1929 1930 vd = mode->CrtcVDisplay-1; 1931 vt = mode->CrtcVTotal-2; 1932 vbs = mode->CrtcVBlankStart-1; 1933 vbe = mode->CrtcVBlankEnd-1; 1934 1935 /* Undo the "KGA fixes" */ 1936 pVga->CRTC[3] = (hbe&0x1F)|0x80; 1937 pVga->CRTC[5] = (((hbe)&0x20)<<2) | (hse&0x1F); 1938 pVga->CRTC[22] =vbe&0xFF; 1939 1940 /* Handle the higher resolution modes */ 1941 tdfxReg->ExtVga[0] = (ht&0x100)>>8 | (hd&0x100)>>6 | (hbs&0x100)>>4 | 1942 (hbe&0x40)>>1 | (hss&0x100)>>2 | (hse&0x20)<<2; 1943 1944 tdfxReg->ExtVga[1] = (vt&0x400)>>10 | (vd&0x400)>>8 | (vbs&0x400)>>6 | 1945 (vbe&0x400)>>4; 1946 1947 if (!SetupVidPLL(pScrn, mode)) return FALSE; 1948 1949 /* Set the screen size */ 1950 if (mode->Flags&V_DBLSCAN) { 1951 pVga->CRTC[9] |= 0x80; 1952 tdfxReg->screensize=mode->HDisplay|(mode->VDisplay<<13); 1953 tdfxReg->vidcfg |= SST_HALF_MODE; 1954 } else { 1955 tdfxReg->screensize=mode->HDisplay|(mode->VDisplay<<12); 1956 tdfxReg->vidcfg &= ~SST_HALF_MODE; 1957 } 1958 if (mode->Flags&V_INTERLACE) { 1959 tdfxReg->vidcfg|=SST_INTERLACE; 1960 } else 1961 tdfxReg->vidcfg&=~SST_INTERLACE; 1962 1963 TDFXTRACEREG("cpp=%d Hdisplay=%d Vdisplay=%d stride=%d screensize=%x\n", 1964 pTDFX->cpp, mode->HDisplay, mode->VDisplay, tdfxReg->stride, 1965 tdfxReg->screensize); 1966 1967 return TRUE; 1968} 1969 1970static Bool 1971TDFXModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) 1972{ 1973 vgaHWPtr hwp; 1974 TDFXPtr pTDFX; 1975 int hd, hbs, hss, hse, hbe, ht, hskew; 1976 Bool dbl; 1977 1978 hd = hbs = hss = hse = hbe = ht = hskew = 0; 1979 hwp = VGAHWPTR(pScrn); 1980 pTDFX = TDFXPTR(pScrn); 1981 1982 TDFXTRACE("TDFXModeInit start\n"); 1983 dbl=FALSE; 1984 /* Check for 2x mode and halve all the timing values */ 1985 if (mode->Clock>TDFX2XCUTOFF) { 1986 hd=mode->CrtcHDisplay; 1987 hbs=mode->CrtcHBlankStart; 1988 hss=mode->CrtcHSyncStart; 1989 hse=mode->CrtcHSyncEnd; 1990 hbe=mode->CrtcHBlankEnd; 1991 ht=mode->CrtcHTotal; 1992 hskew=mode->CrtcHSkew; 1993 mode->CrtcHDisplay=hd>>1; 1994 mode->CrtcHBlankStart=hbs>>1; 1995 mode->CrtcHSyncStart=hss>>1; 1996 mode->CrtcHSyncEnd=hse>>1; 1997 mode->CrtcHBlankEnd=hbe>>1; 1998 mode->CrtcHTotal=ht>>1; 1999 mode->CrtcHSkew=hskew>>1; 2000 dbl=TRUE; 2001 } 2002 2003 vgaHWUnlock(hwp); 2004 2005 if (!vgaHWInit(pScrn, mode)) return FALSE; 2006 2007 pScrn->vtSema = TRUE; 2008 2009 if (!TDFXSetMode(pScrn, mode)) return FALSE; 2010 2011 if (dbl) { 2012 mode->CrtcHDisplay=hd; 2013 mode->CrtcHBlankStart=hbs; 2014 mode->CrtcHSyncStart=hss; 2015 mode->CrtcHSyncEnd=hse; 2016 mode->CrtcHBlankEnd=hbe; 2017 mode->CrtcHTotal=ht; 2018 mode->CrtcHSkew=hskew; 2019 } 2020 2021#ifdef XF86DRI 2022 if (pTDFX->directRenderingEnabled) { 2023 DRILock(screenInfo.screens[pScrn->scrnIndex], 0); 2024 TDFXSwapContextFifo(screenInfo.screens[pScrn->scrnIndex]); 2025 } 2026#endif 2027 DoRestore(pScrn, &hwp->ModeReg, &pTDFX->ModeReg, FALSE); 2028#ifdef XF86DRI 2029 if (pTDFX->directRenderingEnabled) { 2030 DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); 2031 } 2032#endif 2033 2034 return TRUE; 2035} 2036 2037static void 2038TDFXLoadPalette16(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, 2039 VisualPtr pVisual) { 2040 TDFXPtr pTDFX; 2041 int i, j, index, v, repeat, max; 2042 2043 TDFXTRACE("TDFXLoadPalette16 start\n"); 2044 pTDFX = TDFXPTR(pScrn); 2045 2046 for (i=0; i<numColors; i++) { 2047 index=indices[i]; 2048 v=(colors[index/2].red<<16)|(colors[index].green<<8)|colors[index/2].blue; 2049 max=min((index+1)<<2, 256); 2050 for (j = index<<2; j < max; j++) 2051 { 2052 repeat=100; 2053 do { 2054 TDFXWriteLongMMIO(pTDFX, DACADDR, j); 2055 } while (--repeat && TDFXReadLongMMIO(pTDFX, DACADDR)!=j); 2056 if (!repeat) { 2057 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to set dac index, bypassing CLUT\n"); 2058 pTDFX->ModeReg.vidcfg |= SST_DESKTOP_CLUT_BYPASS; 2059 return; 2060 } 2061 2062 repeat=100; 2063 do { 2064 TDFXWriteLongMMIO(pTDFX, DACDATA, v); 2065 } while (--repeat && TDFXReadLongMMIO(pTDFX, DACDATA)!=v); 2066 if (!repeat) { 2067 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to set dac value, bypassing CLUT\n"); 2068 pTDFX->ModeReg.vidcfg |= SST_DESKTOP_CLUT_BYPASS; 2069 return; 2070 } 2071 } 2072 } 2073} 2074 2075static void 2076TDFXLoadPalette24(ScrnInfoPtr pScrn, int numColors, int *indices, LOCO *colors, 2077 VisualPtr pVisual) { 2078 TDFXPtr pTDFX; 2079 int i, index, v, repeat; 2080 2081 TDFXTRACE("TDFXLoadPalette24 start\n"); 2082 pTDFX = TDFXPTR(pScrn); 2083 for (i=0; i<numColors; i++) { 2084 index=indices[i]; 2085 v=(colors[index].red<<16)|(colors[index].green<<8)|colors[index].blue; 2086 repeat=100; 2087 do { 2088 TDFXWriteLongMMIO(pTDFX, DACADDR, index); 2089 } while (--repeat && TDFXReadLongMMIO(pTDFX, DACADDR)!=index); 2090 if (!repeat) { 2091 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to set dac index, " 2092 "bypassing CLUT\n"); 2093 pTDFX->ModeReg.vidcfg |= SST_DESKTOP_CLUT_BYPASS; 2094 return; 2095 } 2096 repeat=100; 2097 do { 2098 TDFXWriteLongMMIO(pTDFX, DACDATA, v); 2099 } while (--repeat && TDFXReadLongMMIO(pTDFX, DACDATA)!=v); 2100 if (!repeat) { 2101 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Failed to set dac value, " 2102 "bypassing CLUT\n"); 2103 pTDFX->ModeReg.vidcfg |= SST_DESKTOP_CLUT_BYPASS; 2104 return; 2105 } 2106 } 2107} 2108 2109#define TILE_WIDTH 128 2110#define TILE_HEIGHT 32 2111 2112static int 2113calcBufferStride(int xres, Bool tiled, int cpp) 2114{ 2115 int strideInTiles; 2116 2117 if (tiled == TRUE) { 2118 /* Calculate tile width stuff */ 2119 strideInTiles = (xres+TILE_WIDTH-1)/TILE_WIDTH; 2120 2121 return strideInTiles*cpp*TILE_WIDTH; 2122 } else { 2123 return xres*cpp; 2124 } 2125} /* calcBufferStride */ 2126 2127static int 2128calcBufferHeightInTiles(int yres) 2129{ 2130 int heightInTiles; /* Height of buffer in tiles */ 2131 2132 2133 /* Calculate tile height stuff */ 2134 heightInTiles = yres >> 5; 2135 2136 if (yres & (TILE_HEIGHT - 1)) 2137 heightInTiles++; 2138 2139 return heightInTiles; 2140 2141} /* calcBufferHeightInTiles */ 2142 2143#if 0 2144static int 2145calcBufferSizeInTiles(int xres, int yres, int cpp) { 2146 int bufSizeInTiles; /* Size of buffer in tiles */ 2147 2148 bufSizeInTiles = 2149 calcBufferHeightInTiles(yres) * (calcBufferStride(xres, TRUE, cpp) >> 7); 2150 2151 return bufSizeInTiles; 2152 2153} /* calcBufferSizeInTiles */ 2154#endif 2155 2156static int 2157calcBufferSize(int xres, int yres, Bool tiled, int cpp) 2158{ 2159 int stride, height, bufSize; 2160 2161 if (tiled) { 2162 stride = calcBufferStride(xres, tiled, cpp); 2163 height = TILE_HEIGHT * calcBufferHeightInTiles(yres); 2164 } else { 2165 stride = xres*cpp; 2166 height = yres; 2167 } 2168 2169 bufSize = stride * height; 2170 2171 return bufSize; 2172 2173} /* calcBufferSize */ 2174 2175static void allocateMemory(ScrnInfoPtr pScrn) { 2176 TDFXPtr pTDFX; 2177 int memRemaining, fifoSize, screenSizeInTiles, cursorSize; 2178 int fbSize; 2179 int verb; 2180 char *str; 2181 2182 pTDFX = TDFXPTR(pScrn); 2183 2184 if (pTDFX->cpp!=3) { 2185 screenSizeInTiles=calcBufferSize(pScrn->virtualX, pScrn->virtualY, 2186 TRUE, pTDFX->cpp); 2187 } 2188 else { 2189 /* cpp==3 needs to bump up to 4 */ 2190 screenSizeInTiles=calcBufferSize(pScrn->virtualX, pScrn->virtualY, 2191 TRUE, 4); 2192 } 2193 2194 /* 2195 * Layout is: 2196 * cursor, fifo, fb, tex, bb, db 2197 */ 2198 2199 fbSize = (pScrn->virtualY + pTDFX->pixmapCacheLinesMin) * pTDFX->stride; 2200 2201 memRemaining=((pScrn->videoRam<<10) - 1) &~ 0xFFF; 2202 /* Note that a page is 4096 bytes, and a */ 2203 /* tile is 32 x 128 = 4096 bytes. So, */ 2204 /* page and tile boundaries are the same */ 2205 /* Place the depth offset first, forcing */ 2206 /* it to be on an *odd* page boundary. */ 2207 pTDFX->depthOffset = (memRemaining - screenSizeInTiles) &~ 0xFFF; 2208 if ((pTDFX->depthOffset & (0x1 << 12)) == 0) { 2209#if 1 2210 if (pTDFX->depthOffset > 0) { 2211 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2212 "Changing depth offset from 0x%08x to 0x%08x\n", 2213 pTDFX->depthOffset, 2214 pTDFX->depthOffset - (0x1 << 12)); 2215 } 2216#endif 2217 pTDFX->depthOffset -= (0x1 << 12); 2218 } 2219 /* Now, place the back buffer, forcing it */ 2220 /* to be on an *even* page boundary. */ 2221 pTDFX->backOffset = (pTDFX->depthOffset - screenSizeInTiles) &~ 0xFFF; 2222 if (pTDFX->backOffset & (0x1 << 12)) { 2223#if 1 2224 if (pTDFX->backOffset > 0) { 2225 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2226 "Changing back offset from 0x%08x to 0x%08x\n", 2227 pTDFX->backOffset, 2228 pTDFX->backOffset - (0x1 << 12)); 2229 } 2230#endif 2231 pTDFX->backOffset -= (0x1 << 12); 2232 } 2233 /* Give the cmd fifo at least */ 2234 /* CMDFIFO_PAGES pages, but no more than */ 2235 /* 64. NOTE: Don't go higher than 64, as */ 2236 /* there is suspect code in Glide3 ! */ 2237 fifoSize = ((64 <= CMDFIFO_PAGES) ? 64 : CMDFIFO_PAGES) << 12; 2238 2239 /* We give 4096 bytes to the cursor */ 2240 cursorSize = 4096; 2241 pTDFX->cursorOffset = 0; 2242 2243 pTDFX->fifoOffset = pTDFX->cursorOffset + cursorSize; 2244 pTDFX->fifoSize = fifoSize; 2245 /* Now, place the front buffer, forcing */ 2246 /* it to be on a page boundary too, just */ 2247 /* for giggles. */ 2248 pTDFX->fbOffset = pTDFX->fifoOffset + pTDFX->fifoSize; 2249 pTDFX->texOffset = pTDFX->fbOffset + fbSize; 2250 if (pTDFX->depthOffset <= pTDFX->texOffset || 2251 pTDFX->backOffset <= pTDFX->texOffset) { 2252 /* 2253 * pTDFX->texSize < 0 means that the DRI is disabled. pTDFX->backOffset 2254 * is used to calculate the maximum amount of memory available for 2255 * 2D offscreen use. With DRI disabled, set this to the top of memory. 2256 */ 2257 2258 pTDFX->texSize = -1; 2259 pTDFX->backOffset = pScrn->videoRam * 1024; 2260 pTDFX->depthOffset = -1; 2261 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2262 "Not enough video memory available for textures and depth buffer\n" 2263 "\tand/or back buffer. Disabling DRI. To use DRI try lower\n" 2264 "\tresolution modes and/or a smaller virtual screen size\n"); 2265 } else { 2266 pTDFX->texSize = pTDFX->backOffset - pTDFX->texOffset; 2267 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Textures Memory %0.02f MB\n", 2268 (float)pTDFX->texSize/1024.0/1024.0); 2269 } 2270 2271/* This could be set to 2 or 3 */ 2272#define OFFSET_VERB 1 2273 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, OFFSET_VERB, 2274 "Cursor Offset: [0x%08X,0x%08X)\n", 2275 pTDFX->cursorOffset, 2276 pTDFX->cursorOffset + cursorSize); 2277 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, OFFSET_VERB, 2278 "Fifo Offset: [0x%08X, 0x%08X)\n", 2279 pTDFX->fifoOffset, 2280 pTDFX->fifoOffset + pTDFX->fifoSize); 2281 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, OFFSET_VERB, 2282 "Front Buffer Offset: [0x%08X, 0x%08X)\n", 2283 pTDFX->fbOffset, 2284 pTDFX->fbOffset + 2285 (pScrn->virtualY+pTDFX->pixmapCacheLinesMin)*pTDFX->stride); 2286 if (pTDFX->texSize > 0) { 2287 verb = OFFSET_VERB; 2288 str = ""; 2289 } else { 2290 verb = 3; 2291 str = "(NOT USED) "; 2292 } 2293 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verb, 2294 "%sTexture Offset: [0x%08X, 0x%08X)\n", str, 2295 pTDFX->texOffset, 2296 pTDFX->texOffset + pTDFX->texSize); 2297 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verb, 2298 "%sBackOffset: [0x%08X, 0x%08X)\n", str, 2299 pTDFX->backOffset, 2300 pTDFX->backOffset + screenSizeInTiles); 2301 xf86DrvMsgVerb(pScrn->scrnIndex, X_INFO, verb, 2302 "%sDepthOffset: [0x%08X, 0x%08X)\n", str, 2303 pTDFX->depthOffset, 2304 pTDFX->depthOffset + screenSizeInTiles); 2305} 2306 2307static Bool 2308TDFXScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) { 2309 ScrnInfoPtr pScrn; 2310 vgaHWPtr hwp; 2311 TDFXPtr pTDFX; 2312 VisualPtr visual; 2313 BoxRec MemBox; 2314#ifdef XF86DRI 2315 MessageType driFrom = X_DEFAULT; 2316#endif 2317 int scanlines; 2318 2319 TDFXTRACE("TDFXScreenInit start\n"); 2320 pScrn = xf86Screens[pScreen->myNum]; 2321 pTDFX = TDFXPTR(pScrn); 2322 hwp = VGAHWPTR(pScrn); 2323 2324 if (!TDFXMapMem(pScrn)) return FALSE; 2325 pScrn->memPhysBase = (int)pTDFX->LinearAddr[0]; 2326 2327 if (!pTDFX->usePIO) TDFXSetMMIOAccess(pTDFX); 2328 2329#if USE_PCIVGAIO 2330 hwp->PIOOffset = pTDFX->PIOBase[0] - 0x300; 2331#endif 2332 vgaHWGetIOBase(hwp); 2333 /* Map VGA memory only for primary cards (to save/restore textmode data). */ 2334 if (pTDFX->Primary) { 2335 if (!vgaHWMapMem(pScrn)) 2336 return FALSE; 2337 } 2338 2339 pTDFX->stride = pScrn->displayWidth*pTDFX->cpp; 2340 2341 /* enough to do DVD */ 2342 pTDFX->pixmapCacheLinesMin = ((720*480*pTDFX->cpp) + 2343 pTDFX->stride - 1)/pTDFX->stride; 2344 2345 if (pTDFX->ChipType > PCI_CHIP_VOODOO3) { 2346 if ((pTDFX->pixmapCacheLinesMin + pScrn->virtualY) > 4095) 2347 pTDFX->pixmapCacheLinesMin = 4095 - pScrn->virtualY; 2348 } else { 2349 if ((pTDFX->pixmapCacheLinesMin + pScrn->virtualY) > 2047) 2350 pTDFX->pixmapCacheLinesMin = 2047 - pScrn->virtualY; 2351 } 2352 2353 allocateMemory(pScrn); 2354 2355 pScrn->fbOffset = pTDFX->fbOffset; 2356 2357#if 0 2358 if (pTDFX->numChips>1) { 2359 if (xf86ReturnOptValBool(pTDFX->Options, OPTION_NO_SLI, FALSE)) { 2360 TDFXSetupSLI(pScrn, FALSE, 0); 2361 } else { 2362 TDFXSetupSLI(pScrn, TRUE, 0); 2363 } 2364 } 2365#endif 2366 2367 TDFXSetLFBConfig(pTDFX); 2368 2369 /* We initialize in the state that our FIFO is up to date */ 2370 pTDFX->syncDone=TRUE; 2371 if (!TDFXInitFifo(pScreen)) { 2372 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to initialize private\n"); 2373 return FALSE; 2374 } 2375 2376 scanlines = (pTDFX->backOffset - pTDFX->fbOffset) / pTDFX->stride; 2377 if(pTDFX->ChipType < PCI_CHIP_VOODOO5) { 2378 if (scanlines > 2047) 2379 scanlines = 2047; 2380 } else { 2381 /* MaxClip seems to have only 12 bits => 0->4095 */ 2382 if (scanlines > 4095) 2383 scanlines = 4095; 2384 } 2385 2386 pTDFX->pixmapCacheLinesMax = scanlines - pScrn->virtualY; 2387 2388 /* 2389 * Note, pTDFX->pixmapCacheLinesMax may be smaller than 2390 * pTDFX->pixmapCacheLinesMin when pTDFX->texSize < 0. DRI is disabled 2391 * in that case, so pTDFX->pixmapCacheLinesMin isn't used when that's true. 2392 */ 2393 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2394 "Minimum %d, Maximum %d lines of offscreen memory available\n", 2395 pTDFX->pixmapCacheLinesMin, pTDFX->pixmapCacheLinesMax); 2396 2397 MemBox.y1 = 0; 2398 MemBox.x1 = 0; 2399 MemBox.x2 = pScrn->displayWidth; 2400 MemBox.y2 = scanlines; 2401 2402 pTDFX->maxClip = MemBox.x2 | (MemBox.y2 << 16); 2403 2404#if 0 2405 TDFXInitWithBIOSData(pScrn); 2406#endif 2407 TDFXInitVGA(pScrn); 2408 TDFXSave(pScrn); 2409 if (!TDFXModeInit(pScrn, pScrn->currentMode)) return FALSE; 2410 2411 TDFXSetLFBConfig(pTDFX); 2412 2413 miClearVisualTypes(); 2414 2415 if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 2416 pScrn->rgbBits, pScrn->defaultVisual)) 2417 return FALSE; 2418 2419 miSetPixmapDepths (); 2420 2421 pTDFX->NoAccel=xf86ReturnOptValBool(pTDFX->Options, OPTION_NOACCEL, FALSE); 2422#ifdef XF86DRI 2423 /* 2424 * Setup DRI after visuals have been established, but before fbScreenInit 2425 * is called. fbScreenInit will eventually call into the drivers 2426 * InitGLXVisuals call back. 2427 */ 2428 if (!xf86ReturnOptValBool(pTDFX->Options, OPTION_DRI, TRUE) || pTDFX->NoAccel) { 2429 pTDFX->directRenderingEnabled = FALSE; 2430 driFrom = X_CONFIG; 2431 } else if (pTDFX->texSize < 0) { 2432 pTDFX->directRenderingEnabled = FALSE; 2433 driFrom = X_PROBED; 2434 } else { 2435 pTDFX->directRenderingEnabled = TDFXDRIScreenInit(pScreen); 2436 } 2437#endif 2438 2439 switch (pScrn->bitsPerPixel) { 2440 case 8: 2441 case 16: 2442 case 24: 2443 case 32: 2444 if (!fbScreenInit(pScreen, pTDFX->FbBase+pTDFX->fbOffset, 2445 pScrn->virtualX, pScrn->virtualY, 2446 pScrn->xDpi, pScrn->yDpi, 2447 pScrn->displayWidth, pScrn->bitsPerPixel)) 2448 return FALSE; 2449 break; 2450 default: 2451 xf86DrvMsg(scrnIndex, X_ERROR, 2452 "Internal error: invalid bpp (%d) in TDFXScrnInit\n", 2453 pScrn->bitsPerPixel); 2454 return FALSE; 2455 } 2456 2457 if (pScrn->bitsPerPixel>8) { 2458 visual = pScreen->visuals + pScreen->numVisuals; 2459 while (--visual >= pScreen->visuals) { 2460 if ((visual->class | DynamicClass) == DirectColor) { 2461 visual->offsetRed = pScrn->offset.red; 2462 visual->offsetGreen = pScrn->offset.green; 2463 visual->offsetBlue = pScrn->offset.blue; 2464 visual->redMask = pScrn->mask.red; 2465 visual->greenMask = pScrn->mask.green; 2466 visual->blueMask = pScrn->mask.blue; 2467 } 2468 } 2469 } 2470 2471 /* must be after RGB ordering fixed */ 2472 fbPictureInit (pScreen, 0, 0); 2473 2474 xf86SetBlackWhitePixels(pScreen); 2475 2476 TDFXDGAInit(pScreen); 2477 2478 xf86InitFBManager(pScreen, &MemBox); 2479 2480 if (!pTDFX->NoAccel) { 2481 if (!TDFXAccelInit(pScreen)) { 2482 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2483 "Hardware acceleration initialization failed\n"); 2484 } 2485 } 2486 2487 miInitializeBackingStore(pScreen); 2488 xf86SetBackingStore(pScreen); 2489 xf86SetSilkenMouse(pScreen); 2490 2491 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 2492 2493 if (!xf86ReturnOptValBool(pTDFX->Options, OPTION_SW_CURSOR, FALSE)) { 2494 if (!TDFXCursorInit(pScreen)) { 2495 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2496 "Hardware cursor initialization failed\n"); 2497 } 2498 } 2499 2500 if (!miCreateDefColormap(pScreen)) return FALSE; 2501 2502 if (pScrn->bitsPerPixel==16) { 2503 if (!xf86HandleColormaps(pScreen, 256, 8, TDFXLoadPalette16, 0, 2504 CMAP_PALETTED_TRUECOLOR|CMAP_RELOAD_ON_MODE_SWITCH)) 2505 return FALSE; 2506 } else { 2507 if (!xf86HandleColormaps(pScreen, 256, 8, TDFXLoadPalette24, 0, 2508 CMAP_PALETTED_TRUECOLOR|CMAP_RELOAD_ON_MODE_SWITCH)) 2509 return FALSE; 2510 } 2511 2512 TDFXAdjustFrame(scrnIndex, 0, 0, 0); 2513 2514 xf86DPMSInit(pScreen, TDFXDisplayPowerManagementSet, 0); 2515 2516 /* Initialize Xv support */ 2517 TDFXInitVideo (pScreen); 2518 2519 pScreen->SaveScreen = TDFXSaveScreen; 2520 pTDFX->CloseScreen = pScreen->CloseScreen; 2521 pScreen->CloseScreen = TDFXCloseScreen; 2522 2523 pTDFX->BlockHandler = pScreen->BlockHandler; 2524 pScreen->BlockHandler = TDFXBlockHandler; 2525 2526 /* 2527 * DRICloseScreen isn't called thru a wrapper but explicitely 2528 * in of TDFXCloseScreen() before the rest is unwrapped 2529 */ 2530 2531#ifdef XF86DRI 2532 if (pTDFX->directRenderingEnabled) { 2533 /* Now that mi, fb, drm and others have done their thing, 2534 * complete the DRI setup. 2535 */ 2536 pTDFX->directRenderingEnabled = TDFXDRIFinishScreenInit(pScreen); 2537 } 2538 if (pTDFX->directRenderingEnabled) { 2539 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); 2540 } else { 2541 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Direct rendering disabled\n"); 2542 } 2543#endif 2544 2545 if (serverGeneration == 1) 2546 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 2547 2548 return TRUE; 2549} 2550 2551Bool 2552TDFXSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { 2553 ScrnInfoPtr pScrn; 2554 2555 TDFXTRACE("TDFXSwitchMode start\n"); 2556 pScrn=xf86Screens[scrnIndex]; 2557 return TDFXModeInit(pScrn, mode); 2558} 2559 2560void 2561TDFXAdjustFrame(int scrnIndex, int x, int y, int flags) { 2562 ScrnInfoPtr pScrn; 2563 TDFXPtr pTDFX; 2564 TDFXRegPtr tdfxReg; 2565 2566 TDFXTRACE("TDFXAdjustFrame start\n"); 2567 pScrn = xf86Screens[scrnIndex]; 2568 pTDFX = TDFXPTR(pScrn); 2569 2570 if (pTDFX->ShowCache && y && pScrn->vtSema) 2571 y += pScrn->virtualY - 1; 2572 2573 tdfxReg = &pTDFX->ModeReg; 2574 if(pTDFX->ShowCache && y && pScrn->vtSema) 2575 y += pScrn->virtualY - 1; 2576 tdfxReg->startaddr = pTDFX->fbOffset+y*pTDFX->stride+(x*pTDFX->cpp); 2577 TDFXTRACE("TDFXAdjustFrame to x=%d y=%d offset=%d\n", x, y, tdfxReg->startaddr); 2578 pTDFX->writeLong(pTDFX, VIDDESKTOPSTARTADDR, tdfxReg->startaddr); 2579} 2580 2581static Bool 2582TDFXEnterVT(int scrnIndex, int flags) { 2583 ScrnInfoPtr pScrn; 2584 ScreenPtr pScreen; 2585#ifdef XF86DRI 2586 TDFXPtr pTDFX; 2587#endif 2588 2589 TDFXTRACE("TDFXEnterVT start\n"); 2590 pScrn = xf86Screens[scrnIndex]; 2591 pScreen = screenInfo.screens[scrnIndex]; 2592 TDFXInitFifo(pScreen); 2593#ifdef XF86DRI 2594 pTDFX = TDFXPTR(pScrn); 2595 if (pTDFX->directRenderingEnabled) { 2596 DRIUnlock(pScreen); 2597 } 2598#endif 2599 if (!TDFXModeInit(pScrn, pScrn->currentMode)) return FALSE; 2600 TDFXAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); 2601 return TRUE; 2602} 2603 2604static void 2605TDFXLeaveVT(int scrnIndex, int flags) { 2606 ScrnInfoPtr pScrn; 2607 vgaHWPtr hwp; 2608 ScreenPtr pScreen; 2609 TDFXPtr pTDFX; 2610 2611 TDFXTRACE("TDFXLeaveVT start\n"); 2612 pScrn = xf86Screens[scrnIndex]; 2613 hwp=VGAHWPTR(pScrn); 2614 TDFXRestore(pScrn); 2615 vgaHWLock(hwp); 2616 pScreen = screenInfo.screens[scrnIndex]; 2617 pTDFX = TDFXPTR(pScrn); 2618 pTDFX->sync(pScrn); 2619 TDFXShutdownFifo(pScreen); 2620#ifdef XF86DRI 2621 if (pTDFX->directRenderingEnabled) { 2622 DRILock(pScreen, 0); 2623 } 2624#endif 2625} 2626 2627static Bool 2628TDFXCloseScreen(int scrnIndex, ScreenPtr pScreen) 2629{ 2630 ScrnInfoPtr pScrn; 2631 vgaHWPtr hwp; 2632 TDFXPtr pTDFX; 2633 2634 TDFXTRACE("TDFXCloseScreen start\n"); 2635 pScrn = xf86Screens[scrnIndex]; 2636 hwp = VGAHWPTR(pScrn); 2637 pTDFX = TDFXPTR(pScrn); 2638 2639#ifdef XF86DRI 2640 if (pTDFX->directRenderingEnabled) { 2641 TDFXDRICloseScreen(pScreen); 2642 pTDFX->directRenderingEnabled=FALSE; 2643 } 2644#endif 2645 2646 TDFXShutdownFifo(pScreen); 2647 2648 if (pScrn->vtSema) { 2649 TDFXRestore(pScrn); 2650 vgaHWLock(hwp); 2651 TDFXUnmapMem(pScrn); 2652 vgaHWUnmapMem(pScrn); 2653 } 2654 2655 if (pTDFX->AccelInfoRec) XAADestroyInfoRec(pTDFX->AccelInfoRec); 2656 pTDFX->AccelInfoRec=0; 2657 if (pTDFX->DGAModes) xfree(pTDFX->DGAModes); 2658 pTDFX->DGAModes=0; 2659 if (pTDFX->scanlineColorExpandBuffers[0]) 2660 xfree(pTDFX->scanlineColorExpandBuffers[0]); 2661 pTDFX->scanlineColorExpandBuffers[0]=0; 2662 if (pTDFX->scanlineColorExpandBuffers[1]) 2663 xfree(pTDFX->scanlineColorExpandBuffers[1]); 2664 pTDFX->scanlineColorExpandBuffers[1]=0; 2665 if (pTDFX->overlayAdaptor) 2666 xfree(pTDFX->overlayAdaptor); 2667 pTDFX->overlayAdaptor=0; 2668 if (pTDFX->textureAdaptor) 2669 xfree(pTDFX->textureAdaptor); 2670 pTDFX->textureAdaptor=0; 2671 2672 pScrn->vtSema=FALSE; 2673 2674 pScreen->BlockHandler = pTDFX->BlockHandler; 2675 pScreen->CloseScreen = pTDFX->CloseScreen; 2676 return (*pScreen->CloseScreen)(scrnIndex, pScreen); 2677} 2678 2679static void 2680TDFXFreeScreen(int scrnIndex, int flags) { 2681 TDFXTRACE("TDFXFreeScreen start\n"); 2682 TDFXFreeRec(xf86Screens[scrnIndex]); 2683 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 2684 vgaHWFreeHWRec(xf86Screens[scrnIndex]); 2685} 2686 2687static ModeStatus 2688TDFXValidMode(int scrnIndex, DisplayModePtr mode, Bool verbose, int flags) { 2689 ScrnInfoPtr pScrn; 2690 TDFXPtr pTDFX; 2691 2692 TDFXTRACE("TDFXValidMode start\n"); 2693 if ((mode->HDisplay>2048) || (mode->VDisplay>1536)) 2694 return MODE_BAD; 2695 /* Banshee doesn't support interlace, but Voodoo 3 and higher do. */ 2696 pScrn = xf86Screens[scrnIndex]; 2697 pTDFX = TDFXPTR(pScrn); 2698 if (mode->Flags&V_INTERLACE) { 2699 switch (pTDFX->ChipType) { 2700 case PCI_CHIP_BANSHEE: 2701 return MODE_BAD; 2702 break; 2703 case PCI_CHIP_VOODOO3: 2704 case PCI_CHIP_VOODOO5: 2705 return MODE_OK; 2706 break; 2707 default: 2708 return MODE_BAD; 2709 break; 2710 } 2711 } 2712 /* In clock doubled mode widths must be divisible by 16 instead of 8 */ 2713 if ((mode->Clock>TDFX2XCUTOFF) && (mode->HDisplay%16)) 2714 return MODE_BAD; 2715 return MODE_OK; 2716} 2717 2718/* replacement of vgaHWBlankScreen(pScrn, unblank) which doesn't unblank 2719 * the screen if it is already unblanked. */ 2720static void 2721TDFXBlankScreen(ScrnInfoPtr pScrn, Bool unblank) 2722{ 2723 vgaHWPtr hwp = VGAHWPTR(pScrn); 2724 unsigned char scrn; 2725 2726 TDFXTRACE("TDFXBlankScreen start\n"); 2727 2728 scrn = hwp->readSeq(hwp, 0x01); 2729 2730 if (unblank) { 2731 if((scrn & 0x20) == 0) return; 2732 scrn &= ~0x20; /* enable screen */ 2733 } else { 2734 scrn |= 0x20; /* blank screen */ 2735 } 2736 2737 vgaHWSeqReset(hwp, TRUE); 2738 hwp->writeSeq(hwp, 0x01, scrn); /* change mode */ 2739 vgaHWSeqReset(hwp, FALSE); 2740} 2741 2742static Bool 2743TDFXSaveScreen(ScreenPtr pScreen, int mode) 2744{ 2745 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 2746 Bool unblank; 2747 2748 TDFXTRACE("TDFXSaveScreen start\n"); 2749 2750 unblank = xf86IsUnblank(mode); 2751 2752 if (unblank) 2753 SetTimeSinceLastInputEvent(); 2754 2755 if (pScrn->vtSema) { 2756 TDFXBlankScreen(pScrn, unblank); 2757 } 2758 return TRUE; 2759} 2760 2761static void 2762TDFXBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) 2763{ 2764 ScreenPtr pScreen = screenInfo.screens[i]; 2765 ScrnInfoPtr pScrn = xf86Screens[i]; 2766 TDFXPtr pTDFX = TDFXPTR(pScrn); 2767 2768 pScreen->BlockHandler = pTDFX->BlockHandler; 2769 (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); 2770 pScreen->BlockHandler = TDFXBlockHandler; 2771 2772 if(pTDFX->VideoTimerCallback) { 2773 (*pTDFX->VideoTimerCallback)(pScrn, currentTime.milliseconds); 2774 } 2775} 2776 2777static void 2778TDFXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 2779 int flags) { 2780 TDFXPtr pTDFX; 2781 int dacmode, state=0; 2782 2783 TDFXTRACE("TDFXDPMS start\n"); 2784 pTDFX = TDFXPTR(pScrn); 2785 dacmode=pTDFX->readLong(pTDFX, DACMODE); 2786 switch (PowerManagementMode) { 2787 case DPMSModeOn: 2788 /* Screen: On; HSync: On, VSync: On */ 2789 state=0; 2790 break; 2791 case DPMSModeStandby: 2792 /* Screen: Off; HSync: Off, VSync: On */ 2793 state=BIT(3); 2794 break; 2795 case DPMSModeSuspend: 2796 /* Screen: Off; HSync: On, VSync: Off */ 2797 state=BIT(1); 2798 break; 2799 case DPMSModeOff: 2800 /* Screen: Off; HSync: Off, VSync: Off */ 2801 state=BIT(1)|BIT(3); 2802 break; 2803 } 2804 dacmode&=~(BIT(1)|BIT(3)); 2805 dacmode|=state; 2806 pTDFX->writeLong(pTDFX, DACMODE, dacmode); 2807} 2808