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