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