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