--- /dev/null
+--- XFree86-4.0.1/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c.chmou Tue Sep 19 17:34:43 2000
++++ XFree86-4.0.1/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_dri.c Tue Sep 19 18:30:25 2000
+@@ -127,9 +127,10 @@
+ }
+ }
+ if (i!=numConfigs) {
+- ErrorF("Incorrect initialization of visuals\n");
++ xf86DrvMsg(pScreen->myNum, X_ERROR,
++ "Incorrect initialization of visuals\n");
+ return FALSE;
+- } else ErrorF("Created %d visuals\n", numConfigs);
++ }
+ break; /* 16bpp */
+
+ case 24:
+@@ -224,7 +225,7 @@
+ xf86DrvMsg(pScreen->myNum, X_ERROR,
+ "Incorrect initialization of visuals\n");
+ return FALSE;
+- } else ErrorF("Created %d visuals\n", numConfigs);
++ }
+ break;
+ }
+ pTDFX->numVisualConfigs = numConfigs;
+@@ -263,12 +264,21 @@
+
+ switch (pScrn->bitsPerPixel) {
+ case 8:
++ xf86DrvMsg(pScreen->myNum, X_ERROR,
++ "DRI not supported in 8 bpp mode, disabling DRI.\n");
+ return FALSE;
+ case 16:
+ break;
+ case 24:
++ xf86DrvMsg(pScreen->myNum, X_ERROR,
++ "DRI not supported in 24 bpp mode, disabling DRI.\n");
++ return FALSE;
+ case 32:
+- if (pTDFX->ChipType<=PCI_CHIP_VOODOO3) return FALSE;
++ if (pTDFX->ChipType<=PCI_CHIP_VOODOO3) {
++ xf86DrvMsg(pScreen->myNum, X_ERROR,
++ "DRI requires Voodoo3 or later, disabling DRI.\n");
++ return FALSE;
++ }
+ }
+
+ /* Check that the GLX, DRI, and DRM modules have been loaded by testing
+@@ -295,8 +305,12 @@
+ }
+
+ pDRIInfo = DRICreateInfoRec();
+- if (!pDRIInfo)
+- return FALSE;
++ if (!pDRIInfo) {
++ xf86DrvMsg(pScreen->myNum, X_ERROR,
++ "DRICreatInfoRect() failed, disabling DRI.\n");
++ return FALSE;
++ }
++
+ pTDFX->pDRIInfo = pDRIInfo;
+
+ pDRIInfo->drmDriverName = TDFXKernelDriverName;
+@@ -336,13 +350,14 @@
+ * in the SAREA header
+ */
+ if (sizeof(XF86DRISAREARec)+sizeof(TDFXSAREAPriv)>SAREA_MAX) {
+- xf86DrvMsg(pScreen->myNum, X_ERROR, "Data does not fit in SAREA\n");
++ xf86DrvMsg(pScreen->myNum, X_ERROR, "Data does not fit in SAREA\n");
+ return FALSE;
+ }
+ pDRIInfo->SAREASize = SAREA_MAX;
+ #endif
+
+ if (!(pTDFXDRI = (TDFXDRIPtr)xnfcalloc(sizeof(TDFXDRIRec),1))) {
++ xf86DrvMsg(pScreen->myNum, X_ERROR, "DRI memory allocation failed, disabling DRI.\n");
+ DRIDestroyInfoRec(pTDFX->pDRIInfo);
+ pTDFX->pDRIInfo=0;
+ return FALSE;
+@@ -363,6 +378,8 @@
+ pDRIInfo->devPrivate=0;
+ DRIDestroyInfoRec(pTDFX->pDRIInfo);
+ pTDFX->pDRIInfo=0;
++ xf86DrvMsg(pScreen->myNum, X_ERROR, "DRIScreenInit failed, disabling DRI.\n");
++
+ return FALSE;
+ }
+
+@@ -391,6 +408,7 @@
+ if (drmAddMap(pTDFX->drmSubFD, (drmHandle)pTDFX->MMIOAddr[0],
+ pTDFXDRI->regsSize, DRM_REGISTERS, 0, &pTDFXDRI->regs)<0) {
+ TDFXDRICloseScreen(pScreen);
++ xf86DrvMsg(pScreen->myNum, X_ERROR, "drmAddMap failed, disabling DRI.\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Registers = 0x%08lx\n",
+@@ -398,6 +416,7 @@
+
+ if (!(TDFXInitVisualConfigs(pScreen))) {
+ TDFXDRICloseScreen(pScreen);
++ xf86DrvMsg(pScreen->myNum, X_ERROR, "TDFXInitVisualConfigs failed, disabling DRI.\n");
+ return FALSE;
+ }
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "visual configs initialized\n" );
+--- XFree86-4.0.1/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c.chmou Tue Sep 19 17:34:43 2000
++++ XFree86-4.0.1/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_driver.c Tue Sep 19 18:30:25 2000
+@@ -636,7 +636,6 @@
+ ClockRangePtr clockRanges;
+ int i;
+ MessageType from;
+- char *mod=0, *reqSym=0;
+ int flags24;
+ rgb defaultWeight = {0, 0, 0};
+ pciVideoPtr match;
+@@ -663,7 +662,7 @@
+
+ if (flags & PROBE_DETECT) {
+ TDFXProbeDDC(pScrn, pTDFX->pEnt->index);
+- return FALSE;
++ return TRUE;
+ }
+
+ /* The vgahw module should be loaded here when needed */
+@@ -1195,7 +1194,10 @@
+ maxm=24;
+ } else {
+ minm=1;
+- maxm=64;
++ maxm=57; /* This used to be 64, alas it seems the last 8 (funny that ?)
++ * values cause jittering at lower resolutions. I've not done
++ * any calculations to what the adjustment affects clock ranges,
++ * but I can still run at 1600x1200@75Hz */
+ }
+ for (n=1; n<256; n++) {
+ f_cur=REFFREQ*(n+2);
+@@ -1604,15 +1606,6 @@
+ pTDFX = TDFXPTR(pScrn);
+ pTDFX->stride = pScrn->displayWidth*pTDFX->cpp;
+
+- /* Layout the memory. Start with all the ram */
+- memRemaining=pScrn->videoRam<<10;
+- /* Remove the cursor space */
+- memRemaining-=4096;
+- /* Remove the main screen and offscreen pixmaps */
+- memRemaining-=pTDFX->stride*(pScrn->virtualY+128);
+- /* Remove one scanline for page alignment */
+- memRemaining-=4095;
+- /* Remove the back and Z buffers */
+ if (pTDFX->cpp!=3) {
+ screenSizeInTiles=calcBufferSize(pScrn->virtualX, pScrn->virtualY,
+ TRUE, pTDFX->cpp);
+@@ -1622,41 +1615,77 @@
+ screenSizeInTiles=calcBufferSize(pScrn->virtualX, pScrn->virtualY,
+ TRUE, 4);
+ }
+- memRemaining-=screenSizeInTiles*2;
+-
+- /* Give all the rest to textures, rounded down to a page */
+- texSize=memRemaining&~0xFFF;
+-
+- /* Make sure fifo has CMDFIFO_PAGES<fifoSize<255 pages */
+- if (memRemaining-texSize<CMDFIFO_PAGES<<12)
+- texSize=(memRemaining-(CMDFIFO_PAGES<<12))&~0xFFF;
+- /* Fifo uses the remaining space up to 255 pages */
+- fifoSize = (memRemaining-texSize)&~0xFFF;
+- if (fifoSize>255<<12) fifoSize=255<<12;
+-
+- /* Assign the variables */
+- /* Cursor */
+- pTDFX->cursorOffset=0; /* Size 1024 bytes */
+-
+- /* Point the fifo at the first page */
++ memRemaining=((pScrn->videoRam<<10) - 1) &~ 0xFFF;
++ /* Note that a page is 4096 bytes, and a */
++ /* tile is 32 x 128 = 4096 bytes. So, */
++ /* page and tile boundaries are the same */
++ /* Place the depth offset first, forcing */
++ /* it to be on an *odd* page boundary. */
++ pTDFX->depthOffset = (memRemaining - screenSizeInTiles) &~ 0xFFF;
++ if ((pTDFX->depthOffset & (0x1 << 12)) == 0) {
++#if 0
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Changing depth offset from 0x%08x to 0x%08x\n",
++ pTDFX->depthOffset,
++ pTDFX->depthOffset - (0x1 << 12));
++#endif
++ pTDFX->depthOffset -= (0x1 << 12);
++ }
++ /* Now, place the back buffer, forcing it */
++ /* to be on an *even* page boundary. */
++ pTDFX->backOffset = (pTDFX->depthOffset - screenSizeInTiles) &~ 0xFFF;
++ if (pTDFX->backOffset & (0x1 << 12)) {
++#if 0
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Changing back offset from 0x%08x to 0x%08x\n",
++ pTDFX->backOffset,
++ pTDFX->backOffset - (0x1 << 12));
++#endif
++ pTDFX->backOffset -= (0x1 << 12);
++ }
++ /* Now, place the front buffer, forcing */
++ /* it to be on a page boundary too, just */
++ /* for giggles. */
++ pTDFX->fbOffset
++ = (pTDFX->backOffset - (pScrn->virtualY+128)*pTDFX->stride) &~ 0xFFF;
++ /* Give the cmd fifo at least */
++ /* CMDFIFO_PAGES pages, but no more than */
++ /* 255. */
++ fifoSize = ((255 <= CMDFIFO_PAGES) ? 255 : CMDFIFO_PAGES) << 12;
++ /* We give 4096 bytes to the cursor, fifoSize to the */
++ /* FIFO, and everything to textures. */
++ texSize = (pTDFX->fbOffset - fifoSize - 4096);
++ pTDFX->texOffset = pTDFX->fbOffset - texSize;
++ pTDFX->texSize = texSize;
+ pTDFX->fifoOffset = 4096;
+ pTDFX->fifoSize = fifoSize;
+-
+- /* Textures */
+- pTDFX->texOffset = pTDFX->fifoOffset+fifoSize;
+- pTDFX->texSize = texSize;
+-
+- /* Frame buffer */
+- pTDFX->fbOffset=pTDFX->texOffset+pTDFX->texSize;
+-
+- /* Back buffer */
+- pTDFX->backOffset=pTDFX->fbOffset+(pScrn->virtualY+128)*pTDFX->stride;
+- /* Round off to a page */
+- pTDFX->backOffset=(pTDFX->backOffset+4095)&~0xFFF;
+-
+- /* Depth buffer */
+- pTDFX->depthOffset=pTDFX->backOffset+screenSizeInTiles;
+-
++ pTDFX->cursorOffset = 0;
++#if 0
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Cursor Offset: [0x%08X,0x%08X)\n",
++ pTDFX->cursorOffset,
++ pTDFX->cursorOffset+1024);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Fifo Offset: [0x%08X, 0x%08X)\n",
++ pTDFX->fifoOffset,
++ pTDFX->fifoOffset+fifoSize);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Texture Offset: [0x%08X, 0x%08X)\n",
++ pTDFX->texOffset,
++ pTDFX->texOffset + texSize);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "Front Buffer Offset: [0x%08X, 0x%08X)\n",
++ pTDFX->fbOffset,
++ pTDFX->fbOffset + (pScrn->virtualY+128)*pTDFX->stride);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "BackOffset: [0x%08X, 0x%08X)\n",
++ pTDFX->backOffset,
++ pTDFX->backOffset+screenSizeInTiles);
++ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
++ "DepthOffset: [0x%08X, 0x%08X)\n",
++ pTDFX->depthOffset,
++ pTDFX->depthOffset+screenSizeInTiles);
++#endif /* 0/1 */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Textures Memory %0.02f MB\n",
+ (float)texSize/1024.0/1024.0);
+ }
+--- XFree86-4.0.1/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_accel.c.chmou Tue Sep 19 17:34:43 2000
++++ XFree86-4.0.1/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_accel.c Tue Sep 19 18:30:25 2000
+@@ -163,12 +163,22 @@
+ } else {
+ int chip;
+ int stride, bits;
++ int TileAperturePitch, lg2TileAperturePitch;
+ if (pTDFX->cpp==2) stride=pTDFX->stride;
+ else stride=4*pTDFX->stride/pTDFX->cpp;
+ bits=pTDFX->backOffset>>12;
++ for (lg2TileAperturePitch = 0, TileAperturePitch = 1024;
++ (lg2TileAperturePitch < 5) &&
++ TileAperturePitch < stride;
++ lg2TileAperturePitch += 1, TileAperturePitch <<= 1);
++#if 0
++ fprintf(stderr, "Using %d (== lg2(%d)-10) for tile aperture pitch\n",
++ lg2TileAperturePitch, TileAperturePitch);
++ fprintf(stderr, "stride == %d\n", stride);
++#endif
+ for (chip=0; chip<pTDFX->numChips; chip++) {
+ TDFXWriteChipLongMMIO(pTDFX, chip, LFBMEMORYCONFIG, (bits&0x1FFF) |
+- SST_RAW_LFB_ADDR_STRIDE_4K |
++ SST_RAW_LFB_ADDR_STRIDE(lg2TileAperturePitch) |
+ ((bits&0x6000)<<10) |
+ ((stride+127)/128)<<SST_RAW_LFB_TILE_STRIDE_SHIFT);
+ }
+--- XFree86-4.0.1/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_sli.c.chmou Tue Sep 19 17:34:43 2000
++++ XFree86-4.0.1/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_sli.c Tue Sep 19 18:30:25 2000
+@@ -1,4 +1,3 @@
+-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfx_sli.c,v 1.2 2000/06/17 18:23:23 dawes Exp $ */
+
+ #include "xf86.h"
+ #include "xf86_ansic.h"
+--- XFree86-4.0.1/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h.chmou Tue Sep 19 17:34:43 2000
++++ XFree86-4.0.1/xc/programs/Xserver/hw/xfree86/drivers/tdfx/tdfxdefs.h Tue Sep 19 18:30:25 2000
+@@ -52,8 +52,26 @@
+
+ #define MEM_TYPE_SGRAM 0
+ #define MEM_TYPE_SDRAM 1
++/*
++ * SST_RAW_LFB_ADDR_STRIDE(Lg2SizeInK) takes the
++ * lfbMemoryConfig value for SGRAMStrideInTiles. This
++ * is given by this table:
++ * SGRAMStrideInBytes lfbMemoryConfig Value
++ * ================== =====================
++ * 1k 0
++ * 2k 1
++ * 4k 2
++ * 8k 3
++ * 16k 4
++ *
++ * FWIW, the right hand column is log2(left hand column)-10
++ */
+ #define SST_RAW_LFB_ADDR_STRIDE_SHIFT 13
+-#define SST_RAW_LFB_ADDR_STRIDE_4K 0x2<<SST_RAW_LFB_ADDR_STRIDE_SHIFT
++#define SST_RAW_LFB_ADDR_STRIDE(Lg2SizeInK) \
++ ((Lg2SizeInK)<<SST_RAW_LFB_ADDR_STRIDE_SHIFT)
++#define SST_RAW_LFB_ADDR_STRIDE_4K SST_RAW_LFB_ADDR_STRIDE(2)
++#define SST_RAW_LFB_ADDR_STRIDE_8K SST_RAW_LFB_ADDR_STRIDE(3)
++#define SST_RAW_LFB_ADDR_STRIDE_16K SST_RAW_LFB_ADDR_STRIDE(4)
+ #define SST_RAW_LFB_TILE_STRIDE_SHIFT 16
+
+ #define BLIT_LEFT 1