summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_dma.h
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2010-02-11 07:37:26 +0100
committerBen Skeggs <bskeggs@redhat.com>2010-02-25 06:08:29 +0100
commit9a391ad8a2cdd7e5be9b6aabb56f4a46683ba377 (patch)
tree2dafd2b541dff055e88406cfb48679530b12192e /drivers/gpu/drm/nouveau/nouveau_dma.h
parentdrm/nouveau: protect channel create/destroy and irq handler with a spinlock (diff)
downloadlinux-9a391ad8a2cdd7e5be9b6aabb56f4a46683ba377.tar.xz
linux-9a391ad8a2cdd7e5be9b6aabb56f4a46683ba377.zip
drm/nv50: switch to indirect push buffer controls
PFIFO on G80 and up has a new mode where the main ring buffer is simply a ring of pointers to indirect buffers containing the actual command/data packets. In order to be able to implement index buffers in the 3D driver we need to be able to submit data-only push buffers right after the cmd packet header, which is only possible using the new command submission method. This commit doesn't make it possible to implement index buffers yet, some userspace interface changes will be required, but it does allow for testing/debugging of the hardware-side support in the meantime. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_dma.h')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.h21
1 files changed, 14 insertions, 7 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h
index dabfd655f93e..da6e16dafa4d 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.h
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.h
@@ -31,6 +31,9 @@
#define NOUVEAU_DMA_DEBUG 0
#endif
+void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *,
+ int delta, int dwords);
+
/*
* There's a hw race condition where you can't jump to your PUT offset,
* to avoid this we jump to offset + SKIPS and fill the difference with
@@ -96,13 +99,11 @@ enum {
static __must_check inline int
RING_SPACE(struct nouveau_channel *chan, int size)
{
- if (chan->dma.free < size) {
- int ret;
+ int ret;
- ret = nouveau_dma_wait(chan, size);
- if (ret)
- return ret;
- }
+ ret = nouveau_dma_wait(chan, 1, size);
+ if (ret)
+ return ret;
chan->dma.free -= size;
return 0;
@@ -146,7 +147,13 @@ FIRE_RING(struct nouveau_channel *chan)
return;
chan->accel_done = true;
- WRITE_PUT(chan->dma.cur);
+ if (chan->dma.ib_max) {
+ nv50_dma_push(chan, chan->pushbuf_bo, chan->dma.put << 2,
+ chan->dma.cur - chan->dma.put);
+ } else {
+ WRITE_PUT(chan->dma.cur);
+ }
+
chan->dma.put = chan->dma.cur;
}