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