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 "nouveau_fence.h"
0027 #include "nouveau_vmm.h"
0028
0029 #include "nv50_display.h"
0030
0031 #include <nvif/push206e.h>
0032
0033 #include <nvhw/class/cl826f.h>
0034
0035 static int
0036 nv84_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence)
0037 {
0038 struct nvif_push *push = chan->chan.push;
0039 int ret = PUSH_WAIT(push, 8);
0040 if (ret == 0) {
0041 PUSH_MTHD(push, NV826F, SET_CONTEXT_DMA_SEMAPHORE, chan->vram.handle);
0042
0043 PUSH_MTHD(push, NV826F, SEMAPHOREA,
0044 NVVAL(NV826F, SEMAPHOREA, OFFSET_UPPER, upper_32_bits(virtual)),
0045
0046 SEMAPHOREB, lower_32_bits(virtual),
0047 SEMAPHOREC, sequence,
0048
0049 SEMAPHORED,
0050 NVDEF(NV826F, SEMAPHORED, OPERATION, RELEASE),
0051
0052 NON_STALLED_INTERRUPT, 0);
0053 PUSH_KICK(push);
0054 }
0055 return ret;
0056 }
0057
0058 static int
0059 nv84_fence_sync32(struct nouveau_channel *chan, u64 virtual, u32 sequence)
0060 {
0061 struct nvif_push *push = chan->chan.push;
0062 int ret = PUSH_WAIT(push, 7);
0063 if (ret == 0) {
0064 PUSH_MTHD(push, NV826F, SET_CONTEXT_DMA_SEMAPHORE, chan->vram.handle);
0065
0066 PUSH_MTHD(push, NV826F, SEMAPHOREA,
0067 NVVAL(NV826F, SEMAPHOREA, OFFSET_UPPER, upper_32_bits(virtual)),
0068
0069 SEMAPHOREB, lower_32_bits(virtual),
0070 SEMAPHOREC, sequence,
0071
0072 SEMAPHORED,
0073 NVDEF(NV826F, SEMAPHORED, OPERATION, ACQ_GEQ));
0074 PUSH_KICK(push);
0075 }
0076 return ret;
0077 }
0078
0079 static int
0080 nv84_fence_emit(struct nouveau_fence *fence)
0081 {
0082 struct nouveau_channel *chan = fence->channel;
0083 struct nv84_fence_chan *fctx = chan->fence;
0084 u64 addr = fctx->vma->addr + chan->chid * 16;
0085
0086 return fctx->base.emit32(chan, addr, fence->base.seqno);
0087 }
0088
0089 static int
0090 nv84_fence_sync(struct nouveau_fence *fence,
0091 struct nouveau_channel *prev, struct nouveau_channel *chan)
0092 {
0093 struct nv84_fence_chan *fctx = chan->fence;
0094 u64 addr = fctx->vma->addr + prev->chid * 16;
0095
0096 return fctx->base.sync32(chan, addr, fence->base.seqno);
0097 }
0098
0099 static u32
0100 nv84_fence_read(struct nouveau_channel *chan)
0101 {
0102 struct nv84_fence_priv *priv = chan->drm->fence;
0103 return nouveau_bo_rd32(priv->bo, chan->chid * 16/4);
0104 }
0105
0106 static void
0107 nv84_fence_context_del(struct nouveau_channel *chan)
0108 {
0109 struct nv84_fence_priv *priv = chan->drm->fence;
0110 struct nv84_fence_chan *fctx = chan->fence;
0111
0112 nouveau_bo_wr32(priv->bo, chan->chid * 16 / 4, fctx->base.sequence);
0113 mutex_lock(&priv->mutex);
0114 nouveau_vma_del(&fctx->vma);
0115 mutex_unlock(&priv->mutex);
0116 nouveau_fence_context_del(&fctx->base);
0117 chan->fence = NULL;
0118 nouveau_fence_context_free(&fctx->base);
0119 }
0120
0121 int
0122 nv84_fence_context_new(struct nouveau_channel *chan)
0123 {
0124 struct nv84_fence_priv *priv = chan->drm->fence;
0125 struct nv84_fence_chan *fctx;
0126 int ret;
0127
0128 fctx = chan->fence = kzalloc(sizeof(*fctx), GFP_KERNEL);
0129 if (!fctx)
0130 return -ENOMEM;
0131
0132 nouveau_fence_context_new(chan, &fctx->base);
0133 fctx->base.emit = nv84_fence_emit;
0134 fctx->base.sync = nv84_fence_sync;
0135 fctx->base.read = nv84_fence_read;
0136 fctx->base.emit32 = nv84_fence_emit32;
0137 fctx->base.sync32 = nv84_fence_sync32;
0138 fctx->base.sequence = nv84_fence_read(chan);
0139
0140 mutex_lock(&priv->mutex);
0141 ret = nouveau_vma_new(priv->bo, chan->vmm, &fctx->vma);
0142 mutex_unlock(&priv->mutex);
0143
0144 if (ret)
0145 nv84_fence_context_del(chan);
0146 return ret;
0147 }
0148
0149 static bool
0150 nv84_fence_suspend(struct nouveau_drm *drm)
0151 {
0152 struct nv84_fence_priv *priv = drm->fence;
0153 int i;
0154
0155 priv->suspend = vmalloc(array_size(sizeof(u32), drm->chan.nr));
0156 if (priv->suspend) {
0157 for (i = 0; i < drm->chan.nr; i++)
0158 priv->suspend[i] = nouveau_bo_rd32(priv->bo, i*4);
0159 }
0160
0161 return priv->suspend != NULL;
0162 }
0163
0164 static void
0165 nv84_fence_resume(struct nouveau_drm *drm)
0166 {
0167 struct nv84_fence_priv *priv = drm->fence;
0168 int i;
0169
0170 if (priv->suspend) {
0171 for (i = 0; i < drm->chan.nr; i++)
0172 nouveau_bo_wr32(priv->bo, i*4, priv->suspend[i]);
0173 vfree(priv->suspend);
0174 priv->suspend = NULL;
0175 }
0176 }
0177
0178 static void
0179 nv84_fence_destroy(struct nouveau_drm *drm)
0180 {
0181 struct nv84_fence_priv *priv = drm->fence;
0182 nouveau_bo_unmap(priv->bo);
0183 if (priv->bo)
0184 nouveau_bo_unpin(priv->bo);
0185 nouveau_bo_ref(NULL, &priv->bo);
0186 drm->fence = NULL;
0187 kfree(priv);
0188 }
0189
0190 int
0191 nv84_fence_create(struct nouveau_drm *drm)
0192 {
0193 struct nv84_fence_priv *priv;
0194 u32 domain;
0195 int ret;
0196
0197 priv = drm->fence = kzalloc(sizeof(*priv), GFP_KERNEL);
0198 if (!priv)
0199 return -ENOMEM;
0200
0201 priv->base.dtor = nv84_fence_destroy;
0202 priv->base.suspend = nv84_fence_suspend;
0203 priv->base.resume = nv84_fence_resume;
0204 priv->base.context_new = nv84_fence_context_new;
0205 priv->base.context_del = nv84_fence_context_del;
0206
0207 priv->base.uevent = drm->client.device.info.family < NV_DEVICE_INFO_V0_AMPERE;
0208
0209 mutex_init(&priv->mutex);
0210
0211
0212 domain = drm->client.device.info.ram_size != 0 ?
0213 NOUVEAU_GEM_DOMAIN_VRAM :
0214
0215
0216
0217
0218 NOUVEAU_GEM_DOMAIN_GART | NOUVEAU_GEM_DOMAIN_COHERENT;
0219 ret = nouveau_bo_new(&drm->client, 16 * drm->chan.nr, 0,
0220 domain, 0, 0, NULL, NULL, &priv->bo);
0221 if (ret == 0) {
0222 ret = nouveau_bo_pin(priv->bo, domain, false);
0223 if (ret == 0) {
0224 ret = nouveau_bo_map(priv->bo);
0225 if (ret)
0226 nouveau_bo_unpin(priv->bo);
0227 }
0228 if (ret)
0229 nouveau_bo_ref(NULL, &priv->bo);
0230 }
0231
0232 if (ret)
0233 nv84_fence_destroy(drm);
0234 return ret;
0235 }