0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include "nouveau_drv.h"
0025 #include "nouveau_dma.h"
0026 #include "nv10_fence.h"
0027
0028 #include <nvif/push006c.h>
0029
0030 #include <nvhw/class/cl006e.h>
0031
0032 int
0033 nv10_fence_emit(struct nouveau_fence *fence)
0034 {
0035 struct nvif_push *push = fence->channel->chan.push;
0036 int ret = PUSH_WAIT(push, 2);
0037 if (ret == 0) {
0038 PUSH_MTHD(push, NV06E, SET_REFERENCE, fence->base.seqno);
0039 PUSH_KICK(push);
0040 }
0041 return ret;
0042 }
0043
0044
0045 static int
0046 nv10_fence_sync(struct nouveau_fence *fence,
0047 struct nouveau_channel *prev, struct nouveau_channel *chan)
0048 {
0049 return -ENODEV;
0050 }
0051
0052 u32
0053 nv10_fence_read(struct nouveau_channel *chan)
0054 {
0055 return NVIF_RD32(&chan->user, NV06E, REFERENCE);
0056 }
0057
0058 void
0059 nv10_fence_context_del(struct nouveau_channel *chan)
0060 {
0061 struct nv10_fence_chan *fctx = chan->fence;
0062 nouveau_fence_context_del(&fctx->base);
0063 nvif_object_dtor(&fctx->sema);
0064 chan->fence = NULL;
0065 nouveau_fence_context_free(&fctx->base);
0066 }
0067
0068 static int
0069 nv10_fence_context_new(struct nouveau_channel *chan)
0070 {
0071 struct nv10_fence_chan *fctx;
0072
0073 fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
0074 if (!fctx)
0075 return -ENOMEM;
0076
0077 nouveau_fence_context_new(chan, &fctx->base);
0078 fctx->base.emit = nv10_fence_emit;
0079 fctx->base.read = nv10_fence_read;
0080 fctx->base.sync = nv10_fence_sync;
0081 return 0;
0082 }
0083
0084 void
0085 nv10_fence_destroy(struct nouveau_drm *drm)
0086 {
0087 struct nv10_fence_priv *priv = drm->fence;
0088 nouveau_bo_unmap(priv->bo);
0089 if (priv->bo)
0090 nouveau_bo_unpin(priv->bo);
0091 nouveau_bo_ref(NULL, &priv->bo);
0092 drm->fence = NULL;
0093 kfree(priv);
0094 }
0095
0096 int
0097 nv10_fence_create(struct nouveau_drm *drm)
0098 {
0099 struct nv10_fence_priv *priv;
0100
0101 priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL);
0102 if (!priv)
0103 return -ENOMEM;
0104
0105 priv->base.dtor = nv10_fence_destroy;
0106 priv->base.context_new = nv10_fence_context_new;
0107 priv->base.context_del = nv10_fence_context_del;
0108 spin_lock_init(&priv->lock);
0109 return 0;
0110 }