diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/savage_accel.c | 1018 | ||||
-rw-r--r-- | src/savage_bci.h | 41 | ||||
-rw-r--r-- | src/savage_cursor.c | 36 | ||||
-rw-r--r-- | src/savage_dga.c | 9 | ||||
-rw-r--r-- | src/savage_driver.c | 833 | ||||
-rw-r--r-- | src/savage_driver.h | 198 | ||||
-rw-r--r-- | src/savage_i2c.c | 8 | ||||
-rw-r--r-- | src/savage_regs.h | 281 | ||||
-rw-r--r-- | src/savage_vbe.c | 24 | ||||
-rw-r--r-- | src/savage_video.c | 452 |
10 files changed, 2479 insertions, 421 deletions
diff --git a/src/savage_accel.c b/src/savage_accel.c index b0ea828..59aede6 100644 --- a/src/savage_accel.c +++ b/src/savage_accel.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v 1.21 2003/08/04 10:32:26 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v 1.14 2001/12/13 18:01:50 eich Exp $ */ /* * @@ -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: * */ @@ -23,6 +24,12 @@ #include "savage_driver.h" #include "savage_regs.h" #include "savage_bci.h" +#include "savage_dri.h" + +#ifdef XF86DRI +#define _XF86DRI_SERVER_ +#include "savage_dri.h" +#endif /* Forward declaration of functions used in the driver */ @@ -65,7 +72,7 @@ static void SavageSubsequentSolidBresenhamLine( int err, int length, int octant); - +#if 0 static void SavageSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn, int x1, @@ -73,7 +80,7 @@ static void SavageSubsequentSolidTwoPointLine( int x2, int y2, int bias); - +#endif #if 0 static void SavageSetupForScreenToScreenColorExpand( ScrnInfoPtr pScrn, @@ -204,6 +211,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 @@ -212,8 +224,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) @@ -242,7 +275,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 ) @@ -260,23 +294,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; @@ -316,9 +365,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(PRI_STREAM_FBUF_ADDR0,0x00000000); + OUTREG32(PRI_STREAM_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) & 0x3FFFE000) | + (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) & 0x3FFFE000) + | 0x80000000 | (psav->lDelta & 0x00001fff)); + } + else if (pScrn->bitsPerPixel == 32) { + OUTREG32(PRI_STREAM_STRIDE, + (((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); @@ -326,6 +1003,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); @@ -354,10 +1034,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 @@ -417,7 +1096,7 @@ SavageInitAccel(ScreenPtr pScreen) #if 1 xaaptr->SetupForScreenToScreenCopy = SavageSetupForScreenToScreenCopy; xaaptr->SubsequentScreenToScreenCopy = SavageSubsequentScreenToScreenCopy; - xaaptr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | NO_PLANEMASK | ROP_NEEDS_SOURCE; + xaaptr->ScreenToScreenCopyFlags = NO_TRANSPARENCY | ROP_NEEDS_SOURCE; #endif @@ -438,7 +1117,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 ) @@ -457,13 +1135,9 @@ 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 +#if 1 if( (psav->Chipset == S3_SAVAGE3D) || (psav->Chipset == S3_SAVAGE4) ) { xaaptr->SetupForColor8x8PatternFill = @@ -472,8 +1146,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 @@ -481,10 +1155,10 @@ SavageInitAccel(ScreenPtr pScreen) /* Solid lines */ #if 1 - xaaptr->SolidLineFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + xaaptr->SolidLineFlags = NO_PLANEMASK; xaaptr->SetupForSolidLine = SavageSetupForSolidFill; xaaptr->SubsequentSolidBresenhamLine = SavageSubsequentSolidBresenhamLine; - xaaptr->SubsequentSolidTwoPointLine = SavageSubsequentSolidTwoPointLine; + /*xaaptr->SubsequentSolidTwoPointLine = SavageSubsequentSolidTwoPointLine;*/ #if 0 xaaptr->SubsequentSolidFillTrap = SavageSubsequentSolidFillTrap; #endif @@ -500,7 +1174,6 @@ SavageInitAccel(ScreenPtr pScreen) | SCANLINE_PAD_DWORD | BIT_ORDER_IN_BYTE_MSBFIRST | LEFT_EDGE_CLIPPING - | ROP_NEEDS_SOURCE ; xaaptr->SetupForImageWrite = SavageSetupForImageWrite; xaaptr->SubsequentImageWriteRect = SavageSubsequentImageWriteRect; @@ -511,7 +1184,7 @@ SavageInitAccel(ScreenPtr pScreen) /* WriteBitmap color expand */ #if 0 - xaaptr->WriteBitmapFlags = NO_PLANEMASK | ROP_NEEDS_SOURCE; + xaaptr->WriteBitmapFlags = NO_PLANEMASK; xaaptr->WriteBitmap = SavageWriteBitmapCPUToScreenColorExpand; #endif @@ -560,6 +1233,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; @@ -568,6 +1516,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); } @@ -1013,7 +1963,8 @@ SavageSetupForColor8x8PatternFill( cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP | BCI_CMD_DEST_GBD | BCI_CMD_PAT_PBD_COLOR_NEW; - mix = XAAHelpSolidROP( pScrn, &trans_col, planemask, &rop ); + /*mix = XAAHelpSolidROP( pScrn, &trans_col, planemask, &rop );*/ + mix = SavageHelpSolidROP( pScrn, &trans_col, planemask, &rop ); BCI_CMD_SET_ROP(cmd, rop); bd = BCI_BD_BW_DISABLE; @@ -1043,10 +1994,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)); } @@ -1088,7 +2040,7 @@ SavageSubsequentSolidBresenhamLine( e2+err)); } - +#if 0 static void SavageSubsequentSolidTwoPointLine( ScrnInfoPtr pScrn, @@ -1148,7 +2100,7 @@ SavageSubsequentSolidTwoPointLine( BCI_SEND( BCI_LINE_STEPS( 2 * (min - max), 2 * min ) ); BCI_SEND( BCI_LINE_MISC( max, ym, xp, yp, 2 * min - max ) ); } - +#endif static void diff --git a/src/savage_bci.h b/src/savage_bci.h index 0d7c489..2e58de2 100644 --- a/src/savage_bci.h +++ b/src/savage_bci.h @@ -1,8 +1,45 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_bci.h,v 1.4 2002/10/02 20:39:54 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_bci.h,v 1.2 2001/10/01 13:44:09 eich Exp $ */ #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 +108,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 16aaabf..614b3e5 100644 --- a/src/savage_cursor.c +++ b/src/savage_cursor.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_cursor.c,v 1.9 2003/01/18 15:22:29 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_cursor.c,v 1.6 2001/11/02 16:24:51 alanh Exp $ */ /* * Hardware cursor support for S3 Savage 4.0 driver. Taken with @@ -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 @@ -39,27 +41,6 @@ static void SavageSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); } #define MAX_CURS 64 -/* - * Disable HW Cursor on stretched LCDs. We don't know how to - * detect if display is stretched. Therefore we cannot rescale - * the HW cursor position. - */ - -static Bool -SavageUseHWCursor(ScreenPtr pScr, CursorPtr pCurs) -{ - ScrnInfoPtr pScrn = xf86Screens[pScr->myNum]; - SavagePtr psav = SAVPTR(pScrn); - - if (psav->PanelX != pScrn->currentMode->HDisplay - || psav->PanelY != pScrn->currentMode->VDisplay) { - /* BIT 1 : CRT is active, BIT 2 : LCD is active */ - unsigned char cr6d = inCRReg( 0x6d ); - if (cr6d & 0x02) - return FALSE; - } - return TRUE; -} Bool SavageHWCursorInit(ScreenPtr pScreen) @@ -101,12 +82,8 @@ SavageHWCursorInit(ScreenPtr pScreen) infoPtr->LoadCursorImage = SavageLoadCursorImage; infoPtr->HideCursor = SavageHideCursor; infoPtr->ShowCursor = SavageShowCursor; + infoPtr->UseHWCursor = NULL; - if ((S3_SAVAGE_MOBILE_SERIES(psav->Chipset) - || (psav->Chipset == S3_PROSAVAGE)) && !psav->CrtOnly) - infoPtr->UseHWCursor = SavageUseHWCursor; - else - infoPtr->UseHWCursor = NULL; if( !psav->CursorKByte ) psav->CursorKByte = pScrn->videoRam - 4; @@ -118,9 +95,8 @@ SavageHWCursorInit(ScreenPtr pScreen) void SavageShowCursor(ScrnInfoPtr pScrn) { - /* Turn cursor on. */ + /* Turn cursor on. */ outCRReg( 0x45, inCRReg(0x45) | 0x01 ); - SAVPTR(pScrn)->hwc_on = TRUE; } @@ -128,12 +104,12 @@ void SavageHideCursor(ScrnInfoPtr pScrn) { /* Turn cursor off. */ + if( S3_SAVAGE4_SERIES( SAVPTR(pScrn)->Chipset ) ) { waitHSync(5); } outCRReg( 0x45, inCRReg(0x45) & 0xfe ); - SAVPTR(pScrn)->hwc_on = FALSE; } static void diff --git a/src/savage_dga.c b/src/savage_dga.c index 55f057e..50a36b0 100644 --- a/src/savage_dga.c +++ b/src/savage_dga.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c,v 1.6 2003/01/18 15:22:29 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_dga.c,v 1.3 2001/05/18 23:35:32 dawes Exp $ */ /* Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. @@ -275,7 +275,7 @@ Savage_SetMode( psav->DGAactive = FALSE; SavageSwitchMode(index, pScrn->currentMode, 0); - if( psav->hwcursor && psav->hwc_on ) + if( psav->hwcursor ) SavageShowCursor(pScrn); } else { Bool holdBIOS = psav->UseBIOS; @@ -289,11 +289,8 @@ Savage_SetMode( pMode->bitsPerPixel, pMode->depth); #endif - if( psav->hwcursor && psav->hwc_on) { + if( psav->hwcursor ) SavageHideCursor(pScrn); - psav->hwc_on = TRUE; /* save for later restauration */ - } - if(!psav->DGAactive) { /* save the old parameters */ OldDisplayWidth[index] = pScrn->displayWidth; diff --git a/src/savage_driver.c b/src/savage_driver.c index 6589044..6dd59fa 100644 --- a/src/savage_driver.c +++ b/src/savage_driver.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v 1.43 2003/08/23 16:09:20 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v 1.24 2001/11/02 16:24:51 alanh Exp $ */ /* * vim: sw=4 ts=8 ai ic: * @@ -18,12 +18,21 @@ #include "globals.h" #define DPMS_SERVER #include "extensions/dpms.h" - +/* +#ifdef XvExtension #include "xf86xv.h" +#endif +*/ #include "savage_driver.h" +#include "savage_regs.h" #include "savage_bci.h" +#ifdef XF86DRI +#define _XF86DRI_SERVER_ +#include "savage_dri.h" +#endif + /* * prototypes @@ -72,13 +81,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 @@ -141,6 +152,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 } }; @@ -158,10 +171,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 }, @@ -189,16 +202,23 @@ typedef enum { ,OPTION_ROTATE ,OPTION_USEBIOS ,OPTION_SHADOW_STATUS + ,OPTION_VIDEORAM ,OPTION_CRT_ONLY ,OPTION_TV_ON ,OPTION_TV_PAL ,OPTION_FORCE_INIT + ,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 }, @@ -206,10 +226,17 @@ static const OptionInfoRec SavageOptions[] = { OPTION_USEBIOS, "UseBIOS", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_LCDCLOCK, "LCDClock", OPTV_FREQ, {0}, FALSE }, { OPTION_SHADOW_STATUS, "ShadowStatus", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_VIDEORAM, "VideoRAM", OPTV_INTEGER, {0}, FALSE }, { OPTION_CRT_ONLY, "CrtOnly", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_TV_ON, "TvOn", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_TV_PAL, "PAL", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_FORCE_INIT,"ForceInit", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_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 } }; @@ -238,6 +265,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 @@ -256,7 +338,6 @@ static const char *vbeSymbols[] = { NULL }; -#ifdef XFree86LOADER static const char *vbeOptSymbols[] = { "vbeModeInit", "VBESetVBEMode", @@ -264,7 +345,6 @@ static const char *vbeOptSymbols[] = { "VBEFreeVBEInfo", NULL }; -#endif static const char *ddcSymbols[] = { "xf86DoEDID_DDC1", @@ -277,6 +357,14 @@ static const char *ddcSymbols[] = { static const char *i2cSymbols[] = { "xf86CreateI2CBusRec", "xf86I2CBusInit", + "xf86CreateI2CDevRec", + "xf86I2CDevInit", + "xf86I2CWriteByte", + "xf86I2CWriteBytes", + "xf86I2CReadByte", + "xf86I2CReadBytes", + "xf86I2CWriteRead", + "xf86DestroyI2CDevRec", NULL }; @@ -285,8 +373,11 @@ static const char *xaaSymbols[] = { "XAACopyROP_PM", "XAACreateInfoRec", "XAADestroyInfoRec", + "XAAFillSolidRects", "XAAHelpPatternROP", +#if 0 /* AGD: this is unresolved... */ "XAAHelpSolidROP", +#endif "XAAInit", "XAAScreenIndex", NULL @@ -344,6 +435,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 { @@ -451,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; } @@ -491,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; } @@ -506,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; } @@ -522,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; @@ -541,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; } @@ -556,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; } @@ -572,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; } @@ -624,12 +715,9 @@ static Bool SavageProbe(DriverPtr drv, int flags) /* sanity checks */ if ((numDevSections = xf86MatchDevice("savage", &devSections)) <= 0) - return FALSE; - if (xf86GetPciVideoInfo() == NULL) { - if (devSections) - xfree(devSections); - return FALSE; - } + return FALSE; + if (xf86GetPciVideoInfo() == NULL) + return FALSE; numUsed = xf86MatchPciInstances("SAVAGE", PCI_VENDOR_S3, SavageChipsets, SavagePciChipsets, @@ -725,7 +813,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) * We support bpp of 8, 16, and 32. */ - if (!xf86SetDepthBpp(pScrn, 0, 0, 0, Support32bppFb)) + if (!xf86SetDepthBpp(pScrn, 8, 8, 8, Support32bppFb)) return FALSE; else { int requiredBpp; @@ -864,6 +952,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 @@ -889,6 +1026,13 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, from, "%ssing video BIOS to set modes\n", psav->UseBIOS ? "U" : "Not u" ); + pScrn->videoRam = 0; + if( xf86GetOptValInteger(psav->Options, OPTION_VIDEORAM, &pScrn->videoRam ) ) + { + xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, + "Option: VideoRAM %dkB\n", pScrn->videoRam ); + } + psav->LCDClock = 0.0; if( xf86GetOptValFreq( psav->Options, OPTION_LCDCLOCK, OPTUNITS_MHZ, &psav->LCDClock ) ) xf86DrvMsg( pScrn->scrnIndex, X_CONFIG, @@ -923,6 +1067,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) { @@ -986,9 +1161,6 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) } else psav->ChipRev = psav->PciInfo->chipRev; - if (pEnt->device->videoRam != 0) - pScrn->videoRam = pEnt->device->videoRam; - xfree(pEnt); /* maybe throw in some more sanity checks here */ @@ -1000,7 +1172,6 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) if (!SavageMapMMIO(pScrn)) { - SavageFreeRec(pScrn); vbeFree(psav->pVbe); return FALSE; } @@ -1032,7 +1203,6 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) if (!xf86SetGamma(pScrn, zeros)) { vbeFree(psav->pVbe); - SavageFreeRec(pScrn); return FALSE; } } @@ -1081,6 +1251,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; @@ -1121,51 +1293,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); @@ -1190,6 +1356,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; @@ -1202,42 +1370,47 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) break; } - /* Do the DDC dance. */ - - if( psav->Chipset != S3_PROSAVAGE ) { - ddc = xf86LoadSubModule(pScrn, "ddc"); - if (ddc) { -#if 0 - xf86MonPtr pMon = NULL; -#endif - - xf86LoaderReqSymLists(ddcSymbols, NULL); -#if 0 -/* - * On many machines, the attempt to read DDC information via VBE puts the - * BIOS access into a state which prevents me from reading mode information. - * This is a complete mystery to me. - */ - if ((psav->pVbe) - && ((pMon = xf86PrintEDID(vbeDoEDID(psav->pVbe, ddc))) != NULL)) - xf86SetDDCproperties(pScrn,pMon); - else -#endif - if (!SavageDDC1(pScrn->scrnIndex)) { - if ( xf86LoadSubModule(pScrn, "i2c") ) { - xf86LoaderReqSymLists(i2cSymbols,NULL); - if (SavageI2CInit(pScrn)) { - unsigned char tmp; - - InI2CREG(psav,tmp); - OutI2CREG(psav,tmp | 0x13); - xf86SetDDCproperties(pScrn,xf86PrintEDID( - xf86DoEDID_DDC2(pScrn->scrnIndex,psav->I2C))); - OutI2CREG(psav,tmp); - } - } - } - } + /* 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 */ @@ -1252,9 +1425,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 */ @@ -1286,7 +1460,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 ); @@ -1353,7 +1528,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; @@ -1476,10 +1663,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); return SavageModeInit(pScrn, pScrn->currentMode); } @@ -1492,11 +1693,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 + SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE); + SavageResetStreams(pScrn); SavageDisableMMIO(pScrn); + } @@ -1638,7 +1853,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); @@ -1696,6 +1912,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)) ) @@ -1852,14 +2075,30 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, /* set the correct clock for some BIOSes */ VGAOUT8(VGA_MISC_OUT_W, VGAIN8(VGA_MISC_OUT_R) | 0x0C); + /* Some BIOSes turn on clock doubling on non-doubled modes */ + if (pScrn->bitsPerPixel < 24) { + VGAOUT8(vgaCRIndex, 0x67); + if (!(VGAIN8(vgaCRReg) & 0x10)) { + VGAOUT8(0x3c4, 0x15); + VGAOUT8(0x3c5, VGAIN8(0x3C5) & ~0x10); + VGAOUT8(0x3c4, 0x18); + VGAOUT8(0x3c5, VGAIN8(0x3c5) & ~0x80); + } + } SavageInitialize2DEngine(pScrn); - SavageSetGBD(pScrn); VGAOUT16(vgaCRIndex, 0x0140); SavageSetGBD(pScrn); + +#ifdef XF86DRI + if (psav->directRenderingEnabled) + DRIUnlock(screenInfo.screens[pScrn->scrnIndex]); + psav->LockHeld = 0; +#endif + return; } @@ -1891,7 +2130,8 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, VGAOUT8(vgaCRIndex, 0x67); cr67 = VGAIN8(vgaCRReg); - VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c); /* no STREAMS yet */ + /*VGAOUT8(vgaCRReg, restore->CR67 & ~0x0c);*/ /* no STREAMS yet */ + VGAOUT8(vgaCRReg, restore->CR67 & ~0xf1); /* no streams for new and old streams engines */ /* restore extended regs */ VGAOUT8(vgaCRIndex, 0x66); @@ -1921,7 +2161,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); @@ -1953,7 +2194,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 & ~0xf1); /* no streams for new and old streams engines */ /* other mode timing and extended regs */ VGAOUT8(vgaCRIndex, 0x34); @@ -1976,6 +2218,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); @@ -2050,7 +2293,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); @@ -2071,7 +2314,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); @@ -2096,12 +2339,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); @@ -2110,6 +2348,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; } @@ -2158,7 +2403,6 @@ static Bool SavageMapMMIO(ScrnInfoPtr pScrn) } - static Bool SavageMapFB(ScrnInfoPtr pScrn) { SavagePtr psav = SAVPTR(pScrn); @@ -2180,6 +2424,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; @@ -2222,6 +2488,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) @@ -2273,6 +2579,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(); if (pScrn->bitsPerPixel == 16) { @@ -2378,8 +2707,29 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, if (xf86DPMSInit(pScreen, SavageDPMS, 0) == FALSE) xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed\n"); +#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->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); @@ -2424,7 +2774,7 @@ static int SavageInternalScreenInit(int scrnIndex, ScreenPtr pScreen) ret = fbScreenInit(pScreen, FBStart, width, height, pScrn->xDpi, pScrn->yDpi, - displayWidth, + psav->ulAperturePitch / (pScrn->bitsPerPixel >> 3), /*displayWidth,*/ pScrn->bitsPerPixel); return ret; } @@ -2502,7 +2852,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; @@ -2547,6 +2912,7 @@ static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode) break; } + if( psav->UseBIOS ) { int refresh; SavageModeEntryPtr pmt; @@ -2769,11 +3135,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; } @@ -2798,6 +3167,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; @@ -2815,6 +3191,7 @@ static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen) if (pScrn->vtSema) { SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr, FALSE); + SavageResetStreams(pScrn); vgaHWLock(hwp); SavageUnmapMem(pScrn, 0); } @@ -2828,22 +3205,71 @@ static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen) static Bool SavageSaveScreen(ScreenPtr pScreen, int mode) { +#if 0 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; +#endif TRACE(("SavageSaveScreen(0x%x)\n", mode)); - - if( pScrn->vtSema && SAVPTR(pScrn)->hwcursor && SAVPTR(pScrn)->hwc_on) { - +#if 0 + if( pScrn->vtSema && SAVPTR(pScrn)->hwcursor ) + { if( xf86IsUnblank(mode) ) SavageShowCursor( pScrn ); else SavageHideCursor( pScrn ); - SAVPTR(pScrn)->hwc_on = TRUE; } - - return vgaHWSaveScreen(pScreen, mode); +#endif + 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(PRI_STREAM_FBUF_ADDR0,address | 0xFFFFFFFC); + OUTREG32(PRI_STREAM_FBUF_ADDR1,address | 0x80000000); + } + + return; +} +#if 0 void SavageAdjustFrame(int scrnIndex, int x, int y, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; @@ -2870,7 +3296,7 @@ void SavageAdjustFrame(int scrnIndex, int x, int y, int flags) return; } - +#endif Bool SavageSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) { @@ -2947,7 +3373,9 @@ void SavageLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, } } +#if 0 #define inStatus1() (hwp->readST01( hwp )) +#endif void SavageLoadPaletteSavage4(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors, VisualPtr pVisual) @@ -2960,11 +3388,11 @@ void SavageLoadPaletteSavage4(ScrnInfoPtr pScrn, int numColors, int *indicies, vgaIOBase = hwp->IOBase; vgaCRIndex = vgaIOBase + 4; vgaCRReg = vgaIOBase + 5; - 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); @@ -3086,6 +3514,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; @@ -3119,6 +3549,7 @@ void SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file) OUTREG(MONO_PAT_1, ~0); SavageSetGBD(pScrn); + } @@ -3189,26 +3620,52 @@ static void SavageDPMS(ScrnInfoPtr pScrn, int mode, int flags) break; } + if ( (!psav->CrtOnly) && psav->UseBIOS && psav->PanelX ) { + SavageSetPanelEnabled(psav, (mode == DPMSModeOn)); + } + else 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); 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)); } @@ -3217,37 +3674,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,vgaHWddc1SetSpeed,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) { @@ -3271,10 +3720,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 b25fc56..712ad00 100644 --- a/src/savage_driver.h +++ b/src/savage_driver.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h,v 1.17 2003/04/23 14:18:37 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h,v 1.11 2001/08/09 19:14:13 dawes Exp $ */ #ifndef SAVAGE_VGAHWMMIO_H #define SAVAGE_VGAHWMMIO_H @@ -21,6 +21,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) @@ -30,10 +54,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 @@ -70,6 +110,47 @@ typedef struct { unsigned int MMPR0, MMPR1, MMPR2, MMPR3; } SavageRegRec, *SavageRegPtr; +/* 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; @@ -81,15 +162,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 endfb; CARD32 CursorKByte; /* These are physical addresses. */ unsigned long FrameBufferBase; unsigned long MmioBase; + unsigned long ApertureBase; unsigned long ShadowPhysical; /* These are linear addresses. */ @@ -97,6 +183,7 @@ typedef struct _Savage { unsigned char* BciMem; unsigned char* MapBaseDense; unsigned char* FBBase; + unsigned char* ApertureMap; unsigned char* FBStart; CARD32 volatile * ShadowVirtual; @@ -118,7 +205,6 @@ typedef struct _Savage { Bool fifo_moderate; Bool fifo_aggressive; Bool hwcursor; - Bool hwc_on; Bool NoAccel; Bool shadowFB; Bool UseBIOS; @@ -132,6 +218,7 @@ typedef struct _Savage { int iDevInfo; int iDevInfoPrim; + Bool FPExpansion; int PanelX; /* panel width */ int PanelY; /* panel height */ int iResX; /* crtc X display */ @@ -203,6 +290,64 @@ typedef struct _Savage { int dwBCIWait2DIdle; XF86OffscreenImagePtr offscreenImages; +#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. */ @@ -211,14 +356,40 @@ typedef struct _Savage { #define SAVPTR(p) ((SavagePtr)((p)->driverPrivate)) -/* Make the names of these externals driver-unique */ -#define gpScrn savagegpScrn -#define myOUTREG savageOUTREG -#define readdw savagereaddw -#define readfb savagereadfb -#define writedw savagewritedw -#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. */ @@ -241,6 +412,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. */ @@ -259,6 +431,7 @@ void SavageRefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox); void SavageSetTextMode( SavagePtr psav ); void SavageSetVESAMode( SavagePtr psav, int n, int Refresh ); +void SavageSetPanelEnabled( SavagePtr psav, Bool active ); void SavageFreeBIOSModeTable( SavagePtr psav, SavageModeTablePtr* ppTable ); SavageModeTablePtr SavageGetBIOSModeTable( SavagePtr psav, int iDepth ); @@ -267,7 +440,6 @@ unsigned short SavageGetBIOSModes( int iDepth, SavageModeEntryPtr s3vModeTable ); - /* In savage_video.c */ void SavageInitVideo( ScreenPtr pScreen ); diff --git a/src/savage_i2c.c b/src/savage_i2c.c index 01ac3e2..f3bda84 100644 --- a/src/savage_i2c.c +++ b/src/savage_i2c.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_i2c.c,v 1.3 2002/10/02 20:39:55 alanh Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_i2c.c,v 1.1 2001/02/13 21:15:19 dawes Exp $ */ /* Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. @@ -48,7 +48,8 @@ SavageI2CPutBits(I2CBusPtr b, int clock, int data) if(clock) reg |= 0x1; if(data) reg |= 0x2; - OutI2CREG(psav,reg); + /*OutI2CREG(psav,reg);*/ /*tim*/ + OutI2CREG(reg,psav->DDCPort); /*s3*/ /*ErrorF("SavageI2CPutBits: %d %d\n", clock, data); */ } @@ -59,7 +60,8 @@ SavageI2CGetBits(I2CBusPtr b, int *clock, int *data) SavagePtr psav = SAVPTR(pScrn); unsigned char reg = 0x10; - InI2CREG(psav,reg); + /*InI2CREG(psav,reg);*/ /*tim*/ + InI2CREG(reg,psav->DDCPort); /*s3*/ *clock = reg & 0x4; *data = reg & 0x8; diff --git a/src/savage_regs.h b/src/savage_regs.h index 8913f95..d66b2e3 100644 --- a/src/savage_regs.h +++ b/src/savage_regs.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h,v 1.13 2003/04/23 14:18:37 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h,v 1.10 2001/11/04 22:17:48 alanh Exp $ */ #ifndef _SAVAGE_REGS_H #define _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,133 @@ 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 + + +/**** S3 streams processor*****/ + +#define EXT_MISC_CTRL2 0x67 +/* CR67[2] = 1 : enable stream 1 */ +#define ENABLE_STREAM1 0x04 +/* CR67[1] = 1 : enable stream 2 */ +#define ENABLE_STREAM2 0x02 +/* mask to clear CR67[2,1] */ +#define NO_STREAMS 0xF9 +/* CR67[3] = 1 : Mem-mapped regs */ +#define USE_MM_FOR_PRI_STREAM 0x08 +#define HDM_SHIFT 16 +#define HDSCALE_4 (2 << HDM_SHIFT) +#define HDSCALE_8 (3 << HDM_SHIFT) +#define HDSCALE_16 (4 << HDM_SHIFT) +#define HDSCALE_32 (5 << HDM_SHIFT) +#define HDSCALE_64 (6 << HDM_SHIFT) + +/* Old Streams */ + +#define ENABLE_STREAMS_OLD 0x0c +#define NO_STREAMS_OLD 0xf3 +/* CR69[0] = 1 : Mem-mapped regs */ +#define USE_MM_FOR_PRI_STREAM_OLD 0x01 + + +#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*/ + +/* + * There are two different streams engines used in the Savage line. + * The old engine is in the 3D, 4, Pro, and Twister. + * The new engine is in the 2000, MX, IX, and Super. + */ + /* Stream Processor 1 */ /* Primary Stream 1 Frame Buffer Address 0 */ @@ -157,6 +291,35 @@ enum S3CHIPTAGS { /* Secondary Stream 2 Opaque Overlay Control */ #define SEC_STREAM2_OPAQUE_OVERLAY 0x8180 +/* streams registers for old engine */ +#define PSTREAM_CONTROL_REG 0x8180 +#define COL_CHROMA_KEY_CONTROL_REG 0x8184 +#define SSTREAM_CONTROL_REG 0x8190 +#define CHROMA_KEY_UPPER_BOUND_REG 0x8194 +#define SSTREAM_STRETCH_REG 0x8198 +#define COLOR_ADJUSTMENT_REG 0x819C +#define BLEND_CONTROL_REG 0x81A0 +#define PSTREAM_FBADDR0_REG 0x81C0 +#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 +#define SSTREAM_VSCALE_REG 0x81E0 +#define SSTREAM_VINITIAL_REG 0x81E4 +#define SSTREAM_LINES_REG 0x81E8 +#define STREAMS_FIFO_REG 0x81EC +#define PSTREAM_WINDOW_START_REG 0x81F0 +#define PSTREAM_WINDOW_SIZE_REG 0x81F4 +#define SSTREAM_WINDOW_START_REG 0x81F8 +#define SSTREAM_WINDOW_SIZE_REG 0x81FC +#define FIFO_CONTROL 0x8200 +#define PSTREAM_FBSIZE_REG 0x8300 +#define SSTREAM_FBSIZE_REG 0x8304 +#define SSTREAM_FBADDR2_REG 0x8308 #define SUBSYS_STAT_REG 0x8504 @@ -168,6 +331,43 @@ 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 */ + +/* 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)) + + +/* + * 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 @@ -188,6 +388,69 @@ enum S3CHIPTAGS { #define MAXFIFO 0x7f00 +#define inStatus1() (VGAHWPTR(pScrn))->readST01( VGAHWPTR(pScrn) ) + + +/* + * 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--) ; \ + } \ +} 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) + +#if 0 /* tim's code */ /* * NOTE: don't remove 'VGAIN8(vgaCRIndex);'. * If not present it will cause lockups on Savage4. @@ -202,19 +465,7 @@ enum S3CHIPTAGS { while ((VGAIN8(psav->vgaIOBase + 0x0a) & 0x08) == 0x00) ; \ } \ } - -#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); \ -} +#endif /* tim's code */ #define HZEXP_COMP_1 0x54 #define HZEXP_BORDER 0x58 diff --git a/src/savage_vbe.c b/src/savage_vbe.c index cf8f417..70059ca 100644 --- a/src/savage_vbe.c +++ b/src/savage_vbe.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_vbe.c,v 1.14 2003/06/18 16:17:40 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_vbe.c,v 1.9 2001/05/19 02:05:55 dawes Exp $ */ #include "savage_driver.h" #include "savage_vbe.h" @@ -92,7 +92,7 @@ SavageSetVESAMode( SavagePtr psav, int n, int Refresh ) SavageClearVM86Regs( psav->pInt10 ); psav->pInt10->ax = 0x4f14; /* S3 extensions */ psav->pInt10->bx = 0x0003; /* set active devices */ - psav->pInt10->cx = psav->PAL ? 0x08 : 0x04; + psav->pInt10->cx = psav->iDevInfo; xf86ExecX86int10( psav->pInt10 ); /* Re-fetch actual device set. */ @@ -123,6 +123,25 @@ SavageSetVESAMode( SavagePtr psav, int n, int Refresh ) } +void +SavageSetPanelEnabled( SavagePtr psav, Bool active ) +{ + int iDevInfo; + if( !psav->PanelX ) + return; /* no panel */ + iDevInfo = SavageGetDevice( psav ); + if( active ) + iDevInfo |= LCD_ACTIVE; + else + iDevInfo &= ~LCD_ACTIVE; + SavageClearVM86Regs( psav->pInt10 ); + psav->pInt10->ax = 0x4f14; /* S3 extensions */ + psav->pInt10->bx = 0x0003; /* set active devices */ + psav->pInt10->cx = iDevInfo; + xf86ExecX86int10( psav->pInt10 ); +} + + /* Function to get supported device list. */ static int SavageGetDevice( SavagePtr psav ) @@ -150,7 +169,6 @@ SavageFreeBIOSModeTable( SavagePtr psav, SavageModeTablePtr* ppTable ) xfree( pMode->RefreshRate ); pMode->RefreshRate = NULL; } - pMode++; } xfree( *ppTable ); diff --git a/src/savage_video.c b/src/savage_video.c index 43522ce..2e4d78d 100644 --- a/src/savage_video.c +++ b/src/savage_video.c @@ -1,12 +1,14 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_video.c,v 1.15 2003/06/18 16:17:40 eich Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_video.c,v 1.7 2001/11/21 22:43:01 dawes Exp $ */ #include "Xv.h" #include "dix.h" #include "dixstruct.h" #include "fourcc.h" -#include "xaalocal.h" #include "savage_driver.h" +#include "savage_regs.h" +#include "savage_bci.h" + #define OFF_DELAY 200 /* milliseconds */ #define FREE_DELAY 60000 @@ -17,6 +19,23 @@ #define TIMER_MASK (OFF_TIMER | FREE_TIMER) +#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) + +#ifndef XvExtension +void SavageInitVideo(ScreenPtr pScreen) {} +void SavageResetVideo(ScrnInfoPtr pScrn) {} +#else + void myOUTREG( SavagePtr psav, unsigned long offset, unsigned long value ); static XF86VideoAdaptorPtr SavageSetupImageVideo(ScreenPtr); @@ -73,6 +92,7 @@ static void (*SavageDisplayVideo)( short drw_w, short drw_h ) = NULL; +static void OverlayTwisterInit(ScrnInfoPtr pScrn); static void OverlayParamInit(ScrnInfoPtr pScrn); static void InitStreamsForExpansion(ScrnInfoPtr pScrn); @@ -207,37 +227,6 @@ typedef struct { #define GET_PORT_PRIVATE(pScrn) \ (SavagePortPrivPtr)((SAVPTR(pScrn))->adaptor->pPortPrivates[0].ptr) -/************************************** - S3 streams processor -**************************************/ - -#define EXT_MISC_CTRL2 0x67 - -/* New streams */ - -/* CR67[2] = 1 : enable stream 1 */ -#define ENABLE_STREAM1 0x04 -/* CR67[1] = 1 : enable stream 2 */ -#define ENABLE_STREAM2 0x02 -/* mask to clear CR67[2,1] */ -#define NO_STREAMS 0xF9 -/* CR67[3] = 1 : Mem-mapped regs */ -#define USE_MM_FOR_PRI_STREAM 0x08 - -#define HDM_SHIFT 16 -#define HDSCALE_4 (2 << HDM_SHIFT) -#define HDSCALE_8 (3 << HDM_SHIFT) -#define HDSCALE_16 (4 << HDM_SHIFT) -#define HDSCALE_32 (5 << HDM_SHIFT) -#define HDSCALE_64 (6 << HDM_SHIFT) - -/* Old Streams */ - -#define ENABLE_STREAMS_OLD 0x0c -#define NO_STREAMS_OLD 0xf3 -/* CR69[0] = 1 : Mem-mapped regs */ -#define USE_MM_FOR_PRI_STREAM_OLD 0x01 - /* * There are two different streams engines used in the Savage line. @@ -246,34 +235,6 @@ typedef struct { */ -/* streams registers for old engine */ -#define PSTREAM_CONTROL_REG 0x8180 -#define COL_CHROMA_KEY_CONTROL_REG 0x8184 -#define SSTREAM_CONTROL_REG 0x8190 -#define CHROMA_KEY_UPPER_BOUND_REG 0x8194 -#define SSTREAM_STRETCH_REG 0x8198 -#define COLOR_ADJUSTMENT_REG 0x819C -#define BLEND_CONTROL_REG 0x81A0 -#define PSTREAM_FBADDR0_REG 0x81C0 -#define PSTREAM_FBADDR1_REG 0x81C4 -#define PSTREAM_STRIDE_REG 0x81C8 -#define DOUBLE_BUFFER_REG 0x81CC -#define SSTREAM_FBADDR0_REG 0x81D0 -#define SSTREAM_FBADDR1_REG 0x81D4 -#define SSTREAM_STRIDE_REG 0x81D8 -#define SSTREAM_VSCALE_REG 0x81E0 -#define SSTREAM_VINITIAL_REG 0x81E4 -#define SSTREAM_LINES_REG 0x81E8 -#define STREAMS_FIFO_REG 0x81EC -#define PSTREAM_WINDOW_START_REG 0x81F0 -#define PSTREAM_WINDOW_SIZE_REG 0x81F4 -#define SSTREAM_WINDOW_START_REG 0x81F8 -#define SSTREAM_WINDOW_SIZE_REG 0x81FC -#define FIFO_CONTROL 0x8200 -#define PSTREAM_FBSIZE_REG 0x8300 -#define SSTREAM_FBSIZE_REG 0x8304 -#define SSTREAM_FBADDR2_REG 0x8308 - #define OS_XY(x,y) (((x+1)<<16)|(y+1)) #define OS_WH(x,y) (((x-1)<<16)|(y)) @@ -307,7 +268,7 @@ void myOUTREG( SavagePtr psav, unsigned long offset, unsigned long value ) void SavageInitStreamsOld(ScrnInfoPtr pScrn) { SavagePtr psav = SAVPTR(pScrn); - unsigned long jDelta; + /*unsigned long jDelta;*/ unsigned long format = 0; /* @@ -320,6 +281,28 @@ void SavageInitStreamsOld(ScrnInfoPtr pScrn) /* Primary stream reflects the frame buffer. */ +/* I don't know if these are needed here or not. seems to work either way + * and the stride should have already been set properly in SavageSetGBD() + */ + 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(PSTREAM_FBSIZE_REG, + pScrn->virtualY * pScrn->virtualX * (pScrn->bitsPerPixel >> 3)); + switch( pScrn->depth ) { case 8: format = 0 << 24; break; case 15: format = 3 << 24; break; @@ -327,14 +310,14 @@ void SavageInitStreamsOld(ScrnInfoPtr pScrn) case 24: format = 7 << 24; break; } - jDelta = pScrn->displayWidth * pScrn->bitsPerPixel / 8; + /*jDelta = pScrn->displayWidth * pScrn->bitsPerPixel / 8;*/ OUTREG( PSTREAM_WINDOW_START_REG, OS_XY(0,0) ); 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 ); @@ -353,19 +336,18 @@ void SavageInitStreamsOld(ScrnInfoPtr pScrn) OUTREG( SSTREAM_VINITIAL_REG, 0 ); OUTREG( SSTREAM_WINDOW_START_REG, OS_XY(0xfffe, 0xfffe) ); OUTREG( SSTREAM_WINDOW_SIZE_REG, OS_WH(10,2) ); -} -#undef OUTREG -#if 0 -#define OUTREG(a,v) myOUTREG(psav,a,v) -#else -#define OUTREG(addr,val) MMIO_OUT32(psav->MapBase, addr, val) -#endif + if (S3_MOBILE_TWISTER_SERIES(psav->Chipset) && + psav->FPExpansion) { + OverlayTwisterInit(pScrn); + } + +} void SavageInitStreamsNew(ScrnInfoPtr pScrn) { SavagePtr psav = SAVPTR(pScrn); - unsigned long jDelta; + /*unsigned long jDelta;*/ xf86ErrorFVerb(XVTRACE, "SavageInitStreams\n" ); @@ -377,13 +359,36 @@ void SavageInitStreamsNew(ScrnInfoPtr pScrn) OverlayParamInit( pScrn ); } +/* I don't know if these are needed here or not. seems to work either way + * and the stride should have already been set properly in SavageSetGBD() + */ /* 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(PSTREAM_FBSIZE_REG, + pScrn->virtualX * pScrn->virtualY * (pScrn->bitsPerPixel >> 3)); + /* Primary stream reflects the frame buffer. */ +#if 0 jDelta = pScrn->displayWidth * pScrn->bitsPerPixel / 8; OUTREG( PRI_STREAM_BUFFERSIZE, jDelta * pScrn->virtualY >> 3 ); OUTREG( PRI_STREAM_FBUF_ADDR0, pScrn->fbOffset ); OUTREG( PRI_STREAM_STRIDE, jDelta ); - +#endif OUTREG( SEC_STREAM_CKEY_LOW, 0 ); OUTREG( SEC_STREAM_CKEY_UPPER, 0 ); OUTREG( SEC_STREAM_HSCALING, 0 ); @@ -435,16 +440,13 @@ void SavageStreamsOn(ScrnInfoPtr pScrn, int id) 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) ) { jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAM1; /* Wait for VBLANK. */ - VerticalRetraceWait(psav); + VerticalRetraceWait(); /* Fire up streams! */ @@ -461,11 +463,17 @@ void SavageStreamsOn(ScrnInfoPtr pScrn, int id) } else { - jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAMS_OLD; - + if (S3_MOBILE_TWISTER_SERIES(psav->Chipset) + && psav->FPExpansion) { + jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAMS_OLD; /* tim */ + /*jStreamsControl = VGAIN8( vgaCRReg ) | 0x8c;*/ /* S3 */ + } else { + jStreamsControl = VGAIN8( vgaCRReg ) | ENABLE_STREAMS_OLD; /* tim */ + /*jStreamsControl = VGAIN8( vgaCRReg ) | 0x04;*/ /* S3 */ + } /* Wait for VBLANK. */ - VerticalRetraceWait(psav); + VerticalRetraceWait(); /* Fire up streams! */ @@ -476,7 +484,7 @@ void SavageStreamsOn(ScrnInfoPtr pScrn, int id) /* Wait for VBLANK. */ - VerticalRetraceWait(psav); + VerticalRetraceWait(); /* Turn on secondary stream TV flicker filter, once we support TV. */ @@ -486,7 +494,6 @@ void SavageStreamsOn(ScrnInfoPtr pScrn, int id) psav->videoFourCC = id; } - void SavageStreamsOff(ScrnInfoPtr pScrn) { SavagePtr psav = SAVPTR(pScrn); @@ -506,7 +513,6 @@ void 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 @@ -514,7 +520,7 @@ void SavageStreamsOff(ScrnInfoPtr pScrn) /* Wait for VBLANK. */ - VerticalRetraceWait(psav); + VerticalRetraceWait(); /* Kill streams. */ @@ -527,7 +533,6 @@ void SavageStreamsOff(ScrnInfoPtr pScrn) psav->videoFlags &= ~VF_STREAMS_ON; } - void SavageInitVideo(ScreenPtr pScreen) { ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; @@ -539,7 +544,6 @@ void SavageInitVideo(ScreenPtr pScreen) xf86ErrorFVerb(XVTRACE,"SavageInitVideo\n"); if( S3_SAVAGE_MOBILE_SERIES(psav->Chipset) || - (psav->Chipset == S3_SUPERSAVAGE) || (psav->Chipset == S3_SAVAGE2000) ) { @@ -873,10 +877,10 @@ SavageSetupImageVideo(ScreenPtr pScreen) psav->adaptor = adapt; -#if 0 + #if 0 psav->BlockHandler = pScreen->BlockHandler; pScreen->BlockHandler = SavageBlockHandler; -#endif + #endif return adapt; } @@ -1079,6 +1083,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( @@ -1195,6 +1282,7 @@ SavageDisplayVideoOld( /*DisplayModePtr mode = pScrn->currentMode;*/ int vgaCRIndex, vgaCRReg, vgaIOBase; unsigned int ssControl; + int scalratio; vgaIOBase = hwp->IOBase; @@ -1210,6 +1298,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. */ OUTREG(SSTREAM_CONTROL_REG, @@ -1221,9 +1321,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. */ @@ -1235,25 +1342,52 @@ SavageDisplayVideoOld( OUTREG(SSTREAM_WINDOW_START_REG, OS_XY(dstBox->x1, dstBox->y1) ); OUTREG(SSTREAM_WINDOW_SIZE_REG, OS_WH(drw_w, drw_h) ); + /* + * 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. */ @@ -1491,13 +1625,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 */ @@ -1517,10 +1661,11 @@ SavagePutImage( x1, y1, x2, y2, &dstBox, src_w, src_h, drw_w, drw_h); /* update cliplist */ - if(!REGION_EQUAL(pScrn->pScreen, &pPriv->clip, clipBoxes)) { - REGION_COPY(pScrn->pScreen, &pPriv->clip, clipBoxes); + if(!REGION_EQUAL(pScreen, &pPriv->clip, clipBoxes)) { + REGION_COPY(pScreen, &pPriv->clip, clipBoxes); /* draw these */ xf86XVFillKeyHelper(pScrn->pScreen, pPriv->colorKey, clipBoxes); + } pPriv->videoStatus = CLIENT_VIDEO_ON; @@ -1544,6 +1689,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; @@ -1576,51 +1725,6 @@ SavageQueryImageAttributes( return size; } -#if 0 - -static void -CHIPSBlockHandler ( - int i, - pointer blockData, - pointer pTimeout, - pointer pReadmask -){ - ScreenPtr pScreen = screenInfo.screens[i]; - ScrnInfoPtr pScrn = xf86Screens[i]; - CHIPSPtr cPtr = CHIPSPTR(pScrn); - CHIPSPortPrivPtr pPriv = GET_PORT_PRIVATE(pScrn); - unsigned char mr3c; - - pScreen->BlockHandler = cPtr->BlockHandler; - - (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); - - pScreen->BlockHandler = CHIPSBlockHandler; - - CHIPSHiQVSync(pScrn); - if(pPriv->videoStatus & TIMER_MASK) { - UpdateCurrentTime(); - if(pPriv->videoStatus & OFF_TIMER) { - if(pPriv->offTime < currentTime.milliseconds) { - mr3c = cPtr->readMR(cPtr, 0x3C); - cPtr->writeMR(cPtr, 0x3C, (mr3c & 0xFE)); - pPriv->videoStatus = FREE_TIMER; - pPriv->freeTime = currentTime.milliseconds + FREE_DELAY; - } - } else { /* FREE_TIMER */ - if(pPriv->freeTime < currentTime.milliseconds) { - if(pPriv->area) { - xf86FreeOffscreenArea(pPriv->area); - pPriv->area = NULL; - } - pPriv->videoStatus = 0; - } - } - } -} - -#endif - /****************** Offscreen stuff ***************/ typedef struct { @@ -1822,6 +1926,52 @@ SavageInitOffscreenImages(ScreenPtr pScreen) xf86XVRegisterOffscreenImages(pScreen, offscreenImages, 1); } +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 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 */ @@ -1914,3 +2064,5 @@ static void InitStreamsForExpansion(ScrnInfoPtr pScrn) ((PanelSizeY - (psav->YExp1 * ViewPortHeight) / psav->YExp2) / 2); } /* InitStreamsForExpansionPM */ + +#endif /* XvExtension */ |