diff options
Diffstat (limited to 'src/nv_xaa.c')
-rw-r--r-- | src/nv_xaa.c | 77 |
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: |