diff options
-rw-r--r-- | src/savage_accel.c | 10 | ||||
-rw-r--r-- | src/savage_driver.c | 50 | ||||
-rw-r--r-- | src/savage_driver.h | 5 |
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; |