diff options
Diffstat (limited to 'src/mesa/drivers/dri/nouveau/nouveau_fifo.c')
-rw-r--r-- | src/mesa/drivers/dri/nouveau/nouveau_fifo.c | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/src/mesa/drivers/dri/nouveau/nouveau_fifo.c b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c new file mode 100644 index 0000000000..a330d5268b --- /dev/null +++ b/src/mesa/drivers/dri/nouveau/nouveau_fifo.c @@ -0,0 +1,96 @@ +/************************************************************************** + +Copyright 2006 Stephane Marchesin +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + + +#include "nouveau_fifo.h" +#include "vblank.h" + +#define RING_SKIPS 8 + +void WAIT_RING(nouveauContextPtr nmesa,u_int32_t size) +{ + u_int32_t fifo_get; + while(nmesa->fifo.free < size+1) { + fifo_get = NV_FIFO_READ(NV03_FIFO_REGS_DMAGET); + + if(nmesa->fifo.put >= fifo_get) { + nmesa->fifo.free = nmesa->fifo.max - nmesa->fifo.current; + if(nmesa->fifo.free < size+1) { + OUT_RING(NV03_FIFO_CMD_REWIND); \ + if(fifo_get <= RING_SKIPS) { + if(nmesa->fifo.put <= RING_SKIPS) /* corner case - will be idle */ + NV_FIFO_WRITE(NV03_FIFO_REGS_DMAPUT, RING_SKIPS + 1); + do { fifo_get = NV_FIFO_READ(NV03_FIFO_REGS_DMAGET); } + while(fifo_get <= RING_SKIPS); + } + NV03_FIFO_REGS_DMAPUT(NV03_FIFO_REGS_DMAPUT, RING_SKIPS); + nmesa->fifo.current = nmesa->fifo.put = RING_SKIPS; + nmesa->fifo.free = fifo_get - (RING_SKIPS + 1); + } + } else + nmesa->fifo.free = fifo_get - nmesa->fifo.current - 1; + } +} + +/* + * Wait for the card to be idle + * XXX we should also wait for an empty fifo + */ +void nouveauWaitForIdleLocked(nouveauContextPtr *nmesa) +{ + int i,status; + + for(i=0;i<1000000;i++) /* 1 second */ + { + switch(nmesa->screen->card_type) + { + case NV_03: + status=NV_READ(NV03_STATUS); + break; + case NV_04: + case NV_05: + case NV_10: + case NV_20: + case NV_30: + case NV_40: + case G_70: + default: + status=NV_READ(NV04_STATUS); + break; + } + if (status) + return 0; + DO_USLEEP(1); + } +} + +void nouveauWaitForIdle(nouveauContextPtr *nmesa) +{ + LOCK_HARDWARE(nmesa); + nouveauWaitForIdleLocked(nmesa); + UNLOCK_HARDWARE(nmesa); +} + |