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