summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/savage_accel.c110
-rw-r--r--src/savage_driver.c35
-rw-r--r--src/savage_driver.h4
-rw-r--r--src/savage_regs.h3
-rw-r--r--src/savage_streams.c3
5 files changed, 102 insertions, 53 deletions
diff --git a/src/savage_accel.c b/src/savage_accel.c
index fa27a34..6f0d321 100644
--- a/src/savage_accel.c
+++ b/src/savage_accel.c
@@ -255,6 +255,30 @@ static int GetTileAperturePitch(unsigned long dwWidth, unsigned long dwBpp)
}
}
+static int GetTileAperturePitch2000(unsigned long dwWidth, unsigned long dwBpp, int lDelta)
+{
+ switch (dwBpp) {
+ case 4:
+ case 8:
+ return(0x2000);
+ break;
+ case 16:
+ if (lDelta > 0x800)
+ return(0x1000);
+ else
+ return(0x800);
+ break;
+ case 32:
+ if (lDelta > 0x1000)
+ return(0x2000);
+ else
+ return(0x1000);
+ break;
+ default:
+ return(0x2000);
+ }
+}
+
void
SavageInitialize2DEngine(ScrnInfoPtr pScrn)
{
@@ -392,8 +416,12 @@ SavageSetGBD(ScrnInfoPtr pScrn)
psav->bTiled = TRUE;
psav->lDelta = ((psav->lDelta + 127) >> 7) << 7;
- if (psav->Chipset == S3_SAVAGE_MX || psav->Chipset == S3_SAVAGE3D)
- psav->ulAperturePitch = 0x2000;
+ if (psav->Chipset == S3_SAVAGE_MX)
+ psav->ulAperturePitch = 0x2000;
+ else if (psav->Chipset == S3_SAVAGE2000)
+ psav->ulAperturePitch = GetTileAperturePitch2000(pScrn->virtualX,
+ pScrn->bitsPerPixel,
+ psav->lDelta);
else
psav->ulAperturePitch = GetTileAperturePitch(pScrn->virtualX,pScrn->bitsPerPixel);
@@ -1254,7 +1282,7 @@ void SavageSetGBD_PM(ScrnInfoPtr pScrn)
void SavageSetGBD_2000(ScrnInfoPtr pScrn)
{
SavagePtr psav = SAVPTR(pScrn);
- unsigned long ulTmp;
+ unsigned long ulTmp, ulYRange;
unsigned char byte;
int bci_enable, tile16, tile32;
@@ -1262,6 +1290,11 @@ void SavageSetGBD_2000(ScrnInfoPtr pScrn)
tile16 = TILE_DESTINATION;
tile32 = TILE_DESTINATION;
+ if (pScrn->virtualX > 1024)
+ ulYRange = 0x40000000;
+ else
+ ulYRange = 0x20000000;
+
/* following is the enable case */
@@ -1270,25 +1303,11 @@ void SavageSetGBD_2000(ScrnInfoPtr pScrn)
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);
+ /* MM81C0 and 81B0 are used to control primary stream. */
+ OUTREG32(PRI_STREAM_FBUF_ADDR0, pScrn->fbOffset);
+ OUTREG32(PRI_STREAM2_FBUF_ADDR0, pScrn->fbOffset);
- /*
- * 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.
@@ -1302,22 +1321,28 @@ void SavageSetGBD_2000(ScrnInfoPtr pScrn)
*/
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) {
+ ((psav->lDelta << 4) & 0x7ff0));
+ OUTREG32(PRI_STREAM2_STRIDE,
+ ((psav->lDelta << 4) & 0x7ff0));
+ } else {
OUTREG32(PRI_STREAM_STRIDE,
- (((psav->lDelta * 2) << 16) & 0x3FFF0000)
- | 0xC0000000 | (psav->lDelta & 0x00001fff));
+ (0x80000000 |((psav->lDelta << 4) & 0x7ff0)));
+ OUTREG32(PRI_STREAM2_STRIDE,
+ (0x80000000 |((psav->lDelta << 4) & 0x7ff0)));
}
- /* MM81C0 and 81C4 are used to control primary stream. */
- OUTREG32(PRI_STREAM_FBUF_ADDR0,pScrn->fbOffset);
- OUTREG32(PRI_STREAM_FBUF_ADDR1,0x80000000);
+ /*
+ * 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);
+
OUTREG32(0x8128, 0xFFFFFFFFL);
OUTREG32(0x812C, 0xFFFFFFFFL);
@@ -1330,6 +1355,11 @@ void SavageSetGBD_2000(ScrnInfoPtr pScrn)
byte = INREG8(CRT_DATA_REG) | 0xC1;
OUTREG8(CRT_DATA_REG, byte);
+ /* CR73 bit 5 = 0 block write disable */
+ OUTREG8(CRT_ADDRESS_REG,0x73);
+ byte = INREG8(CRT_DATA_REG) & ~0x20;
+ OUTREG8(CRT_DATA_REG, byte);
+
if (!psav->bTiled) {
/*
* Do not enable block_write even for non-tiling modes, because
@@ -1341,13 +1371,19 @@ void SavageSetGBD_2000(ScrnInfoPtr pScrn)
}
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));
+ ulTmp = (((pScrn->virtualX + 0x3f) & 0x0000ffc0) >> 6) << 23;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP16_2000 | ulYRange);
+ ulTmp |= (TILED_SURF_BPP16_2000 | ulYRange);
+ OUTREG32(PRI_STREAM_STRIDE, ((ulTmp >> 19) & 0x03f0) | 0x80000000);
+ OUTREG32(PRI_STREAM2_STRIDE, ((ulTmp >> 19) & 0x03f0) | 0x80000000);
}
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));
+ ulTmp = (((pScrn->virtualX + 0x1f) & 0x0000ffe0) >> 5) << 23;
+ OUTREG32(TILED_SURFACE_REGISTER_0,ulTmp | TILED_SURF_BPP32_2000 | ulYRange);
+ ulTmp |= (TILED_SURF_BPP32_2000 | ulYRange);
+ OUTREG32(PRI_STREAM_STRIDE, ((ulTmp >> 19) & 0x03f0) | 0x80000000);
+ OUTREG32(PRI_STREAM2_STRIDE, ((ulTmp >> 19) & 0x03f0) | 0x80000000);
}
psav->GlobalBD.bd1.HighPart.ResBWTile |= 0x10;/* disable block write */
diff --git a/src/savage_driver.c b/src/savage_driver.c
index 640de4e..cdcd097 100644
--- a/src/savage_driver.c
+++ b/src/savage_driver.c
@@ -1347,11 +1347,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
#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;
+ 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"));
@@ -2673,8 +2669,8 @@ static Bool SavageMapFB(ScrnInfoPtr pScrn)
psav->FBStart = psav->FBBase;
}
- if (psav->Chipset == S3_SUPERSAVAGE)
- /* paramount aperture 0 is pci base 2 */
+ if ((psav->Chipset == S3_SUPERSAVAGE) || (psav->Chipset == S3_SAVAGE2000))
+ /* paramount, savage2000 aperture 0 is pci base 2 */
psav->ApertureBase = psav->PciInfo->memBase[2];
else
psav->ApertureBase = psav->FrameBufferBase + 0x02000000;
@@ -3615,23 +3611,31 @@ SavageDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int crtc2)
{
SavagePtr psav = SAVPTR(pScrn);
DisplayModePtr currentMode = pScrn->currentMode;
- int address=0,top=0,left=0;
-
- TRACE(("SavageAdjustFrame(%d,%d,%x)\n", x, y, flags));
+ int address=0,top=0,left=0,tile_height,tile_size;
+ TRACE(("SavageDoAdjustFrame(%d,%d,%x)\n", x, y, flags));
+
+ if (psav->Chipset == S3_SAVAGE2000) {
+ tile_height = TILEHEIGHT_2000; /* 32 */
+ tile_size = TILE_SIZE_BYTE_2000; /* 4096 */
+ } else {
+ tile_height = TILEHEIGHT; /* 16 */
+ tile_size = TILE_SIZE_BYTE; /* 2048 */
+ }
+
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;
+ top = y - y % tile_height;
if (pScrn->bitsPerPixel == 16) {
left = x - x % TILEWIDTH_16BPP;
- address = top * psav->lDelta + left * TILE_SIZE_BYTE / TILEWIDTH_16BPP;
+ address = top * psav->lDelta + left * tile_size / TILEWIDTH_16BPP;
} else if (pScrn->bitsPerPixel == 32) {
left = x - x % TILEWIDTH_32BPP;
- address = top * psav->lDelta + left * TILE_SIZE_BYTE / TILEWIDTH_32BPP;
+ address = top * psav->lDelta + left * tile_size / TILEWIDTH_32BPP;
}
}
@@ -3665,8 +3669,9 @@ SavageDoAdjustFrame(ScrnInfoPtr pScrn, int x, int y, int crtc2)
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);
+ /* certain Y values seems to cause havoc, not sure why */
+ OUTREG32(PRI_STREAM_FBUF_ADDR0, (address & 0xFFFFFFF8));
+ OUTREG32(PRI_STREAM2_FBUF_ADDR0, (address & 0xFFFFFFF8));
} else {
OUTREG32(PRI_STREAM_FBUF_ADDR0,address | 0xFFFFFFFC);
OUTREG32(PRI_STREAM_FBUF_ADDR1,address | 0x80000000);
diff --git a/src/savage_driver.h b/src/savage_driver.h
index 61c5914..44da652 100644
--- a/src/savage_driver.h
+++ b/src/savage_driver.h
@@ -122,11 +122,13 @@ typedef struct {
} savageOverlayRec;
/* Tiling defines */
-#define TILE_SIZE_BYTE 2048 /* 0x800, 2K */
+#define TILE_SIZE_BYTE 2048 /* 0x800, 2K */
+#define TILE_SIZE_BYTE_2000 4096
#define TILEHEIGHT_16BPP 16
#define TILEHEIGHT_32BPP 16
#define TILEHEIGHT 16 /* all 16 and 32bpp tiles are 16 lines high */
+#define TILEHEIGHT_2000 32 /* 32 lines on savage 2000 */
#define TILEWIDTH_BYTES 128 /* 2048/TILEHEIGHT (** not for use w/8bpp tiling) */
#define TILEWIDTH8BPP_BYTES 64 /* 2048/TILEHEIGHT_8BPP */
diff --git a/src/savage_regs.h b/src/savage_regs.h
index ab2ec27..ae1c636 100644
--- a/src/savage_regs.h
+++ b/src/savage_regs.h
@@ -200,6 +200,9 @@ do { \
#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 */
+#define TILED_SURF_BPP16_2000 0x00000000 /* bit 31=0 for 16 bits/pixel */
+#define TILED_SURF_BPP32_2000 0x80000000 /* bit 31=1 for 32 bits/pixel */
+
/*
* CR88_4 =1 : disable block write
* the "2D" is partly to set this apart from "BLOCK_WRITE_DISABLE"
diff --git a/src/savage_streams.c b/src/savage_streams.c
index e1639a8..8b6d560 100644
--- a/src/savage_streams.c
+++ b/src/savage_streams.c
@@ -307,6 +307,9 @@ void SavageInitStreams2000(ScrnInfoPtr pScrn)
OUTREG(PRI_STREAM_BUFFERSIZE,
pScrn->virtualX * pScrn->virtualY * (pScrn->bitsPerPixel >> 3));
+ OUTREG(PRI_STREAM2_BUFFERSIZE,
+ pScrn->virtualX * pScrn->virtualY * (pScrn->bitsPerPixel >> 3));
+
if (psav->FBStart2nd) {
unsigned long jDelta = pScrn->displayWidth;