diff options
-rw-r--r-- | man/savage.man | 59 | ||||
-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 |
11 files changed, 2525 insertions, 434 deletions
diff --git a/man/savage.man b/man/savage.man index cfd00ae..8a09fb2 100644 --- a/man/savage.man +++ b/man/savage.man @@ -14,42 +14,49 @@ savage \- S3 Savage video driver .fi .SH DESCRIPTION .B savage -is an XFree86 driver for the S3 Savage family video accelerator chips. The +is an XFree86 driver for the S3 Savage family video accelerator chips. 2D, 3D, and Xv acceleration +is supported on all chips except the Savage2000 (2D only). The .B savage driver supports PCI and AGP boards with the following chips: .TP 16 .BI Savage3D -(8a20 and 8a21) +(8a20 and 8a21) (2D, 3D) .TP 16 .B Savage4 -(8a22) +(8a22) (2D, 3D) .TP 16 .B Savage2000 -(9102) +(9102) (2D only) .TP 16 .B Savage/MX -(8c10 and 8c11) +(8c10 and 8c11) (2D, 3D) .TP 16 .B Savage/IX -(8c12 and 8c13) +(8c12 and 8c13) (2D, 3D) +.TP 16 +.B SuperSavage/MX +(8c22, 8c24, and 8c26) (2D, 3D) +.TP 16 +.B SuperSavage/IX +(8c2a, 8c2b, 8c2c, 8c2d, 8c2e, and 8c2f) (2D, 3D) .TP 16 .B ProSavage PM133 -(8a25) +(8a25) (2D, 3D) .TP 16 .B ProSavage KM133 -(8a26) +(8a26) (2D, 3D) .TP 16 .B Twister (ProSavage PN133) -(8d01) +(8d01) (2D, 3D) .TP 16 .B TwisterK (ProSavage KN133) -(8d02) +(8d02) (2D, 3D) .TP 16 .B ProSavage DDR -(8d03) +(8d03) (2D, 3D) .TP 16 .B ProSavage DDR-K -(8d04) +(8d04) (2D, 3D) .SH CONFIGURATION DETAILS Please refer to XF86Config(__filemansuffix__) for general configuration details. This section only covers configuration details specific to this @@ -108,7 +115,7 @@ you would rather have the driver use your mode line timing exactly, turn off the UseBios option. Default: on (use the BIOS). .TP -.BI "Option \*qShadowStatus\*q \q*" boolean \*q +.BI "Option \*qShadowStatus\*q \*q" boolean \*q Enables the use of a shadow status register. There is a chip bug in the Savage graphics engine that can cause a bus lock when reading the engine status register under heavy load, such as when scrolling text or dragging @@ -117,6 +124,32 @@ hangs regularly while scrolling text or dragging windows, try turning this option on. This uses an alternate method of reading the engine status which is slightly more expensive, but avoids the problem. Default: off (use normal status register). +.TP +.BI "Option \*qDisableCOB\*q \*q" boolean \*q +Disables the COB (Command Overflow Buffer) on savage4 and newer chips. +There is supposedly a HW cache coherency problem on certain savage4 and +newer chips that renders the COB useless. If you are having problems with +2D or 3D acceleration you can disable the COB, however you will lose some +performance. This option only applies to Savage4 and newer chips. Default: on +(use COB). +.TP +.BI "Option \*qBCIforXv\*q \*q" boolean \*q +Use the BCI to copy and reformat Xv pixel data. Using the BCI for Xv causes +graphics artifacts on some chips. This option only applies to Savage4 and +prosavage/twister chips. Default: on for prosavage and twister (use BCI for Xv); +off for savage4 (do not use the BCI for Xv). +.TP +.BI "Option \*qAGPMode\*q \*q" integer \*q +Set AGP data transfer rate. +(used only when DRI is enabled) +.br +1 \-\- x1 (default) +.br +2 \-\- x2 +.br +4 \-\- x4 +.br +others \-\- invalid .SH FILES savage_drv.o .SH "SEE ALSO" 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 */ |