summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Deucher <agd5f@yahoo.com>2004-10-16 21:10:40 +0000
committerAlex Deucher <agd5f@yahoo.com>2004-10-16 21:10:40 +0000
commit352b7566ac11a13bbced74d8a9c8ff944525c097 (patch)
tree2944ee1083af89be3368cfa30ff7d7a2a67e6ef2
parent16af70368f042d6a5c54e57affe7c2e00f782baf (diff)
- fix savage2000, savage3D
- attempt to fix Xv on savage2000 (not there yet)
-rw-r--r--src/savage_accel.c296
-rw-r--r--src/savage_driver.c202
-rw-r--r--src/savage_streams.c61
-rw-r--r--src/savage_streams.h5
-rw-r--r--src/savage_video.c244
5 files changed, 678 insertions, 130 deletions
diff --git a/src/savage_accel.c b/src/savage_accel.c
index 29f1747..fa27a34 100644
--- a/src/savage_accel.c
+++ b/src/savage_accel.c
@@ -218,9 +218,11 @@ unsigned long writefb( unsigned long addr, unsigned long value );
void writescan( unsigned long scan, unsigned long color );
static int GetTileAperturePitch(unsigned long dwWidth, unsigned long dwBpp);
-void SavageSetGBD_M7(ScrnInfoPtr pScrn);
+void SavageSetGBD_M7(ScrnInfoPtr pScrn);
+void SavageSetGBD_3D(ScrnInfoPtr pScrn);
void SavageSetGBD_Twister(ScrnInfoPtr pScrn);
void SavageSetGBD_PM(ScrnInfoPtr pScrn);
+void SavageSetGBD_2000(ScrnInfoPtr pScrn);
/*
* This is used to cache the last known value for routines we want to
@@ -445,6 +447,8 @@ SavageSetGBD(ScrnInfoPtr pScrn)
*/
switch (psav->Chipset) {
case S3_SAVAGE3D:
+ SavageSetGBD_3D(pScrn);
+ break;
case S3_SAVAGE_MX:
SavageSetGBD_M7(pScrn);
break;
@@ -452,12 +456,14 @@ SavageSetGBD(ScrnInfoPtr pScrn)
case S3_TWISTER:
case S3_PROSAVAGE:
case S3_PROSAVAGEDDR:
- case S3_SAVAGE2000:
SavageSetGBD_Twister(pScrn);
break;
case S3_SUPERSAVAGE:
SavageSetGBD_PM(pScrn);
break;
+ case S3_SAVAGE2000:
+ SavageSetGBD_2000(pScrn);
+ break;
}
}
@@ -592,7 +598,158 @@ void SavageSetGBD_Twister(ScrnInfoPtr pScrn)
/* HW uses width */
psav->GlobalBD.bd1.HighPart.Stride = (unsigned short) psav->lDelta / (pScrn->bitsPerPixel >> 3);
psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
- psav->GlobalBD.bd1.Offset = 0;
+ psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
+
+
+ /*
+ * CR88, bit 4 - Block write enabled/disabled.
+ *
+ * Note: Block write must be disabled when writing to tiled
+ * memory. Even when writing to non-tiled memory, block
+ * write should only be enabled for certain types of SGRAM.
+ */
+ OUTREG8(CRT_ADDRESS_REG,0x88);
+ byte = INREG8(CRT_DATA_REG) | DISABLE_BLOCK_WRITE_2D;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ /*
+ * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
+ * bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
+ * at A000:0.
+ */
+ OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG); /* cr31 */
+ byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
+ OUTREG8(CRT_DATA_REG,byte); /* perhaps this should be 0x0c */
+
+ /* turn on screen */
+ OUTREG8(SEQ_ADDRESS_REG,0x01);
+ byte = INREG8(SEQ_DATA_REG) & ~0x20;
+ OUTREG8(SEQ_DATA_REG,byte);
+
+ /* program the GBD and SBD's */
+ OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart);
+ OUTREG32(S3_GLB_BD_HIGH,psav->GlobalBD.bd2.HiPart | bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
+ OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
+ OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
+ OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
+ OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
+}
+
+void SavageSetGBD_3D(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ unsigned long ulTmp;
+ unsigned char byte;
+ int bci_enable, tile16, tile32;
+
+ bci_enable = BCI_ENABLE;
+ tile16 = TILE_FORMAT_16BPP;
+ tile32 = TILE_FORMAT_32BPP;
+
+ /* MM81C0 and 81C4 are used to control primary stream. */
+ OUTREG32(PSTREAM_FBADDR0_REG,0x00000000);
+ OUTREG32(PSTREAM_FBADDR1_REG,0x00000000);
+
+ /*
+ * Program Primary Stream Stride Register.
+ *
+ * Tell engine if tiling on or off, set primary stream stride, and
+ * if tiling, set tiling bits/pixel and primary stream tile offset.
+ * Note that tile offset (bits 16 - 29) must be scanline width in
+ * bytes/128bytespertile * 256 Qwords/tile. This is equivalent to
+ * lDelta * 2. Remember that if tiling, lDelta is screenwidth in
+ * bytes padded up to an even number of tilewidths.
+ */
+ if (!psav->bTiled) {
+ OUTREG32(PSTREAM_STRIDE_REG,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000) |
+ (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
+ OUTREG32(PSTREAM_STRIDE_REG,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0x80000000 | (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ OUTREG32(PSTREAM_STRIDE_REG,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0xC0000000 | (psav->lDelta & 0x00001fff));
+ }
+
+ /*
+ * CR69, bit 7 = 1
+ * to use MM streams processor registers to control primary stream.
+ */
+ OUTREG8(CRT_ADDRESS_REG,0x69);
+ byte = INREG8(CRT_DATA_REG) | 0x80;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ OUTREG32(0x8128, 0xFFFFFFFFL);
+ OUTREG32(0x812C, 0xFFFFFFFFL);
+
+ OUTREG32(S3_BCI_GLB_BD_HIGH, bci_enable | S3_LITTLE_ENDIAN | S3_BD64);
+
+
+ /* CR50, bit 7,6,0 = 111, Use GBD.*/
+ OUTREG8(CRT_ADDRESS_REG,0x50);
+ byte = INREG8(CRT_DATA_REG) | 0xC1;
+ OUTREG8(CRT_DATA_REG, byte);
+
+ /*
+ * if MS1NB style linear tiling mode.
+ * bit MM850C[15] = 0 select NB linear tile mode.
+ * bit MM850C[15] = 1 select MS-1 128-bit non-linear tile mode.
+ */
+ ulTmp = INREG32(ADVANCED_FUNC_CTRL) | 0x8000; /* use MS-s style tile mode*/
+ OUTREG32(ADVANCED_FUNC_CTRL,ulTmp);
+
+ /*
+ * Set up Tiled Surface Registers
+ * Bit 25:20 - Surface width in tiles.
+ * Bit 29 - Y Range Flag.
+ * Bit 31:30 = 00, 4 bpp.
+ * = 01, 8 bpp.
+ * = 10, 16 bpp.
+ * = 11, 32 bpp.
+ */
+ /*
+ * Global Bitmap Descriptor Register MM816C
+ * bit 24~25: tile format
+ * 00: linear
+ * 01: reserved
+ * 10: 16 bpp tiles
+ * 11: 32 bpp tiles
+ * bit 28: block write disable/enable
+ * 0: enable
+ * 1: disable
+ */
+ if (!psav->bTiled) {
+ /*
+ * Do not enable block_write even for non-tiling modes, because
+ * the driver cannot determine if the memory type is the certain
+ * type of SGRAM for which block_write can be used.
+ */
+ psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ psav->GlobalBD.bd1.HighPart.ResBWTile = tile16; /* 16 bpp/destination tiling format */
+
+ ulTmp = (((pScrn->virtualX + 0x3F) & 0x0000FFC0) >> 6) << 20;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16);
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ psav->GlobalBD.bd1.HighPart.ResBWTile = tile32; /* 32 bpp/destination tiling format */
+
+ ulTmp = ( ((pScrn->virtualX + 0x1F) & 0x0000FFE0) >> 5) << 20;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32);
+ }
+
+ psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write - was 0 */
+ /* HW uses width */
+ psav->GlobalBD.bd1.HighPart.Stride = (unsigned short) psav->lDelta / (pScrn->bitsPerPixel >> 3);
+ psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
+ psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
/*
@@ -891,9 +1048,7 @@ void SavageSetGBD_PM(ScrnInfoPtr pScrn)
unsigned char byte;
int bci_enable, tile16, tile32;
- /* Is supersavage like savage4 or twister?
- * change the bci_enable and tile bits here.
- */
+
bci_enable = BCI_ENABLE_TWISTER;
tile16 = TILE_DESTINATION;
tile32 = TILE_DESTINATION;
@@ -1096,6 +1251,135 @@ void SavageSetGBD_PM(ScrnInfoPtr pScrn)
OUTREG8(SEQ_DATA_REG,byte);
}
+void SavageSetGBD_2000(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ unsigned long ulTmp;
+ unsigned char byte;
+ int bci_enable, tile16, tile32;
+
+ bci_enable = BCI_ENABLE_TWISTER;
+ tile16 = TILE_DESTINATION;
+ tile32 = TILE_DESTINATION;
+
+
+ /* following is the enable case */
+
+ /* SR01:turn off screen */
+ OUTREG8 (SEQ_ADDRESS_REG,0x01);
+ byte = INREG8(SEQ_DATA_REG) | 0x20;
+ OUTREG8(SEQ_DATA_REG,byte);
+
+ /*
+ * 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 to control the primary streams
+ */
+
+ OUTREG8(CRT_ADDRESS_REG,0x67);
+ byte = INREG8(CRT_DATA_REG) | 0x08;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ /*
+ * 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);
+
+ /*
+ * Program Primary Stream Stride Register.
+ *
+ * Tell engine if tiling on or off, set primary stream stride, and
+ * if tiling, set tiling bits/pixel and primary stream tile offset.
+ * Note that tile offset (bits 16 - 29) must be scanline width in
+ * bytes/128bytespertile * 256 Qwords/tile. This is equivalent to
+ * lDelta * 2. Remember that if tiling, lDelta is screenwidth in
+ * bytes padded up to an even number of tilewidths.
+ */
+ if (!psav->bTiled) {
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
+ (psav->lDelta & 0x00001fff));
+ } else if (pScrn->bitsPerPixel == 16) {
+ /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0x80000000 | (psav->lDelta & 0x00001fff));
+ } else if (pScrn->bitsPerPixel == 32) {
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0xC0000000 | (psav->lDelta & 0x00001fff));
+ }
+
+ /* MM81C0 and 81C4 are used to control primary stream. */
+ OUTREG32(PRI_STREAM_FBUF_ADDR0,pScrn->fbOffset);
+ OUTREG32(PRI_STREAM_FBUF_ADDR1,0x80000000);
+
+ OUTREG32(0x8128, 0xFFFFFFFFL);
+ OUTREG32(0x812C, 0xFFFFFFFFL);
+
+ /* bit 28:block write disable */
+ OUTREG32(S3_GLB_BD_HIGH, bci_enable | S3_BD64 | 0x10000000);
+
+ /* CR50, bit 7,6,0 = 111, Use GBD.*/
+ OUTREG8(CRT_ADDRESS_REG,0x50);
+ byte = INREG8(CRT_DATA_REG) | 0xC1;
+ OUTREG8(CRT_DATA_REG, byte);
+
+ if (!psav->bTiled) {
+ /*
+ * Do not enable block_write even for non-tiling modes, because
+ * the driver cannot determine if the memory type is the certain
+ * type of SGRAM for which block_write can be used.
+ */
+ psav->GlobalBD.bd1.HighPart.ResBWTile = TILE_FORMAT_LINEAR;/* linear */
+
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ psav->GlobalBD.bd1.HighPart.ResBWTile = tile16;/* tile format destination */
+ ulTmp = (((pScrn->virtualX + 0x3f) & 0x0000ffc0) >> 6) << 20;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16 | (pScrn->fbOffset>>6));
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ psav->GlobalBD.bd1.HighPart.ResBWTile = tile32;/* tile format destination */
+ ulTmp = (((pScrn->virtualX + 0x1f) & 0x0000ffe0) >> 5) << 20;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32 | (pScrn->fbOffset>>6));
+ }
+
+ psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write */
+ /* HW uses width */
+ psav->GlobalBD.bd1.HighPart.Stride = (unsigned short)(psav->lDelta / (pScrn->bitsPerPixel >> 3));
+ psav->GlobalBD.bd1.HighPart.Bpp = (unsigned char) (pScrn->bitsPerPixel);
+ psav->GlobalBD.bd1.Offset = pScrn->fbOffset;
+
+ /*
+ * CR31, bit 0 = 0, Disable address offset bits(CR6A_6-0).
+ * bit 0 = 1, Enable 8 Mbytes of display memory thru 64K window
+ * at A000:0.
+ */
+ OUTREG8(CRT_ADDRESS_REG,MEMORY_CONFIG_REG);
+ byte = INREG8(CRT_DATA_REG) & (~(ENABLE_CPUA_BASE_A0000));
+ OUTREG8(CRT_DATA_REG,byte);
+
+ /* program the GBD and SBDs */
+ OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
+ OUTREG32(S3_GLB_BD_HIGH,(psav->GlobalBD.bd2.HiPart
+ | bci_enable | S3_LITTLE_ENDIAN | 0x10000000 | S3_BD64));
+ OUTREG32(S3_PRI_BD_LOW,psav->GlobalBD.bd2.LoPart);
+ OUTREG32(S3_PRI_BD_HIGH,psav->GlobalBD.bd2.HiPart);
+ OUTREG32(S3_SEC_BD_LOW,psav->GlobalBD.bd2.LoPart);
+ OUTREG32(S3_SEC_BD_HIGH,psav->GlobalBD.bd2.HiPart);
+
+ /* turn on screen */
+ OUTREG8(SEQ_ADDRESS_REG,0x01);
+ byte = INREG8(SEQ_DATA_REG) & ~0x20;
+ OUTREG8(SEQ_DATA_REG,byte);
+}
+
static
void SavageRestoreAccelState(ScrnInfoPtr pScrn)
{
diff --git a/src/savage_driver.c b/src/savage_driver.c
index d99b16a..012c0ee 100644
--- a/src/savage_driver.c
+++ b/src/savage_driver.c
@@ -1177,55 +1177,6 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->NoAccel = TRUE;
}
- /* Set AGP Mode from config */
- /* We support 1X 2X and 4X */
-#ifdef XF86DRI
- from = X_DEFAULT;
- psav->agpMode = SAVAGE_DEFAULT_AGP_MODE;
- /*psav->agpMode = SAVAGE_MAX_AGP_MODE;*/
- psav->agpSize = 16;
-
- if (xf86GetOptValInteger(psav->Options,
- OPTION_AGP_MODE, &(psav->agpMode))) {
- if (psav->agpMode < 1) {
- psav->agpMode = 1;
- }
- if (psav->agpMode > SAVAGE_MAX_AGP_MODE) {
- psav->agpMode = SAVAGE_MAX_AGP_MODE;
- }
- if ((psav->agpMode > 2) &&
- (psav->Chipset == S3_SAVAGE3D ||
- psav->Chipset == S3_SAVAGE_MX))
- psav->agpMode = 2; /* old savages only support 2x */
- from = X_CONFIG;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, from, "Using AGP %dx mode\n",
- psav->agpMode);
-
- if (xf86GetOptValInteger(psav->Options,
- OPTION_AGP_SIZE, (int *)&(psav->agpSize))) {
- switch (psav->agpSize) {
- case 4:
- case 8:
- case 16:
- case 32:
- case 64:
- case 128:
- case 256:
- break;
- default:
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "Illegal AGP size: %d MB, defaulting to 16 MB\n", psav->agpSize);
- psav->agpSize = 16;
- }
- }
-
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using %d MB AGP aperture\n", psav->agpSize);
-
-#endif
-
/*
* The SWCursor setting takes priority over HWCursor. The default
* if neither is specified is HW, unless ShadowFB is specified,
@@ -1284,45 +1235,6 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xf86DrvMsg( pScrn->scrnIndex, X_CONFIG,
"Option: ForceInit enabled\n" );
- /* we can use Option "DisableTile TRUE" to disable tile mode */
- psav->bDisableTile = FALSE;
- if (xf86GetOptValBool(psav->Options, OPTION_DISABLE_TILE,&psav->bDisableTile)) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Option: %s Tile Mode and Program it \n",(psav->bDisableTile?"Disable":"Enable"));
- }
-
-#ifdef XF86DRI
- /* disabled by default...doesn't seem to work */
- psav->bDisableXvMC = TRUE; /* if you want to free up more mem for DRI,etc. */
- if (xf86GetOptValBool(psav->Options, OPTION_DISABLE_XVMC, &psav->bDisableXvMC)) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "Option: %s Hardware XvMC support\n",(psav->bDisableXvMC?"Disable":"Enable"));
- }
-#endif
-
- 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"));
- }
- if (psav->Chipset == S3_PROSAVAGE ||
- psav->Chipset == S3_TWISTER ||
- psav->Chipset == S3_PROSAVAGEDDR)
- psav->BCIforXv = TRUE;
- else
- 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?"Enable":"Disable"));
- }
- psav->dvi = FALSE;
- if (xf86GetOptValBool(psav->Options, OPTION_DVI, &psav->dvi)) {
- xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
- "%s DVI port support (Savage4 only)\n",(psav->dvi?"Force":"Disable"));
- }
-
- /* Add more options here. */
-
if (pScrn->numEntities > 1) {
SavageFreeRec(pScrn);
return FALSE;
@@ -1385,6 +1297,99 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
xfree(pEnt);
+ /* Set AGP Mode from config */
+ /* We support 1X 2X and 4X */
+#ifdef XF86DRI
+ from = X_DEFAULT;
+ psav->agpMode = SAVAGE_DEFAULT_AGP_MODE;
+ /*psav->agpMode = SAVAGE_MAX_AGP_MODE;*/
+ psav->agpSize = 16;
+
+ if (xf86GetOptValInteger(psav->Options,
+ OPTION_AGP_MODE, &(psav->agpMode))) {
+ if (psav->agpMode < 1) {
+ psav->agpMode = 1;
+ }
+ if (psav->agpMode > SAVAGE_MAX_AGP_MODE) {
+ psav->agpMode = SAVAGE_MAX_AGP_MODE;
+ }
+ if ((psav->agpMode > 2) &&
+ (psav->Chipset == S3_SAVAGE3D ||
+ psav->Chipset == S3_SAVAGE_MX))
+ psav->agpMode = 2; /* old savages only support 2x */
+ from = X_CONFIG;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "Using AGP %dx mode\n",
+ psav->agpMode);
+
+ if (xf86GetOptValInteger(psav->Options,
+ OPTION_AGP_SIZE, (int *)&(psav->agpSize))) {
+ switch (psav->agpSize) {
+ case 4:
+ case 8:
+ case 16:
+ case 32:
+ case 64:
+ case 128:
+ case 256:
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Illegal AGP size: %d MB, defaulting to 16 MB\n", psav->agpSize);
+ psav->agpSize = 16;
+ }
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d MB AGP aperture\n", psav->agpSize);
+
+#endif
+
+ /* we can use Option "DisableTile TRUE" to disable tile mode */
+ /* savage2000 tile mode is broken. I suspect it uses different tile sizes from other savages */
+ if (psav->Chipset == S3_SAVAGE2000)
+ psav->bDisableTile = TRUE;
+ else
+ psav->bDisableTile = FALSE;
+ if (xf86GetOptValBool(psav->Options, OPTION_DISABLE_TILE,&psav->bDisableTile)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Option: %s Tile Mode and Program it \n",(psav->bDisableTile?"Disable":"Enable"));
+ }
+
+#ifdef XF86DRI
+ /* disabled by default...doesn't seem to work */
+ psav->bDisableXvMC = TRUE; /* if you want to free up more mem for DRI,etc. */
+ if (xf86GetOptValBool(psav->Options, OPTION_DISABLE_XVMC, &psav->bDisableXvMC)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "Option: %s Hardware XvMC support\n",(psav->bDisableXvMC?"Disable":"Enable"));
+ }
+#endif
+
+ 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"));
+ }
+ if (psav->Chipset == S3_PROSAVAGE ||
+ psav->Chipset == S3_TWISTER ||
+ psav->Chipset == S3_PROSAVAGEDDR)
+ psav->BCIforXv = TRUE;
+ else
+ 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?"Enable":"Disable"));
+ }
+ psav->dvi = FALSE;
+ if (xf86GetOptValBool(psav->Options, OPTION_DVI, &psav->dvi)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_CONFIG,
+ "%s DVI port support (Savage4 only)\n",(psav->dvi?"Force":"Disable"));
+ }
+
+ /* Add more options here. */
+
+
psav = SAVPTR(pScrn);
psav->IsSecondary = FALSE;
psav->IsPrimary = FALSE;
@@ -1805,8 +1810,8 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
i = xf86ValidateModes(pScrn, pScrn->monitor->Modes,
pScrn->display->modes, clockRanges, NULL,
- 256, 4096, 16 * pScrn->bitsPerPixel,
- 128, 4096,
+ 256, 4095, 16 * pScrn->bitsPerPixel,
+ 128, 4095,
pScrn->virtualX, pScrn->virtualY,
psav->videoRambytes, LOOKUP_BEST_REFRESH);
@@ -3640,6 +3645,9 @@ SavageDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int crtc2)
OUTREG32(PRI_STREAM2_FBUF_ADDR0, ((address & 0xFFFFFFF8) | 0x80000000));
OUTREG32(PRI_STREAM2_FBUF_ADDR1, address & 0xFFFFFFF8);
}
+ } else if (psav->Chipset == S3_SAVAGE2000) {
+ OUTREG32(PRI_STREAM_FBUF_ADDR0, 0x80000000);
+ OUTREG32(PRI_STREAM_FBUF_ADDR1, address & 0xFFFFFFF8);
} else {
OUTREG32(PRI_STREAM_FBUF_ADDR0,address | 0xFFFFFFFC);
OUTREG32(PRI_STREAM_FBUF_ADDR1,address | 0x80000000);
@@ -4145,7 +4153,6 @@ SavageResetStreams(ScrnInfoPtr pScrn)
/* disable streams */
switch (psav->Chipset) {
- case S3_SAVAGE3D:
case S3_SAVAGE_MX:
case S3_SUPERSAVAGE:
OUTREG32(PRI_STREAM_STRIDE,0);
@@ -4161,11 +4168,11 @@ SavageResetStreams(ScrnInfoPtr pScrn)
cr67 &= ~0x02; /* CR67[1] = 1 : enable stream 2 */
OUTREG8(CRT_DATA_REG, cr67);
break;
+ case S3_SAVAGE3D:
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);
@@ -4178,6 +4185,17 @@ SavageResetStreams(ScrnInfoPtr pScrn)
cr69 &= ~0x80; /* CR69[0] = 1 : Mem-mapped regs */
OUTREG8(CRT_DATA_REG, cr69);
break;
+ case S3_SAVAGE2000:
+ OUTREG32(PRI_STREAM_STRIDE,0);
+ OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000);
+ OUTREG32(PRI_STREAM_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;
default:
break;
}
diff --git a/src/savage_streams.c b/src/savage_streams.c
index 1b865aa..f29623a 100644
--- a/src/savage_streams.c
+++ b/src/savage_streams.c
@@ -302,6 +302,48 @@ SavageInitStreamsNew(ScrnInfoPtr pScrn)
}
}
+static void
+SavageInitStreams2000(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ /*unsigned long jDelta;*/
+
+ xf86ErrorFVerb(STREAMS_TRACE, "SavageInitStreams\n" );
+
+ OUTREG(PRI_STREAM_BUFFERSIZE,
+ pScrn->virtualX * pScrn->virtualY * (pScrn->bitsPerPixel >> 3));
+
+ if (psav->FBStart2nd) {
+ unsigned long jDelta = pScrn->displayWidth;
+ OUTREG( PRI_STREAM_BUFFERSIZE, jDelta * pScrn->virtualY >> 3 );
+ OUTREG( PRI_STREAM_FBUF_ADDR0, pScrn->fbOffset );
+ OUTREG( PRI_STREAM_STRIDE, jDelta );
+ }
+
+
+ OUTREG( SEC_STREAM_CKEY_LOW, 0 );
+ OUTREG( SEC_STREAM_CKEY_UPPER, 0 );
+ OUTREG( SEC_STREAM_HSCALING, 0 );
+ OUTREG( SEC_STREAM_VSCALING, 0 );
+ OUTREG( BLEND_CONTROL, 0 );
+ OUTREG( SEC_STREAM_FBUF_ADDR0, 0 );
+ OUTREG( SEC_STREAM_FBUF_ADDR1, 0 );
+ OUTREG( SEC_STREAM_FBUF_ADDR2, 0 );
+ OUTREG( SEC_STREAM_WINDOW_START, 0 );
+ OUTREG( SEC_STREAM_WINDOW_SZ, 0 );
+/* OUTREG( SEC_STREAM_BUFFERSIZE, 0 ); */
+ OUTREG( SEC_STREAM_TILE_OFF, 0 );
+ OUTREG( SEC_STREAM_OPAQUE_OVERLAY, 0 );
+ OUTREG( SEC_STREAM_STRIDE, 0 );
+
+ /* These values specify brightness, contrast, saturation and hue. */
+ OUTREG( SEC_STREAM_COLOR_CONVERT0_2000, 0x0000C892 );
+ OUTREG( SEC_STREAM_COLOR_CONVERT1_2000, 0x00033400 );
+ OUTREG( SEC_STREAM_COLOR_CONVERT2_2000, 0x000001CF );
+ OUTREG( SEC_STREAM_COLOR_CONVERT3_2000, 0x01F1547E );
+
+}
+
/*
* Function to get lcd factor, display offset for overlay use
* Input: pScrn; Output: x,yfactor, displayoffset in pScrn
@@ -465,8 +507,7 @@ SavageStreamsOn(ScrnInfoPtr pScrn)
VGAOUT8( vgaCRIndex, EXT_MISC_CTRL2 );
- if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
- (psav->Chipset == S3_SAVAGE2000) )
+ if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) )
{
SavageInitStreamsNew( pScrn );
@@ -517,6 +558,22 @@ SavageStreamsOn(ScrnInfoPtr pScrn)
#endif
}
}
+ else if (psav->Chipset == S3_SAVAGE2000)
+ {
+ SavageInitStreams2000( pScrn );
+
+ jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAM1;
+
+ /* Wait for VBLANK. */
+ VerticalRetraceWait();
+ /* Fire up streams! */
+ VGAOUT16( vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2 );
+ /* These values specify brightness, contrast, saturation and hue. */
+ OUTREG( SEC_STREAM_COLOR_CONVERT0_2000, 0x0000C892 );
+ OUTREG( SEC_STREAM_COLOR_CONVERT1_2000, 0x00033400 );
+ OUTREG( SEC_STREAM_COLOR_CONVERT2_2000, 0x000001CF );
+ OUTREG( SEC_STREAM_COLOR_CONVERT3_2000, 0x01F1547E );
+ }
else
{
jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAMS_OLD;
diff --git a/src/savage_streams.h b/src/savage_streams.h
index 2799ca5..8991109 100644
--- a/src/savage_streams.h
+++ b/src/savage_streams.h
@@ -192,6 +192,11 @@
/* Secondary Stream 2 Opaque Overlay Control */
#define SEC_STREAM2_OPAQUE_OVERLAY 0x8180
+/* savage 2000 */
+#define SEC_STREAM_COLOR_CONVERT0_2000 0x8198
+#define SEC_STREAM_COLOR_CONVERT1_2000 0x819c
+#define SEC_STREAM_COLOR_CONVERT2_2000 0x81e0
+#define SEC_STREAM_COLOR_CONVERT3_2000 0x81e4
#define BASE_PAD 0xf
diff --git a/src/savage_video.c b/src/savage_video.c
index 7e4b22c..43de050 100644
--- a/src/savage_video.c
+++ b/src/savage_video.c
@@ -38,10 +38,12 @@ void SavageResetVideo(ScrnInfoPtr pScrn);
static void SavageSetColorKeyOld(ScrnInfoPtr pScrn);
static void SavageSetColorKeyNew(ScrnInfoPtr pScrn);
+static void SavageSetColorKey2000(ScrnInfoPtr pScrn);
static void (*SavageSetColorKey)(ScrnInfoPtr pScrn) = NULL;
static void SavageSetColorOld(ScrnInfoPtr pScrn );
static void SavageSetColorNew(ScrnInfoPtr pScrn );
+static void SavageSetColor2000(ScrnInfoPtr pScrn );
static void (*SavageSetColor)(ScrnInfoPtr pScrn ) = NULL;
static void SavageDisplayVideoOld(
@@ -60,6 +62,14 @@ static void SavageDisplayVideoNew(
short src_w, short src_h,
short drw_w, short drw_h
);
+static void SavageDisplayVideo2000(
+ ScrnInfoPtr pScrn, int id, int offset,
+ short width, short height, int pitch,
+ int x1, int y1, int x2, int y2,
+ BoxPtr dstBox,
+ short src_w, short src_h,
+ short drw_w, short drw_h
+);
static void (*SavageDisplayVideo)(
ScrnInfoPtr pScrn, int id, int offset,
short width, short height, int pitch,
@@ -235,8 +245,7 @@ SavageClipVWindow(ScrnInfoPtr pScrn)
SavagePtr psav = SAVPTR(pScrn);
if( (psav->Chipset == S3_SAVAGE_MX) ||
- (psav->Chipset == S3_SUPERSAVAGE) ||
- (psav->Chipset == S3_SAVAGE2000) ) {
+ (psav->Chipset == S3_SUPERSAVAGE) ) {
if (psav->IsSecondary) {
OUTREG(SEC_STREAM2_WINDOW_SZ, 0);
} else if (psav->IsPrimary) {
@@ -247,6 +256,8 @@ SavageClipVWindow(ScrnInfoPtr pScrn)
OUTREG(SEC_STREAM2_WINDOW_SZ, 0);
#endif
}
+ } else if (psav->Chipset == S3_SAVAGE2000) {
+ OUTREG(SEC_STREAM_WINDOW_SZ, 0);
} else {
OUTREG( SSTREAM_WINDOW_SIZE_REG, 1);
OUTREG( SSTREAM_WINDOW_START_REG, 0x03ff03ff);
@@ -262,8 +273,7 @@ void SavageInitVideo(ScreenPtr pScreen)
int num_adaptors;
xf86ErrorFVerb(XVTRACE,"SavageInitVideo\n");
- if (S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
- (psav->Chipset == S3_SAVAGE2000))
+ if (S3_SAVAGE_MOBILE_SERIES(psav->Chipset))
{
newAdaptor = SavageSetupImageVideo(pScreen);
SavageInitOffscreenImages(pScreen);
@@ -272,12 +282,20 @@ void SavageInitVideo(ScreenPtr pScreen)
SavageSetColorKey = SavageSetColorKeyNew;
SavageDisplayVideo = SavageDisplayVideoNew;
}
+ else if (psav->Chipset == S3_SAVAGE2000)
+ {
+ newAdaptor = SavageSetupImageVideo(pScreen);
+ SavageInitOffscreenImages(pScreen);
+
+ SavageSetColor = SavageSetColor2000;
+ SavageSetColorKey = SavageSetColorKey2000;
+ SavageDisplayVideo = SavageDisplayVideo2000;
+ }
else
{
newAdaptor = SavageSetupImageVideo(pScreen);
SavageInitOffscreenImages(pScreen);
- /*DELETENEXTLINE*/
- /* Since newAdaptor is still NULL, these are still disabled for now. */
+
SavageSetColor = SavageSetColorOld;
SavageSetColorKey = SavageSetColorKeyOld;
SavageDisplayVideo = SavageDisplayVideoOld;
@@ -512,6 +530,55 @@ void SavageSetColorKeyNew(ScrnInfoPtr pScrn)
}
}
+void SavageSetColorKey2000(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr;
+ int red, green, blue;
+
+ /* Here, we reset the colorkey and all the controls. */
+
+ red = (pPriv->colorKey & pScrn->mask.red) >> pScrn->offset.red;
+ green = (pPriv->colorKey & pScrn->mask.green) >> pScrn->offset.green;
+ blue = (pPriv->colorKey & pScrn->mask.blue) >> pScrn->offset.blue;
+
+ if( !pPriv->colorKey ) {
+ OUTREG( SEC_STREAM_CKEY_LOW, 0 );
+ OUTREG( SEC_STREAM_CKEY_UPPER, 0 );
+ OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 ));
+ }
+ else {
+ switch (pScrn->depth) {
+ case 8:
+ OUTREG( SEC_STREAM_CKEY_LOW,
+ 0x47000000 | (pPriv->colorKey & 0xFF) );
+ OUTREG( SEC_STREAM_CKEY_UPPER,
+ 0x47000000 | (pPriv->colorKey & 0xFF) );
+ break;
+ case 15:
+ OUTREG( SEC_STREAM_CKEY_LOW,
+ 0x45000000 | (red<<19) | (green<<11) | (blue<<3) );
+ OUTREG( SEC_STREAM_CKEY_UPPER,
+ 0x45000000 | (red<<19) | (green<<11) | (blue<<3) );
+ break;
+ case 16:
+ OUTREG( SEC_STREAM_CKEY_LOW,
+ 0x46000000 | (red<<19) | (green<<10) | (blue<<3) );
+ OUTREG( SEC_STREAM_CKEY_UPPER,
+ 0x46020002 | (red<<19) | (green<<10) | (blue<<3) );
+ break;
+ case 24:
+ OUTREG( SEC_STREAM_CKEY_LOW,
+ 0x47000000 | (red<<16) | (green<<8) | (blue) );
+ OUTREG( SEC_STREAM_CKEY_UPPER,
+ 0x47000000 | (red<<16) | (green<<8) | (blue) );
+ break;
+ }
+
+ /* We assume destination colorkey */
+ OUTREG( BLEND_CONTROL, (INREG32(BLEND_CONTROL) | (psav->blendBase << 9) | 0x08 ));
+ }
+}
void SavageSetColorOld( ScrnInfoPtr pScrn )
{
@@ -623,6 +690,61 @@ void SavageSetColorNew( ScrnInfoPtr pScrn )
}
}
+void SavageSetColor2000( ScrnInfoPtr pScrn )
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr;
+
+ /* Brightness/contrast/saturation/hue computations. */
+
+ double k, dk1, dk2, dk3, dk4, dk5, dk6, dk7, dkb;
+ int k1, k2, k3, k4, k5, k6, k7, kb;
+ double s = pPriv->saturation / 128.0;
+ double h = pPriv->hue * 0.017453292;
+ unsigned long assembly1, assembly2, assembly3, assembly4;
+
+ xf86ErrorFVerb(XVTRACE, "bright %d, contrast %d, saturation %d, hue %d\n",
+ pPriv->brightness, (int)pPriv->contrast, (int)pPriv->saturation, pPriv->hue );
+
+ if( psav->videoFourCC == FOURCC_Y211 )
+ k = 1.0;/* YUV */
+ else
+ k = 1.14;/* YCrCb */
+
+
+ dk1 = 128 * k * pPriv->contrast;
+ dk2 = 64.0 * 1.371 * k * s * cos(h);
+ dk3 = -64.0 * 1.371 * k * s * sin(h);
+ dk4 = -128.0 * k * s * (0.698 * cos(h) - 0.336 * sin(h));
+ dk5 = -128.0 * k * s * (0.698 * sin(h) + 0.336 * cos(h));
+ dk6 = 64.0 * 1.732 * k * s * sin(h);/* == k3 / 1.26331, right? */
+ dk7 = 64.0 * 1.732 * k * s * cos(h);/* == k2 / -1.26331, right? */
+ dkb = 128.0 * pPriv->brightness + 0.5;
+ if( psav->videoFourCC != FOURCC_Y211 )
+ dkb = 128 * (pPriv->brightness * k * pPriv->contrast + 0.5);
+
+ k1 = (int)(dk1 /*+0.5*/) & 0x1ff;
+ k2 = (int)(dk2 /*+0.5*/) & 0x1ff;
+ assembly1 = (k2<<16) | k1;
+
+ k3 = (int)(dk3 /*+0.5*/) & 0x1ff;
+ k4 = (int)(dk4 /*+0.5*/) & 0x1ff;
+ assembly2 = (k4<<16) | k3;
+
+ k5 = (int)(dk5 /*+0.5*/) & 0x1ff;
+ k6 = (int)(dk6 /*+0.5*/) & 0x1ff;
+ assembly3 = (k6<<16) | k5;
+
+ k7 = (int)(dk7 /*+0.5*/) & 0x1ff;
+ kb = (int)(dkb /*+0.5*/) & 0xffff;
+ assembly4 = (kb<<16) | k7;
+
+ OUTREG( SEC_STREAM_COLOR_CONVERT0_2000, assembly1 );
+ OUTREG( SEC_STREAM_COLOR_CONVERT1_2000, assembly2 );
+ OUTREG( SEC_STREAM_COLOR_CONVERT2_2000, assembly3 );
+ OUTREG( SEC_STREAM_COLOR_CONVERT3_2000, assembly4 );
+
+}
void SavageResetVideo(ScrnInfoPtr pScrn)
{
@@ -678,6 +800,7 @@ SavageSetupImageVideo(ScreenPtr pScreen)
xvColorKey = MAKE_ATOM("XV_COLORKEY");
xvHue = MAKE_ATOM("XV_HUE");
xvSaturation = MAKE_ATOM("XV_SATURATION");
+ /* interpolation option only available on "old" streams */
xvInterpolation = MAKE_ATOM("XV_VERTICAL_INTERPOLATION");
pPriv->colorKey =
@@ -1287,32 +1410,18 @@ SavageDisplayVideoNew(
/* Calculate horizontal and vertical scale factors. */
- if( psav->Chipset == S3_SAVAGE2000 )
- {
- OUTREG(SEC_STREAM_HSCALING,
- (65536 * src_w / drw_w) & 0x1FFFFF );
- if( src_w < drw_w )
- OUTREG(SEC_STREAM_HSCALE_NORMALIZE,
- ((2048 * src_w / drw_w) & 0x7ff) << 16 );
- else
- OUTREG(SEC_STREAM_HSCALE_NORMALIZE, 2048 << 16 );
- OUTREG(SEC_STREAM_VSCALING,
- (65536 * src_h / drw_h) & 0x1FFFFF );
- }
- else
- {
- if ( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) &&
+ if ( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) &&
(psav->DisplayType == MT_LCD) &&
!psav->CrtOnly &&
!psav->TvOn)
- {
- drw_w = (drw_w * psav->XExp1)/psav->XExp2 + 1;
- drw_h = (drw_h * psav->YExp1)/psav->YExp2 + 1;
- dstBox->x1 = (dstBox->x1 * psav->XExp1)/psav->XExp2;
- dstBox->y1 = (dstBox->y1 * psav->YExp1)/psav->YExp2;
- dstBox->x1 += psav->displayXoffset;
- dstBox->y1 += psav->displayYoffset;
- }
+ {
+ drw_w = (drw_w * psav->XExp1)/psav->XExp2 + 1;
+ drw_h = (drw_h * psav->YExp1)/psav->YExp2 + 1;
+ dstBox->x1 = (dstBox->x1 * psav->XExp1)/psav->XExp2;
+ dstBox->y1 = (dstBox->y1 * psav->YExp1)/psav->YExp2;
+ dstBox->x1 += psav->displayXoffset;
+ dstBox->y1 += psav->displayYoffset;
+ }
if (psav->IsSecondary) {
OUTREG(SEC_STREAM2_HSCALING,
@@ -1340,7 +1449,6 @@ SavageDisplayVideoNew(
((src_h&0xfff)<<20) | ((65536 * src_h / drw_h) & 0x1FFFF ));
#endif
}
- }
/*
* Set surface location and stride. We use x1>>15 because all surfaces
@@ -1400,6 +1508,82 @@ SavageDisplayVideoNew(
}
}
+static void
+SavageDisplayVideo2000(
+ ScrnInfoPtr pScrn,
+ int id,
+ int offset,
+ short width, short height,
+ int pitch,
+ int x1, int y1, int x2, int y2,
+ BoxPtr dstBox,
+ short src_w, short src_h,
+ short drw_w, short drw_h
+){
+ SavagePtr psav = SAVPTR(pScrn);
+ vgaHWPtr hwp = VGAHWPTR(pScrn);
+ /*DisplayModePtr mode = pScrn->currentMode;*/
+ SavagePortPrivPtr pPriv = psav->adaptor->pPortPrivates[0].ptr;
+ int vgaCRIndex, vgaCRReg, vgaIOBase;
+
+
+ vgaIOBase = hwp->IOBase;
+ vgaCRIndex = vgaIOBase + 4;
+ vgaCRReg = vgaIOBase + 5;
+
+ if ( psav->videoFourCC != id ) {
+ SavageSetBlend(pScrn,id);
+ SavageResetVideo(pScrn);
+ }
+
+ /* Calculate horizontal and vertical scale factors. */
+
+ OUTREG(SEC_STREAM_HSCALING,
+ (65536 * src_w / drw_w) & 0x1FFFFF );
+
+ if( src_w < drw_w )
+ OUTREG(SEC_STREAM_HSCALE_NORMALIZE,
+ ((2048 * src_w / drw_w) & 0x7ff) << 16 );
+ else
+ OUTREG(SEC_STREAM_HSCALE_NORMALIZE, 2048 << 16 );
+
+ OUTREG(SEC_STREAM_VSCALING,
+ (65536 * src_h / drw_h) & 0x1FFFFF );
+
+ /*
+ * Set surface location and stride. We use x1>>15 because all surfaces
+ * are 2 bytes/pixel.
+ */
+
+ OUTREG(SEC_STREAM_FBUF_ADDR0, (offset + (x1>>15))
+ & (0x7ffffff & ~BASE_PAD));
+ OUTREG(SEC_STREAM_STRIDE, pitch & 0xfff );
+ OUTREG(SEC_STREAM_WINDOW_START, ((dstBox->x1+1) << 16) | (dstBox->y1+1) );
+ OUTREG(SEC_STREAM_WINDOW_SZ, ((dstBox->x2-dstBox->x1) << 16)
+ | (dstBox->x2-dstBox->x1) );
+
+#if 0
+ /* Set color key on primary. */
+
+ SavageSetColor2000( pScrn );
+#endif
+
+ /* Set FIFO L2 on second stream. */
+ /* Is CR92 shadowed for crtc2? -- AGD */
+ if( pPriv->lastKnownPitch != pitch )
+ {
+ unsigned char cr92;
+
+ pPriv->lastKnownPitch = pitch;
+ pitch = (pitch + 7) / 8 - 4;
+ VGAOUT8(vgaCRIndex, 0x92);
+ cr92 = VGAIN8(vgaCRReg);
+ VGAOUT8(vgaCRReg, (cr92 & 0x40) | (pitch >> 8) | 0x80);
+ VGAOUT8(vgaCRIndex, 0x93);
+ VGAOUT8(vgaCRReg, pitch);
+ }
+}
+
static int
SavagePutImage(
ScrnInfoPtr pScrn,