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