tdfx_driver.c revision 3dd2ccd7
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 hwp->PIOOffset = pTDFX->PIOBase[0] - 0x300; 2260#endif 2261 /* Map VGA memory only for primary cards (to save/restore textmode data). */ 2262 if (pTDFX->Primary) { 2263 if (!vgaHWMapMem(pScrn)) 2264 return FALSE; 2265 } 2266 2267 pTDFX->stride = pScrn->displayWidth*pTDFX->cpp; 2268 2269 /* enough to do DVD */ 2270 pTDFX->pixmapCacheLinesMin = ((720*480*pTDFX->cpp) + 2271 pTDFX->stride - 1)/pTDFX->stride; 2272 2273 if (pTDFX->ChipType > PCI_CHIP_VOODOO3) { 2274 if ((pTDFX->pixmapCacheLinesMin + pScrn->virtualY) > 4095) 2275 pTDFX->pixmapCacheLinesMin = 4095 - pScrn->virtualY; 2276 } else { 2277 if ((pTDFX->pixmapCacheLinesMin + pScrn->virtualY) > 2047) 2278 pTDFX->pixmapCacheLinesMin = 2047 - pScrn->virtualY; 2279 } 2280 2281 allocateMemory(pScrn); 2282 2283 pScrn->fbOffset = pTDFX->fbOffset; 2284 2285#if 0 2286 if (pTDFX->numChips>1) { 2287 if (xf86ReturnOptValBool(pTDFX->Options, OPTION_NO_SLI, FALSE)) { 2288 TDFXSetupSLI(pScrn, FALSE, 0); 2289 } else { 2290 TDFXSetupSLI(pScrn, TRUE, 0); 2291 } 2292 } 2293#endif 2294 2295 TDFXSetLFBConfig(pTDFX); 2296 2297 /* We initialize in the state that our FIFO is up to date */ 2298 pTDFX->syncDone=TRUE; 2299 if (!TDFXInitFifo(pScreen)) { 2300 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Failed to initialize private\n"); 2301 return FALSE; 2302 } 2303 2304 scanlines = (pTDFX->backOffset - pTDFX->fbOffset) / pTDFX->stride; 2305 if(pTDFX->ChipType < PCI_CHIP_VOODOO4) { 2306 if (scanlines > 2047) 2307 scanlines = 2047; 2308 } else { 2309 /* MaxClip seems to have only 12 bits => 0->4095 */ 2310 if (scanlines > 4095) 2311 scanlines = 4095; 2312 } 2313 2314 pTDFX->pixmapCacheLinesMax = scanlines - pScrn->virtualY; 2315 2316 /* 2317 * Note, pTDFX->pixmapCacheLinesMax may be smaller than 2318 * pTDFX->pixmapCacheLinesMin when pTDFX->texSize < 0. DRI is disabled 2319 * in that case, so pTDFX->pixmapCacheLinesMin isn't used when that's true. 2320 */ 2321 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 2322 "Minimum %d, Maximum %d lines of offscreen memory available\n", 2323 pTDFX->pixmapCacheLinesMin, pTDFX->pixmapCacheLinesMax); 2324 2325 MemBox.y1 = 0; 2326 MemBox.x1 = 0; 2327 MemBox.x2 = pScrn->displayWidth; 2328 MemBox.y2 = scanlines; 2329 2330 pTDFX->maxClip = MemBox.x2 | (MemBox.y2 << 16); 2331 2332#if 0 2333 TDFXInitWithBIOSData(pScrn); 2334#endif 2335 TDFXInitVGA(pScrn); 2336 TDFXSave(pScrn); 2337 if (!TDFXModeInit(pScrn, pScrn->currentMode)) return FALSE; 2338 2339 TDFXSetLFBConfig(pTDFX); 2340 2341 miClearVisualTypes(); 2342 2343 if (!miSetVisualTypes(pScrn->depth, miGetDefaultVisualMask(pScrn->depth), 2344 pScrn->rgbBits, pScrn->defaultVisual)) 2345 return FALSE; 2346 2347 miSetPixmapDepths (); 2348 2349#ifdef TDFXDRI 2350 /* 2351 * Setup DRI after visuals have been established, but before fbScreenInit 2352 * is called. fbScreenInit will eventually call into the drivers 2353 * InitGLXVisuals call back. 2354 */ 2355 if (!xf86ReturnOptValBool(pTDFX->Options, OPTION_DRI, TRUE) || pTDFX->NoAccel) { 2356 pTDFX->directRenderingEnabled = FALSE; 2357 driFrom = X_CONFIG; 2358 } else if (pTDFX->texSize < 0) { 2359 pTDFX->directRenderingEnabled = FALSE; 2360 driFrom = X_PROBED; 2361 } else { 2362 pTDFX->directRenderingEnabled = TDFXDRIScreenInit(pScreen); 2363 } 2364#endif 2365 2366 switch (pScrn->bitsPerPixel) { 2367 case 8: 2368 case 16: 2369 case 24: 2370 case 32: 2371 if (!fbScreenInit(pScreen, pTDFX->FbBase+pTDFX->fbOffset, 2372 pScrn->virtualX, pScrn->virtualY, 2373 pScrn->xDpi, pScrn->yDpi, 2374 pScrn->displayWidth, pScrn->bitsPerPixel)) 2375 return FALSE; 2376 break; 2377 default: 2378 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2379 "Internal error: invalid bpp (%d) in TDFXScrnInit\n", 2380 pScrn->bitsPerPixel); 2381 return FALSE; 2382 } 2383 2384 if (pScrn->bitsPerPixel>8) { 2385 visual = pScreen->visuals + pScreen->numVisuals; 2386 while (--visual >= pScreen->visuals) { 2387 if ((visual->class | DynamicClass) == DirectColor) { 2388 visual->offsetRed = pScrn->offset.red; 2389 visual->offsetGreen = pScrn->offset.green; 2390 visual->offsetBlue = pScrn->offset.blue; 2391 visual->redMask = pScrn->mask.red; 2392 visual->greenMask = pScrn->mask.green; 2393 visual->blueMask = pScrn->mask.blue; 2394 } 2395 } 2396 } 2397 2398 /* must be after RGB ordering fixed */ 2399 fbPictureInit (pScreen, 0, 0); 2400 2401 xf86SetBlackWhitePixels(pScreen); 2402 2403 TDFXDGAInit(pScreen); 2404 2405 xf86InitFBManager(pScreen, &MemBox); 2406 2407 if (!pTDFX->NoAccel) { 2408 if (!TDFXAccelInit(pScreen)) { 2409 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2410 "Hardware acceleration initialization failed\n"); 2411 } 2412 } 2413 2414 xf86SetBackingStore(pScreen); 2415 xf86SetSilkenMouse(pScreen); 2416 2417 miDCInitialize(pScreen, xf86GetPointerScreenFuncs()); 2418 2419 if (!xf86ReturnOptValBool(pTDFX->Options, OPTION_SW_CURSOR, FALSE)) { 2420 if (!TDFXCursorInit(pScreen)) { 2421 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 2422 "Hardware cursor initialization failed\n"); 2423 } 2424 } 2425 2426 if (!miCreateDefColormap(pScreen)) return FALSE; 2427 2428 if (pScrn->bitsPerPixel==16) { 2429 if (!xf86HandleColormaps(pScreen, 256, 8, TDFXLoadPalette16, 0, 2430 CMAP_PALETTED_TRUECOLOR|CMAP_RELOAD_ON_MODE_SWITCH)) 2431 return FALSE; 2432 } else { 2433 if (!xf86HandleColormaps(pScreen, 256, 8, TDFXLoadPalette24, 0, 2434 CMAP_PALETTED_TRUECOLOR|CMAP_RELOAD_ON_MODE_SWITCH)) 2435 return FALSE; 2436 } 2437 2438 TDFXAdjustFrame(ADJUST_FRAME_ARGS(pScrn, 0, 0)); 2439 2440 xf86DPMSInit(pScreen, TDFXDisplayPowerManagementSet, 0); 2441 2442 /* Initialize Xv support */ 2443 TDFXInitVideo (pScreen); 2444 2445 pScreen->SaveScreen = TDFXSaveScreen; 2446 pTDFX->CloseScreen = pScreen->CloseScreen; 2447 pScreen->CloseScreen = TDFXCloseScreen; 2448 2449 pTDFX->BlockHandler = pScreen->BlockHandler; 2450 pScreen->BlockHandler = TDFXBlockHandler; 2451 2452 /* 2453 * DRICloseScreen isn't called thru a wrapper but explicitely 2454 * in of TDFXCloseScreen() before the rest is unwrapped 2455 */ 2456 2457#ifdef TDFXDRI 2458 if (pTDFX->directRenderingEnabled) { 2459 /* Now that mi, fb, drm and others have done their thing, 2460 * complete the DRI setup. 2461 */ 2462 pTDFX->directRenderingEnabled = TDFXDRIFinishScreenInit(pScreen); 2463 } 2464 if (pTDFX->directRenderingEnabled) { 2465 xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n"); 2466 } else { 2467 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, "Direct rendering disabled\n"); 2468 } 2469#endif 2470 2471 if (serverGeneration == 1) 2472 xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); 2473 2474 return TRUE; 2475} 2476 2477Bool 2478TDFXSwitchMode(SWITCH_MODE_ARGS_DECL) { 2479 SCRN_INFO_PTR(arg); 2480 2481 TDFXTRACE("TDFXSwitchMode start\n"); 2482 return TDFXModeInit(pScrn, mode); 2483} 2484 2485void 2486TDFXAdjustFrame(ADJUST_FRAME_ARGS_DECL) { 2487 SCRN_INFO_PTR(arg); 2488 TDFXPtr pTDFX; 2489 TDFXRegPtr tdfxReg; 2490 2491 TDFXTRACE("TDFXAdjustFrame start\n"); 2492 pTDFX = TDFXPTR(pScrn); 2493 2494 if (pTDFX->ShowCache && y && pScrn->vtSema) 2495 y += pScrn->virtualY - 1; 2496 2497 tdfxReg = &pTDFX->ModeReg; 2498 if(pTDFX->ShowCache && y && pScrn->vtSema) 2499 y += pScrn->virtualY - 1; 2500 tdfxReg->startaddr = pTDFX->fbOffset+y*pTDFX->stride+(x*pTDFX->cpp); 2501 TDFXTRACE("TDFXAdjustFrame to x=%d y=%d offset=%d\n", x, y, tdfxReg->startaddr); 2502 pTDFX->writeLong(pTDFX, VIDDESKTOPSTARTADDR, tdfxReg->startaddr); 2503} 2504 2505static Bool 2506TDFXEnterVT(VT_FUNC_ARGS_DECL) { 2507 SCRN_INFO_PTR(arg); 2508 ScreenPtr pScreen; 2509#ifdef TDFXDRI 2510 TDFXPtr pTDFX; 2511#endif 2512 2513 TDFXTRACE("TDFXEnterVT start\n"); 2514 pScreen = xf86ScrnToScreen(pScrn); 2515 TDFXInitFifo(pScreen); 2516#ifdef TDFXDRI 2517 pTDFX = TDFXPTR(pScrn); 2518 if (pTDFX->directRenderingEnabled) { 2519 DRIUnlock(pScreen); 2520 } 2521#endif 2522 if (!TDFXModeInit(pScrn, pScrn->currentMode)) return FALSE; 2523 TDFXAdjustFrame(ADJUST_FRAME_ARGS(pScrn, pScrn->frameX0, pScrn->frameY0)); 2524 return TRUE; 2525} 2526 2527static void 2528TDFXLeaveVT(VT_FUNC_ARGS_DECL) { 2529 SCRN_INFO_PTR(arg); 2530 vgaHWPtr hwp; 2531 ScreenPtr pScreen; 2532 TDFXPtr pTDFX; 2533 2534 TDFXTRACE("TDFXLeaveVT start\n"); 2535 hwp=VGAHWPTR(pScrn); 2536 TDFXRestore(pScrn); 2537 vgaHWLock(hwp); 2538 pScreen = xf86ScrnToScreen(pScrn); 2539 pTDFX = TDFXPTR(pScrn); 2540 pTDFX->sync(pScrn); 2541 TDFXShutdownFifo(pScreen); 2542#ifdef TDFXDRI 2543 if (pTDFX->directRenderingEnabled) { 2544 DRILock(pScreen, 0); 2545 } 2546#endif 2547} 2548 2549static Bool 2550TDFXCloseScreen(CLOSE_SCREEN_ARGS_DECL) 2551{ 2552 ScrnInfoPtr pScrn; 2553 vgaHWPtr hwp; 2554 TDFXPtr pTDFX; 2555 2556 TDFXTRACE("TDFXCloseScreen start\n"); 2557 pScrn = xf86ScreenToScrn(pScreen); 2558 hwp = VGAHWPTR(pScrn); 2559 pTDFX = TDFXPTR(pScrn); 2560 2561#ifdef TDFXDRI 2562 if (pTDFX->directRenderingEnabled) { 2563 TDFXDRICloseScreen(pScreen); 2564 pTDFX->directRenderingEnabled=FALSE; 2565 } 2566#endif 2567 2568 TDFXShutdownFifo(pScreen); 2569 2570 if (pScrn->vtSema) { 2571 TDFXRestore(pScrn); 2572 vgaHWLock(hwp); 2573 TDFXUnmapMem(pScrn); 2574 vgaHWUnmapMem(pScrn); 2575 } 2576 2577#ifdef HAVE_XAA_H 2578 if (pTDFX->AccelInfoRec) XAADestroyInfoRec(pTDFX->AccelInfoRec); 2579 pTDFX->AccelInfoRec=0; 2580#endif 2581 if (pTDFX->DGAModes) free(pTDFX->DGAModes); 2582 pTDFX->DGAModes=0; 2583 if (pTDFX->scanlineColorExpandBuffers[0]) 2584 free(pTDFX->scanlineColorExpandBuffers[0]); 2585 pTDFX->scanlineColorExpandBuffers[0]=0; 2586 if (pTDFX->scanlineColorExpandBuffers[1]) 2587 free(pTDFX->scanlineColorExpandBuffers[1]); 2588 pTDFX->scanlineColorExpandBuffers[1]=0; 2589 if (pTDFX->overlayAdaptor) 2590 free(pTDFX->overlayAdaptor); 2591 pTDFX->overlayAdaptor=0; 2592 if (pTDFX->textureAdaptor) 2593 free(pTDFX->textureAdaptor); 2594 pTDFX->textureAdaptor=0; 2595 2596 pScrn->vtSema=FALSE; 2597 2598 pScreen->BlockHandler = pTDFX->BlockHandler; 2599 pScreen->CloseScreen = pTDFX->CloseScreen; 2600 return (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS); 2601} 2602 2603static void 2604TDFXFreeScreen(FREE_SCREEN_ARGS_DECL) { 2605 SCRN_INFO_PTR(arg); 2606 TDFXTRACE("TDFXFreeScreen start\n"); 2607 TDFXFreeRec(pScrn); 2608 if (xf86LoaderCheckSymbol("vgaHWFreeHWRec")) 2609 vgaHWFreeHWRec(pScrn); 2610} 2611 2612static ModeStatus 2613TDFXValidMode(SCRN_ARG_TYPE arg, DisplayModePtr mode, Bool verbose, int flags) { 2614 SCRN_INFO_PTR(arg); 2615 TDFXPtr pTDFX; 2616 2617 TDFXTRACE("TDFXValidMode start\n"); 2618 if ((mode->HDisplay>2048) || (mode->VDisplay>1536)) 2619 return MODE_BAD; 2620 /* Banshee doesn't support interlace, but Voodoo 3 and higher do. */ 2621 pTDFX = TDFXPTR(pScrn); 2622 if (mode->Flags&V_INTERLACE) { 2623 switch (pTDFX->ChipType) { 2624 case PCI_CHIP_BANSHEE: 2625 return MODE_BAD; 2626 case PCI_CHIP_VELOCITY: 2627 case PCI_CHIP_VOODOO3: 2628 case PCI_CHIP_VOODOO4: 2629 case PCI_CHIP_VOODOO5: 2630 return MODE_OK; 2631 default: 2632 return MODE_BAD; 2633 } 2634 } 2635 /* In clock doubled mode widths must be divisible by 16 instead of 8 */ 2636 if ((mode->Clock>TDFX2XCUTOFF) && (mode->HDisplay%16)) 2637 return MODE_BAD; 2638 return MODE_OK; 2639} 2640 2641/* replacement of vgaHWBlankScreen(pScrn, unblank) which doesn't unblank 2642 * the screen if it is already unblanked. */ 2643static void 2644TDFXBlankScreen(ScrnInfoPtr pScrn, Bool unblank) 2645{ 2646 vgaHWPtr hwp = VGAHWPTR(pScrn); 2647 unsigned char scrn; 2648 2649 TDFXTRACE("TDFXBlankScreen start\n"); 2650 2651 scrn = hwp->readSeq(hwp, 0x01); 2652 2653 if (unblank) { 2654 if((scrn & 0x20) == 0) return; 2655 scrn &= ~0x20; /* enable screen */ 2656 } else { 2657 scrn |= 0x20; /* blank screen */ 2658 } 2659 2660 vgaHWSeqReset(hwp, TRUE); 2661 hwp->writeSeq(hwp, 0x01, scrn); /* change mode */ 2662 vgaHWSeqReset(hwp, FALSE); 2663} 2664 2665static Bool 2666TDFXSaveScreen(ScreenPtr pScreen, int mode) 2667{ 2668 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2669 Bool unblank; 2670 2671 TDFXTRACE("TDFXSaveScreen start\n"); 2672 2673 unblank = xf86IsUnblank(mode); 2674 2675 if (unblank) 2676 SetTimeSinceLastInputEvent(); 2677 2678 if (pScrn->vtSema) { 2679 TDFXBlankScreen(pScrn, unblank); 2680 } 2681 return TRUE; 2682} 2683 2684static void 2685TDFXBlockHandler(BLOCKHANDLER_ARGS_DECL) 2686{ 2687 SCREEN_PTR(arg); 2688 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen); 2689 TDFXPtr pTDFX = TDFXPTR(pScrn); 2690 2691 pScreen->BlockHandler = pTDFX->BlockHandler; 2692 (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS); 2693 pScreen->BlockHandler = TDFXBlockHandler; 2694 2695 if(pTDFX->VideoTimerCallback) { 2696 (*pTDFX->VideoTimerCallback)(pScrn, currentTime.milliseconds); 2697 } 2698} 2699 2700static void 2701TDFXDisplayPowerManagementSet(ScrnInfoPtr pScrn, int PowerManagementMode, 2702 int flags) { 2703 TDFXPtr pTDFX; 2704 int dacmode, state=0; 2705 2706 TDFXTRACE("TDFXDPMS start\n"); 2707 pTDFX = TDFXPTR(pScrn); 2708 dacmode=pTDFX->readLong(pTDFX, DACMODE); 2709 switch (PowerManagementMode) { 2710 case DPMSModeOn: 2711 /* Screen: On; HSync: On, VSync: On */ 2712 state=0; 2713 break; 2714 case DPMSModeStandby: 2715 /* Screen: Off; HSync: Off, VSync: On */ 2716 state=BIT(3); 2717 break; 2718 case DPMSModeSuspend: 2719 /* Screen: Off; HSync: On, VSync: Off */ 2720 state=BIT(1); 2721 break; 2722 case DPMSModeOff: 2723 /* Screen: Off; HSync: Off, VSync: Off */ 2724 state=BIT(1)|BIT(3); 2725 break; 2726 } 2727 dacmode&=~(BIT(1)|BIT(3)); 2728 dacmode|=state; 2729 pTDFX->writeLong(pTDFX, DACMODE, dacmode); 2730} 2731