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