summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelix Kuehling <fxkuehl@gmx.de>2005-01-31 01:09:27 +0000
committerFelix Kuehling <fxkuehl@gmx.de>2005-01-31 01:09:27 +0000
commit37e6666824a771271f60ad12174a29b2ac6b826b (patch)
treef0a82ea5d4beb877525652543743791a6b93b779
parent7712602bccc71210ad4319aaf2bc8e1b15b6a01a (diff)
- Shadow status update thresholds on Savage4 were reversed. Fixed now.
- Fixed cobIndex on Savage2K. It used only a 4K COB so far. Now we have full 128K. - Program the shadow status thresholds correctly on Savage2K. - Savage2K reports used entries in the queue in qword units instead of dwords. Fixed WaitQueue2K accordingly. - Event counter 0 is in status word 2 instead of status word 1 on Savage2K. Fixed ShadowWait accordingly. - Added a ShadowWaitQueue function that doesn't idle the engine all the time. This improves 3D animation smoothness with concurrent 2D activity when shadow status is enabled.
-rw-r--r--src/savage_accel.c10
-rw-r--r--src/savage_driver.c50
-rw-r--r--src/savage_driver.h5
3 files changed, 46 insertions, 19 deletions
diff --git a/src/savage_accel.c b/src/savage_accel.c
index d7fdd3d..12a1afe 100644
--- a/src/savage_accel.c
+++ b/src/savage_accel.c
@@ -342,8 +342,8 @@ SavageInitialize2DEngine(ScrnInfoPtr pScrn)
}
/* Program shadow status update */ /* AGD: what should this be? */
{
- unsigned long thresholds = ((psav->bciThresholdHi & 0x1fffe0) << 11) |
- ((psav->bciThresholdLo & 0x1fffe0) >> 5);
+ unsigned long thresholds = ((psav->bciThresholdLo & 0x1fffe0) << 11) |
+ ((psav->bciThresholdHi & 0x1fffe0) >> 5);
OUTREG(0x48C10, thresholds);
}
/*OUTREG(0x48C10, 0x00700040);*/ /* tim */
@@ -378,8 +378,10 @@ SavageInitialize2DEngine(ScrnInfoPtr pScrn)
if( psav->ShadowStatus )
{
/* Set shadow update threshholds. */
- OUTREG(0x48C10, 0x6090 );
- OUTREG(0x48C14, 0x70A8 );
+ /*OUTREG(0x48C10, 0x6090 );
+ OUTREG(0x48C14, 0x70A8 );*/
+ OUTREG(0x48C10, psav->bciThresholdLo >> 2);
+ OUTREG(0x48C14, psav->bciThresholdHi >> 2);
/* Enable shadow status update */
OUTREG(0x48A30, psav->ShadowPhysical );
/* Enable BCI, command overflow buffer and shadow status. */
diff --git a/src/savage_driver.c b/src/savage_driver.c
index 3d9ba39..4a121d8 100644
--- a/src/savage_driver.c
+++ b/src/savage_driver.c
@@ -506,8 +506,8 @@ ShadowWait( SavagePtr psav )
BCI_SEND( 0x98000000 + psav->ShadowCounter );
while(
- (int)(psav->ShadowVirtual[1] & 0xffff) != psav->ShadowCounter &&
- (loop++ < MAXLOOP)
+ (int)(psav->ShadowVirtual[psav->eventStatusReg] & 0xffff) !=
+ psav->ShadowCounter && (loop++ < MAXLOOP)
)
;
@@ -515,11 +515,26 @@ ShadowWait( SavagePtr psav )
}
static Bool
-ShadowWait1( SavagePtr psav, int v )
+ShadowWaitQueue( SavagePtr psav, int v )
{
- return ShadowWait( psav );
-}
+ int loop = 0;
+ CARD32 slots = MAXFIFO - v;
+
+ if (slots >= psav->bciThresholdHi)
+ slots = psav->bciThresholdHi;
+ else
+ return ShadowWait( psav );
+
+ /* Savage 2000 reports only entries filled in the COB, not the on-chip
+ * queue. Also it reports in qword units instead of dwords. */
+ if (psav->Chipset == S3_SAVAGE2000)
+ slots = (slots - 32) / 4;
+
+ while( ((psav->ShadowVirtual[0] & psav->bciUsedMask) >= slots) && (loop++ < MAXLOOP))
+ ;
+ return loop >= MAXLOOP;
+}
/* Wait until "v" queue entries are free */
@@ -532,8 +547,8 @@ WaitQueue3D( SavagePtr psav, int v )
mem_barrier();
if( psav->ShadowVirtual )
{
- psav->WaitQueue = ShadowWait1;
- return ShadowWait(psav);
+ psav->WaitQueue = ShadowWaitQueue;
+ return ShadowWaitQueue(psav, v);
}
else
{
@@ -555,8 +570,8 @@ WaitQueue4( SavagePtr psav, int v )
mem_barrier();
if( psav->ShadowVirtual )
{
- psav->WaitQueue = ShadowWait1;
- return ShadowWait(psav);
+ psav->WaitQueue = ShadowWaitQueue;
+ return ShadowWaitQueue(psav, v);
}
else
while( ((ALT_STATUS_WORD0 & 0x001fffff) > slots) && (loop++ < MAXLOOP));
@@ -567,15 +582,15 @@ static int
WaitQueue2K( SavagePtr psav, int v )
{
int loop = 0;
- CARD32 slots = MAXFIFO - v;
+ CARD32 slots = (MAXFIFO - v) / 4;
if( !psav->NoPCIRetry )
return 0;
mem_barrier();
if( psav->ShadowVirtual )
{
- psav->WaitQueue = ShadowWait1;
- return ShadowWait(psav);
+ psav->WaitQueue = ShadowWaitQueue;
+ return ShadowWaitQueue(psav, v);
}
else
while( ((ALT_STATUS_WORD0 & 0x000fffff) > slots) && (loop++ < MAXLOOP))
@@ -1680,7 +1695,8 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
} else {
/* We use 128kB for the COB on all other chips. */
psav->cobSize = 0x20000;
- if (S3_SAVAGE3D_SERIES(psav->Chipset)) {
+ if (S3_SAVAGE3D_SERIES(psav->Chipset) ||
+ psav->Chipset == S3_SAVAGE2000) {
psav->cobIndex = 7; /* rev.A savage4 apparently also uses 7 */
} else {
psav->cobIndex = 2;
@@ -1734,6 +1750,8 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->WaitQueue = WaitQueue3D;
psav->WaitIdle = WaitIdle3D;
psav->WaitIdleEmpty = WaitIdleEmpty3D;
+ psav->bciUsedMask = 0x1ffff;
+ psav->eventStatusReg= 1;
break;
case S3_SAVAGE4:
@@ -1744,12 +1762,16 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags)
psav->WaitQueue = WaitQueue4;
psav->WaitIdle = WaitIdle4;
psav->WaitIdleEmpty = WaitIdleEmpty4;
+ psav->bciUsedMask = 0x1fffff;
+ psav->eventStatusReg= 1;
break;
case S3_SAVAGE2000:
psav->WaitQueue = WaitQueue2K;
psav->WaitIdle = WaitIdle2K;
psav->WaitIdleEmpty = WaitIdleEmpty2K;
+ psav->bciUsedMask = 0xfffff;
+ psav->eventStatusReg= 2;
break;
}
@@ -2924,7 +2946,7 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen,
"Shadow area physical %08lx, linear %p\n",
psav->ShadowPhysical, (void *)psav->ShadowVirtual );
- psav->WaitQueue = ShadowWait1;
+ psav->WaitQueue = ShadowWaitQueue;
psav->WaitIdle = ShadowWait;
psav->WaitIdleEmpty = ShadowWait;
diff --git a/src/savage_driver.h b/src/savage_driver.h
index cd1d71f..2a04a53 100644
--- a/src/savage_driver.h
+++ b/src/savage_driver.h
@@ -293,8 +293,11 @@ typedef struct _Savage {
unsigned long cobIndex; /* size index */
unsigned long cobSize; /* size in bytes */
unsigned long cobOffset; /* offset in frame buffer */
- unsigned long bciThresholdLo; /* low and hight thresholds for */
+ unsigned long bciThresholdLo; /* low and high thresholds for */
unsigned long bciThresholdHi; /* shadow status update (32bit words) */
+ unsigned long bciUsedMask; /* BCI entries used mask */
+ unsigned int eventStatusReg; /* Status register index that holds
+ * event counter 0. */
/* Support for DGA */
int numDGAModes;