summaryrefslogtreecommitdiff
path: root/src/nv_xaa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nv_xaa.c')
-rw-r--r--src/nv_xaa.c77
1 files changed, 50 insertions, 27 deletions
diff --git a/src/nv_xaa.c b/src/nv_xaa.c
index 2dd2bc1..0723788 100644
--- a/src/nv_xaa.c
+++ b/src/nv_xaa.c
@@ -37,7 +37,7 @@
|* *|
\***************************************************************************/
-/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c,v 1.32 2003/08/18 21:40:04 mvojkovi Exp $ */
+/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/nv/nv_xaa.c,v 1.35 2004/03/20 16:25:18 mvojkovi Exp $ */
#include "nv_include.h"
#include "xaalocal.h"
@@ -113,6 +113,13 @@ NVDmaKickoff(NVPtr pNv)
}
}
+
+/* There is a HW race condition with videoram command buffers.
+ You can't jump to the location of your put offset. We write put
+ at the jump offset + SKIPS dwords with noop padding in between
+ to solve this problem */
+#define SKIPS 8
+
void
NVDmaWait (
NVPtr pNv,
@@ -129,21 +136,34 @@ NVDmaWait (
pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent;
if(pNv->dmaFree < size) {
NVDmaNext(pNv, 0x20000000);
- if(!dmaGet) {
- if(!pNv->dmaPut) /* corner case - idle */
- NVDmaKickoff(pNv);
+ if(dmaGet <= SKIPS) {
+ if(pNv->dmaPut <= SKIPS) /* corner case - will be idle */
+ WRITE_PUT(pNv, SKIPS + 1);
do { dmaGet = READ_GET(pNv); }
- while(!dmaGet);
+ while(dmaGet <= SKIPS);
}
- WRITE_PUT(pNv, 0);
- pNv->dmaCurrent = pNv->dmaPut = 0;
- pNv->dmaFree = dmaGet - 1;
+ WRITE_PUT(pNv, SKIPS);
+ pNv->dmaCurrent = pNv->dmaPut = SKIPS;
+ pNv->dmaFree = dmaGet - (SKIPS + 1);
}
} else
pNv->dmaFree = dmaGet - pNv->dmaCurrent - 1;
}
}
+void
+NVWaitVSync(NVPtr pNv)
+{
+ NVDmaStart(pNv, 0x0000A12C, 1);
+ NVDmaNext (pNv, 0);
+ NVDmaStart(pNv, 0x0000A134, 1);
+ NVDmaNext (pNv, pNv->CRTCnumber);
+ NVDmaStart(pNv, 0x0000A100, 1);
+ NVDmaNext (pNv, 0);
+ NVDmaStart(pNv, 0x0000A130, 1);
+ NVDmaNext (pNv, 0);
+}
+
/*
currentRop = 0-15 solid fill
16-31 8x8 pattern fill
@@ -194,7 +214,7 @@ void NVResetGraphics(ScrnInfoPtr pScrn)
{
NVPtr pNv = NVPTR(pScrn);
CARD32 surfaceFormat, patternFormat, rectFormat, lineFormat;
- int pitch;
+ int pitch, i;
if(pNv->NoAccel) return;
@@ -203,27 +223,30 @@ void NVResetGraphics(ScrnInfoPtr pScrn)
pNv->dmaBase = (CARD32*)(&pNv->FbStart[pNv->FbUsableSize]);
- pNv->dmaBase[0x0] = 0x00040000;
- pNv->dmaBase[0x1] = 0x80000010;
- pNv->dmaBase[0x2] = 0x00042000;
- pNv->dmaBase[0x3] = 0x80000011;
- pNv->dmaBase[0x4] = 0x00044000;
- pNv->dmaBase[0x5] = 0x80000012;
- pNv->dmaBase[0x6] = 0x00046000;
- pNv->dmaBase[0x7] = 0x80000013;
- pNv->dmaBase[0x8] = 0x00048000;
- pNv->dmaBase[0x9] = 0x80000014;
- pNv->dmaBase[0xA] = 0x0004A000;
- pNv->dmaBase[0xB] = 0x80000015;
- pNv->dmaBase[0xC] = 0x0004C000;
- pNv->dmaBase[0xD] = 0x80000016;
- pNv->dmaBase[0xE] = 0x0004E000;
- pNv->dmaBase[0xF] = 0x80000017;
+ for(i = 0; i < SKIPS; i++)
+ pNv->dmaBase[i] = 0x00000000;
+
+ pNv->dmaBase[0x0 + SKIPS] = 0x00040000;
+ pNv->dmaBase[0x1 + SKIPS] = 0x80000010;
+ pNv->dmaBase[0x2 + SKIPS] = 0x00042000;
+ pNv->dmaBase[0x3 + SKIPS] = 0x80000011;
+ pNv->dmaBase[0x4 + SKIPS] = 0x00044000;
+ pNv->dmaBase[0x5 + SKIPS] = 0x80000012;
+ pNv->dmaBase[0x6 + SKIPS] = 0x00046000;
+ pNv->dmaBase[0x7 + SKIPS] = 0x80000013;
+ pNv->dmaBase[0x8 + SKIPS] = 0x00048000;
+ pNv->dmaBase[0x9 + SKIPS] = 0x80000014;
+ pNv->dmaBase[0xA + SKIPS] = 0x0004A000;
+ pNv->dmaBase[0xB + SKIPS] = 0x80000015;
+ pNv->dmaBase[0xC + SKIPS] = 0x0004C000;
+ pNv->dmaBase[0xD + SKIPS] = 0x80000016;
+ pNv->dmaBase[0xE + SKIPS] = 0x0004E000;
+ pNv->dmaBase[0xF + SKIPS] = 0x80000017;
pNv->dmaPut = 0;
- pNv->dmaCurrent = 16;
+ pNv->dmaCurrent = 16 + SKIPS;
pNv->dmaMax = 8191;
- pNv->dmaFree = 8175;
+ pNv->dmaFree = pNv->dmaMax - pNv->dmaCurrent;
switch(pNv->CurrentLayout.depth) {
case 24: