summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/savage_accel.c1000
-rw-r--r--src/savage_bci.h38
-rw-r--r--src/savage_cursor.c11
-rw-r--r--src/savage_dri.c1
-rw-r--r--src/savage_driver.c833
-rw-r--r--src/savage_driver.h189
-rw-r--r--src/savage_regs.h208
-rw-r--r--src/savage_streams.c137
-rw-r--r--src/savage_streams.h32
-rw-r--r--src/savage_video.c182
10 files changed, 2363 insertions, 268 deletions
diff --git a/src/savage_accel.c b/src/savage_accel.c
index 680ae1e..2c13f14 100644
--- a/src/savage_accel.c
+++ b/src/savage_accel.c
@@ -11,6 +11,7 @@
*
* Created 20/03/97 by Sebastien Marineau for 3.3.6
* Modified 17-Nov-2000 by Tim Roberts for 4.0.1
+ * Modified Feb-2004 by Alex Deucher - integrating DRI support
* Revision:
*
*/
@@ -25,6 +26,11 @@
#include "savage_bci.h"
#include "savage_streams.h"
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "savage_dri.h"
+#endif
+
/* Forward declaration of functions used in the driver */
static void SavageSetupForScreenToScreenCopy(
@@ -209,6 +215,11 @@ unsigned long readfb( unsigned long addr );
unsigned long writefb( unsigned long addr, unsigned long value );
void writescan( unsigned long scan, unsigned long color );
+static int GetTileAperturePitch(ulong dwWidth, ulong dwBpp);
+void SavageSetGBD_M7(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
@@ -217,8 +228,29 @@ void writescan( unsigned long scan, unsigned long color );
ScrnInfoPtr gpScrn = 0;
-
-
+/*
+ * returns the aperture pitch for tiled mode.
+ * if MM850C_15 = 0 (use NB linear tile mode) the pitch is screen stride aligned to 128bytes
+ * if MM850C_15 = 1 (use MS-1 128bit non-linear tile mode),we should do it as follows
+ * we now only support the later, and don't use Y range flag,see tile surface register
+*/
+static int GetTileAperturePitch(ulong dwWidth, ulong dwBpp)
+{
+ switch (dwBpp) {
+ case 4:
+ case 8:
+ return(0x2000);
+ break;
+ case 16:
+ return(0x1000);
+ break;
+ case 32:
+ return(0x2000);
+ break;
+ default:
+ return(0x2000);
+ }
+}
void
SavageInitialize2DEngine(ScrnInfoPtr pScrn)
@@ -247,7 +279,8 @@ SavageInitialize2DEngine(ScrnInfoPtr pScrn)
/* Disable BCI */
OUTREG(0x48C18, INREG(0x48C18) & 0x3FF0);
/* Setup BCI command overflow buffer */
- OUTREG(0x48C14, (psav->cobOffset >> 11) | (psav->cobIndex << 29));
+ OUTREG(0x48C14, (psav->cobOffset >> 11) | (psav->cobIndex << 29)); /* tim */
+ /*OUTREG(S3_OVERFLOW_BUFFER, psav->cobOffset >> 11 | 0xE0000000);*/ /* S3 */
/* Program shadow status update. */
OUTREG(0x48C10, 0x78207220);
if( psav->ShadowStatus )
@@ -265,23 +298,38 @@ SavageInitialize2DEngine(ScrnInfoPtr pScrn)
break;
case S3_SAVAGE4:
+ case S3_TWISTER:
case S3_PROSAVAGE:
+ case S3_PROSAVAGEDDR:
case S3_SUPERSAVAGE:
/* Disable BCI */
OUTREG(0x48C18, INREG(0x48C18) & 0x3FF0);
- /* Program shadow status update */
- OUTREG(0x48C10, 0x00700040);
+ 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;
@@ -321,9 +369,637 @@ SavageInitialize2DEngine(ScrnInfoPtr pScrn)
SavageSetGBD(pScrn);
}
-
void
-SavageSetGBD( ScrnInfoPtr pScrn )
+SavageSetGBD(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+
+ UnProtectCRTC();
+ UnLockExtRegs();
+ VerticalRetraceWait();
+
+ psav->lDelta = pScrn->virtualX * (pScrn->bitsPerPixel >> 3);
+
+ /*
+ * we can use Option "DisableTile" "TRUE" to disable tile mode
+ * if don't disable tile,we only support tile mode under 16/32bpp
+ */
+ if ((!psav->bDisableTile) && ((pScrn->bitsPerPixel == 16) || (pScrn->bitsPerPixel == 32))) {
+ /* tileing in 16/32 BPP */
+ psav->bTiled = TRUE;
+ psav->lDelta = ((psav->lDelta + 127) >> 7) << 7;
+
+ if (psav->Chipset == S3_SAVAGE_MX || psav->Chipset == S3_SAVAGE3D)
+ psav->ulAperturePitch = 0x2000;
+ else
+ psav->ulAperturePitch = GetTileAperturePitch(pScrn->virtualX,pScrn->bitsPerPixel);
+
+ /* Use the aperture for linear screen */
+ psav->FBStart = psav->ApertureMap;
+ } else {
+ psav->bTiled = FALSE;
+ /* 32: Alignment for nontiled mode */
+ psav->lDelta = ((psav->lDelta + 31) >> 5) << 5;
+ psav->ulAperturePitch = psav->lDelta;
+ }
+
+ /* if you are using linear mode for 2D, 3D still needs to be tiled, linear AperturePitch/Delta
+ seem to be wrong for savagespan */
+ if (psav->Chipset == S3_SAVAGE_MX || psav->Chipset == S3_SAVAGE3D)
+ psav->ul3DAperturePitch = 0x2000;
+ else
+ psav->ul3DAperturePitch = GetTileAperturePitch(pScrn->virtualX,pScrn->bitsPerPixel);
+
+ psav->l3DDelta = (((pScrn->virtualX * (pScrn->bitsPerPixel >> 3)) + 127) >> 7) << 7;
+
+ psav->Bpp = pScrn->bitsPerPixel >> 3;
+ psav->cxMemory = psav->lDelta / (psav->Bpp);
+ psav->cyMemory = psav->endfb / psav->lDelta - 1;
+ /*psav->cyMemory = (psav->CursorKByte << 10) / (pScrn->displayWidth * (pScrn->bitsPerPixel / 8));*/
+ /* ??????????? */
+ if (psav->cyMemory > 2048)
+ psav->cyMemory = 2048;
+
+ /*
+ * If tiling, adjust down psav->cyMemory to the last multiple
+ * of a tileheight, so that we don't try to use partial tiles.
+ */
+ if (psav->bTiled) {
+ psav->cyMemory -= (psav->cyMemory % 16);
+ }
+
+ /*
+ * Initialization per GX-3.
+ *
+ * 1. MM48C18 - Disable BCI.
+ * 2. MM48C0C - Enable updating shadow status
+ * and initialize shadow memory address.
+ * 2b. MM48C18 - bit 1 = 1, Enable Command Buffer status updates
+ * (S3_OVERFLOW_BUFFER_PTR)
+ * 3. MM48C10 - Initialize command buffer threshold
+ * (S3_BUFFER_THRESHOLD)
+ * 4. MM48C14 - Setup command buffer offset and size
+ * (S3_OVERFLOW_BUFFER)
+ * 5. MM816C - Enable BCI.
+ * 6. MM48C40 - Setup tiled surface 0 register.
+ * 7. CR31 - bit 0 = 0, Disable address offset bits(CR6A_6-0).
+ * 8. CR50 - bit 7,6,0 = 111, Use Global Bitmap Descriptor.
+ * 9. CR88 - bit 4 = 0, Block write on (linear mode) IFF we know we
+ * have the right kind of SGRAM memory,
+ * bit 4 = 1, Block write off (always off if tiling)
+ * 10.CR69 - Bit 7 = 1, MM81C0 and 81C4 are used to control
+ * primary stream.
+ * 11.MM8128, MM812c - Setup read/write mask registers
+ * 12.MM816C, MM8168 - Set up Global Bitmap Descriptor 1 and 2.
+ */
+ switch (psav->Chipset) {
+ case S3_SAVAGE3D:
+ case S3_SAVAGE_MX:
+ SavageSetGBD_M7(pScrn);
+ break;
+ case S3_SAVAGE4:
+ case S3_TWISTER:
+ case S3_PROSAVAGE:
+ case S3_PROSAVAGEDDR:
+ SavageSetGBD_Twister(pScrn);
+ break;
+ case S3_SUPERSAVAGE:
+ SavageSetGBD_PM(pScrn);
+ break;
+ case S3_SAVAGE2000:
+ SavageSetGBD_2000(pScrn);
+ break;
+ }
+}
+
+void SavageSetGBD_Twister(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ ulong ulTmp;
+ uchar byte;
+ int bci_enable, tile16, tile32;
+
+ if (psav->Chipset == S3_SAVAGE4) {
+ bci_enable = BCI_ENABLE;
+ tile16 = TILE_FORMAT_DESTINATION16;
+ tile32 = TILE_FORMAT_DESTINATION32;
+ } else {
+ bci_enable = BCI_ENABLE_TWISTER;
+ tile16 = TILE_DESTINATION;
+ tile32 = TILE_DESTINATION;
+ }
+
+ /* 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 - twister/prosavage
+ * bit 24~25: tile format
+ * 00: linear
+ * 01: destination tiling format
+ * 10: texture tiling format
+ * 11: reserved
+ * bit 28: block write disble/enable
+ * 0: disable
+ * 1: enable
+ */
+ /*
+ * Global Bitmap Descriptor Register MM816C - savage4
+ * 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 = (ushort) psav->lDelta / (pScrn->bitsPerPixel >> 3);
+ psav->GlobalBD.bd1.HighPart.Bpp = (uchar) (pScrn->bitsPerPixel);
+ psav->GlobalBD.bd1.Offset = 0;
+
+
+ /*
+ * 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_M7(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ ulong ulTmp;
+ uchar byte;
+ int bci_enable, tile16, tile32;
+
+ bci_enable = BCI_ENABLE;
+ tile16 = TILE_FORMAT_DESTINATION16;
+ tile32 = TILE_FORMAT_DESTINATION32;
+
+
+ /* 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);
+
+ /* IGA 2 */
+ OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES);
+
+ OUTREG8(CRT_ADDRESS_REG,0x67);
+ byte = INREG8(CRT_DATA_REG) | 0x08;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
+
+ /*
+ * 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) ;
+ OUTREG8(CRT_DATA_REG,byte);
+ /*
+ * if we have 8MB of frame buffer here then we must really be a 16MB
+ * card and that means that the second device is always in the upper
+ * bank of memory (MHS)
+ */
+ if (psav->videoRambytes >= 0x800000) {
+ /* 16MB Video Memory cursor is at the end in Bank 1 */
+ 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);
+ OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000);
+ OUTREG32(PRI_STREAM2_FBUF_ADDR0,0x00000000);
+ OUTREG32(PRI_STREAM2_FBUF_ADDR1,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(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
+ (psav->lDelta & 0x00003fff));
+ OUTREG32(PRI_STREAM2_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000) |
+ (psav->lDelta & 0x00003fff));
+ } 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 & 0x00003fff));
+ OUTREG32(PRI_STREAM2_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0x80000000 | (psav->lDelta & 0x00003fff));
+
+ } else if (pScrn->bitsPerPixel == 32) {
+ OUTREG32(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0xC0000000 | (psav->lDelta & 0x00003fff));
+ OUTREG32(PRI_STREAM2_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0xC0000000 | (psav->lDelta & 0x00003fff));
+ }
+
+ 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);
+
+ /*
+ * CR78, bit 3 - Block write enabled(1)/disabled(0).
+ * bit 2 - Block write cycle time(0:2 cycles,1: 1 cycle)
+ * 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,0x78);
+ /*byte = INREG8(CRT_DATA_REG) & ~0x0C;*/
+ byte = INREG8(CRT_DATA_REG) | 0xfb;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ /*
+ * Tiled Surface 0 Registers MM48C40:
+ * bit 0~23: tile surface 0 frame buffer offset
+ * bit 24~29:tile surface 0 width
+ * bit 30~31:tile surface 0 bits/pixel
+ * 00: reserved
+ * 01, 8 bits
+ * 10, 16 Bits.
+ * 11, 32 Bits.
+ */
+ /*
+ * Global Bitmap Descriptor Register MM816C
+ * bit 24~25: tile format
+ * 00: linear
+ * 01: reserved
+ * 10: 16 bit
+ * 11: 32 bit
+ * bit 28: block write disble/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 bit */
+
+ ulTmp = ((psav->lDelta / 2) >> 6) << 24;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16);
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ psav->GlobalBD.bd1.HighPart.ResBWTile = tile32;/* 32 bit */
+
+ ulTmp = ((psav->lDelta / 4) >> 5) << 24;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32);
+ }
+
+ psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write */
+ /* HW uses width */
+ psav->GlobalBD.bd1.HighPart.Stride = (ushort)(psav->lDelta / (pScrn->bitsPerPixel >> 3));
+ psav->GlobalBD.bd1.HighPart.Bpp = (uchar) (pScrn->bitsPerPixel);
+ psav->GlobalBD.bd1.Offset = 0;
+
+
+ /*
+ * 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);
+
+ /* program the GBD and SBD's */
+ OUTREG32(S3_GLB_BD_LOW,psav->GlobalBD.bd2.LoPart );
+ /* 8: bci enable */
+ 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);
+
+ /* turn on screen */
+ OUTREG8(SEQ_ADDRESS_REG,0x01);
+ byte = INREG8(SEQ_DATA_REG) & ~0X20;
+ OUTREG8(SEQ_DATA_REG,byte);
+}
+
+void SavageSetGBD_PM(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ ulong ulTmp;
+ uchar 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;
+
+
+ /* 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);
+
+ /* IGA 2 */
+ OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA2_READS_WRITES);
+
+ OUTREG8(CRT_ADDRESS_REG,0x67);
+ byte = INREG8(CRT_DATA_REG) | 0x08;
+ OUTREG8(CRT_DATA_REG,byte);
+
+ OUTREG16(SEQ_ADDRESS_REG,SELECT_IGA1);
+
+ /*
+ * 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));
+ OUTREG32(PRI_STREAM2_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));
+ OUTREG32(PRI_STREAM2_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));
+ OUTREG32(PRI_STREAM2_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFF0000)
+ | 0xC0000000 | (psav->lDelta & 0x00001fff));
+ }
+
+ /* MM81C0 and 81C4 are used to control primary stream. */
+ /*OUTREG32(PRI_STREAM_FBUF_ADDR0,0x80000000);*/
+ OUTREG32(PRI_STREAM_FBUF_ADDR0,0x00000000);
+ OUTREG32(PRI_STREAM_FBUF_ADDR1,0x00000000);
+ /*OUTREG32(PRI_STREAM2_FBUF_ADDR0,0x80000000);*/
+ OUTREG32(PRI_STREAM2_FBUF_ADDR0,0x00000000);
+ OUTREG32(PRI_STREAM2_FBUF_ADDR1,0x00000000);
+
+ 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);
+ }
+ 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);
+ }
+
+ psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write */
+ /* HW uses width */
+ psav->GlobalBD.bd1.HighPart.Stride = (ushort)(psav->lDelta / (pScrn->bitsPerPixel >> 3));
+ psav->GlobalBD.bd1.HighPart.Bpp = (uchar) (pScrn->bitsPerPixel);
+ psav->GlobalBD.bd1.Offset = 0;
+
+ /*
+ * 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 /* AGD: shouldn't BCI be enabled? */
+ | 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);
+}
+
+void SavageSetGBD_2000(ScrnInfoPtr pScrn)
{
vgaHWPtr hwp = VGAHWPTR(pScrn);
SavagePtr psav = SAVPTR(pScrn);
@@ -331,6 +1007,9 @@ SavageSetGBD( ScrnInfoPtr pScrn )
unsigned int vgaCRReg = hwp->IOBase + 5;
unsigned long GlobalBitmapDescriptor;
+
+/* AGD: no idea how to program savage2000 GBD... for now default to Tim's method */
+
GlobalBitmapDescriptor = 1 | 8 | BCI_BD_BW_DISABLE;
BCI_BD_SET_BPP(GlobalBitmapDescriptor, pScrn->bitsPerPixel);
BCI_BD_SET_STRIDE(GlobalBitmapDescriptor, pScrn->displayWidth);
@@ -359,10 +1038,9 @@ SavageSetGBD( ScrnInfoPtr pScrn )
OUTREG(0x817C, GlobalBitmapDescriptor);
OUTREG(PRI_STREAM_STRIDE, pScrn->displayWidth * pScrn->bitsPerPixel >> 3);
- OUTREG(SEC_STREAM_STRIDE, pScrn->displayWidth * pScrn->bitsPerPixel >> 3);
+ OUTREG(SEC_STREAM_STRIDE, pScrn->displayWidth * pScrn->bitsPerPixel >> 3);
}
-
/* Acceleration init function, sets up pointers to our accelerated functions */
Bool
@@ -446,7 +1124,6 @@ SavageInitAccel(ScreenPtr pScreen)
xaaptr->Mono8x8PatternFillFlags = 0
| HARDWARE_PATTERN_PROGRAMMED_BITS
| HARDWARE_PATTERN_SCREEN_ORIGIN
- | ROP_NEEDS_SOURCE
| BIT_ORDER_IN_BYTE_MSBFIRST
;
if( psav->Chipset == S3_SAVAGE4 )
@@ -465,10 +1142,6 @@ SavageInitAccel(ScreenPtr pScreen)
* We could double the width ourselves into a reserved frame buffer
* section, but since I went 18 months with only ONE report of this
* error, it seems hardly worth the trouble.
- * Savage4 seems to have problems with 8x8 color patterns.
- * Not sending the pattern offsetsfixes the lockup but the
- * drawing problems remain.
- * Until further investigation we have to disable this.
*/
#if 0
@@ -480,8 +1153,8 @@ SavageInitAccel(ScreenPtr pScreen)
SavageSubsequentColor8x8PatternFillRect;
xaaptr->Color8x8PatternFillFlags = 0
| NO_TRANSPARENCY
- | HARDWARE_PATTERN_SCREEN_ORIGIN
- | ROP_NEEDS_SOURCE
+ | HARDWARE_PATTERN_PROGRAMMED_BITS
+ | HARDWARE_PATTERN_PROGRAMMED_ORIGIN
;
}
#endif
@@ -489,7 +1162,7 @@ SavageInitAccel(ScreenPtr pScreen)
/* Solid lines */
#if 1
- xaaptr->SolidLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
+ xaaptr->SolidLineFlags = NO_PLANEMASK;
xaaptr->SetupForSolidLine = SavageSetupForSolidFill;
xaaptr->SubsequentSolidBresenhamLine = SavageSubsequentSolidBresenhamLine;
#if 0
@@ -507,7 +1180,6 @@ SavageInitAccel(ScreenPtr pScreen)
| SCANLINE_PAD_DWORD
| BIT_ORDER_IN_BYTE_MSBFIRST
| LEFT_EDGE_CLIPPING
- | ROP_NEEDS_SOURCE
;
xaaptr->SetupForImageWrite = SavageSetupForImageWrite;
xaaptr->SubsequentImageWriteRect = SavageSubsequentImageWriteRect;
@@ -518,7 +1190,7 @@ SavageInitAccel(ScreenPtr pScreen)
/* WriteBitmap color expand */
#if 0
- xaaptr->WriteBitmapFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE;
+ xaaptr->WriteBitmapFlags = NO_PLANEMASK;
xaaptr->WriteBitmap = SavageWriteBitmapCPUToScreenColorExpand;
#endif
@@ -567,6 +1239,281 @@ SavageInitAccel(ScreenPtr pScreen)
* enabled the PIXMAP_CACHE flag, then these lines can be omitted.
*/
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled) {
+ SAVAGEDRIServerPrivatePtr pSAVAGEDRIServer = psav->DRIServerInfo;
+ BoxRec MemBox;
+ int cpp = pScrn->bitsPerPixel / 8;
+ /*int widthBytes = pScrn->displayWidth * cpp;*/
+ int widthBytes = psav->lDelta;
+ /*int widthBytes = psav->l3DDelta;*/
+ int bufferSize = ((pScrn->virtualY * widthBytes + SAVAGE_BUFFER_ALIGN)
+ & ~SAVAGE_BUFFER_ALIGN);
+ int tiledwidthBytes,tiledBufferSize;
+
+ pSAVAGEDRIServer->frontbufferSize = bufferSize;
+ /*tiledwidthBytes = psav->lDelta;*/
+ tiledwidthBytes = psav->l3DDelta;
+
+ if (cpp == 2) {
+ tiledBufferSize = ((pScrn->virtualX+63)/64)*((pScrn->virtualY+15)/16)
+ *2048;
+ } else {
+ tiledBufferSize = ((pScrn->virtualX+31)/32)*((pScrn->virtualY+15)/16)
+ *2048;
+ }
+ /*set Depth buffer to 32bpp*/
+ /*tiledwidthBytes_Z = ((pScrn->virtualX + 31)& ~0x0000001F)*4;
+ tiledBufferSize_Z = ((pScrn->virtualX+31)/32)*((pScrn->virtualY+15)/16)
+ *2048;*/
+
+ pSAVAGEDRIServer->backbufferSize = tiledBufferSize;
+ /*pSAVAGEDRIServer->depthbufferSize = tiledBufferSize_Z;*/
+ pSAVAGEDRIServer->depthbufferSize = tiledBufferSize;
+
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,
+ "virtualX:%d,virtualY:%d\n",
+ pScrn->virtualX,pScrn->virtualY);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "bpp:%d,tiledwidthBytes:%d,tiledBufferSize:%d \n",
+ pScrn->bitsPerPixel,
+ tiledwidthBytes,tiledBufferSize);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "bpp:%d,widthBytes:%d,BufferSize:%d \n",
+ pScrn->bitsPerPixel,
+ widthBytes,bufferSize);
+
+ pSAVAGEDRIServer->frontOffset = 0; /* AGD: should probably be pScrn->fbOffset */
+ pSAVAGEDRIServer->frontPitch = widthBytes;
+
+ /* Try for front, back, depth, and two framebuffers worth of
+ * pixmap cache. Should be enough for a fullscreen background
+ * image plus some leftovers.
+ */
+ /* pSAVAGEDRIServer->textureSize = psav->videoRambytes -
+ tiledBufferSize -
+ tiledBufferSize_Z -
+ -0x602000;*/
+ pSAVAGEDRIServer->textureSize = psav->videoRambytes -
+ 4096 - /* hw cursor*/
+ psav->cobSize - /*COB*/
+ bufferSize-
+ tiledBufferSize -
+ tiledBufferSize -
+ 0x200000;
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "videoRambytes:0x%08lx \n",
+ psav->videoRambytes);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "textureSize:0x%08lx \n",
+ pSAVAGEDRIServer->textureSize);
+
+ /* If that gives us less than half the available memory, let's
+ * be greedy and grab some more. Sorry, I care more about 3D
+ * performance than playing nicely, and you'll get around a full
+ * framebuffer's worth of pixmap cache anyway.
+ */
+#if 0
+ if ( pSAVAGEDRIServer->textureSize < (int)psav->FbMapSize / 2 ) {
+ pSAVAGEDRIServer->textureSize = psav->FbMapSize - 4 * bufferSize;
+ }
+#endif
+ /* Check to see if there is more room available after the maximum
+ * scanline for textures.
+ */
+#if 0
+ if ( (int)psav->FbMapSize - maxlines * widthBytes - bufferSize * 2
+ > pSAVAGEDRIServer->textureSize ) {
+ pSAVAGEDRIServer->textureSize = (psav->FbMapSize -
+ maxlines * widthBytes -
+ bufferSize * 2);
+ }
+#endif
+ /* Set a minimum usable local texture heap size. This will fit
+ * two 256x256x32bpp textures.
+ */
+ if ( pSAVAGEDRIServer->textureSize < 512 * 1024 ) {
+ pSAVAGEDRIServer->textureOffset = 0;
+ pSAVAGEDRIServer->textureSize = 0;
+ }
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "textureSize:0x%08lx \n",
+ pSAVAGEDRIServer->textureSize);
+
+ /* Reserve space for textures */
+ /* if (pSAVAGEDRIServer->textureSize)*/
+ pSAVAGEDRIServer->textureOffset = (psav->videoRambytes -
+ 4096 - /* hw cursor*/
+ psav->cobSize - /*COB*/
+ pSAVAGEDRIServer->textureSize) & ~SAVAGE_BUFFER_ALIGN;
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "textureOffset:0x%08lx \n",
+ pSAVAGEDRIServer->textureOffset);
+
+ /* Reserve space for the shared depth buffer */
+ /*pSAVAGEDRIServer->depthOffset = (pSAVAGEDRIServer->textureOffset -
+ tiledBufferSize_Z + SAVAGE_BUFFER_ALIGN) & ~SAVAGE_BUFFER_ALIGN;
+ */
+ pSAVAGEDRIServer->depthOffset = (pSAVAGEDRIServer->textureOffset -
+ tiledBufferSize) & ~SAVAGE_BUFFER_ALIGN;
+ /*pSAVAGEDRIServer->depthPitch = tiledwidthBytes_Z;*/
+ pSAVAGEDRIServer->depthPitch = tiledwidthBytes;
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "depthOffset:0x%08lx,depthPitch:%d\n",
+ pSAVAGEDRIServer->depthOffset,pSAVAGEDRIServer->depthPitch);
+
+ /* Reserve space for the shared back buffer */
+ pSAVAGEDRIServer->backOffset = (pSAVAGEDRIServer->depthOffset -
+ tiledBufferSize ) & ~SAVAGE_BUFFER_ALIGN;
+
+ pSAVAGEDRIServer->backPitch = tiledwidthBytes;
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "backOffset:0x%08lx,backPitch:%d\n",
+ pSAVAGEDRIServer->backOffset,pSAVAGEDRIServer->backPitch);
+
+ /*scanlines = pSAVAGEDRIServer->backOffset / widthBytes - 1;*/
+ /*if ( scanlines > maxlines ) scanlines = maxlines;*/
+ /* CR47983, XvMC do not work on system with frame buffer less than 32MB.
+ * VBE reports frame buffer size a little less than 16MB, this makes the condition
+ * truns out FALSE.
+ * Now just reduce the level to 14.5MB, things should be OK, while the hwmc frame buffer layout
+ * caculation need more understanding and should be fixed.
+ */
+ /*if total memory is less than 16M, there is no HWMC support */
+ if((psav->videoRambytes < /*16*/(14*1024+512)*1024L) || psav->bDisableXvMC)
+ {
+ psav->hwmcOffset = 0;
+ psav->hwmcSize = 0;
+ }
+ else
+ {
+ psav->hwmcSize = (10*1024+512)*1024; /* HWMC needs 10MB FB */
+ psav->hwmcOffset = (psav->videoRambytes - 0x2000 - psav->hwmcSize) &
+ ~SAVAGE_BUFFER_ALIGN;
+ if (psav->hwmcOffset < bufferSize) {
+ /* If hwmc buffer will lay in on-screen buffer. */
+ psav->hwmcSize = 0;
+ psav->hwmcOffset = 0;
+ }
+ }
+
+ /* CR48438: Title: "Lots of garbage appear on the background when
+ * drag the DVD player XINE window at 1024x768 or higher mode."
+ * hwmc used xserver's memory, now xserver will get less memory.
+ * Both 3D and hwmc's memory usage are considered now.
+ */
+#if 0
+ if (pSAVAGEDRIServer->backOffset < psav->hwmcOffset )
+ psav->cyMemory = pSAVAGEDRIServer->backOffset / widthBytes - 1;
+ else
+ psav->cyMemory = psav->hwmcOffset / widthBytes -1;
+#endif
+
+ psav->cyMemory = pSAVAGEDRIServer->backOffset / widthBytes - 1;
+ if (psav->cyMemory > 0x7FFF) {
+ psav->cyMemory = 0x7FFF;
+ }
+
+ MemBox.x1 = 0;
+ MemBox.y1 = 0;
+ MemBox.x2 = psav->cxMemory;
+ MemBox.y2 = psav->cyMemory;
+
+ if (!xf86InitFBManager(pScreen, &MemBox)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Memory manager initialization to (%d,%d) (%d,%d) failed\n",
+ MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 );
+ return FALSE;
+ } else {
+ int tmp,width, height;
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Memory manager initialized to (%d,%d) (%d,%d)\n",
+ MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2 );
+ /*
+ * because the alignment requirement,the on-screen need more memory
+ * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract
+ * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so
+ * here,we should reserve some memory for on-screen
+ */
+ tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY)
+ + psav->cxMemory -1) / (psav->cxMemory);
+ if (tmp)
+ xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL);
+
+ if (xf86QueryLargestOffscreenArea(pScreen, &width,
+ &height, 0, 0, 0 ) ) {
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Largest offscreen area available: %d x %d\n",
+ width, height );
+ }
+ }
+ psav->reserved = 0;
+
+ if(tiledBufferSize > bufferSize)
+ {
+ psav->reserved = xf86AllocateOffscreenLinear(pScreen,
+ (tiledBufferSize - bufferSize),1,0,0,0);
+
+ }
+ if(psav->reserved)
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Reserved for tiled front buffer at offset 0x%08lx ,size:0x%08lx\n",
+ psav->reserved->offset, psav->reserved->size);
+
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Reserved back buffer at offset 0x%x\n",
+ pSAVAGEDRIServer->backOffset );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Reserved depth buffer at offset 0x%x\n",
+ pSAVAGEDRIServer->depthOffset );
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Reserved %d kb for textures at offset 0x%x\n",
+ pSAVAGEDRIServer->textureSize/1024,
+ pSAVAGEDRIServer->textureOffset );
+ }
+ else
+#endif
+ {
+ int tmp;
+
+ /*
+ * why this code? because BoxRec members are short int
+ * if cyMemory is bigger than 0x7fff,then it will overflow
+ */
+ if (psav->cyMemory > 0x7FFF) {
+ psav->cyMemory = 0x7FFF;
+ }
+
+ AvailFBArea.x1 = 0;
+ AvailFBArea.y1 = 0;
+ AvailFBArea.x2 = psav->cxMemory;
+ AvailFBArea.y2 = psav->cyMemory;
+ xf86InitFBManager(pScreen, &AvailFBArea);
+ /*
+ * because the alignment requirement,the on-screen need more memory
+ * than (0,0,virtualX,virtualY), but xf86InitFBManager only subtract
+ * (pScrn->virtualX * pScrn->virtualY from (0,0,cxMemory,cyMemory),so
+ * here,we should reserver some memory for on-screen
+ */
+ tmp = ((psav->cxMemory * pScrn->virtualY - pScrn->virtualX * pScrn->virtualY)
+ + psav->cxMemory -1) / (psav->cxMemory);
+ if (tmp)
+ xf86AllocateOffscreenArea(pScreen, psav->cxMemory,tmp, 0, NULL, NULL, NULL);
+
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using %d lines for offscreen memory.\n",
+ psav->cyMemory - pScrn->virtualY );
+ }
+
+#if 0
AvailFBArea.x1 = 0;
AvailFBArea.y1 = 0;
AvailFBArea.x2 = pScrn->displayWidth;
@@ -575,6 +1522,8 @@ SavageInitAccel(ScreenPtr pScreen)
xf86DrvMsg( pScrn->scrnIndex, X_INFO,
"Using %d lines for offscreen memory.\n",
psav->ScissB - pScrn->virtualY );
+#endif
+
return XAAInit(pScreen, xaaptr);
}
@@ -1050,10 +1999,11 @@ SavageSubsequentColor8x8PatternFillRect(
if( !w || !h )
return;
- psav->WaitQueue(psav,5);
+ psav->WaitQueue(psav,6);
BCI_SEND(psav->SavedBciCmd);
BCI_SEND(psav->SavedSbdOffset);
BCI_SEND(psav->SavedSbd);
+ BCI_SEND(BCI_X_Y(patternx,patterny));
BCI_SEND(BCI_X_Y(x, y));
BCI_SEND(BCI_W_H(w, h));
}
@@ -1096,7 +2046,6 @@ SavageSubsequentSolidBresenhamLine(
e2+err));
}
-
#if 0
static void
SavageSubsequentSolidTwoPointLine(
@@ -1160,7 +2109,6 @@ SavageSubsequentSolidTwoPointLine(
#endif
-
static void
SavageSetClippingRectangle(
ScrnInfoPtr pScrn,
diff --git a/src/savage_bci.h b/src/savage_bci.h
index 0c57957..4874be7 100644
--- a/src/savage_bci.h
+++ b/src/savage_bci.h
@@ -3,6 +3,42 @@
#ifndef _S3BCI_H_
#define _S3BCI_H_
+
+/* BCI Control Register */
+#define S3_BCI_CONTROL 0x816C
+
+/*
+ * High 8 bit of primary bitmap descriptor 2 register.
+ * Bits 25-24: Tile Format 00 = Linear ; 10 = 16 bits; 11 = 32 bits (Savage4)
+ * 00 = Linear ; 01 = Tile; 10 = Texture tiling format/ Destination Tiling format
+ * 11 = Reserved/Destination tiling format.
+ */
+
+
+#define TILE_LINEAR 0
+#define TILE_FORMAT_LINEAR 0
+#define TILE_TEXTURE 2
+#define TILE_DESTINATION 1
+#define TILE_FORMAT_DESTINATION16 2
+#define TILE_FORMAT_DESTINATION32 3
+
+/* BD - BCI enable */
+/* savage4, MX, IX, 3D */
+#define BCI_ENABLE 8
+/* twister, prosavage */
+/* not sure which one supersavage fits into */
+#define BCI_ENABLE_TWISTER 0
+
+#define S3_BIG_ENDIAN 4
+#define S3_LITTLE_ENDIAN 0
+#define S3_BD64 1
+
+
+
+/* Global Bitmap Descriptor */
+#define S3_BCI_GLB_BD_LOW 0x8168
+#define S3_BCI_GLB_BD_HIGH 0x816C
+
#define REVERSE_BYTE_ORDER32(dword) {\
unsigned int temp; \
dword = (temp & 0xFF) << 24; \
@@ -71,7 +107,7 @@
#define BCI_BD_TILE_MASK 0x03000000
#define BCI_BD_TILE_NONE 0x00000000
#define BCI_BD_TILE_16 0x02000000
-#define BCI_BD_TILE_32 0x04000000
+#define BCI_BD_TILE_32 0x03000000
#define BCI_BD_GET_BPP(bd) (((bd) >> 16) & 0xFF)
#define BCI_BD_SET_BPP(bd, bpp) ((bd) |= (((bpp) & 0xFF) << 16))
#define BCI_BD_GET_STRIDE(bd) ((bd) & 0xFFFF)
diff --git a/src/savage_cursor.c b/src/savage_cursor.c
index ad4aa9f..3f968eb 100644
--- a/src/savage_cursor.c
+++ b/src/savage_cursor.c
@@ -24,7 +24,9 @@ static void SavageSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
#define outCRReg(reg, val) (VGAHWPTR(pScrn))->writeCrtc( VGAHWPTR(pScrn), reg, val )
#define inSRReg(reg) (VGAHWPTR(pScrn))->readSeq( VGAHWPTR(pScrn), reg )
#define outSRReg(reg, val) (VGAHWPTR(pScrn))->writeSeq( VGAHWPTR(pScrn), reg, val )
+#if 0
#define inStatus1() (VGAHWPTR(pScrn))->readST01( VGAHWPTR(pScrn) )
+#endif
/*
* certain HW cursor operations seem
@@ -104,12 +106,14 @@ SavageHWCursorInit(ScreenPtr pScreen)
infoPtr->LoadCursorImage = SavageLoadCursorImage;
infoPtr->HideCursor = SavageHideCursor;
infoPtr->ShowCursor = SavageShowCursor;
-
+ infoPtr->UseHWCursor = NULL;
+#if 0 /*AGD: HW cursor seems to work fine even with expansion... */
if ((S3_SAVAGE_MOBILE_SERIES(psav->Chipset)
- || (psav->Chipset == S3_PROSAVAGE)) && !psav->CrtOnly)
+ || (S3_MOBILE_TWISTER_SERIES(psav->Chipset))) && !psav->CrtOnly)
infoPtr->UseHWCursor = SavageUseHWCursor;
else
infoPtr->UseHWCursor = NULL;
+#endif
if( !psav->CursorKByte )
psav->CursorKByte = pScrn->videoRam - 4;
@@ -121,7 +125,7 @@ SavageHWCursorInit(ScreenPtr pScreen)
void
SavageShowCursor(ScrnInfoPtr pScrn)
{
- /* Turn cursor on. */
+ /* Turn cursor on. */
outCRReg( 0x45, inCRReg(0x45) | 0x01 );
SAVPTR(pScrn)->hwc_on = TRUE;
}
@@ -131,6 +135,7 @@ void
SavageHideCursor(ScrnInfoPtr pScrn)
{
/* Turn cursor off. */
+
if( S3_SAVAGE4_SERIES( SAVPTR(pScrn)->Chipset ) )
{
waitHSync(5);
diff --git a/src/savage_dri.c b/src/savage_dri.c
index 08fa24d..d42b4b6 100644
--- a/src/savage_dri.c
+++ b/src/savage_dri.c
@@ -51,6 +51,7 @@
#include "savage_regs.h"
#include "savage_driver.h"
#include "savage_bci.h"
+#include "savage_streams.h"
#define _XF86DRI_SERVER_
#include "GL/glxtokens.h"
diff --git a/src/savage_driver.c b/src/savage_driver.c
index c2e63b8..226fbb6 100644
--- a/src/savage_driver.c
+++ b/src/savage_driver.c
@@ -22,10 +22,18 @@
#include "xf86xv.h"
#include "savage_driver.h"
+#include "savage_regs.h"
#include "savage_bci.h"
+#include "savage_streams.h"
#define TRANSPARENCY_KEY 0xff;
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "savage_dri.h"
+#endif
+
+
/*
* prototypes
*/
@@ -74,13 +82,15 @@ static unsigned int SavageDDC1Read(ScrnInfoPtr pScrn);
static void SavageProbeDDC(ScrnInfoPtr pScrn, int index);
static void SavageGetTvMaxSize(SavagePtr psav);
static Bool SavagePanningCheck(ScrnInfoPtr pScrn);
+static Bool SavageCheckAvailableRamFor3D(ScrnInfoPtr pScrn);
+static void SavageResetStreams(ScrnInfoPtr pScrn);
extern ScrnInfoPtr gpScrn;
#define iabs(a) ((int)(a)>0?(a):(-(a)))
#define DRIVER_NAME "savage"
-#define DRIVER_VERSION "1.1.27"
+#define DRIVER_VERSION "1.1.27a"
#define VERSION_MAJOR 1
#define VERSION_MINOR 1
#define PATCHLEVEL 27
@@ -143,6 +153,8 @@ static SymTabRec SavageChipsets[] = {
{ S3_SAVAGE2000, "Savage2000" },
{ S3_SAVAGE_MX, "MobileSavage" },
{ S3_PROSAVAGE, "ProSavage" },
+ { S3_TWISTER, "Twister"},
+ { S3_PROSAVAGEDDR, "ProSavageDDR"},
{ S3_SUPERSAVAGE, "SuperSavage" },
{ -1, NULL }
};
@@ -160,10 +172,10 @@ static PciChipsets SavagePciChipsets[] = {
{ S3_SAVAGE_MX, PCI_CHIP_SAVAGE_IX, RES_SHARED_VGA },
{ S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_PM, RES_SHARED_VGA },
{ S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_KM, RES_SHARED_VGA },
- { S3_PROSAVAGE, PCI_CHIP_S3TWISTER_P, RES_SHARED_VGA },
- { S3_PROSAVAGE, PCI_CHIP_S3TWISTER_K, RES_SHARED_VGA },
- { S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_DDR, RES_SHARED_VGA },
- { S3_PROSAVAGE, PCI_CHIP_PROSAVAGE_DDRK, RES_SHARED_VGA },
+ { S3_TWISTER, PCI_CHIP_S3TWISTER_P, RES_SHARED_VGA },
+ { S3_TWISTER, PCI_CHIP_S3TWISTER_K, RES_SHARED_VGA },
+ { S3_PROSAVAGEDDR, PCI_CHIP_PROSAVAGE_DDR, RES_SHARED_VGA },
+ { S3_PROSAVAGEDDR, PCI_CHIP_PROSAVAGE_DDRK, RES_SHARED_VGA },
{ S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_MX128, RES_SHARED_VGA },
{ S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_MX64, RES_SHARED_VGA },
{ S3_SUPERSAVAGE, PCI_CHIP_SUPSAV_MX64C, RES_SHARED_VGA },
@@ -177,32 +189,38 @@ static PciChipsets SavagePciChipsets[] = {
};
typedef enum {
- OPTION_PCI_BURST,
- OPTION_PCI_RETRY,
- OPTION_NOACCEL,
- OPTION_LCD_CENTER,
- OPTION_LCDCLOCK,
- OPTION_MCLK,
- OPTION_REFCLK,
- OPTION_SHOWCACHE,
- OPTION_SWCURSOR,
- OPTION_HWCURSOR,
- OPTION_SHADOW_FB,
- OPTION_ROTATE,
- OPTION_USEBIOS,
- OPTION_SHADOW_STATUS,
- OPTION_CRT_ONLY,
- OPTION_TV_ON,
- OPTION_TV_PAL,
- OPTION_FORCE_INIT,
- OPTION_OVERLAY,
- OPTION_T_KEY
+ OPTION_PCI_BURST
+ ,OPTION_PCI_RETRY
+ ,OPTION_NOACCEL
+ ,OPTION_LCD_CENTER
+ ,OPTION_LCDCLOCK
+ ,OPTION_MCLK
+ ,OPTION_REFCLK
+ ,OPTION_SHOWCACHE
+ ,OPTION_SWCURSOR
+ ,OPTION_HWCURSOR
+ ,OPTION_SHADOW_FB
+ ,OPTION_ROTATE
+ ,OPTION_USEBIOS
+ ,OPTION_SHADOW_STATUS
+ ,OPTION_CRT_ONLY
+ ,OPTION_TV_ON
+ ,OPTION_TV_PAL
+ ,OPTION_FORCE_INIT
+ ,OPTION_OVERLAY
+ ,OPTION_T_KEY
+ ,OPTION_DISABLE_XVMC
+ ,OPTION_DISABLE_TILE
+ ,OPTION_DISABLE_COB
+ ,OPTION_BCI_FOR_XV
+ ,OPTION_AGP_MODE
+ ,OPTION_AGP_SIZE
} 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 },
@@ -216,6 +234,13 @@ static const OptionInfoRec SavageOptions[] =
{ OPTION_FORCE_INIT,"ForceInit", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_OVERLAY, "Overlay", OPTV_ANYSTR, {0}, FALSE },
{ OPTION_T_KEY, "TransparencyKey", OPTV_ANYSTR, {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_COB, "DisableCOB", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_BCI_FOR_XV, "BCIforXv", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE },
+ { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
@@ -244,6 +269,61 @@ static const char *vgaHWSymbols[] = {
NULL
};
+#ifdef XF86DRI
+static const char *drmSymbols[] = {
+ "drmAvailable",
+ "drmAddBufs",
+ "drmAddMap",
+ "drmCtlInstHandler",
+ "drmGetInterruptFromBusID",
+ "drmFreeVersion",
+ "drmGetVersion",
+ "drmMap",
+ "drmUnmap",
+ "drmMapBufs",
+ "drmUnmapBufs",
+ "drmAgpAcquire",
+ "drmAgpRelease",
+ "drmAgpEnable",
+ "drmAgpAlloc",
+ "drmAgpFree",
+ "drmAgpBind",
+ "drmAgpUnbind",
+ "drmAgpGetMode",
+ "drmAgpBase",
+ "drmAgpSize",
+ "drmAgpVendorId",
+ "drmAgpDeviceId",
+ "drmMGAInitDMA",
+ "drmMGACleanupDMA",
+ "drmMGAFlushDMA",
+ "drmMGAEngineReset",
+ NULL
+};
+
+static const char *driSymbols[] = {
+ "DRIGetDrawableIndex",
+ "DRIFinishScreenInit",
+ "DRIDestroyInfoRec",
+ "DRICloseScreen",
+ "DRIDestroyInfoRec",
+ "DRIScreenInit",
+ "DRIDestroyInfoRec",
+ "DRICreateInfoRec",
+ "DRILock",
+ "DRIUnlock",
+ "DRIGetSAREAPrivate",
+ "DRIGetContext",
+ "DRIQueryVersion",
+ "DRIAdjustFrame",
+ "DRIOpenFullScreen",
+ "DRICloseFullScreen",
+ "GlxSetVisualConfigs",
+ NULL
+};
+#endif
+
+
static const char *ramdacSymbols[] = {
"xf86CreateCursorInfoRec",
#if 0
@@ -260,6 +340,7 @@ static const char *int10Symbols[] = {
"xf86Int10FreePages"
};
+#ifdef XFree86LOADER
static const char *vbeSymbols[] = {
"VBEInit",
"vbeDoEDID",
@@ -268,8 +349,8 @@ static const char *vbeSymbols[] = {
#endif
NULL
};
+#endif
-#ifdef XFree86LOADER
static const char *vbeOptSymbols[] = {
"vbeModeInit",
"VBESetVBEMode",
@@ -277,7 +358,6 @@ static const char *vbeOptSymbols[] = {
"VBEFreeVBEInfo",
NULL
};
-#endif
static const char *ddcSymbols[] = {
"xf86DoEDID_DDC1",
@@ -290,6 +370,14 @@ static const char *ddcSymbols[] = {
static const char *i2cSymbols[] = {
"xf86CreateI2CBusRec",
"xf86I2CBusInit",
+ "xf86CreateI2CDevRec",
+ "xf86I2CDevInit",
+ "xf86I2CWriteByte",
+ "xf86I2CWriteBytes",
+ "xf86I2CReadByte",
+ "xf86I2CReadBytes",
+ "xf86I2CWriteRead",
+ "xf86DestroyI2CDevRec",
NULL
};
@@ -298,8 +386,9 @@ static const char *xaaSymbols[] = {
"XAAGetCopyROP_PM",
"XAACreateInfoRec",
"XAADestroyInfoRec",
+ "XAAFillSolidRects",
"XAAHelpPatternROP",
- "XAAHelpSolidROP",
+ "XAAHelpSolidROP",
"XAAInit",
"XAAScreenIndex",
NULL
@@ -345,6 +434,9 @@ static pointer SavageSetup(pointer module, pointer opts, int *errmaj,
xf86AddDriver(&SAVAGE, module, 0);
LoaderRefSymLists(vgaHWSymbols, fbSymbols, ramdacSymbols,
xaaSymbols, shadowSymbols, vbeSymbols, vbeOptSymbols,
+#ifdef XF86DRI
+ drmSymbols, driSymbols,
+#endif
int10Symbols, i2cSymbols, ddcSymbols, NULL);
return (pointer) 1;
} else {
@@ -453,8 +545,7 @@ WaitQueue4( SavagePtr psav, int v )
return ShadowWait(psav);
}
else
- while( ((ALT_STATUS_WORD0 & 0x001fffff) > slots) && (loop++ < MAXLOOP))
- ;
+ while( ((ALT_STATUS_WORD0 & 0x001fffff) > slots) && (loop++ < MAXLOOP));
return loop >= MAXLOOP;
}
@@ -493,8 +584,7 @@ WaitIdleEmpty3D(SavagePtr psav)
return ShadowWait(psav);
}
loop &= STATUS_WORD0;
- while( ((STATUS_WORD0 & 0x0008ffff) != 0x80000) && (loop++ < MAXLOOP) )
- ;
+ while( ((STATUS_WORD0 & 0x0008ffff) != 0x80000) && (loop++ < MAXLOOP) );
return loop >= MAXLOOP;
}
@@ -508,8 +598,9 @@ WaitIdleEmpty4(SavagePtr psav)
psav->WaitIdleEmpty = ShadowWait;
return ShadowWait(psav);
}
- while( ((ALT_STATUS_WORD0 & 0x00a1ffff) != 0x00a00000) && (loop++ < MAXLOOP) )
- ;
+ /* which is right?*/
+ /*while( ((ALT_STATUS_WORD0 & 0x00a1ffff) != 0x00a00000) && (loop++ < MAXLOOP) );*/ /* tim */
+ while (((ALT_STATUS_WORD0 & 0x00e1ffff) != 0x00e00000) && (loop++ < MAXLOOP)); /* S3 */
return loop >= MAXLOOP;
}
@@ -524,8 +615,7 @@ WaitIdleEmpty2K(SavagePtr psav)
return ShadowWait(psav);
}
loop &= ALT_STATUS_WORD0;
- while( ((ALT_STATUS_WORD0 & 0x009fffff) != 0) && (loop++ < MAXLOOP) )
- ;
+ while( ((ALT_STATUS_WORD0 & 0x009fffff) != 0) && (loop++ < MAXLOOP) );
if( loop >= MAXLOOP )
ResetBCI2K(psav);
return loop >= MAXLOOP;
@@ -543,8 +633,7 @@ WaitIdle3D(SavagePtr psav)
psav->WaitIdle = ShadowWait;
return ShadowWait(psav);
}
- while( (!(STATUS_WORD0 & 0x00080000)) && (loop++ < MAXLOOP) )
- ;
+ while( (!(STATUS_WORD0 & 0x00080000)) && (loop++ < MAXLOOP) );
return loop >= MAXLOOP;
}
@@ -558,8 +647,9 @@ WaitIdle4(SavagePtr psav)
psav->WaitIdle = ShadowWait;
return ShadowWait(psav);
}
- while( (!(ALT_STATUS_WORD0 & 0x00800000)) && (loop++ < MAXLOOP) )
- ;
+ /* which is right?*/
+ /*while( (!(ALT_STATUS_WORD0 & 0x00800000)) && (loop++ < MAXLOOP) );*/ /* tim */
+ while (((ALT_STATUS_WORD0 & 0x00E00000)!=0x00E00000) && (loop++ < MAXLOOP)); /* S3 */
return loop >= MAXLOOP;
}
@@ -574,8 +664,7 @@ WaitIdle2K(SavagePtr psav)
return ShadowWait(psav);
}
loop &= ALT_STATUS_WORD0;
- while( (ALT_STATUS_WORD0 & 0x00900000) && (loop++ < MAXLOOP) )
- ;
+ while( (ALT_STATUS_WORD0 & 0x00900000) && (loop++ < MAXLOOP) );
return loop >= MAXLOOP;
}
@@ -626,7 +715,7 @@ static Bool SavageProbe(DriverPtr drv, int flags)
/* sanity checks */
if ((numDevSections = xf86MatchDevice("savage", &devSections)) <= 0)
- return FALSE;
+ return FALSE;
if (xf86GetPciVideoInfo() == NULL) {
if (devSections)
xfree(devSections);
@@ -910,6 +999,55 @@ 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;
+
+ /* temporatly remove by Jiayo */
+ 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
@@ -969,6 +1107,37 @@ 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"));
+ }
+ psav->bDisableXvMC = FALSE; /* 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"));
+ }
+ if (S3_SAVAGE3D_SERIES(psav->Chipset)) {
+ psav->bDisableXvMC = TRUE; /* no xvmc on old savages */
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "No Hardware XvMC support on Savage3D based chips.\n");
+ }
+ 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"));
+ }
+
/* Add more options here. */
if (pScrn->numEntities > 1) {
@@ -1124,6 +1293,8 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
break;
case S3_PROSAVAGE:
+ case S3_PROSAVAGEDDR:
+ case S3_TWISTER:
pScrn->videoRam = RamSavageNB[ (config1 & 0xE0) >> 5 ] * 1024;
break;
@@ -1146,40 +1317,6 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
pScrn->videoRam);
}
- /* Do the DDC dance. */
-
- {
- ddc = xf86LoadSubModule(pScrn, "ddc");
- if (ddc) {
- xf86MonPtr pMon = NULL;
-
- xf86LoaderReqSymLists(ddcSymbols, NULL);
-/*
- * 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 if (( psav->Chipset != S3_PROSAVAGE )
- && !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);
- }
- }
- }
- }
- }
-
/* Get video RAM */
if( !pScrn->videoRam && psav->pVbe )
{
@@ -1199,51 +1336,45 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->videoRambytes = pScrn->videoRam * 1024;
}
+
/*
- * If we're running with acceleration, compute the command overflow
+ * If we're running with acceleration, compute the command overflow
* buffer location. The command overflow buffer must END at a
* 4MB boundary; for all practical purposes, that means the very
* end of the frame buffer.
*/
-
- if( psav->NoAccel ) {
- psav->CursorKByte = pScrn->videoRam - 4;
- psav->cobIndex = 0;
- psav->cobSize = 0;
- psav->cobOffset = psav->videoRambytes;
- }
- else if( (S3_SAVAGE4_SERIES(psav->Chipset)) ||
- (S3_SUPERSAVAGE == psav->Chipset) ) {
+ if (psav->NoAccel) {
+ psav->cobIndex = 0;
+ psav->cobSize = 0;
+ }
+ 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.
+ */
/*
- * The Savage4 and ProSavage have COB coherency bugs which render
- * the buffer useless. COB seems to make the SuperSavage slower.
- * We disable it.
- */
- psav->CursorKByte = pScrn->videoRam - 4;
- psav->cobIndex = 2;
- psav->cobSize = 0x8000 << psav->cobIndex;
- psav->cobOffset = psav->videoRambytes;
- }
- else
- {
- /* We use 128kB for the COB on all other chips. */
-
- psav->cobSize = 1 << 17;
- if (psav->Chipset == S3_SUPERSAVAGE) {
+ psav->cobIndex = 2;
+ psav->cobSize = 0x8000 << psav->cobIndex;
+ */
+ psav->cobIndex = 0;
+ psav->cobSize = 0;
+ } else {
+ /* We use 128kB for the COB on all other chips. */
+ psav->cobSize = 0x20000;
+ if (S3_SAVAGE3D_SERIES(psav->Chipset)) {
+ psav->cobIndex = 7; /* rev.A savage4 also uses 7 */
+ } else {
psav->cobIndex = 2;
}
- else {
- psav->cobIndex = 7;
- }
- psav->cobOffset = psav->videoRambytes - psav->cobSize;
}
-
- /*
- * We place the cursor in high memory, just before the command overflow
- * buffer. The cursor must be aligned on a 4k boundary.
- */
-
- psav->CursorKByte = (psav->cobOffset >> 10) - 4;
+
+ /* align cob to 128k */
+ psav->cobOffset = (psav->videoRambytes - psav->cobSize) & ~0x1ffff;
+
+ /* The cursor must be aligned on a 4k boundary. */
+ psav->CursorKByte = (psav->cobOffset >> 10) - 4;
+ psav->endfb = (psav->CursorKByte << 10) - 1;
/* reset graphics engine to avoid memory corruption */
VGAOUT8(vgaCRIndex, 0x66);
@@ -1268,6 +1399,8 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
case S3_SAVAGE4:
case S3_PROSAVAGE:
case S3_SUPERSAVAGE:
+ case S3_PROSAVAGEDDR:
+ case S3_TWISTER:
psav->WaitQueue = WaitQueue4;
psav->WaitIdle = WaitIdle4;
psav->WaitIdleEmpty = WaitIdleEmpty4;
@@ -1280,6 +1413,49 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
break;
}
+ /* Do the DDC dance. */ /* S3/VIA's DDC code */
+ ddc = xf86LoadSubModule(pScrn, "ddc");
+ if (ddc) {
+ xf86LoaderReqSymLists(ddcSymbols, NULL);
+ switch( psav->Chipset ) {
+ case S3_SAVAGE3D:
+ case S3_SAVAGE_MX:
+ case S3_SUPERSAVAGE:
+ psav->DDCPort = 0xAA;
+ psav->I2CPort = 0xA0;
+ break;
+
+ case S3_SAVAGE4:
+ case S3_PROSAVAGE:
+ case S3_TWISTER:
+ case S3_PROSAVAGEDDR:
+ psav->DDCPort = 0xB1;
+ psav->I2CPort = 0xA0;
+ break;
+
+ case S3_SAVAGE2000:
+ psav->DDCPort = 0xAA;
+ psav->I2CPort = 0xA0;
+ break;
+ }
+
+ if (!SavageDDC1(pScrn->scrnIndex)) {
+ /* DDC1 failed,switch to DDC2 */
+ if (xf86LoadSubModule(pScrn, "i2c")) {
+ xf86LoaderReqSymLists(i2cSymbols,NULL);
+ if (SavageI2CInit(pScrn)) {
+ unsigned char tmp;
+
+ InI2CREG(tmp,psav->DDCPort);
+ OutI2CREG(tmp | 0x13,psav->DDCPort);
+ xf86SetDDCproperties(pScrn,xf86PrintEDID(
+ xf86DoEDID_DDC2(pScrn->scrnIndex,psav->I2C)));
+ OutI2CREG(tmp,psav->DDCPort);
+ }
+ }
+ }
+ }
+
/* Savage ramdac speeds */
pScrn->numClocks = 4;
pScrn->clock[0] = 250000;
@@ -1292,9 +1468,10 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->dacSpeedBpp = pScrn->clock[3];
else if (pScrn->bitsPerPixel >= 24)
psav->dacSpeedBpp = pScrn->clock[2];
- else if (pScrn->bitsPerPixel > 8)
+ else if ((pScrn->bitsPerPixel > 8) && (pScrn->bitsPerPixel < 24))
psav->dacSpeedBpp = pScrn->clock[1];
- else psav->dacSpeedBpp = pScrn->clock[0];
+ else if (pScrn->bitsPerPixel <= 8)
+ psav->dacSpeedBpp = pScrn->clock[0];
}
/* Set ramdac limits */
@@ -1326,7 +1503,8 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
/* Check LCD panel information */
- if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) && !psav->CrtOnly )
+ if( (S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
+ S3_MOBILE_TWISTER_SERIES(psav->Chipset)) && !psav->CrtOnly )
{
unsigned char cr6b = hwp->readCrtc( hwp, 0x6b );
@@ -1393,7 +1571,19 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
}
}
- clockRanges = xnfcalloc(sizeof(ClockRange),1);
+#if 0
+ if (psav->CrtOnly && !psav->UseBIOS) {
+ VGAOUT8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
+ VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x10); /* disable FP */
+ if (S3_SAVAGE_MOBILE_SERIES(psav->Chipset) /*||
+ S3_MOBILE_TWISTER_SERIES(psav->Chipset)*/) { /* not sure this works on mobile prosavage */
+ VGAOUT8(0x3c4, 0x31);
+ VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x04); /* make sure crtc1 is crt source */
+ }
+ }
+#endif
+
+ clockRanges = xnfalloc(sizeof(ClockRange));
clockRanges->next = NULL;
clockRanges->minClock = psav->minClock;
clockRanges->maxClock = psav->maxClock;
@@ -1524,10 +1714,24 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
static Bool SavageEnterVT(int scrnIndex, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+#ifdef XF86DRI
+ SavagePtr psav= SAVPTR(pScrn);
+ ScreenPtr pScreen;
+#endif
+
TRACE(("SavageEnterVT(%d)\n", flags));
gpScrn = pScrn;
SavageEnableMMIO(pScrn);
+
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled) {
+ pScreen = screenInfo.screens[scrnIndex];
+ DRIUnlock(pScreen);
+ psav->LockHeld = 0;
+ }
+#endif
+
SavageSave(pScrn);
if(SavageModeInit(pScrn, pScrn->currentMode)) {
/* some BIOSes seem to enable HW cursor on PM resume */
@@ -1546,12 +1750,25 @@ static void SavageLeaveVT(int scrnIndex, int flags)
SavagePtr psav = SAVPTR(pScrn);
vgaRegPtr vgaSavePtr = &hwp->SavedReg;
SavageRegPtr SavageSavePtr = &psav->SavedReg;
+#ifdef XF86DRI
+ ScreenPtr pScreen;
+#endif
TRACE(("SavageLeaveVT(%d)\n", flags));
gpScrn = pScrn;
+
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled) {
+ pScreen = screenInfo.screens[scrnIndex];
+ DRILock(pScreen, 0);
+ psav->LockHeld = 1;
+ }
+#endif
SavageStreamsOff(pScrn);
SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE);
+ SavageResetStreams(pScrn);
SavageDisableMMIO(pScrn);
+
}
@@ -1693,7 +1910,8 @@ static void SavageSave(ScrnInfoPtr pScrn)
/* Save flat panel expansion regsters. */
- if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) {
+ if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
+ S3_MOBILE_TWISTER_SERIES(psav->Chipset)) {
int i;
for( i = 0; i < 8; i++ ) {
VGAOUT8(0x3c4, 0x54+i);
@@ -1751,6 +1969,13 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
TRACE(("SavageWriteMode(%x)\n", restore->mode));
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled) {
+ DRILock(screenInfo.screens[pScrn->scrnIndex], 0);
+ psav->LockHeld = 1;
+ }
+#endif
+
if( Entering &&
(!S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || (psav->ForceInit))
)
@@ -1924,12 +2149,18 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
}
SavageInitialize2DEngine(pScrn);
- SavageSetGBD(pScrn);
VGAOUT16(vgaCRIndex, 0x0140);
SavageSetGBD(pScrn);
+
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled)
+ DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
+ psav->LockHeld = 0;
+#endif
+
return;
}
@@ -1961,7 +2192,8 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
VGAOUT8(vgaCRIndex, 0x67);
(void) VGAIN8(vgaCRReg);
- VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c); /* no STREAMS yet */
+ /*VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c);*/ /* no STREAMS yet */
+ VGAOUT8(vgaCRReg, restore->CR67 & ~0x0e); /* no STREAMS yet old and new */
/* restore extended regs */
VGAOUT8(vgaCRIndex, 0x66);
@@ -1991,7 +2223,8 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
VGAOUT8(0x3c5, restore->SR15);
/* Restore flat panel expansion regsters. */
- if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ) {
+ if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
+ S3_MOBILE_TWISTER_SERIES(psav->Chipset)) {
int i;
for( i = 0; i < 8; i++ ) {
VGAOUT8(0x3c4, 0x54+i);
@@ -2023,7 +2256,8 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
/* 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 & ~0x0e); /* no streams for new and old streams engines */
/* other mode timing and extended regs */
VGAOUT8(vgaCRIndex, 0x34);
@@ -2046,6 +2280,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
VGAOUT8(vgaCRReg, restore->CR60);
VGAOUT8(vgaCRIndex, 0x68);
VGAOUT8(vgaCRReg, restore->CR68);
+ VerticalRetraceWait();
VGAOUT8(vgaCRIndex, 0x69);
VGAOUT8(vgaCRReg, restore->CR69);
VGAOUT8(vgaCRIndex, 0x6f);
@@ -2120,7 +2355,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
VGAOUT8(0x3c5, restore->SR08);
/* now write out cr67 in full, possibly starting STREAMS */
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
VGAOUT8(vgaCRIndex, 0x67);
#if 0
VGAOUT8(vgaCRReg, 0x50);
@@ -2141,7 +2376,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
if( !S3_SAVAGE_MOBILE_SERIES(psav->Chipset) )
{
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
OUTREG(FIFO_CONTROL_REG, restore->MMPR0);
OUTREG(MIU_CONTROL_REG, restore->MMPR1);
OUTREG(STREAMS_TIMEOUT_REG, restore->MMPR2);
@@ -2166,12 +2401,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
VGAOUT8(vgaCRReg, cr3a);
if( Entering ) {
- /* We reinit the engine here just as in the UseBIOS case
- * as otherwise we lose performance because the engine
- * isn't setup properly (Alan Hourihane - alanh@fairlite.demon.co.uk).
- */
SavageInitialize2DEngine(pScrn);
- SavageSetGBD(pScrn);
VGAOUT16(vgaCRIndex, 0x0140);
@@ -2180,6 +2410,13 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr,
vgaHWProtect(pScrn, FALSE);
+
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled)
+ DRIUnlock(screenInfo.screens[pScrn->scrnIndex]);
+ psav->LockHeld = 0;
+#endif
+
return;
}
@@ -2250,6 +2487,28 @@ static Bool SavageMapFB(ScrnInfoPtr pScrn)
}
psav->FBStart = psav->FBBase;
}
+
+ if (psav->Chipset == S3_SUPERSAVAGE)
+ /* paramount aperture 0 is pci base 2 */
+ psav->ApertureBase = psav->PciInfo->memBase[2];
+ else
+ psav->ApertureBase = psav->FrameBufferBase + 0x02000000;
+
+ psav->ApertureMap = xf86MapPciMem(pScrn->scrnIndex, VIDMEM_FRAMEBUFFER,
+ psav->PciTag, psav->ApertureBase,
+ 0x01000000 * 5);
+ if (!psav->ApertureMap) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "Internal error: could not map aperture\n");
+ return FALSE;
+ }
+ else
+ {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "map aperture:%p\n",psav->ApertureMap);
+
+ }
+
pScrn->memPhysBase = psav->PciInfo->memBase[0];
pScrn->fbOffset = 0;
@@ -2292,6 +2551,46 @@ static void SavageUnmapMem(ScrnInfoPtr pScrn, int All)
return;
}
+static Bool SavageCheckAvailableRamFor3D(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ int cpp = pScrn->bitsPerPixel / 8;
+ /*int widthBytes = pScrn->displayWidth * cpp;*/
+ int widthBytes = psav->lDelta;
+ /*int widthBytes = psav->l3DDelta;*/
+ int bufferSize = ((pScrn->virtualY * widthBytes + SAVAGE_BUFFER_ALIGN)
+ & ~SAVAGE_BUFFER_ALIGN);
+ int tiledwidthBytes, tiledBufferSize, RamNeededFor3D;
+ /*tiledwidthBytes = psav->lDelta;*/
+ tiledwidthBytes = psav->l3DDelta;
+
+ if (cpp == 2) {
+ tiledBufferSize = ((pScrn->virtualX+63)/64)*((pScrn->virtualY+15)/16) * 2048;
+ } else {
+ tiledBufferSize = ((pScrn->virtualX+31)/32)*((pScrn->virtualY+15)/16) * 2048;
+ }
+
+ RamNeededFor3D = 4096 + /* hw cursor*/
+ psav->cobSize + /*COB*/
+ bufferSize + /* front buffer */
+ tiledBufferSize + /* back buffer */
+ tiledBufferSize; /* depth buffer */
+
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,
+ "%d kB of Videoram needed for 3D; %d kB of Videoram available\n",
+ RamNeededFor3D/1024, psav->videoRambytes/1024);
+
+ if (RamNeededFor3D <= psav->videoRambytes) {
+ xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Sufficient Videoram available for 3D\n");
+ return TRUE;
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Insufficient Videoram available for 3D\n");
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"Try a lower color depth or smaller desktop.\n");
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,
+ "For integrated savages try increasing the videoram in the BIOS.\n");
+ return FALSE;
+ }
+}
static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
int argc, char **argv)
@@ -2358,6 +2657,29 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
if (!SavageModeInit(pScrn, pScrn->currentMode))
return FALSE;
+#ifdef XF86DRI
+ if (((psav->Chipset == S3_TWISTER)
+ || (psav->Chipset == S3_PROSAVAGE)
+ || (psav->Chipset == S3_SAVAGE4)
+ || (psav->Chipset == S3_SAVAGE_MX)
+ || (psav->Chipset == S3_SAVAGE3D)
+ || (psav->Chipset == S3_SUPERSAVAGE)
+ || (psav->Chipset == S3_PROSAVAGEDDR))
+ && (!psav->NoAccel)
+ && (SavageCheckAvailableRamFor3D(pScrn))) {
+ /* Setup DRI after visuals have been established */
+ psav->directRenderingEnabled = SAVAGEDRIScreenInit(pScreen);
+ } else
+ psav->directRenderingEnabled = FALSE;
+
+ if(psav->directRenderingEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"DRI is enabled\n");
+ }
+ else {
+ xf86DrvMsg(pScrn->scrnIndex,X_ERROR,"DRI isn't enabled\n");
+ }
+#endif
+
miClearVisualTypes();
{
@@ -2512,8 +2834,29 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
if (xf86DPMSInit(pScreen, SavageDPMS, 0) == FALSE)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed\n");
- if( !psav->FBStart2nd && !SavagePanningCheck(pScrn) )
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled) {
+ /* complete the DRI setup.*/
+ psav->directRenderingEnabled = SAVAGEDRIFinishScreenInit(pScreen);
+ }
+ if (psav->directRenderingEnabled) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Direct rendering enabled\n");
+ } else {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Direct rendering disabled\n");
+ }
+#endif
+
+#ifdef XvExtension
+ if( !psav->FBStart2nd && !psav->NoAccel && !SavagePanningCheck(pScrn) )
SavageInitVideo( pScreen );
+#endif
+
+ if ((psav->directRenderingEnabled) && (!psav->bDisableXvMC)) {
+ if (SAVAGEInitMC(pScreen))
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"XvMC is enabled\n");
+ else
+ xf86DrvMsg(pScrn->scrnIndex,X_CONFIG,"XvMC is not enabled\n");
+ }
if (serverGeneration == 1)
xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options);
@@ -2557,10 +2900,17 @@ static int SavageInternalScreenInit(int scrnIndex, ScreenPtr pScreen)
}
if (!psav->FBStart2nd) {
+#if 0
ret = fbScreenInit(pScreen, FBStart, width, height,
pScrn->xDpi, pScrn->yDpi,
displayWidth,
pScrn->bitsPerPixel);
+#endif
+ ret = fbScreenInit(pScreen, FBStart, width, height,
+ pScrn->xDpi, pScrn->yDpi,
+ psav->ulAperturePitch / (pScrn->bitsPerPixel >> 3), /*displayWidth,*/
+ pScrn->bitsPerPixel);
+
} else {
FbOverlayScrPrivPtr pScrPriv;
int Depth2nd = DEPTH_2ND(pScrn);
@@ -2664,7 +3014,22 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
- psav->HorizScaleFactor = 1;
+ if (pScrn->bitsPerPixel == 8)
+ psav->HorizScaleFactor = 1;
+ else if (pScrn->bitsPerPixel == 16)
+ psav->HorizScaleFactor = 1; /* I don't think we ever want 2 */
+ else
+ psav->HorizScaleFactor = 1;
+
+ if (psav->HorizScaleFactor == 2)
+ if (!mode->CrtcHAdjusted) {
+ mode->CrtcHDisplay *= 2;
+ mode->CrtcHSyncStart *= 2;
+ mode->CrtcHSyncEnd *= 2;
+ mode->CrtcHTotal *= 2;
+ mode->CrtcHSkew *= 2;
+ mode->CrtcHAdjusted = TRUE;
+ }
if (!vgaHWInit(pScrn, mode))
return FALSE;
@@ -2709,6 +3074,7 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
break;
}
+
if( psav->UseBIOS ) {
int refresh;
SavageModeEntryPtr pmt;
@@ -2931,11 +3297,14 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode)
new->CR36 = VGAIN8(vgaCRReg);
VGAOUT8(vgaCRIndex, 0x68);
new->CR68 = VGAIN8(vgaCRReg);
+
new->CR69 = 0;
VGAOUT8(vgaCRIndex, 0x6f);
new->CR6F = VGAIN8(vgaCRReg);
- VGAOUT8(vgaCRIndex, 0x88);
+ VGAOUT8(vgaCRIndex, 0x86);
new->CR86 = VGAIN8(vgaCRReg) | 0x08;
+ VGAOUT8(vgaCRIndex, 0x88);
+ new->CR88 = VGAIN8(vgaCRReg) | DISABLE_BLOCK_WRITE_2D;
VGAOUT8(vgaCRIndex, 0xb0);
new->CRB0 = VGAIN8(vgaCRReg) | 0x80;
}
@@ -2965,6 +3334,13 @@ static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen)
TRACE(("SavageCloseScreen\n"));
+#ifdef XF86DRI
+ if (psav->directRenderingEnabled) {
+ SAVAGEDRICloseScreen(pScreen);
+ psav->directRenderingEnabled=FALSE;
+ }
+#endif
+
if (psav->pVbe)
vbeFree(psav->pVbe);
psav->pVbe = NULL;
@@ -2983,6 +3359,7 @@ static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen)
if (pScrn->vtSema) {
SavageStreamsOff(pScrn);
SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE);
+ SavageResetStreams(pScrn);
vgaHWLock(hwp);
SavageUnmapMem(pScrn, 0);
}
@@ -2997,10 +3374,11 @@ static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen)
static Bool SavageSaveScreen(ScreenPtr pScreen, int mode)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- TRACE(("SavageSaveScreen(0x%x)\n", mode));
- if( pScrn->vtSema && SAVPTR(pScrn)->hwcursor && SAVPTR(pScrn)->hwc_on) {
+ TRACE(("SavageSaveScreen(0x%x)\n", mode));
+ if( pScrn->vtSema && SAVPTR(pScrn)->hwcursor && SAVPTR(pScrn)->hwc_on )
+ {
if( xf86IsUnblank(mode) )
SavageShowCursor( pScrn );
else
@@ -3008,10 +3386,58 @@ static Bool SavageSaveScreen(ScreenPtr pScreen, int mode)
SAVPTR(pScrn)->hwc_on = TRUE; /*restore */
}
- return vgaHWSaveScreen(pScreen, mode);
+ return vgaHWSaveScreen(pScreen, mode);
}
+void
+SavageAdjustFrame(int scrnIndex, int x, int y, int flags)
+{
+ ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
+ SavagePtr psav = SAVPTR(pScrn);
+ DisplayModePtr currentMode = pScrn->currentMode;
+ int address=0,top=0,left=0;
+
+ TRACE(("SavageAdjustFrame(%d,%d,%x)\n", x, y, flags));
+
+ if (!psav->bTiled) {
+ left = x - x % 64;
+ top = y;
+ address = (top * psav->lDelta) + left * (pScrn->bitsPerPixel >> 3);
+ address = (address >> 5) << 5;
+ } else {
+ top = y - y % TILEHEIGHT;
+ if (pScrn->bitsPerPixel == 16) {
+ left = x - x % TILEWIDTH_16BPP;
+ address = top * psav->lDelta + left * TILE_SIZE_BYTE / TILEWIDTH_16BPP;
+ } else if (pScrn->bitsPerPixel == 32) {
+ left = x - x % TILEWIDTH_32BPP;
+ address = top * psav->lDelta + left * TILE_SIZE_BYTE / TILEWIDTH_32BPP;
+ }
+ }
+
+ /*
+ * because we align the viewport to the width and height of one tile
+ * we shoud update the locate of frame
+ */
+ pScrn->frameX0 = left;
+ pScrn->frameY0 = top;
+ pScrn->frameX1 = left + currentMode->HDisplay - 1;
+ pScrn->frameY1 = top+ currentMode->VDisplay - 1;
+
+ if (S3_SAVAGE_MOBILE_SERIES(psav->Chipset)) {
+ OUTREG32(PRI_STREAM_FBUF_ADDR0,address | 0xFFFFFFFC); /* IGA1 */
+ OUTREG32(PRI_STREAM_FBUF_ADDR1,address | 0x80000000);
+ OUTREG32(PRI_STREAM2_FBUF_ADDR0,address | 0xFFFFFFFC); /* IGA2 */
+ OUTREG32(PRI_STREAM2_FBUF_ADDR1,address | 0x80000000);
+ } else {
+ OUTREG32(PSTREAM_FBADDR0_REG,address | 0xFFFFFFFC);
+ OUTREG32(PSTREAM_FBADDR1_REG,address | 0x80000000);
+ }
+
+ return;
+}
+#if 0
void SavageAdjustFrame(int scrnIndex, int x, int y, int flags)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
@@ -3038,7 +3464,7 @@ void SavageAdjustFrame(int scrnIndex, int x, int y, int flags)
return;
}
-
+#endif
Bool SavageSwitchMode(int scrnIndex, DisplayModePtr mode, int flags)
{
@@ -3150,7 +3576,9 @@ SavageUpdateKey(ScrnInfoPtr pScrn, int r, int g, int b)
}
}
+#if 0
#define inStatus1() (hwp->readST01( hwp ))
+#endif
void SavageLoadPaletteSavage4(ScrnInfoPtr pScrn, int numColors, int *indicies,
LOCO *colors, VisualPtr pVisual)
@@ -3160,11 +3588,11 @@ void SavageLoadPaletteSavage4(ScrnInfoPtr pScrn, int numColors, int *indicies,
int updateKey = -1;
vgaHWPtr hwp = VGAHWPTR(pScrn);
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
for (i=0; i<numColors; i++) {
if (!(inStatus1()) & 0x08)
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
index = indicies[i];
VGAOUT8(0x3c8, index);
VGAOUT8(0x3c9, colors[index].red);
@@ -3288,6 +3716,8 @@ void SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file)
break;
case S3_SAVAGE4:
case S3_PROSAVAGE:
+ case S3_PROSAVAGEDDR:
+ case S3_TWISTER:
case S3_SUPERSAVAGE:
success = (ALT_STATUS_WORD0 & 0x0081ffff) == 0x00800000;
break;
@@ -3321,6 +3751,7 @@ void SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file)
OUTREG(MONO_PAT_1, ~0);
SavageSetGBD(pScrn);
+
}
@@ -3390,6 +3821,24 @@ static void SavageDPMS(ScrnInfoPtr pScrn, int mode, int flags)
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n", mode);
break;
}
+
+ if ((!psav->CrtOnly) && psav->PanelX) {
+ switch (mode) {
+ case DPMSModeOn:
+ VGAOUT8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
+ VGAOUT8(0x3c5, VGAIN8(0x3c5) | 0x10);
+ break;
+ case DPMSModeStandby:
+ case DPMSModeSuspend:
+ case DPMSModeOff:
+ VGAOUT8(0x3c4, 0x31); /* SR31 bit 4 - FP enable */
+ VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x10);
+ break;
+ default:
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n", mode);
+ break;
+ }
+ }
VGAOUT8(0x3c4, 0x0d);
VGAOUT8(0x3c5, srd);
@@ -3397,20 +3846,25 @@ static void SavageDPMS(ScrnInfoPtr pScrn, int mode, int flags)
return;
}
+static void
+SavageProbeDDC(ScrnInfoPtr pScrn, int index)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ ConfiguredMonitor = vbeDoEDID(psav->pVbe, NULL);
+}
static unsigned int
SavageDDC1Read(ScrnInfoPtr pScrn)
{
- register vgaHWPtr hwp = VGAHWPTR(pScrn);
register unsigned char tmp;
SavagePtr psav = SAVPTR(pScrn);
- VerticalRetraceWait(psav);
-
- InI2CREG(psav,tmp);
- while (hwp->readST01(hwp)&0x8) {};
- while (!(hwp->readST01(hwp)&0x8)) {};
-
+ UnLockExtRegs();
+
+ VerticalRetraceWait();
+
+ InI2CREG(tmp,psav->I2CPort);
+
return ((unsigned int) (tmp & 0x08));
}
@@ -3419,38 +3873,29 @@ SavageDDC1(int scrnIndex)
{
ScrnInfoPtr pScrn = xf86Screens[scrnIndex];
SavagePtr psav = SAVPTR(pScrn);
- unsigned char tmp;
- Bool success = FALSE;
+ uchar byte;
xf86MonPtr pMon;
+
+ UnLockExtRegs();
/* initialize chipset */
- InI2CREG(psav,tmp);
- OutI2CREG(psav,tmp | 0x12);
+ InI2CREG(byte,psav->I2CPort);
+ OutI2CREG(byte | 0x12,psav->I2CPort);
+
+ pMon = xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeed,SavageDDC1Read);
+ if (!pMon)
+ return FALSE;
+
+ xf86PrintEDID(pMon);
- if ((pMon = xf86PrintEDID(
- xf86DoEDID_DDC1(scrnIndex,vgaHWddc1SetSpeedWeak(),
- SavageDDC1Read))) != NULL)
- success = TRUE;
xf86SetDDCproperties(pScrn,pMon);
/* undo initialization */
- OutI2CREG(psav,tmp);
- return success;
-}
+ OutI2CREG(byte,psav->I2CPort);
-
-static void
-SavageProbeDDC(ScrnInfoPtr pScrn, int index)
-{
- vbeInfoPtr pVbe;
- if (xf86LoadSubModule(pScrn, "vbe")) {
- pVbe = VBEInit(NULL,index);
- ConfiguredMonitor = vbeDoEDID(pVbe, NULL);
- vbeFree(pVbe);
- }
+ return TRUE;
}
-
static void
SavageGetTvMaxSize(SavagePtr psav)
{
@@ -3474,10 +3919,62 @@ SavagePanningCheck(ScrnInfoPtr pScrn)
pMode = pScrn->currentMode;
psav->iResX = pMode->CrtcHDisplay;
psav->iResY = pMode->CrtcVDisplay;
+
+ if ((psav->iResX < psav->PanelX || psav->iResY < psav->PanelY))
+ psav->FPExpansion = TRUE;
+ else
+ psav->FPExpansion = FALSE;
+
if( psav->iResX < pScrn->virtualX || psav->iResY < pScrn->virtualY )
return TRUE;
else
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;
+ }
+}
diff --git a/src/savage_driver.h b/src/savage_driver.h
index ccf3972..ca7856e 100644
--- a/src/savage_driver.h
+++ b/src/savage_driver.h
@@ -24,6 +24,30 @@
#include "xf86xv.h"
#include "savage_regs.h"
+#include "savage_vbe.h"
+
+#ifdef XF86DRI
+#define _XF86DRI_SERVER_
+#include "savage_dripriv.h"
+#include "savage_dri.h"
+#include "savage_drm.h"
+#include "dri.h"
+#include "GL/glxint.h"
+#endif
+
+
+#ifndef uint
+typedef unsigned int uint;
+#endif
+#ifndef ulong
+typedef unsigned long ulong;
+#endif
+#ifndef ushort
+typedef unsigned short ushort;
+#endif
+#ifndef uchar
+typedef unsigned char uchar;
+#endif
#define VGAIN8(addr) MMIO_IN8(psav->MapBase+0x8000, addr)
#define VGAIN16(addr) MMIO_IN16(psav->MapBase+0x8000, addr)
@@ -33,10 +57,26 @@
#define VGAOUT16(addr,val) MMIO_OUT16(psav->MapBase+0x8000, addr, val)
#define VGAOUT(addr,val) MMIO_OUT32(psav->MapBase+0x8000, addr, val)
-#define INREG(addr) MMIO_IN32(psav->MapBase, addr)
-#define OUTREG(addr,val) MMIO_OUT32(psav->MapBase, addr, val)
+#define INREG8(addr) MMIO_IN8(psav->MapBase, addr)
#define INREG16(addr) MMIO_IN16(psav->MapBase, addr)
+#define INREG32(addr) MMIO_IN32(psav->MapBase, addr)
+#define OUTREG8(addr,val) MMIO_OUT8(psav->MapBase, addr, val)
#define OUTREG16(addr,val) MMIO_OUT16(psav->MapBase, addr, val)
+#define OUTREG32(addr,val) MMIO_OUT32(psav->MapBase, addr, val)
+#define INREG(addr) INREG32(addr)
+#define OUTREG(addr,val) OUTREG32(addr,val)
+
+#if X_BYTE_ORDER == X_LITTLE_ENDIAN
+#define B_O16(x) (x)
+#define B_O32(x) (x)
+#else
+#define B_O16(x) ((((x) & 0xff) << 8) | (((x) & 0xff) >> 8))
+#define B_O32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \
+ | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24))
+#endif
+#define L_ADD(x) (B_O32(x) & 0xffff) + ((B_O32(x) >> 12) & 0xffff00)
+
+#define SAVAGEIOMAPSIZE 0x80000
#define SAVAGE_CRT_ON 1
#define SAVAGE_LCD_ON 2
@@ -78,6 +118,48 @@ typedef struct {
int redShift, greenShift, blueShift;
} savageOverlayRec;
+/* Tiling defines */
+#define TILE_SIZE_BYTE 2048 /* 0x800, 2K */
+
+#define TILEHEIGHT_16BPP 16
+#define TILEHEIGHT_32BPP 16
+#define TILEHEIGHT 16 /* all 16 and 32bpp tiles are 16 lines high */
+
+#define TILEWIDTH_BYTES 128 /* 2048/TILEHEIGHT (** not for use w/8bpp tiling) */
+#define TILEWIDTH8BPP_BYTES 64 /* 2048/TILEHEIGHT_8BPP */
+#define TILEWIDTH_16BPP 64 /* TILEWIDTH_BYTES/2-BYTES-PER-PIXEL */
+#define TILEWIDTH_32BPP 32 /* TILEWIDTH_BYTES/4-BYTES-PER-PIXEL */
+
+/* Bitmap descriptor structures for BCI */
+typedef struct _HIGH {
+ ushort Stride;
+ uchar Bpp;
+ uchar ResBWTile;
+} HIGH;
+
+typedef struct _BMPDESC1 {
+ ulong Offset;
+ HIGH HighPart;
+} BMPDESC1;
+
+typedef struct _BMPDESC2 {
+ ulong LoPart;
+ ulong HiPart;
+} BMPDESC2;
+
+typedef union _BMPDESC {
+ BMPDESC1 bd1;
+ BMPDESC2 bd2;
+} BMPDESC;
+
+typedef struct _StatInfo {
+ int origMode;
+ int pageCnt;
+ pointer statBuf;
+ int realSeg;
+ int realOff;
+} StatInfoRec,*StatInfoPtr;
+
typedef struct _Savage {
SavageRegRec SavedReg;
SavageRegRec ModeReg;
@@ -88,15 +170,20 @@ typedef struct _Savage {
int Bpp, Bpl, ScissB;
unsigned PlaneMask;
I2CBusPtr I2C;
+ I2CBusPtr DVI;
+ unsigned char DDCPort;
+ unsigned char I2CPort;
int videoRambytes;
int videoRamKbytes;
int MemOffScreen;
int CursorKByte;
+ int endfb;
/* These are physical addresses. */
unsigned long FrameBufferBase;
unsigned long MmioBase;
+ unsigned long ApertureBase;
unsigned long ShadowPhysical;
/* These are linear addresses. */
@@ -104,6 +191,7 @@ typedef struct _Savage {
unsigned char* BciMem;
unsigned char* MapBaseDense;
unsigned char* FBBase;
+ unsigned char* ApertureMap;
unsigned char* FBStart;
CARD32 volatile * ShadowVirtual;
@@ -139,6 +227,7 @@ typedef struct _Savage {
int iDevInfo;
int iDevInfoPrim;
+ Bool FPExpansion;
int PanelX; /* panel width */
int PanelY; /* panel height */
int iResX; /* crtc X display */
@@ -213,6 +302,65 @@ typedef struct _Savage {
savageOverlayRec overlay;
int overlayDepth;
int primStreamBpp;
+
+#ifdef XF86DRI
+ int LockHeld;
+ Bool directRenderingEnabled;
+ DRIInfoPtr pDRIInfo;
+ int drmFD;
+ int numVisualConfigs;
+ __GLXvisualConfig* pVisualConfigs;
+ SAVAGEConfigPrivPtr pVisualConfigsPriv;
+ SAVAGEDRIServerPrivatePtr DRIServerInfo;
+
+
+#if 0
+ Bool haveQuiescense;
+ void (*GetQuiescence)(ScrnInfoPtr pScrn);
+#endif
+
+ int agpMode;
+ drmSize agpSize;
+ FBLinearPtr reserved;
+
+ unsigned int surfaceAllocation[7];
+ unsigned int xvmcContext;
+ unsigned int DRIrunning;
+ unsigned int hwmcOffset;
+ unsigned int hwmcSize;
+
+#endif
+
+ Bool bDisableXvMC;
+ Bool disableCOB;
+ Bool BCIforXv;
+
+ /* Bitmap Descriptors for BCI */
+ BMPDESC GlobalBD;
+ BMPDESC PrimaryBD;
+ BMPDESC SecondBD;
+ /* do we disable tile mode by option? */
+ Bool bDisableTile;
+ /* if we enable tile,we only support tile under 16/32bpp */
+ Bool bTiled;
+ int lDelta;
+ int ulAperturePitch; /* aperture pitch */
+
+ int l3DDelta;
+ int ul3DAperturePitch; /* pitch for 3D */
+ /*
+ * cxMemory is number of pixels across screen width
+ * cyMemory is number of scanlines in available adapter memory.
+ *
+ * cxMemory * cyMemory is used to determine how much memory to
+ * allocate to our heap manager. So make sure that any space at the
+ * end of video memory set aside at bInitializeHardware time is kept
+ * out of the cyMemory calculation.
+ */
+ int cxMemory,cyMemory;
+
+ StatInfoRec StatInfo; /* save the SVGA state */
+
} SavageRec, *SavagePtr;
/* Video flags. */
@@ -229,6 +377,41 @@ typedef struct _Savage {
#define writefb savagewritefb
#define writescan savagewritescan
+/* add for support DRI */
+#ifdef XF86DRI
+
+#define SAVAGE_FRONT 0x1
+#define SAVAGE_BACK 0x2
+#define SAVAGE_DEPTH 0x4
+#define SAVAGE_STENCIL 0x8
+
+Bool SAVAGEDRIScreenInit( ScreenPtr pScreen );
+Bool SAVAGEInitMC(ScreenPtr pScreen);
+void SAVAGEDRICloseScreen( ScreenPtr pScreen );
+Bool SAVAGEDRIFinishScreenInit( ScreenPtr pScreen );
+
+Bool SAVAGELockUpdate( ScrnInfoPtr pScrn, drmLockFlags flags );
+
+#if 0
+void SAVAGEGetQuiescence( ScrnInfoPtr pScrn );
+void SAVAGEGetQuiescenceShared( ScrnInfoPtr pScrn );
+#endif
+
+void SAVAGESelectBuffer(ScrnInfoPtr pScrn, int which);
+
+#if 0
+Bool SAVAGECleanupDma(ScrnInfoPtr pScrn);
+Bool SAVAGEInitDma(ScrnInfoPtr pScrn, int prim_size);
+#endif
+
+#define SAVAGE_AGP_1X_MODE 0x01
+#define SAVAGE_AGP_2X_MODE 0x02
+#define SAVAGE_AGP_4X_MODE 0x04
+#define SAVAGE_AGP_MODE_MASK 0x07
+
+#endif
+
+
/* Prototypes. */
extern void SavageCommonCalcClock(long freq, int min_m, int min_n1,
@@ -250,6 +433,7 @@ Bool SavageInitAccel(ScreenPtr);
void SavageInitialize2DEngine(ScrnInfoPtr);
void SavageSetGBD(ScrnInfoPtr);
void SavageAccelSync(ScrnInfoPtr);
+/*int SavageHelpSolidROP(ScrnInfoPtr pScrn, int *fg, int pm, int *rop);*/
/* In savage_i2c.c. */
@@ -276,7 +460,6 @@ unsigned short SavageGetBIOSModes(
int iDepth,
SavageModeEntryPtr s3vModeTable );
-
/* In savage_video.c */
void SavageInitVideo( ScreenPtr pScreen );
diff --git a/src/savage_regs.h b/src/savage_regs.h
index 92f0584..9d80e94 100644
--- a/src/savage_regs.h
+++ b/src/savage_regs.h
@@ -29,12 +29,17 @@
#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX))
-#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) || (chip==S3_PROSAVAGE))
+#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) \
+ || (chip==S3_PROSAVAGE) \
+ || (chip==S3_TWISTER) \
+ || (chip==S3_PROSAVAGEDDR))
#define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE))
#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000))
+#define S3_MOBILE_TWISTER_SERIES(chip) ((chip==S3_TWISTER) \
+ ||(chip==S3_PROSAVAGEDDR))
/* Chip tags. These are used to group the adapters into
* related families.
@@ -46,6 +51,8 @@ enum S3CHIPTAGS {
S3_SAVAGE_MX,
S3_SAVAGE4,
S3_PROSAVAGE,
+ S3_TWISTER,
+ S3_PROSAVAGEDDR,
S3_SUPERSAVAGE,
S3_SAVAGE2000,
S3_LAST
@@ -66,6 +73,99 @@ enum S3CHIPTAGS {
#define STREAMS_TIMEOUT_REG 0x8208
#define MISC_TIMEOUT_REG 0x820c
+#define SAVAGE_NEWMMIO_REGBASE_S3 0x1000000 /* 16MB */
+#define SAVAGE_NEWMMIO_REGBASE_S4 0x0000000
+#define SAVAGE_NEWMMIO_REGSIZE 0x0080000 /* 512kb */
+#define SAVAGE_NEWMMIO_VGABASE 0x8000
+
+#define ADVANCED_FUNC_CTRL 0x850C
+
+/*
+ * CR/SR registers MMIO offset
+ * MISC Output Register(W:0x3c2,R:0x3cc) controls CR is 0X83Cx or 0X83Bx
+ * but do we need to set MISC Output Register ???
+ * (Note that CRT_ADDRESS_REG and CRT_DATA_REG are assumed to be COLOR)???
+ */
+#define MMIO_BASE_OF_VGA3C0 0X83C0
+#define MMIO_BASE_OF_VGA3D0 0X83D0
+
+#define ATTR_ADDRESS_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C0 - 0x03C0))
+#define ATTR_DATA_WRITE_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C0 - 0x03C0))
+#define ATTR_DATA_READ_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C1 - 0x03C0))
+#define VIDEO_SUBSYSTEM_ENABLE \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C3 - 0x03C0))
+#define SEQ_ADDRESS_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C4 - 0x03C0))
+#define SEQ_DATA_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C5 - 0x03C0))
+#define DAC_PIXEL_MASK_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C6 - 0x03C0))
+#define DAC_PEL_MASK \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C6 - 0x03C0))
+#define DAC_STATUS_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C7 - 0x03C0))
+#define DAC_ADDRESS_READ_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C7 - 0x03C0))
+#define DAC_ADDRESS_WRITE_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C8 - 0x03C0))
+#define DAC_DATA_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C9 - 0x03C0))
+#define DAC_DATA_REG_PORT \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C9 - 0x03C0))
+#define MISC_OUTPUT_REG_WRITE \
+ (MMIO_BASE_OF_VGA3C0 + (0x03C2 - 0x03C0))
+#define MISC_OUTPUT_REG_READ \
+ (MMIO_BASE_OF_VGA3C0 + (0x03CC - 0x03C0))
+#define GR_ADDRESS_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03CE - 0x03C0))
+#define GR_DATA_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x03CF - 0x03C0))
+#define WAKEUP_REG \
+ (MMIO_BASE_OF_VGA3C0 + (0x0510 - 0x03C0))
+
+#define CRT_ADDRESS_REG \
+ (MMIO_BASE_OF_VGA3D0 + (0x03D4 - 0x03D0))
+#define CRT_DATA_REG \
+ (MMIO_BASE_OF_VGA3D0 + (0x03D5 - 0x03D0))
+#define SYSTEM_CONTROL_REG \
+ (MMIO_BASE_OF_VGA3D0 + (0x03DA - 0x03D0))
+
+/* GX-3 Configuration/Status Registers */
+#define S3_SHADOW_STATUS 0x48C0C
+#define S3_BUFFER_THRESHOLD 0x48C10
+#define S3_OVERFLOW_BUFFER 0x48C14
+#define S3_OVERFLOW_BUFFER_PTR 0x48C18
+
+#define ENABLE_BCI 0x08 /* MM48C18_3 */
+#define ENABLE_COMMAND_OVERFLOW_BUF 0x04 /* MM48C18_2 */
+#define ENABLE_COMMAND_BUF_STATUS_UPDATE 0x02 /* MM48C18_1 */
+#define ENABLE_SHADOW_STATUS_UPDATE 0x01 /* MM48C0C_0 */
+
+
+#define MEMORY_CTRL0_REG 0xCA
+#define MEMORY_CTRL1_REG 0xCB
+#define MEMORY_CTRL2_REG 0xCC
+
+#define MEMORY_CONFIG_REG 0x31
+
+/* bitmap descriptor register */
+#define S3_GLB_BD_LOW 0X8168
+#define S3_GLB_BD_HIGH 0X816C
+#define S3_PRI_BD_LOW 0X8170
+#define S3_PRI_BD_HIGH 0X8174
+#define S3_SEC_BD_LOW 0X8178
+#define S3_SEC_BD_HIGH 0X817c
+
+#define SELECT_IGA1 0x4026
+#define SELECT_IGA2_READS_WRITES 0x4f26
+
+#define MEM_PS1 0x10 /*CRCA_4 :Primary stream 1*/
+#define MEM_PS2 0x20 /*CRCA_5 :Primary stream 2*/
+#define MEM_SS1 0x40 /*CRCA_6 :Secondary stream 1*/
+#define MEM_SS2 0x80 /*CRCA_7 :Secondary stream 2*/
#define SUBSYS_STAT_REG 0x8504
@@ -77,6 +177,28 @@ enum S3CHIPTAGS {
#define MONO_PAT_0 0xa4e8
#define MONO_PAT_1 0xa4ec
+#define TILED_SURFACE_REGISTER_0 0x48c40
+#define TILED_SURFACE_REGISTER_1 0x48c44
+#define TILED_SURFACE_REGISTER_2 0x48c48
+#define TILED_SURFACE_REGISTER_3 0x48c4c
+#define TILED_SURFACE_REGISTER_4 0x48c50
+
+#define TILED_SURF_BPP4 0x00000000 /* bits 31-30=00 for 4 bits/pixel */
+#define TILED_SURF_BPP8 0x40000000 /* bits 31-30=01 for 8 bits/pixel */
+#define TILED_SURF_BPP16 0x80000000 /* bits 31-30=10 for 16 bits/pixel */
+#define TILED_SURF_BPP32 0xC0000000 /* bits 31-30=11 for 32 bits/pixel */
+
+/*
+ * CR88_4 =1 : disable block write
+ * the "2D" is partly to set this apart from "BLOCK_WRITE_DISABLE"
+ * constant used for bitmap descriptor
+ */
+#define DISABLE_BLOCK_WRITE_2D 0x10
+#define BLOCK_WRITE_DISABLE 0x0
+
+/* CR31[0] set = Enable 8MB display memory through 64K window at A0000H. */
+#define ENABLE_CPUA_BASE_A0000 0x01
+
/* Constants for CR69. */
#define CRT_ACTIVE 0x01
@@ -97,33 +219,67 @@ enum S3CHIPTAGS {
#define MAXFIFO 0x7f00
+#define inStatus1() (VGAHWPTR(pScrn))->readST01( VGAHWPTR(pScrn) )
+
+
/*
- * NOTE: don't remove 'VGAIN8(vgaCRIndex);'.
- * If not present it will cause lockups on Savage4.
- * Ask S3, why.
- */
-#define VerticalRetraceWait(psav) \
-{ \
- VGAIN8(psav->vgaIOBase+4); \
- VGAOUT8(psav->vgaIOBase+4, 0x17); \
- if (VGAIN8(psav->vgaIOBase+5) & 0x80) { \
- while ((VGAIN8(psav->vgaIOBase + 0x0a) & 0x08) == 0x08) {}; \
- while ((VGAIN8(psav->vgaIOBase + 0x0a) & 0x08) == 0x00) {}; \
+ * unprotect CRTC[0-7]
+ * CR11_7 = 0: Writing to all CRT Controller registers enabled
+ * = 1: Writing to all bits of CR0~CR7 except CR7_4 disabled
+ */
+#define UnProtectCRTC() \
+do { \
+ uchar byte; \
+ OUTREG8(CRT_ADDRESS_REG,0x11); \
+ byte = INREG8(CRT_DATA_REG) & 0X7F; \
+ OUTREG16(CRT_ADDRESS_REG,byte << 8 | 0x11); \
+} while (0)
+
+/*
+ * unlock extended regs
+ * CR38:unlock CR20~CR3F
+ * CR39:unlock CR40~CRFF
+ * SR08:unlock SR09~SRFF
+ */
+#define UnLockExtRegs() \
+do { \
+ OUTREG16(CRT_ADDRESS_REG,0X4838); \
+ OUTREG16(CRT_ADDRESS_REG,0XA039); \
+ OUTREG16(SEQ_ADDRESS_REG,0X0608); \
+} while (0)
+
+#define VerticalRetraceWait() \
+do { \
+ INREG8(CRT_ADDRESS_REG); \
+ OUTREG8(CRT_ADDRESS_REG, 0x17); \
+ if (INREG8(CRT_DATA_REG) & 0x80) { \
+ int i = 0x10000; \
+ while ((INREG8(SYSTEM_CONTROL_REG) & 0x08) == 0x08 && i--) ; \
+ i = 0x10000; \
+ while ((INREG8(SYSTEM_CONTROL_REG) & 0x08) == 0x00 && i--) ; \
} \
-}
-
-#define I2C_REG 0xa0
-#define InI2CREG(psav,a) \
-{ \
- VGAOUT8(psav->vgaIOBase + 4, I2C_REG); \
- a = VGAIN8(psav->vgaIOBase + 5); \
-}
-
-#define OutI2CREG(psav,a) \
-{ \
- VGAOUT8(psav->vgaIOBase + 4, I2C_REG); \
- VGAOUT8(psav->vgaIOBase + 5, a); \
-}
+} while (0)
+
+/*
+ * Jiayo Hsu, Mar 21, 2002
+ * modify this to scalable schema,because different chips have differnt regs,
+ * besides add in patch code for Paramount(SuperSavage) from 2K
+ */
+#define InI2CREG(a,reg) \
+do { \
+ OUTREG8(CRT_ADDRESS_REG, reg); \
+ if (psav->Chipset == S3_SUPERSAVAGE) \
+ OUTREG8(CRT_DATA_REG, INREG8(CRT_DATA_REG)); \
+ a = INREG8(CRT_DATA_REG); \
+} while (0)
+
+#define OutI2CREG(a,reg) \
+do { \
+ OUTREG8(CRT_ADDRESS_REG, reg); \
+ if (psav->Chipset == S3_SUPERSAVAGE) \
+ OUTREG8(CRT_DATA_REG, a); \
+ OUTREG8(CRT_DATA_REG, a); \
+} while (0)
#define HZEXP_COMP_1 0x54
#define HZEXP_BORDER 0x58
diff --git a/src/savage_streams.c b/src/savage_streams.c
index 88936e3..fa11c40 100644
--- a/src/savage_streams.c
+++ b/src/savage_streams.c
@@ -10,8 +10,10 @@
static void SavageInitStreamsOld(ScrnInfoPtr pScrn);
static void SavageInitStreamsNew(ScrnInfoPtr pScrn);
+static void OverlayTwisterInit(ScrnInfoPtr pScrn);
static void OverlayParamInit(ScrnInfoPtr pScrn);
static void InitStreamsForExpansion(ScrnInfoPtr pScrn);
+static void PatchEnableSPofPanel(ScrnInfoPtr pScrn);
static void
SavageInitSecondaryStreamOld(ScrnInfoPtr pScrn)
@@ -108,7 +110,6 @@ SavageInitSecondaryStream(ScrnInfoPtr pScrn)
SavagePtr psav = SAVPTR(pScrn);
if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
- (psav->Chipset == S3_SUPERSAVAGE) ||
(psav->Chipset == S3_SAVAGE2000) )
SavageInitSecondaryStreamNew(pScrn);
else
@@ -118,7 +119,7 @@ SavageInitSecondaryStream(ScrnInfoPtr pScrn)
void SavageInitStreamsOld(ScrnInfoPtr pScrn)
{
SavagePtr psav = SAVPTR(pScrn);
- unsigned long jDelta;
+ /*unsigned long jDelta;*/
unsigned long format = 0;
/*
@@ -131,11 +132,33 @@ void SavageInitStreamsOld(ScrnInfoPtr pScrn)
/* Primary stream reflects the frame buffer. */
+ if (!psav->bTiled) {
+ OUTREG(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 */
+ OUTREG(PSTREAM_STRIDE_REG,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0x80000000 | (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ OUTREG(PSTREAM_STRIDE_REG,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0xC0000000 | (psav->lDelta & 0x00001fff));
+ }
+ OUTREG(PSTREAM_FBSIZE_REG,
+ pScrn->virtualY * pScrn->virtualX * (pScrn->bitsPerPixel >> 3));
+
+
if (psav->FBStart2nd) {
- jDelta = pScrn->displayWidth;
+ unsigned long jDelta = pScrn->displayWidth;
format = 0 << 24;
+ OUTREG( PSTREAM_STRIDE_REG, jDelta );
+ OUTREG( PSTREAM_FBSIZE_REG, jDelta * pScrn->virtualY >> 3 );
} else {
- jDelta = pScrn->displayWidth * (pScrn->bitsPerPixel + 7) / 8;
+ /*jDelta = pScrn->displayWidth * (pScrn->bitsPerPixel + 7) / 8;*/
switch( pScrn->depth ) {
case 8: format = 0 << 24; break;
case 15: format = 3 << 24; break;
@@ -148,9 +171,9 @@ void SavageInitStreamsOld(ScrnInfoPtr pScrn)
OUTREG( PSTREAM_WINDOW_SIZE_REG, OS_WH(pScrn->displayWidth, pScrn->virtualY) );
OUTREG( PSTREAM_FBADDR0_REG, pScrn->fbOffset );
OUTREG( PSTREAM_FBADDR1_REG, 0 );
- OUTREG( PSTREAM_STRIDE_REG, jDelta );
+ /*OUTREG( PSTREAM_STRIDE_REG, jDelta );*/
OUTREG( PSTREAM_CONTROL_REG, format );
- OUTREG( PSTREAM_FBSIZE_REG, jDelta * pScrn->virtualY >> 3 );
+ /*OUTREG( PSTREAM_FBSIZE_REG, jDelta * pScrn->virtualY >> 3 );*/
OUTREG( COL_CHROMA_KEY_CONTROL_REG, 0 );
OUTREG( SSTREAM_CONTROL_REG, 0 );
@@ -171,6 +194,11 @@ void SavageInitStreamsOld(ScrnInfoPtr pScrn)
OUTREG( SSTREAM_WINDOW_SIZE_REG, OS_WH(10,2) );
OUTREG(STREAMS_FIFO_REG, 2 | 25 << 5 | 32 << 11);
+ if (S3_MOBILE_TWISTER_SERIES(psav->Chipset) &&
+ psav->FPExpansion) {
+ OverlayTwisterInit(pScrn);
+ }
+
{
vgaHWPtr hwp;
unsigned short vgaIOBase, vgaCRIndex, vgaCRReg;
@@ -193,7 +221,7 @@ static void
SavageInitStreamsNew(ScrnInfoPtr pScrn)
{
SavagePtr psav = SAVPTR(pScrn);
- unsigned long jDelta;
+ /*unsigned long jDelta;*/
xf86ErrorFVerb(STREAMS_TRACE, "SavageInitStreams\n" );
@@ -206,15 +234,40 @@ SavageInitStreamsNew(ScrnInfoPtr pScrn)
}
/* Primary stream reflects the frame buffer. */
+ OUTREG32(PRI_STREAM_FBUF_ADDR0, pScrn->fbOffset);
+ if (!psav->bTiled) {
+ OUTREG(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000) |
+ (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 16) {
+ /* Scanline-length-in-bytes/128-bytes-per-tile * 256 Qwords/tile */
+ OUTREG(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0x80000000 | (psav->lDelta & 0x00001fff));
+ }
+ else if (pScrn->bitsPerPixel == 32) {
+ OUTREG(PRI_STREAM_STRIDE,
+ (((psav->lDelta * 2) << 16) & 0x3FFFE000)
+ | 0xC0000000 | (psav->lDelta & 0x00001fff));
+ }
+ OUTREG(PRI_STREAM_BUFFERSIZE,
+ pScrn->virtualX * pScrn->virtualY * (pScrn->bitsPerPixel >> 3));
- if (psav->FBStart2nd)
- jDelta = pScrn->displayWidth;
- else
+ 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 );
+ }
+#if 0
+ else {
jDelta = pScrn->displayWidth * (pScrn->bitsPerPixel + 7) / 8;
-
- OUTREG( PRI_STREAM_BUFFERSIZE, jDelta * pScrn->virtualY >> 3 );
+ }
+#endif
+ /*OUTREG( PRI_STREAM_BUFFERSIZE, jDelta * pScrn->virtualY >> 3 );*/
OUTREG( PRI_STREAM_FBUF_ADDR0, pScrn->fbOffset );
- OUTREG( PRI_STREAM_STRIDE, jDelta );
+ /*OUTREG( PRI_STREAM_STRIDE, jDelta );*/
OUTREG( SEC_STREAM_CKEY_LOW, 0 );
OUTREG( SEC_STREAM_CKEY_UPPER, 0 );
@@ -254,6 +307,18 @@ SavageInitStreamsNew(ScrnInfoPtr pScrn)
#endif
}
+/*
+ * Function to get lcd factor, display offset for overlay use
+ * Input: pScrn; Output: x,yfactor, displayoffset in pScrn
+ */
+static void OverlayTwisterInit(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+
+ psav->cxScreen = psav->iResX;
+ InitStreamsForExpansion(pScrn);
+ PatchEnableSPofPanel(pScrn);
+}
/* Function to get lcd factor, display offset for overlay use
* Input: pScrn; Output: x,yfactor, displayoffset in pScrn
@@ -267,6 +332,40 @@ static void OverlayParamInit(ScrnInfoPtr pScrn)
InitStreamsForExpansion(pScrn);
}
+static
+void PatchEnableSPofPanel(ScrnInfoPtr pScrn)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+
+ UnLockExtRegs();
+
+ if (pScrn->bitsPerPixel == 8) {
+ OUTREG8(CRT_ADDRESS_REG,0x90);
+ OUTREG8(CRT_DATA_REG,INREG8(CRT_DATA_REG)|0x40);
+ }
+ else {
+ OUTREG8(CRT_ADDRESS_REG,0x90);
+ OUTREG8(CRT_DATA_REG,INREG8(CRT_DATA_REG)|0x48);
+ }
+
+ VerticalRetraceWait();
+
+ OUTREG8(CRT_ADDRESS_REG,0x67);
+ OUTREG8(CRT_DATA_REG,(INREG8(CRT_DATA_REG)&0xf3)|0x04);
+
+ OUTREG8(CRT_ADDRESS_REG,0x65);
+ OUTREG8(CRT_DATA_REG,INREG8(CRT_DATA_REG)|0xC0);
+
+ if (pScrn->bitsPerPixel == 8) {
+ OUTREG32(PSTREAM_CONTROL_REG,0x00000000);
+ } else {
+ OUTREG32(PSTREAM_CONTROL_REG,0x02000000);
+ }
+ OUTREG32(PSTREAM_WINDOW_SIZE_REG, 0x0);
+
+}
+
+
/* Function to calculate lcd expansion x,y factor and offset for overlay
*/
static void InitStreamsForExpansion(ScrnInfoPtr pScrn)
@@ -372,9 +471,6 @@ SavageStreamsOn(ScrnInfoPtr pScrn)
VGAOUT8( vgaCRIndex, EXT_MISC_CTRL2 );
if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
-#if 0 /* I don't think commenting this out is correct (EE) */
- (psav->Chipset == S3_SUPERSAVAGE) ||
-#endif
(psav->Chipset == S3_SAVAGE2000) )
{
SavageInitStreamsNew( pScrn );
@@ -383,7 +479,7 @@ SavageStreamsOn(ScrnInfoPtr pScrn)
/* Wait for VBLANK. */
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
/* Fire up streams! */
@@ -400,7 +496,7 @@ SavageStreamsOn(ScrnInfoPtr pScrn)
/* Wait for VBLANK. */
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
/* Fire up streams! */
@@ -411,7 +507,7 @@ SavageStreamsOn(ScrnInfoPtr pScrn)
/* Wait for VBLANK. */
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
/* Turn on secondary stream TV flicker filter, once we support TV. */
@@ -439,7 +535,6 @@ SavageStreamsOff(ScrnInfoPtr pScrn)
VGAOUT8( vgaCRIndex, EXT_MISC_CTRL2 );
if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
- (psav->Chipset == S3_SUPERSAVAGE) ||
(psav->Chipset == S3_SAVAGE2000) )
jStreamsControl = VGAIN8( vgaCRReg ) & NO_STREAMS;
else
@@ -447,7 +542,7 @@ SavageStreamsOff(ScrnInfoPtr pScrn)
/* Wait for VBLANK. */
- VerticalRetraceWait(psav);
+ VerticalRetraceWait();
/* Kill streams. */
diff --git a/src/savage_streams.h b/src/savage_streams.h
index 9707765..12fbd7d 100644
--- a/src/savage_streams.h
+++ b/src/savage_streams.h
@@ -10,9 +10,9 @@
/* New streams */
-/* CR67[2] = 1 : enable stream 1 */
+/* CR67[2] = 1 : enable secondary stream 1 */
#define ENABLE_STREAM1 0x04
-/* CR67[1] = 1 : enable stream 2 */
+/* CR67[1] = 1 : enable secondary stream 2 */
#define ENABLE_STREAM2 0x02
/* mask to clear CR67[2,1] */
#define NO_STREAMS 0xF9
@@ -53,6 +53,8 @@
#define PSTREAM_FBADDR1_REG 0x81C4
#define PSTREAM_STRIDE_REG 0x81C8
#define DOUBLE_BUFFER_REG 0x81CC
+/* updated by peterzhu,original define is DOUBLE_BUFFER_REG*/
+#define MULTIPLE_BUFFER_REG 0x81CC
#define SSTREAM_FBADDR0_REG 0x81D0
#define SSTREAM_FBADDR1_REG 0x81D4
#define SSTREAM_STRIDE_REG 0x81D8
@@ -72,6 +74,32 @@
#define OS_XY(x,y) (((x+1)<<16)|(y+1))
#define OS_WH(x,y) (((x-1)<<16)|(y))
+/* Streams Processor macros */
+#define H_Shift 0
+#define H_Mask (((1L << 11) - 1) << H_Shift)
+#define W_Shift 16
+#define W_Mask (((1L << 11) - 1) << W_Shift)
+
+#define Y_Shift 0
+#define Y_Mask (((1L << 11) - 1) << Y_Shift)
+#define X_Shift 16
+#define X_Mask (((1L << 11) - 1) << X_Shift)
+
+#define XY(x,y) ((((x+1)<<X_Shift)&X_Mask) | (((y+1)<<Y_Shift)&Y_Mask))
+#define WH(w,h) ((((w-1)<<W_Shift)&W_Mask) | (((h)<<H_Shift)&H_Mask))
+
+#define HSCALING_Shift 0
+#define HSCALING_Mask (((1L << 16)-1) << HSCALING_Shift)
+#define HSCALING(w0,w1) ((((unsigned int)(((double)w0/(double)w1) * (1 << 15))) \
+ << HSCALING_Shift) \
+ & HSCALING_Mask)
+
+#define VSCALING_Shift 0
+#define VSCALING_Mask (((1L << 20)-1) << VSCALING_Shift)
+#define VSCALING(h0,h1) ((((unsigned int) (((double)h0/(double)h1) * (1 << 15))) \
+ << VSCALING_Shift) \
+ & VSCALING_Mask)
+
/* New Streams Processor */
/* Stream Processor 1 */
diff --git a/src/savage_video.c b/src/savage_video.c
index 56c9a8f..848ae6b 100644
--- a/src/savage_video.c
+++ b/src/savage_video.c
@@ -4,10 +4,11 @@
#include "dix.h"
#include "dixstruct.h"
#include "fourcc.h"
-#include "xaalocal.h"
#include "savage_driver.h"
#include "savage_streams.h"
+#include "savage_regs.h"
+#include "savage_bci.h"
#define OFF_DELAY 200 /* milliseconds */
#define FREE_DELAY 60000
@@ -226,7 +227,6 @@ void savageOUTREG( SavagePtr psav, unsigned long offset, unsigned long value )
ErrorF( " now %08lx\n", (CARD32)MMIO_IN32( psav->MapBase, offset ) );
}
-
static void
SavageClipVWindow(ScrnInfoPtr pScrn)
{
@@ -254,7 +254,6 @@ void SavageInitVideo(ScreenPtr pScreen)
xf86ErrorFVerb(XVTRACE,"SavageInitVideo\n");
if(
S3_SAVAGE_MOBILE_SERIES(psav->Chipset) ||
- (psav->Chipset == S3_SUPERSAVAGE) ||
(psav->Chipset == S3_SAVAGE2000)
)
{
@@ -583,10 +582,10 @@ SavageSetupImageVideo(ScreenPtr pScreen)
psav->adaptor = adapt;
-#if 0
+ #if 0
psav->BlockHandler = pScreen->BlockHandler;
pScreen->BlockHandler = SavageBlockHandler;
-#endif
+ #endif
return adapt;
}
@@ -790,6 +789,89 @@ SavageQueryBestSize(
if(*p_w > 16384) *p_w = 16384;
}
+/* SavageCopyPlanarDataBCI() causes artifacts on the screen when used on savage4.
+ * It's probably something with the BCI. Maybe we need a waitforidle() or
+ * something...
+ */
+static void
+SavageCopyPlanarDataBCI(
+ ScrnInfoPtr pScrn,
+ unsigned char *srcY, /* Y */
+ unsigned char *srcV, /* V */
+ unsigned char *srcU, /* U */
+ unsigned char *dst,
+ int srcPitch, int srcPitch2,
+ int dstPitch,
+ int h,int w)
+{
+ SavagePtr psav = SAVPTR(pScrn);
+ /* half of the dest buffer for copying the YVU data to it ??? */
+ unsigned char *dstCopy = (unsigned char *)(((unsigned long)dst
+ + 2 * srcPitch * h
+ + 0x0f) & ~0x0f);
+ /* for pixel transfer */
+ unsigned long offsetY = (unsigned long)dstCopy - (unsigned long)psav->FBBase;
+ unsigned long offsetV = offsetY + srcPitch * h;
+ unsigned long offsetU = offsetV + srcPitch2 * (h>>1);
+ unsigned long dstOffset = (unsigned long)dst - (unsigned long)psav->FBBase;
+ int i;
+
+ BCI_GET_PTR;
+
+ /* copy Y planar */
+ for (i=0;i<srcPitch * h;i++) {
+ dstCopy[i] = srcY[i];
+ }
+
+ /* copy V planar */
+ dstCopy = dstCopy + srcPitch * h;
+ for (i=0;i<srcPitch2 * (h>>1);i++) {
+ dstCopy[i] = srcV[i];
+ }
+
+ /* copy U planar */
+ dstCopy = dstCopy + srcPitch2 * (h>>1);
+ for (i=0;i<srcPitch2 * (h>>1);i++) {
+ dstCopy[i] = srcU[i];
+ }
+
+ /*
+ * Transfer pixel data from one memory location to another location
+ * and reformat the data during the transfer
+ * a. program BCI51 to specify the source information
+ * b. program BCI52 to specify the destination information
+ * c. program BCI53 to specify the source dimensions
+ * d. program BCI54 to specify the destination dimensions
+ * e. (if the data is in YCbCr420 format)program BCI55,BCI56,BCI57 to
+ * locations of the Y,Cb,and Cr data
+ * f. program BCI50(command=011) to specify the formatting options and
+ * kick off the transfer
+ * this command can be used for color space conversion(YCbCr to RGB)
+ * or for oversampling, but not for both simultaneously. it can also be
+ * used to do mastered image transfer when the source is tiled
+ */
+
+ w = (w+0xf)&0xff0;
+ psav->WaitQueue(psav,11);
+ BCI_SEND(0x96070051);
+ BCI_SEND(offsetY);
+
+ BCI_SEND(dstOffset);
+
+ BCI_SEND(((h-1)<<16)|((w-1)>>3));
+
+ BCI_SEND(dstPitch >> 3);
+
+
+ BCI_SEND(offsetU);
+ BCI_SEND(offsetV);
+
+ BCI_SEND((srcPitch2 << 16)| srcPitch2);
+
+ BCI_SEND(0x96010050);
+ BCI_SEND(0x00200003 | srcPitch);
+ BCI_SEND(0xC0170000);
+}
static void
SavageCopyData(
@@ -922,6 +1004,7 @@ SavageDisplayVideoOld(
/*DisplayModePtr mode = pScrn->currentMode;*/
int vgaCRIndex, vgaCRReg, vgaIOBase;
CARD32 ssControl;
+ int scalratio;
vgaIOBase = hwp->IOBase;
@@ -933,6 +1016,18 @@ SavageDisplayVideoOld(
SavageResetVideo(pScrn);
}
+ /* Calculate horizontal scale factor. */
+ if (S3_MOBILE_TWISTER_SERIES(psav->Chipset)
+ && psav->FPExpansion) {
+ drw_w = (((float)(drw_w * psav->XExp1)/(float)psav->XExp2)+1);
+ drw_h = (float)(drw_h * psav->YExp1)/(float)psav->YExp2+1;
+ dstBox->x1 = (float)(dstBox->x1 * psav->XExp1)/(float)psav->XExp2;
+ dstBox->y1 = (float)(dstBox->y1 * psav->YExp1)/(float)psav->YExp2;
+
+ dstBox->x1 += psav->displayXoffset;
+ dstBox->y1 += psav->displayYoffset;
+ }
+
/* Set surface format. */
ssControl = (GetBlendForFourCC(psav->videoFourCC) << 24) | src_w;
@@ -944,9 +1039,16 @@ SavageDisplayVideoOld(
/* Calculate vertical scale factor. */
- OUTREG(SSTREAM_LINES_REG, src_h );
+ /*
+ * MM81E8:Secondary Stream Source Line Count
+ * bit_0~10: # of lines in the source image (before scaling)
+ * bit_15 = 1: Enable vertical interpolation
+ * 0: Line duplicaion
+ */
+ OUTREG(SSTREAM_LINES_REG, 0x00008000 | src_h );
OUTREG(SSTREAM_VINITIAL_REG, 0 );
- OUTREG(SSTREAM_VSCALE_REG, (src_h << 15) / drw_h );
+ /*OUTREG(SSTREAM_VSCALE_REG, (src_h << 15) / drw_h );*/
+ OUTREG(SSTREAM_VSCALE_REG, VSCALING(src_h,drw_h));
/* Set surface location and stride. */
@@ -957,23 +1059,52 @@ SavageDisplayVideoOld(
OUTREG(SSTREAM_WINDOW_SIZE_REG, OS_WH(dstBox->x2-dstBox->x1,
dstBox->y2-dstBox->y1));
+ /*
+ * Process horizontal scaling
+ * upscaling and downscaling smaller than 2:1 controled by MM8198
+ * MM8190 controls downscaling mode larger than 2:1
+ */
+ scalratio = 0;
+ ssControl = 0;
+#if 0
if( src_w > (drw_w << 1) )
{
+ /* BUGBUG shouldn't this be >=? */
if( src_w <= (drw_w << 2) )
ssControl |= HDSCALE_4;
- else if( src_w <= (drw_w << 3) )
+ else if( src_w > (drw_w << 3) )
ssControl |= HDSCALE_8;
- else if( src_w <= (drw_w << 4) )
+ else if( src_w > (drw_w << 4) )
ssControl |= HDSCALE_16;
- else if( src_w <= (drw_w << 5) )
+ else if( src_w > (drw_w << 5) )
ssControl |= HDSCALE_32;
- else if( src_w <= (drw_w << 6) )
+ else if( src_w > (drw_w << 6) )
ssControl |= HDSCALE_64;
}
+#endif
+ if (src_w >= (drw_w * 2)) {
+ if (src_w < (drw_w * 4)) {
+ scalratio = HSCALING(2,1);
+ } else if (src_w < (drw_w * 8)) {
+ ssControl |= HDSCALE_4;
+ } else if (src_w < (drw_w * 16)) {
+ ssControl |= HDSCALE_8;
+ } else if (src_w < (drw_w * 32)) {
+ ssControl |= HDSCALE_16;
+ } else if (src_w < (drw_w * 64)) {
+ ssControl |= HDSCALE_32;
+ } else
+ ssControl |= HDSCALE_64;
+ } else
+ scalratio = HSCALING(src_w,drw_w);
ssControl |= src_w;
ssControl |= (1 << 24);
+ /* Wait for VBLANK. */
+ VerticalRetraceWait();
OUTREG(SSTREAM_CONTROL_REG, ssControl);
+ if (scalratio)
+ OUTREG(SSTREAM_STRETCH_REG,scalratio);
#if 0
/* Set color key on primary. */
@@ -1196,13 +1327,23 @@ SavagePutImage(
top &= ~1;
tmp = ((top >> 1) * srcPitch2) + (left >> 2);
offsetU += tmp;
- offsetV += tmp;
+ offsetV += tmp;
nlines = ((((y2 + 0xffff) >> 16) + 1) & ~1) - top;
- SavageCopyPlanarData(
- buf + (top * srcPitch) + (left >> 1),
- buf + offsetV,
- buf + offsetU,
- dst_start, srcPitch, srcPitch2, dstPitch, nlines, npixels);
+ if (S3_SAVAGE4_SERIES(psav->Chipset) && psav->BCIforXv
+ /*&& (!psav->disableCOB)*/) {
+ SavageCopyPlanarDataBCI(
+ pScrn,
+ buf + (top * srcPitch) + (left >> 1),
+ buf + offsetV,
+ 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);
+ }
break;
case FOURCC_Y211: /* Y211 */
case FOURCC_RV15: /* RGB15 */
@@ -1226,6 +1367,7 @@ SavagePutImage(
REGION_COPY(pScreen, &pPriv->clip, clipBoxes);
/* draw these */
xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes);
+
}
pPriv->videoStatus = CLIENT_VIDEO_ON;
@@ -1249,6 +1391,10 @@ SavageQueryImageAttributes(
if(offsets) offsets[0] = 0;
switch(id) {
+ case FOURCC_IA44:
+ if (pitches) pitches[0]=*w;
+ size=(*w)*(*h);
+ break;
case FOURCC_Y211:
size = *w << 2;
if(pitches) pitches[0] = size;
@@ -1281,7 +1427,6 @@ SavageQueryImageAttributes(
return size;
}
-
/****************** Offscreen stuff ***************/
typedef struct {
@@ -1483,3 +1628,4 @@ SavageInitOffscreenImages(ScreenPtr pScreen)
xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1);
}
+