summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nouveau_dma.c
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2009-12-26 02:42:45 +0100
committerBen Skeggs <bskeggs@redhat.com>2010-01-11 09:06:37 +1000
commitf03a314b4671407c4ff69a2d85e72413e8064c48 (patch)
treebe9db286225f6bce82cdbe776e4c5444413157fa /drivers/gpu/drm/nouveau/nouveau_dma.c
parenta510604df9444a2a1bdecafc048749e0f35816b5 (diff)
drm/nouveau: Allocate a per-channel instance of NV_SW.
It will be useful for various synchronization purposes, mostly stolen from "[PATCH] drm/nv50: synchronize user channel after buffer object move on kernel channel" by Maarten Maathuis. Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_dma.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.c17
1 files changed, 17 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
index 703553687b20..f1fd3f2b9813 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
@@ -35,6 +35,7 @@ nouveau_dma_init(struct nouveau_channel *chan)
struct drm_device *dev = chan->dev;
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_gpuobj *m2mf = NULL;
+ struct nouveau_gpuobj *nvsw = NULL;
int ret, i;
/* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */
@@ -47,6 +48,15 @@ nouveau_dma_init(struct nouveau_channel *chan)
if (ret)
return ret;
+ /* Create an NV_SW object for various sync purposes */
+ ret = nouveau_gpuobj_sw_new(chan, NV_SW, &nvsw);
+ if (ret)
+ return ret;
+
+ ret = nouveau_gpuobj_ref_add(dev, chan, NvSw, nvsw, NULL);
+ if (ret)
+ return ret;
+
/* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */
ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy);
if (ret)
@@ -87,6 +97,13 @@ nouveau_dma_init(struct nouveau_channel *chan)
BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
OUT_RING(chan, NvNotify0);
+ /* Initialise NV_SW */
+ ret = RING_SPACE(chan, 2);
+ if (ret)
+ return ret;
+ BEGIN_RING(chan, NvSubSw, 0, 1);
+ OUT_RING(chan, NvSw);
+
/* Sit back and pray the channel works.. */
FIRE_RING(chan);