? Makefile
? savage.4.html
? savage._man
? streams_cleanup.diff
? streams_cleanup_big.diff
Index: savage_accel.c
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v
retrieving revision 1.15
diff -u -r1.15 savage_accel.c
--- savage_accel.c	2 Mar 2004 18:15:45 -0000	1.15
+++ savage_accel.c	19 Mar 2004 20:25:08 -0000
@@ -297,23 +297,35 @@
     case S3_TWISTER:
     case S3_PROSAVAGE:
     case S3_PROSAVAGEDDR:
-    case S3_SUPERSAVAGE: /* AGD: S3 does supersavage differently. we may have to fix this. */
+    case S3_SUPERSAVAGE:
 	/* Disable BCI */
 	OUTREG(0x48C18, INREG(0x48C18) & 0x3FF0);
+	if (!psav->disableCOB) {
+	    /* Setup BCI command overflow buffer */
+	    OUTREG(0x48C14, (psav->cobOffset >> 11) | (psav->cobIndex << 29));
+	}
 	/* Program shadow status update */ /* AGD: what should this be? */
 	OUTREG(0x48C10, 0x00700040); /* tim */
         /*OUTREG(0x48C10, 0x0e440f04L);*/ /* S3 */
 	if( psav->ShadowStatus )
 	{
 	    OUTREG(0x48C0C, psav->ShadowPhysical | 1 );
-	    /* Enable BCI without the COB */
-	    OUTREG(0x48C18, INREG(0x48C18) | 0x0a);
+	    if (psav->disableCOB) {
+	    	/* Enable BCI without the COB */
+		OUTREG(0x48C18, INREG(0x48C18) | 0x0a);
+	    } else {
+		OUTREG32(0x48C18, INREG32(0x48C18) | 0x0E);
+	    }
 	}
 	else
 	{
 	    OUTREG(0x48C0C, 0);
-	    /* Enable BCI without the COB */
-	    OUTREG(0x48C18, INREG(0x48C18) | 0x08);
+	    if (psav->disableCOB) {
+	    	/* Enable BCI without the COB */
+	    	OUTREG(0x48C18, INREG(0x48C18) | 0x08);
+	    } else {
+		OUTREG32(0x48C18, INREG32(0x48C18) | 0x0C);
+	    }
 	}
 	break;
 
@@ -504,6 +516,7 @@
                  | 0xC0000000 | (psav->lDelta & 0x00001fff));
     }
 
+#if 0
     /*
      *  CR69, bit 7 = 1
      *  to use MM streams processor registers to control primary stream.
@@ -511,6 +524,7 @@
     OUTREG8(CRT_ADDRESS_REG,0x69);
     byte = INREG8(CRT_DATA_REG) | 0x80;
     OUTREG8(CRT_DATA_REG,byte);
+#endif
 
     OUTREG32(0x8128, 0xFFFFFFFFL);
     OUTREG32(0x812C, 0xFFFFFFFFL);
@@ -643,12 +657,13 @@
     byte = INREG8(SEQ_DATA_REG) | 0x20;
     OUTREG8(SEQ_DATA_REG,byte);
 
+#if 0
     /*
      * CR67_3:
      *  = 1  stream processor MMIO address and stride register
      *       are used to control the primary stream
      *  = 0  standard VGA address and stride registers
-     *       are used t control the primary streams
+     *       are used to control the primary streams
      */
     OUTREG8(CRT_ADDRESS_REG,0x67); 
     byte =  INREG8(CRT_DATA_REG) | 0x08;
@@ -662,7 +677,17 @@
     OUTREG8(CRT_DATA_REG,byte);
              
     OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
+#endif
 
+    /*
+     * load ps1 active registers as determined by MM81C0/81C4
+     * load ps2 active registers as determined by MM81B0/81B4
+     */
+    OUTREG8(CRT_ADDRESS_REG,0x65); 
+    byte =  INREG8(CRT_DATA_REG) | 0x03;
+    OUTREG8(CRT_DATA_REG,byte);
+
+#if 0
     /* Set primary stream to bank 0 */
     OUTREG8(CRT_ADDRESS_REG, MEMORY_CTRL0_REG);/* CRCA */
     byte =  INREG8(CRT_DATA_REG) & ~(MEM_PS1 + MEM_PS2) ;
@@ -677,6 +702,7 @@
         byte |= 0x3;
         OUTREG16(CRT_ADDRESS_REG, (byte << 8) | MEMORY_CTRL0_REG);
     }
+#endif
 
     /* MM81C0 and 81C4 are used to control primary stream. */
     OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000);
@@ -838,12 +864,13 @@
     byte = INREG8(SEQ_DATA_REG) | 0x20;
     OUTREG8(SEQ_DATA_REG,byte);
 
+#if 0
     /*
      * CR67_3:
      *  = 1  stream processor MMIO address and stride register
      *       are used to control the primary stream
      *  = 0  standard VGA address and stride registers
-     *       are used t control the primary streams
+     *       are used to control the primary streams
      */
     OUTREG8(CRT_ADDRESS_REG,0x67); 
     byte =  INREG8(CRT_DATA_REG) | 0x08;
@@ -857,6 +884,7 @@
     OUTREG8(CRT_DATA_REG,byte);
     
     OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
+#endif
 
     /*
      * load ps1 active registers as determined by MM81C0/81C4
Index: savage_driver.c
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v
retrieving revision 1.15
diff -u -r1.15 savage_driver.c
--- savage_driver.c	4 Mar 2004 19:33:10 -0000	1.15
+++ savage_driver.c	19 Mar 2004 20:25:11 -0000
@@ -82,6 +82,7 @@
 static void SavageGetTvMaxSize(SavagePtr psav);
 static Bool SavagePanningCheck(ScrnInfoPtr pScrn);
 static Bool SavageCheckAvailableRamFor3D(ScrnInfoPtr pScrn);
+static void SavageResetStreams(ScrnInfoPtr pScrn);
 
 extern ScrnInfoPtr gpScrn;
 
@@ -208,12 +209,14 @@
     ,OPTION_FORCE_INIT
     ,OPTION_DISABLE_XVMC
     ,OPTION_DISABLE_TILE
+    ,OPTION_DISABLE_COB
+    ,OPTION_BCI_FOR_XV
 } SavageOpts;
 
 
 static const OptionInfoRec SavageOptions[] =
 {
-    { OPTION_NOACCEL,	"NoAccel",	OPTV_BOOLEAN, {0}, FALSE  },
+    { OPTION_NOACCEL,	"NoAccel",	OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_HWCURSOR,	"HWCursor",	OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_SWCURSOR,	"SWCursor",	OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_SHADOW_FB,	"ShadowFB",	OPTV_BOOLEAN, {0}, FALSE },
@@ -226,8 +229,10 @@
     { OPTION_TV_ON,     "TvOn",         OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_TV_PAL,    "PAL",          OPTV_BOOLEAN, {0}, FALSE },
     { OPTION_FORCE_INIT,"ForceInit",    OPTV_BOOLEAN, {0}, FALSE },
-    { OPTION_DISABLE_XVMC, "DisableXVMC",  OPTV_BOOLEAN,   {0}, FALSE },
-    { OPTION_DISABLE_TILE, "DisableTile",  OPTV_BOOLEAN,   {0}, FALSE  },
+    { OPTION_DISABLE_XVMC, "DisableXVMC", OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_DISABLE_TILE, "DisableTile", OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_DISABLE_COB,  "DisableCOB",  OPTV_BOOLEAN, {0}, FALSE },
+    { OPTION_BCI_FOR_XV,   "BCIforXv",    OPTV_BOOLEAN, {0}, FALSE },
     { -1,		NULL,		OPTV_NONE,    {0}, FALSE }
 };
 
@@ -1043,10 +1048,20 @@
                    "Option: %s Tile Mode and Program it \n",(psav->bDisableTile?"Disable":"Enable"));
     }
     psav->bDisableXvMC = FALSE; /* if you want to free up more mem for DRI,etc. */
-    if (xf86GetOptValBool(psav->Options, OPTION_DISABLE_XVMC,&psav->bDisableXvMC)) {
+    if (xf86GetOptValBool(psav->Options, OPTION_DISABLE_XVMC, &psav->bDisableXvMC)) {
         xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
                    "Option: %s Hardware XvMC support\n",(psav->bDisableXvMC?"Disable":"Enable"));
     }
+    psav->disableCOB = FALSE; /* if you are having problems on savage4+ */
+    if (xf86GetOptValBool(psav->Options, OPTION_DISABLE_COB, &psav->disableCOB)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+                   "Option: %s the COB\n",(psav->disableCOB?"Disable":"Enable"));
+    }
+    psav->BCIforXv = FALSE; /* use the BCI for Xv */
+    if (xf86GetOptValBool(psav->Options, OPTION_BCI_FOR_XV, &psav->BCIforXv)) {
+        xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+                   "Option: %s use of the BCI for Xv\n",(psav->BCIforXv?"Disable":"Enable"));
+    }
 
     /* Add more options here. */
 
@@ -1260,8 +1275,8 @@
 	psav->cobOffset = psav->videoRambytes;
         /*psav->cobOffset = endfb;*/
     }
-    else if( (S3_SAVAGE4_SERIES(psav->Chipset)) ||
-             (S3_SUPERSAVAGE == psav->Chipset) ) {
+    else if( ((S3_SAVAGE4_SERIES(psav->Chipset)) ||
+             (S3_SUPERSAVAGE == psav->Chipset)) && psav->disableCOB ) {
 	/*
 	 * The Savage4 and ProSavage have COB coherency bugs which render 
 	 * the buffer useless.  COB seems to make the SuperSavage slower.
@@ -1384,45 +1399,6 @@
         }
     }
 
-#if 0 /* Tim's DDC */
-    /* Do the DDC dance. */
-    if( psav->Chipset != S3_PROSAVAGE ) {
-	ddc = xf86LoadSubModule(pScrn, "ddc");
-	if (ddc) {
-#if 0
-	    xf86MonPtr pMon = NULL;
-#endif
-	   
-	    xf86LoaderReqSymLists(ddcSymbols, NULL);
-#if 0
-/*
- * On many machines, the attempt to read DDC information via VBE puts the
- * BIOS access into a state which prevents me from reading mode information.
- * This is a complete mystery to me.
- */
-	    if ((psav->pVbe) 
-	       && ((pMon = xf86PrintEDID(vbeDoEDID(psav->pVbe, ddc))) != NULL))
-	       xf86SetDDCproperties(pScrn,pMon);
-	    else 
-#endif
-	    if (!SavageDDC1(pScrn->scrnIndex)) {
-		if ( xf86LoadSubModule(pScrn, "i2c") ) {
-		    xf86LoaderReqSymLists(i2cSymbols,NULL);
-		    if (SavageI2CInit(pScrn)) {
-			unsigned char tmp;
-
-			InI2CREG(psav,tmp);
-			OutI2CREG(psav,tmp | 0x13);
-			xf86SetDDCproperties(pScrn,xf86PrintEDID(
-			    xf86DoEDID_DDC2(pScrn->scrnIndex,psav->I2C)));
-			OutI2CREG(psav,tmp);
-		    }
-		}
-	    }
-	}
-    }
-#endif /* tim's DDC */
-
     /* Savage ramdac speeds */
     pScrn->numClocks = 4;
     pScrn->clock[0] = 250000;
@@ -1719,6 +1695,7 @@
 #endif
 
     SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE);
+    SavageResetStreams(pScrn);
     SavageDisableMMIO(pScrn);
 
 }
@@ -2095,6 +2072,13 @@
 	    }
 	}
 
+	/* enable streams */
+	VerticalRetraceWait();
+	VGAOUT8(vgaCRIndex, 0x69);
+	VGAOUT8(vgaCRReg, restore->CR69);
+	VGAOUT8(vgaCRIndex, 0x67);
+	VGAOUT8(vgaCRReg, restore->CR67);
+
 	SavageInitialize2DEngine(pScrn);
 
 	VGAOUT16(vgaCRIndex, 0x0140);
@@ -2139,7 +2123,8 @@
 
     VGAOUT8(vgaCRIndex, 0x67);
     cr67 = VGAIN8(vgaCRReg);
-    VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c); /* no STREAMS yet */
+    /*VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c);*/ /* no STREAMS yet */
+    VGAOUT8(vgaCRReg, restore->CR67 & ~0xf1); /* no streams for new and old streams engines */
 
     /* restore extended regs */
     VGAOUT8(vgaCRIndex, 0x66);
@@ -2202,7 +2187,8 @@
 
     /* restore the desired video mode with cr67 */
     VGAOUT8(vgaCRIndex, 0x67);
-    VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c); /* no STREAMS yet */
+    /*VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c);*/ /* no STREAMS yet */
+    VGAOUT8(vgaCRReg, restore->CR67 & ~0xf1); /* no streams for new and old streams engines */
 
     /* other mode timing and extended regs */
     VGAOUT8(vgaCRIndex, 0x34);
@@ -2225,6 +2211,7 @@
     VGAOUT8(vgaCRReg, restore->CR60);
     VGAOUT8(vgaCRIndex, 0x68);
     VGAOUT8(vgaCRReg, restore->CR68);
+    VerticalRetraceWait();
     VGAOUT8(vgaCRIndex, 0x69);
     VGAOUT8(vgaCRReg, restore->CR69);
     VGAOUT8(vgaCRIndex, 0x6f);
@@ -2918,6 +2905,28 @@
 	break;
     }
 
+    /* setup streams */
+    switch (psav->Chipset) {
+	case S3_SAVAGE3D:
+        case S3_SAVAGE_MX:
+        case S3_SUPERSAVAGE:
+	    new->CR67 |= 0x08; /* CR67[3] = 1 : Mem-mapped regs */
+	    new->CR67 |= 0x04; /* CR67[2] = 1 : enable stream 1 */
+	    new->CR67 |= 0x02; /* CR67[1] = 1 : enable stream 2 */
+	    new->CR69 = 0;
+            break;
+        case S3_SAVAGE4:
+        case S3_TWISTER:
+        case S3_PROSAVAGE:            
+        case S3_PROSAVAGEDDR:
+        case S3_SAVAGE2000:
+	    new->CR69 = 0x80; /* CR69[0] = 1 : Mem-mapped regs */
+	    /*new->CR67 |= 0x0c;*/ /* CR67[2] = 1 : enable stream 1 */
+            break;
+        default:
+            break;
+    }
+
     if( psav->UseBIOS ) {
 	int refresh;
 	SavageModeEntryPtr pmt;
@@ -3141,7 +3150,6 @@
 	VGAOUT8(vgaCRIndex, 0x68);
 	new->CR68 = VGAIN8(vgaCRReg);
 
-        new->CR69 = 0x80;
 	/*new->CR69 = 0;*/
 	VGAOUT8(vgaCRIndex, 0x6f);
 	new->CR6F = VGAIN8(vgaCRReg);
@@ -3197,6 +3205,7 @@
 
     if (pScrn->vtSema) {
 	SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE);
+        SavageResetStreams(pScrn);
 	vgaHWLock(hwp);
 	SavageUnmapMem(pScrn, 0);
     }
@@ -3741,4 +3750,50 @@
 	return FALSE;
 }
 
+static void
+SavageResetStreams(ScrnInfoPtr pScrn)
+{
+    SavagePtr psav = SAVPTR(pScrn);
+    uchar cr67;
+    uchar cr69;
 
+    /* disable streams */
+    switch (psav->Chipset) {
+	case S3_SAVAGE3D:
+        case S3_SAVAGE_MX:
+        case S3_SUPERSAVAGE:
+            OUTREG32(PRI_STREAM_STRIDE,0);
+            OUTREG32(PRI_STREAM2_STRIDE, 0);
+            OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000);
+            OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000);
+            OUTREG32(PRI_STREAM2_FBUF_ADDR0,0x00000000);
+            OUTREG32(PRI_STREAM2_FBUF_ADDR1,0x00000000);
+	    OUTREG8(CRT_ADDRESS_REG, 0x67);
+            cr67 = INREG8(CRT_DATA_REG);
+	    cr67 &= ~0x08; /* CR67[3] = 1 : Mem-mapped regs */
+	    cr67 &= ~0x04; /* CR67[2] = 1 : enable stream 1 */
+	    cr67 &= ~0x02; /* CR67[1] = 1 : enable stream 2 */
+            OUTREG8(CRT_DATA_REG, cr67);
+            break;
+        case S3_SAVAGE4:
+        case S3_TWISTER:
+        case S3_PROSAVAGE:            
+        case S3_PROSAVAGEDDR:
+        case S3_SAVAGE2000: /* don't know about savage2000 */
+            OUTREG32(PRI_STREAM_STRIDE,0);
+            OUTREG32(PRI_STREAM_FBUF_ADDR0,0);
+            OUTREG32(PRI_STREAM_FBUF_ADDR1,0);
+	    OUTREG8(CRT_ADDRESS_REG, 0x67);
+            cr67 = INREG8(CRT_DATA_REG);
+	    cr67 &= ~0x0c; /* CR67[2] = 1 : enable stream 1 */
+            OUTREG8(CRT_DATA_REG, cr67);
+	    OUTREG8(CRT_ADDRESS_REG, 0x69);
+            cr69 = INREG8(CRT_DATA_REG);
+	    cr69 &= ~0x80; /* CR69[0] = 1 : Mem-mapped regs */
+            OUTREG8(CRT_DATA_REG, cr69);
+            break;
+        default:
+            break;
+    }
+
+}
Index: savage_driver.h
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h,v
retrieving revision 1.10
diff -u -r1.10 savage_driver.h
--- savage_driver.h	22 Feb 2004 16:14:42 -0000	1.10
+++ savage_driver.h	19 Mar 2004 20:25:11 -0000
@@ -308,8 +308,6 @@
 
     int 		agpMode;
     FBLinearPtr		reserved;
-
-    Bool bDisableXvMC;
     
     unsigned int surfaceAllocation[7];
     unsigned int xvmcContext;
@@ -318,6 +316,11 @@
     unsigned int hwmcSize;
 
 #endif
+
+    Bool bDisableXvMC;
+    Bool disableCOB;
+    Bool BCIforXv;
+
     /* Bitmap Descriptors for BCI */
     BMPDESC GlobalBD;
     BMPDESC PrimaryBD;
Index: savage_video.c
===================================================================
RCS file: /cvs/dri/xc/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_video.c,v
retrieving revision 1.4
diff -u -r1.4 savage_video.c
--- savage_video.c	8 Mar 2004 17:56:18 -0000	1.4
+++ savage_video.c	19 Mar 2004 20:25:12 -0000
@@ -9,14 +9,6 @@
 #include "savage_regs.h"
 #include "savage_bci.h"
 
-/* AGD: Uncomment this to use the BCI copy planar data method on
- * savages with the old streams engine.  It's off by default
- * as it leaves artifacts on the screen when moving the output
- * window. It may also be possible to use a similar method
- * on chips using the new streams engine.  That remains to be
- * seen.
- */
-/*#define BCI_COPY_DATA 1*/
 
 #define OFF_DELAY 	200  /* milliseconds */
 #define FREE_DELAY 	60000
@@ -1103,13 +1095,12 @@
     if(*p_w > 16384) *p_w = 16384;
 }
 
-#ifdef BCI_COPY_DATA
-/* SavageCopyPlanarDataOld() causes artifacts on the screen when used. 
+/* SavageCopyPlanarDataBCI() causes artifacts on the screen when used. 
  * It's probably something with the BCI.  Maybe we need a waitforidle() or
  * something...
  */
 static void
-SavageCopyPlanarDataOld(
+SavageCopyPlanarDataBCI(
     ScrnInfoPtr pScrn,
     unsigned char *srcY, /* Y */
     unsigned char *srcV, /* V */
@@ -1187,7 +1178,6 @@
     BCI_SEND(0x00200003 | srcPitch);
     BCI_SEND(0xC0170000);
 }
-#endif
 
 static void
 SavageCopyData(
@@ -1643,9 +1633,9 @@
 	offsetU += tmp;
 	offsetV += tmp;
 	nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
-#ifdef BCI_COPY_DATA
-        if (S3_SAVAGE4_SERIES(psav->Chipset)) {
-            SavageCopyPlanarDataOld(
+        if (S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv 
+	    && (!psav->disableCOB)) {
+            SavageCopyPlanarDataBCI(
                 pScrn,
 	    	buf + (top * srcPitch) + (left >> 1), 
 	    	buf + offsetV, 
@@ -1658,13 +1648,6 @@
 	    	buf + offsetU, 
 	    	dst_start, srcPitch, srcPitch2, dstPitch, nlines, npixels);
         }
-#else
-	SavageCopyPlanarData(
-	    buf + (top * srcPitch) + (left >> 1), 
-	    buf + offsetV, 
-	    buf + offsetU, 
-	    dst_start, srcPitch, srcPitch2, dstPitch, nlines, npixels);
-#endif
 	break;
     case FOURCC_Y211:		/* Y211 */
     case FOURCC_RV15:		/* RGB15 */
