1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "nouveau_drv.h"
25#include "nouveau_dma.h"
26#include "nouveau_fence.h"
27
28#include "nv50_display.h"
29
30#include <nvif/push906f.h>
31
32#include <nvhw/class/cl906f.h>
33
34static int
35nvc0_fence_emit32(struct nouveau_channel *chan, u64 virtual, u32 sequence)
36{
37 struct nvif_push *push = chan->chan.push;
38 int ret = PUSH_WAIT(push, 6);
39 if (ret == 0) {
40 PUSH_MTHD(push, NV906F, SEMAPHOREA,
41 NVVAL(NV906F, SEMAPHOREA, OFFSET_UPPER, upper_32_bits(virtual)),
42
43 SEMAPHOREB, lower_32_bits(virtual),
44 SEMAPHOREC, sequence,
45
46 SEMAPHORED,
47 NVDEF(NV906F, SEMAPHORED, OPERATION, RELEASE) |
48 NVDEF(NV906F, SEMAPHORED, RELEASE_WFI, EN) |
49 NVDEF(NV906F, SEMAPHORED, RELEASE_SIZE, 16BYTE),
50
51 NON_STALL_INTERRUPT, 0);
52 PUSH_KICK(push);
53 }
54 return ret;
55}
56
57static int
58nvc0_fence_sync32(struct nouveau_channel *chan, u64 virtual, u32 sequence)
59{
60 struct nvif_push *push = chan->chan.push;
61 int ret = PUSH_WAIT(push, 5);
62 if (ret == 0) {
63 PUSH_MTHD(push, NV906F, SEMAPHOREA,
64 NVVAL(NV906F, SEMAPHOREA, OFFSET_UPPER, upper_32_bits(virtual)),
65
66 SEMAPHOREB, lower_32_bits(virtual),
67 SEMAPHOREC, sequence,
68
69 SEMAPHORED,
70 NVDEF(NV906F, SEMAPHORED, OPERATION, ACQ_GEQ) |
71 NVDEF(NV906F, SEMAPHORED, ACQUIRE_SWITCH, ENABLED));
72 PUSH_KICK(push);
73 }
74 return ret;
75}
76
77static int
78nvc0_fence_context_new(struct nouveau_channel *chan)
79{
80 int ret = nv84_fence_context_new(chan);
81 if (ret == 0) {
82 struct nv84_fence_chan *fctx = chan->fence;
83 fctx->base.emit32 = nvc0_fence_emit32;
84 fctx->base.sync32 = nvc0_fence_sync32;
85 }
86 return ret;
87}
88
89int
90nvc0_fence_create(struct nouveau_drm *drm)
91{
92 int ret = nv84_fence_create(drm);
93 if (ret == 0) {
94 struct nv84_fence_priv *priv = drm->fence;
95 priv->base.context_new = nvc0_fence_context_new;
96 }
97 return ret;
98}
99