Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/nouveau/fence: make internal hooks part of the context

A step towards being able to provide fences from other engines not
connected to PFIFO.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>

+48 -45
+4 -6
drivers/gpu/drm/nouveau/nouveau_fence.c
··· 61 61 static void 62 62 nouveau_fence_update(struct nouveau_channel *chan) 63 63 { 64 - struct nouveau_fence_priv *priv = chan->drm->fence; 65 64 struct nouveau_fence_chan *fctx = chan->fence; 66 65 struct nouveau_fence *fence, *fnext; 67 66 68 67 spin_lock(&fctx->lock); 69 68 list_for_each_entry_safe(fence, fnext, &fctx->pending, head) { 70 - if (priv->read(chan) < fence->sequence) 69 + if (fctx->read(chan) < fence->sequence) 71 70 break; 72 71 73 72 if (fence->work) ··· 81 82 int 82 83 nouveau_fence_emit(struct nouveau_fence *fence, struct nouveau_channel *chan) 83 84 { 84 - struct nouveau_fence_priv *priv = chan->drm->fence; 85 85 struct nouveau_fence_chan *fctx = chan->fence; 86 86 int ret; 87 87 ··· 88 90 fence->timeout = jiffies + (3 * DRM_HZ); 89 91 fence->sequence = ++fctx->sequence; 90 92 91 - ret = priv->emit(fence); 93 + ret = fctx->emit(fence); 92 94 if (!ret) { 93 95 kref_get(&fence->kref); 94 96 spin_lock(&fctx->lock); ··· 217 219 int 218 220 nouveau_fence_sync(struct nouveau_fence *fence, struct nouveau_channel *chan) 219 221 { 220 - struct nouveau_fence_priv *priv = chan->drm->fence; 222 + struct nouveau_fence_chan *fctx = chan->fence; 221 223 struct nouveau_channel *prev; 222 224 int ret = 0; 223 225 224 226 prev = fence ? fence->channel : NULL; 225 227 if (prev) { 226 228 if (unlikely(prev != chan && !nouveau_fence_done(fence))) { 227 - ret = priv->sync(fence, prev, chan); 229 + ret = fctx->sync(fence, prev, chan); 228 230 if (unlikely(ret)) 229 231 ret = nouveau_fence_wait(fence, true, false); 230 232 }
+7 -6
drivers/gpu/drm/nouveau/nouveau_fence.h
··· 29 29 struct list_head pending; 30 30 struct list_head flip; 31 31 32 + int (*emit)(struct nouveau_fence *); 33 + int (*sync)(struct nouveau_fence *, struct nouveau_channel *, 34 + struct nouveau_channel *); 35 + u32 (*read)(struct nouveau_channel *); 36 + int (*emit32)(struct nouveau_channel *, u64, u32); 37 + int (*sync32)(struct nouveau_channel *, u64, u32); 38 + 32 39 spinlock_t lock; 33 40 u32 sequence; 34 41 }; ··· 46 39 void (*resume)(struct nouveau_drm *); 47 40 int (*context_new)(struct nouveau_channel *); 48 41 void (*context_del)(struct nouveau_channel *); 49 - int (*emit32)(struct nouveau_channel *, u64, u32); 50 - int (*emit)(struct nouveau_fence *); 51 - int (*sync32)(struct nouveau_channel *, u64, u32); 52 - int (*sync)(struct nouveau_fence *, struct nouveau_channel *, 53 - struct nouveau_channel *); 54 - u32 (*read)(struct nouveau_channel *); 55 42 56 43 wait_queue_head_t waiting; 57 44 bool uevent;
+3 -3
drivers/gpu/drm/nouveau/nv04_fence.c
··· 78 78 struct nv04_fence_chan *fctx = kzalloc(sizeof(*fctx), GFP_KERNEL); 79 79 if (fctx) { 80 80 nouveau_fence_context_new(&fctx->base); 81 + fctx->base.emit = nv04_fence_emit; 82 + fctx->base.sync = nv04_fence_sync; 83 + fctx->base.read = nv04_fence_read; 81 84 chan->fence = fctx; 82 85 return 0; 83 86 } ··· 107 104 priv->base.dtor = nv04_fence_destroy; 108 105 priv->base.context_new = nv04_fence_context_new; 109 106 priv->base.context_del = nv04_fence_context_del; 110 - priv->base.emit = nv04_fence_emit; 111 - priv->base.sync = nv04_fence_sync; 112 - priv->base.read = nv04_fence_read; 113 107 return 0; 114 108 }
+3 -3
drivers/gpu/drm/nouveau/nv10_fence.c
··· 75 75 return -ENOMEM; 76 76 77 77 nouveau_fence_context_new(&fctx->base); 78 + fctx->base.emit = nv10_fence_emit; 79 + fctx->base.read = nv10_fence_read; 80 + fctx->base.sync = nv10_fence_sync; 78 81 return 0; 79 82 } 80 83 ··· 105 102 priv->base.dtor = nv10_fence_destroy; 106 103 priv->base.context_new = nv10_fence_context_new; 107 104 priv->base.context_del = nv10_fence_context_del; 108 - priv->base.emit = nv10_fence_emit; 109 - priv->base.read = nv10_fence_read; 110 - priv->base.sync = nv10_fence_sync; 111 105 spin_lock_init(&priv->lock); 112 106 return 0; 113 107 }
+3 -3
drivers/gpu/drm/nouveau/nv17_fence.c
··· 84 84 return -ENOMEM; 85 85 86 86 nouveau_fence_context_new(&fctx->base); 87 + fctx->base.emit = nv10_fence_emit; 88 + fctx->base.read = nv10_fence_read; 89 + fctx->base.sync = nv17_fence_sync; 87 90 88 91 ret = nouveau_object_new(nv_object(chan->cli), chan->handle, 89 92 NvSema, 0x0002, ··· 124 121 priv->base.resume = nv17_fence_resume; 125 122 priv->base.context_new = nv17_fence_context_new; 126 123 priv->base.context_del = nv10_fence_context_del; 127 - priv->base.emit = nv10_fence_emit; 128 - priv->base.read = nv10_fence_read; 129 - priv->base.sync = nv17_fence_sync; 130 124 spin_lock_init(&priv->lock); 131 125 132 126 ret = nouveau_bo_new(drm->dev, 4096, 0x1000, TTM_PL_FLAG_VRAM,
+8 -9
drivers/gpu/drm/nouveau/nv50_fence.c
··· 46 46 return -ENOMEM; 47 47 48 48 nouveau_fence_context_new(&fctx->base); 49 + fctx->base.emit = nv10_fence_emit; 50 + fctx->base.read = nv10_fence_read; 51 + fctx->base.sync = nv17_fence_sync; 49 52 50 53 ret = nouveau_object_new(nv_object(chan->cli), chan->handle, 51 54 NvSema, 0x0002, ··· 91 88 return -ENOMEM; 92 89 93 90 priv->base.dtor = nv10_fence_destroy; 91 + priv->base.resume = nv17_fence_resume; 94 92 priv->base.context_new = nv50_fence_context_new; 95 93 priv->base.context_del = nv10_fence_context_del; 96 - priv->base.emit = nv10_fence_emit; 97 - priv->base.read = nv10_fence_read; 98 - priv->base.sync = nv17_fence_sync; 99 94 spin_lock_init(&priv->lock); 100 95 101 96 ret = nouveau_bo_new(drm->dev, 4096, 0x1000, TTM_PL_FLAG_VRAM, ··· 109 108 nouveau_bo_ref(NULL, &priv->bo); 110 109 } 111 110 112 - if (ret == 0) { 113 - nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); 114 - priv->base.sync = nv17_fence_sync; 115 - priv->base.resume = nv17_fence_resume; 111 + if (ret) { 112 + nv10_fence_destroy(drm); 113 + return ret; 116 114 } 117 115 118 - if (ret) 119 - nv10_fence_destroy(drm); 116 + nouveau_bo_wr32(priv->bo, 0x000, 0x00000000); 120 117 return ret; 121 118 }
+7 -9
drivers/gpu/drm/nouveau/nv84_fence.c
··· 80 80 nv84_fence_emit(struct nouveau_fence *fence) 81 81 { 82 82 struct nouveau_channel *chan = fence->channel; 83 - struct nv84_fence_priv *priv = chan->drm->fence; 84 83 struct nv84_fence_chan *fctx = chan->fence; 85 84 struct nouveau_fifo_chan *fifo = (void *)chan->object; 86 85 u64 addr = fctx->vma.offset + fifo->chid * 16; 87 - return priv->base.emit32(chan, addr, fence->sequence); 86 + return fctx->base.emit32(chan, addr, fence->sequence); 88 87 } 89 88 90 89 int 91 90 nv84_fence_sync(struct nouveau_fence *fence, 92 91 struct nouveau_channel *prev, struct nouveau_channel *chan) 93 92 { 94 - struct nv84_fence_priv *priv = chan->drm->fence; 95 93 struct nv84_fence_chan *fctx = chan->fence; 96 94 struct nouveau_fifo_chan *fifo = (void *)prev->object; 97 95 u64 addr = fctx->vma.offset + fifo->chid * 16; 98 - return priv->base.sync32(chan, addr, fence->sequence); 96 + return fctx->base.sync32(chan, addr, fence->sequence); 99 97 } 100 98 101 99 u32 ··· 137 139 return -ENOMEM; 138 140 139 141 nouveau_fence_context_new(&fctx->base); 142 + fctx->base.emit = nv84_fence_emit; 143 + fctx->base.sync = nv84_fence_sync; 144 + fctx->base.read = nv84_fence_read; 145 + fctx->base.emit32 = nv84_fence_emit32; 146 + fctx->base.sync32 = nv84_fence_sync32; 140 147 141 148 ret = nouveau_bo_vma_add(priv->bo, client->vm, &fctx->vma); 142 149 if (ret) ··· 216 213 priv->base.resume = nv84_fence_resume; 217 214 priv->base.context_new = nv84_fence_context_new; 218 215 priv->base.context_del = nv84_fence_context_del; 219 - priv->base.emit32 = nv84_fence_emit32; 220 - priv->base.emit = nv84_fence_emit; 221 - priv->base.sync32 = nv84_fence_sync32; 222 - priv->base.sync = nv84_fence_sync; 223 - priv->base.read = nv84_fence_read; 224 216 225 217 init_waitqueue_head(&priv->base.waiting); 226 218 priv->base.uevent = true;
+13 -6
drivers/gpu/drm/nouveau/nvc0_fence.c
··· 66 66 return ret; 67 67 } 68 68 69 + static int 70 + nvc0_fence_context_new(struct nouveau_channel *chan) 71 + { 72 + int ret = nv84_fence_context_new(chan); 73 + if (ret == 0) { 74 + struct nv84_fence_chan *fctx = chan->fence; 75 + fctx->base.emit32 = nvc0_fence_emit32; 76 + fctx->base.sync32 = nvc0_fence_sync32; 77 + } 78 + return ret; 79 + } 80 + 69 81 int 70 82 nvc0_fence_create(struct nouveau_drm *drm) 71 83 { ··· 92 80 priv->base.dtor = nv84_fence_destroy; 93 81 priv->base.suspend = nv84_fence_suspend; 94 82 priv->base.resume = nv84_fence_resume; 95 - priv->base.context_new = nv84_fence_context_new; 83 + priv->base.context_new = nvc0_fence_context_new; 96 84 priv->base.context_del = nv84_fence_context_del; 97 - priv->base.emit32 = nvc0_fence_emit32; 98 - priv->base.emit = nv84_fence_emit; 99 - priv->base.sync32 = nvc0_fence_sync32; 100 - priv->base.sync = nv84_fence_sync; 101 - priv->base.read = nv84_fence_read; 102 85 103 86 init_waitqueue_head(&priv->base.waiting); 104 87 priv->base.uevent = true;