diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/savage_accel.c | 1000 | ||||
-rw-r--r-- | src/savage_bci.h | 38 | ||||
-rw-r--r-- | src/savage_cursor.c | 11 | ||||
-rw-r--r-- | src/savage_dri.c | 1 | ||||
-rw-r--r-- | src/savage_driver.c | 833 | ||||
-rw-r--r-- | src/savage_driver.h | 189 | ||||
-rw-r--r-- | src/savage_regs.h | 208 | ||||
-rw-r--r-- | src/savage_streams.c | 137 | ||||
-rw-r--r-- | src/savage_streams.h | 32 | ||||
-rw-r--r-- | src/savage_video.c | 182 |
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); } + |