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