2 * Copyright 2018 Red Hat Inc.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
22 #include "changk104.h"
25 #include <core/client.h>
26 #include <core/gpuobj.h>
28 #include <nvif/clc36f.h>
29 #include <nvif/unpack.h>
32 gv100_fifo_gpfifo_submit_token(struct nvkm_fifo_chan
*chan
)
38 gv100_fifo_gpfifo_engine_valid(struct gk104_fifo_chan
*chan
, bool ce
, bool valid
)
40 struct nvkm_subdev
*subdev
= &chan
->base
.fifo
->engine
.subdev
;
41 struct nvkm_device
*device
= subdev
->device
;
42 const u32 mask
= ce
? 0x00020000 : 0x00010000;
43 const u32 data
= valid
? mask
: 0x00000000;
46 /* Block runlist to prevent the channel from being rescheduled. */
47 mutex_lock(&subdev
->mutex
);
48 nvkm_mask(device
, 0x002630, BIT(chan
->runl
), BIT(chan
->runl
));
50 /* Preempt the channel. */
51 ret
= gk104_fifo_gpfifo_kick_locked(chan
);
53 /* Update engine context validity. */
54 nvkm_kmap(chan
->base
.inst
);
55 nvkm_mo32(chan
->base
.inst
, 0x0ac, mask
, data
);
56 nvkm_done(chan
->base
.inst
);
60 nvkm_mask(device
, 0x002630, BIT(chan
->runl
), 0);
61 mutex_unlock(&subdev
->mutex
);
66 gv100_fifo_gpfifo_engine_fini(struct nvkm_fifo_chan
*base
,
67 struct nvkm_engine
*engine
, bool suspend
)
69 struct gk104_fifo_chan
*chan
= gk104_fifo_chan(base
);
70 struct nvkm_gpuobj
*inst
= chan
->base
.inst
;
73 if (engine
->subdev
.index
>= NVKM_ENGINE_CE0
&&
74 engine
->subdev
.index
<= NVKM_ENGINE_CE_LAST
)
75 return gk104_fifo_gpfifo_kick(chan
);
77 ret
= gv100_fifo_gpfifo_engine_valid(chan
, false, false);
82 nvkm_wo32(inst
, 0x0210, 0x00000000);
83 nvkm_wo32(inst
, 0x0214, 0x00000000);
89 gv100_fifo_gpfifo_engine_init(struct nvkm_fifo_chan
*base
,
90 struct nvkm_engine
*engine
)
92 struct gk104_fifo_chan
*chan
= gk104_fifo_chan(base
);
93 struct nvkm_gpuobj
*inst
= chan
->base
.inst
;
96 if (engine
->subdev
.index
>= NVKM_ENGINE_CE0
&&
97 engine
->subdev
.index
<= NVKM_ENGINE_CE_LAST
)
100 addr
= chan
->engn
[engine
->subdev
.index
].vma
->addr
;
102 nvkm_wo32(inst
, 0x210, lower_32_bits(addr
) | 0x00000004);
103 nvkm_wo32(inst
, 0x214, upper_32_bits(addr
));
106 return gv100_fifo_gpfifo_engine_valid(chan
, false, true);
109 static const struct nvkm_fifo_chan_func
110 gv100_fifo_gpfifo
= {
111 .dtor
= gk104_fifo_gpfifo_dtor
,
112 .init
= gk104_fifo_gpfifo_init
,
113 .fini
= gk104_fifo_gpfifo_fini
,
114 .ntfy
= gf100_fifo_chan_ntfy
,
115 .engine_ctor
= gk104_fifo_gpfifo_engine_ctor
,
116 .engine_dtor
= gk104_fifo_gpfifo_engine_dtor
,
117 .engine_init
= gv100_fifo_gpfifo_engine_init
,
118 .engine_fini
= gv100_fifo_gpfifo_engine_fini
,
119 .submit_token
= gv100_fifo_gpfifo_submit_token
,
123 gv100_fifo_gpfifo_new_(const struct nvkm_fifo_chan_func
*func
,
124 struct gk104_fifo
*fifo
, u64
*runlists
, u16
*chid
,
125 u64 vmm
, u64 ioffset
, u64 ilength
, u64
*inst
, bool priv
,
126 u32
*token
, const struct nvkm_oclass
*oclass
,
127 struct nvkm_object
**pobject
)
129 struct nvkm_device
*device
= fifo
->base
.engine
.subdev
.device
;
130 struct gk104_fifo_chan
*chan
;
131 int runlist
= ffs(*runlists
) -1, ret
, i
;
137 if (!vmm
|| runlist
< 0 || runlist
>= fifo
->runlist_nr
)
139 *runlists
= BIT_ULL(runlist
);
141 engm
= fifo
->runlist
[runlist
].engm
;
142 for_each_set_bit(i
, &engm
, fifo
->engine_nr
) {
143 if (fifo
->engine
[i
].engine
)
144 subdevs
|= BIT_ULL(fifo
->engine
[i
].engine
->subdev
.index
);
147 /* Allocate the channel. */
148 if (!(chan
= kzalloc(sizeof(*chan
), GFP_KERNEL
)))
150 *pobject
= &chan
->base
.object
;
152 chan
->runl
= runlist
;
153 INIT_LIST_HEAD(&chan
->head
);
155 ret
= nvkm_fifo_chan_ctor(func
, &fifo
->base
, 0x1000, 0x1000, true, vmm
,
156 0, subdevs
, 1, fifo
->user
.bar
->addr
, 0x200,
157 oclass
, &chan
->base
);
161 *chid
= chan
->base
.chid
;
162 *inst
= chan
->base
.inst
->addr
;
163 *token
= chan
->base
.func
->submit_token(&chan
->base
);
165 /* Hack to support GPUs where even individual channels should be
166 * part of a channel group.
168 if (fifo
->func
->cgrp_force
) {
169 if (!(chan
->cgrp
= kmalloc(sizeof(*chan
->cgrp
), GFP_KERNEL
)))
171 chan
->cgrp
->id
= chan
->base
.chid
;
172 INIT_LIST_HEAD(&chan
->cgrp
->head
);
173 INIT_LIST_HEAD(&chan
->cgrp
->chan
);
174 chan
->cgrp
->chan_nr
= 0;
177 /* Clear channel control registers. */
178 usermem
= chan
->base
.chid
* 0x200;
179 ilength
= order_base_2(ilength
/ 8);
181 nvkm_kmap(fifo
->user
.mem
);
182 for (i
= 0; i
< 0x200; i
+= 4)
183 nvkm_wo32(fifo
->user
.mem
, usermem
+ i
, 0x00000000);
184 nvkm_done(fifo
->user
.mem
);
185 usermem
= nvkm_memory_addr(fifo
->user
.mem
) + usermem
;
187 /* Allocate fault method buffer (magics come from nvgpu). */
188 size
= nvkm_rd32(device
, 0x104028); /* NV_PCE_PCE_MAP */
189 size
= 27 * 5 * (((9 + 1 + 3) * hweight32(size
)) + 2);
190 size
= roundup(size
, PAGE_SIZE
);
192 ret
= nvkm_memory_new(device
, NVKM_MEM_TARGET_INST
, size
, 0x1000, true,
197 mthd
= nvkm_memory_bar2(chan
->mthd
);
202 nvkm_kmap(chan
->base
.inst
);
203 nvkm_wo32(chan
->base
.inst
, 0x008, lower_32_bits(usermem
));
204 nvkm_wo32(chan
->base
.inst
, 0x00c, upper_32_bits(usermem
));
205 nvkm_wo32(chan
->base
.inst
, 0x010, 0x0000face);
206 nvkm_wo32(chan
->base
.inst
, 0x030, 0x7ffff902);
207 nvkm_wo32(chan
->base
.inst
, 0x048, lower_32_bits(ioffset
));
208 nvkm_wo32(chan
->base
.inst
, 0x04c, upper_32_bits(ioffset
) |
210 nvkm_wo32(chan
->base
.inst
, 0x084, 0x20400000);
211 nvkm_wo32(chan
->base
.inst
, 0x094, 0x30000001);
212 nvkm_wo32(chan
->base
.inst
, 0x0e4, priv
? 0x00000020 : 0x00000000);
213 nvkm_wo32(chan
->base
.inst
, 0x0e8, chan
->base
.chid
);
214 nvkm_wo32(chan
->base
.inst
, 0x0f4, 0x00001000);
215 nvkm_wo32(chan
->base
.inst
, 0x0f8, 0x10003080);
216 nvkm_mo32(chan
->base
.inst
, 0x218, 0x00000000, 0x00000000);
217 nvkm_wo32(chan
->base
.inst
, 0x220, lower_32_bits(mthd
));
218 nvkm_wo32(chan
->base
.inst
, 0x224, upper_32_bits(mthd
));
219 nvkm_done(chan
->base
.inst
);
220 return gv100_fifo_gpfifo_engine_valid(chan
, true, true);
224 gv100_fifo_gpfifo_new(struct gk104_fifo
*fifo
, const struct nvkm_oclass
*oclass
,
225 void *data
, u32 size
, struct nvkm_object
**pobject
)
227 struct nvkm_object
*parent
= oclass
->parent
;
229 struct volta_channel_gpfifo_a_v0 v0
;
233 nvif_ioctl(parent
, "create channel gpfifo size %d\n", size
);
234 if (!(ret
= nvif_unpack(ret
, &data
, &size
, args
->v0
, 0, 0, false))) {
235 nvif_ioctl(parent
, "create channel gpfifo vers %d vmm %llx "
236 "ioffset %016llx ilength %08x "
237 "runlist %016llx priv %d\n",
238 args
->v0
.version
, args
->v0
.vmm
, args
->v0
.ioffset
,
239 args
->v0
.ilength
, args
->v0
.runlist
, args
->v0
.priv
);
240 if (args
->v0
.priv
&& !oclass
->client
->super
)
242 return gv100_fifo_gpfifo_new_(&gv100_fifo_gpfifo
, fifo
,