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