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
0028 #include "nv50_display.h"
0029
0030 #include <nvif/push906f.h>
0031
0032 #include <nvhw/class/cl906f.h>
0033
0034 static int
0035 nvc0_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence)
0036 {
0037 struct nvif_push *push = chan->chan.push;
0038 int ret = PUSH_WAIT(push, 6);
0039 if (ret == 0) {
0040 PUSH_MTHD(push, NV906F, SEMAPHOREA,
0041 NVVAL(NV906F, SEMAPHOREA, OFFSET_UPPER, upper_32_bits(virtual)),
0042
0043 SEMAPHOREB, lower_32_bits(virtual),
0044 SEMAPHOREC, sequence,
0045
0046 SEMAPHORED,
0047 NVDEF(NV906F, SEMAPHORED, OPERATION, RELEASE) |
0048 NVDEF(NV906F, SEMAPHORED, RELEASE_WFI, EN) |
0049 NVDEF(NV906F, SEMAPHORED, RELEASE_SIZE, 16BYTE),
0050
0051 NON_STALL_INTERRUPT, 0);
0052 PUSH_KICK(push);
0053 }
0054 return ret;
0055 }
0056
0057 static int
0058 nvc0_fence_sync32(struct nouveau_channel *chan, u64 virtual, u32 sequence)
0059 {
0060 struct nvif_push *push = chan->chan.push;
0061 int ret = PUSH_WAIT(push, 5);
0062 if (ret == 0) {
0063 PUSH_MTHD(push, NV906F, SEMAPHOREA,
0064 NVVAL(NV906F, SEMAPHOREA, OFFSET_UPPER, upper_32_bits(virtual)),
0065
0066 SEMAPHOREB, lower_32_bits(virtual),
0067 SEMAPHOREC, sequence,
0068
0069 SEMAPHORED,
0070 NVDEF(NV906F, SEMAPHORED, OPERATION, ACQ_GEQ) |
0071 NVDEF(NV906F, SEMAPHORED, ACQUIRE_SWITCH, ENABLED));
0072 PUSH_KICK(push);
0073 }
0074 return ret;
0075 }
0076
0077 static int
0078 nvc0_fence_context_new(struct nouveau_channel *chan)
0079 {
0080 int ret = nv84_fence_context_new(chan);
0081 if (ret == 0) {
0082 struct nv84_fence_chan *fctx = chan->fence;
0083 fctx->base.emit32 = nvc0_fence_emit32;
0084 fctx->base.sync32 = nvc0_fence_sync32;
0085 }
0086 return ret;
0087 }
0088
0089 int
0090 nvc0_fence_create(struct nouveau_drm *drm)
0091 {
0092 int ret = nv84_fence_create(drm);
0093 if (ret == 0) {
0094 struct nv84_fence_priv *priv = drm->fence;
0095 priv->base.context_new = nvc0_fence_context_new;
0096 }
0097 return ret;
0098 }