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