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