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