summaryrefslogtreecommitdiff
path: root/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c')
-rw-r--r--xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c101
1 files changed, 70 insertions, 31 deletions
diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c
index 2dfaf1432..b31a08d26 100644
--- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c
+++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c
@@ -1,4 +1,4 @@
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v 1.4 2000/12/07 20:26:22 dawes Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v 1.5 2001/02/13 21:15:19 dawes Exp $ */
/*
*
@@ -15,14 +15,10 @@
*
*/
+#include <math.h>
#include "Xarch.h"
-#include "xf86.h"
-#include "xf86_ansic.h"
-#include "xf86_OSproc.h"
-#include "compiler.h"
#include "xaalocal.h"
#include "xaarop.h"
-#include "xf86PciInfo.h"
#include "miline.h"
#include "savage_driver.h"
@@ -30,16 +26,10 @@
#include "savage_bci.h"
-/* Globals used in driver */
-extern pointer s3savMmioMem;
-#ifdef __alpha__
-extern pointer s3savMmioMemSparse;
-#endif
+static unsigned int dwBCIWait2DIdle;
/* Forward declaration of functions used in the driver */
-static void SavageAccelSync( ScrnInfoPtr );
-
static void SavageSetupForScreenToScreenCopy(
ScrnInfoPtr pScrn,
int xdir,
@@ -220,7 +210,7 @@ void SavageSetGBD( ScrnInfoPtr );
* call from the debugger.
*/
-static ScrnInfoPtr gpScrn = 0;
+ScrnInfoPtr gpScrn = 0;
@@ -265,7 +255,7 @@ SavageInitialize2DEngine(ScrnInfoPtr pScrn)
OUTREG(0x48C18, INREG(0x48C18) & 0x3FF0);
/* Disable shadow status update */
OUTREG(0x48C0C, 0);
- /* Enabel BCI without the COB */
+ /* Enable BCI without the COB */
OUTREG(0x48C18, INREG(0x48C18) | 0x08);
break;
@@ -294,6 +284,14 @@ SavageInitialize2DEngine(ScrnInfoPtr pScrn)
BCI_BD_SET_STRIDE(psav->SavedGbd, pScrn->displayWidth);
SavageSetGBD(pScrn);
+
+ if( psav->StatusHack )
+ {
+ if( psav->Chipset == S3_SAVAGE2000 )
+ dwBCIWait2DIdle = 0xc0040000;
+ else
+ dwBCIWait2DIdle = 0xc0020000;
+ }
}
@@ -335,8 +333,8 @@ SavageSetGBD( ScrnInfoPtr pScrn )
OUTREG(0x8178,0);
OUTREG(0x817C,psav->SavedGbd);
- OUTREG(0x81C8, pScrn->displayWidth << 4);
- OUTREG(0x81D8, pScrn->displayWidth << 4);
+ OUTREG(PRI_STREAM_STRIDE, pScrn->displayWidth * pScrn->bitsPerPixel >> 3);
+ OUTREG(SEC_STREAM_STRIDE, pScrn->displayWidth * pScrn->bitsPerPixel >> 3);
}
@@ -352,18 +350,18 @@ SavageInitAccel(ScreenPtr pScreen)
/* Set-up our GE command primitive */
- if (pScrn->bitsPerPixel == 8) {
- psav->PlaneMask = 0xFF;
- }
- else if (pScrn->bitsPerPixel == 16) {
- psav->PlaneMask = 0xFFFF;
- }
- else if (pScrn->bitsPerPixel == 24) {
- psav->PlaneMask = 0xFFFFFF;
- }
- else if (pScrn->bitsPerPixel == 32) {
- psav->PlaneMask = 0xFFFFFFFF;
- }
+ if (pScrn->depth == 8) {
+ psav->PlaneMask = 0xFF;
+ }
+ else if (pScrn->depth == 15) {
+ psav->PlaneMask = 0x7FFF;
+ }
+ else if (pScrn->depth == 16) {
+ psav->PlaneMask = 0xFFFF;
+ }
+ else if (pScrn->depth == 24) {
+ psav->PlaneMask = 0xFFFFFF;
+ }
/* General acceleration flags */
@@ -504,7 +502,7 @@ SavageInitAccel(ScreenPtr pScreen)
psav->Bpp = pScrn->bitsPerPixel / 8;
psav->Bpl = pScrn->displayWidth * psav->Bpp;
- psav->ScissB = psav->CursorKByte / psav->Bpl;
+ psav->ScissB = (psav->CursorKByte << 10) / psav->Bpl;
if (psav->ScissB > 2047)
psav->ScissB = 2047;
@@ -520,6 +518,9 @@ SavageInitAccel(ScreenPtr pScreen)
AvailFBArea.x2 = pScrn->displayWidth;
AvailFBArea.y2 = psav->ScissB;
xf86InitFBManager(pScreen, &AvailFBArea);
+ xf86DrvMsg( pScrn->scrnIndex, X_INFO,
+ "Using %d lines for offscreen memory.\n",
+ psav->ScissB - pScrn->virtualY );
return XAAInit(pScreen, xaaptr);
}
@@ -532,9 +533,44 @@ void
SavageAccelSync(ScrnInfoPtr pScrn)
{
SavagePtr psav = SAVPTR(pScrn);
- WaitIdleEmpty();
+
+ if( psav->StatusHack )
+ {
+ static int counter = 0;
+ int i;
+
+ /*
+ * This is an attempt to work around the status register read hang
+ * that affects about 4% of all Savage chips. Instead of reading
+ * the register through MMIO, we send a BCI command to wait for
+ * engine idle (which does not hang), then another BCI command to
+ * set an incrementing value into an innocuous register (the
+ * Cr Base register used in YUV page flipping). Then we loop
+ * waiting for the MMIO value of that register to change.
+ */
+
+ BCI_GET_PTR;
+ BCI_SEND(dwBCIWait2DIdle); /* wait for 2D idle */
+ BCI_SEND(0x96010045); /* update New Cr Base Address ... */
+ counter++;
+ BCI_SEND(counter); /* ... to this value */
+ for(
+ i = 0;
+ (INREG(0x48914) != counter) && (i < 100000);
+ i++
+ )
+ ;
+ }
+ else
+ {
+ if( psav->StatusDelay )
+ usleep( psav->StatusDelay );
+ WaitIdleEmpty();
+ }
}
+#undef WaitQueue
+#define WaitQueue(x) SavageAccelSync(pScrn)
/*
* The XAA ROP helper routines all assume that a solid color is a
@@ -731,6 +767,9 @@ SavageSubsequentSolidFillRect(
{
SavagePtr psav = SAVPTR(pScrn);
BCI_GET_PTR;
+
+ if( !w || !h )
+ return;
WaitQueue(5);