forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-31 f70575805708cabdedea7498aaa3f710fde4d920
kernel/drivers/gpu/drm/nouveau/nouveau_chan.c
....@@ -21,18 +21,16 @@
2121 *
2222 * Authors: Ben Skeggs
2323 */
24
+#include <nvif/push006c.h>
2425
25
-#include <nvif/os.h>
2626 #include <nvif/class.h>
2727 #include <nvif/cl0002.h>
2828 #include <nvif/cl006b.h>
2929 #include <nvif/cl506f.h>
3030 #include <nvif/cl906f.h>
3131 #include <nvif/cla06f.h>
32
+#include <nvif/clc36f.h>
3233 #include <nvif/ioctl.h>
33
-
34
-/*XXX*/
35
-#include <core/client.h>
3634
3735 #include "nouveau_drv.h"
3836 #include "nouveau_dma.h"
....@@ -41,6 +39,7 @@
4139 #include "nouveau_fence.h"
4240 #include "nouveau_abi16.h"
4341 #include "nouveau_vmm.h"
42
+#include "nouveau_svm.h"
4443
4544 MODULE_PARM_DESC(vram_pushbuf, "Create DMA push buffers in VRAM");
4645 int nouveau_vram_pushbuf;
....@@ -53,6 +52,8 @@
5352 struct nouveau_cli *cli = (void *)chan->user.client;
5453 NV_PRINTK(warn, cli, "channel %d killed!\n", chan->chid);
5554 atomic_set(&chan->killed, 1);
55
+ if (chan->fence)
56
+ nouveau_fence_context_kill(chan->fence, -ENODEV);
5657 return NVIF_NOTIFY_DROP;
5758 }
5859
....@@ -94,12 +95,16 @@
9495
9596 if (chan->fence)
9697 nouveau_fence(chan->drm)->context_del(chan);
97
- nvif_object_fini(&chan->nvsw);
98
- nvif_object_fini(&chan->gart);
99
- nvif_object_fini(&chan->vram);
100
- nvif_notify_fini(&chan->kill);
101
- nvif_object_fini(&chan->user);
102
- nvif_object_fini(&chan->push.ctxdma);
98
+
99
+ if (cli)
100
+ nouveau_svmm_part(chan->vmm->svmm, chan->inst);
101
+
102
+ nvif_object_dtor(&chan->nvsw);
103
+ nvif_object_dtor(&chan->gart);
104
+ nvif_object_dtor(&chan->vram);
105
+ nvif_notify_dtor(&chan->kill);
106
+ nvif_object_dtor(&chan->user);
107
+ nvif_object_dtor(&chan->push.ctxdma);
103108 nouveau_vma_del(&chan->push.vma);
104109 nouveau_bo_unmap(chan->push.buffer);
105110 if (chan->push.buffer && chan->push.buffer->pin_refcnt)
....@@ -111,6 +116,31 @@
111116 cli->base.super = super;
112117 }
113118 *pchan = NULL;
119
+}
120
+
121
+static void
122
+nouveau_channel_kick(struct nvif_push *push)
123
+{
124
+ struct nouveau_channel *chan = container_of(push, typeof(*chan), chan._push);
125
+ chan->dma.cur = chan->dma.cur + (chan->chan._push.cur - chan->chan._push.bgn);
126
+ FIRE_RING(chan);
127
+ chan->chan._push.bgn = chan->chan._push.cur;
128
+}
129
+
130
+static int
131
+nouveau_channel_wait(struct nvif_push *push, u32 size)
132
+{
133
+ struct nouveau_channel *chan = container_of(push, typeof(*chan), chan._push);
134
+ int ret;
135
+ chan->dma.cur = chan->dma.cur + (chan->chan._push.cur - chan->chan._push.bgn);
136
+ ret = RING_SPACE(chan, size);
137
+ if (ret == 0) {
138
+ chan->chan._push.bgn = chan->chan._push.mem.object.map.ptr;
139
+ chan->chan._push.bgn = chan->chan._push.bgn + chan->dma.cur;
140
+ chan->chan._push.cur = chan->chan._push.bgn;
141
+ chan->chan._push.end = chan->chan._push.bgn + size;
142
+ }
143
+ return ret;
114144 }
115145
116146 static int
....@@ -129,12 +159,13 @@
129159
130160 chan->device = device;
131161 chan->drm = drm;
162
+ chan->vmm = cli->svm.cli ? &cli->svm : &cli->vmm;
132163 atomic_set(&chan->killed, 0);
133164
134165 /* allocate memory for dma push buffer */
135
- target = TTM_PL_FLAG_TT | TTM_PL_FLAG_UNCACHED;
166
+ target = NOUVEAU_GEM_DOMAIN_GART | NOUVEAU_GEM_DOMAIN_COHERENT;
136167 if (nouveau_vram_pushbuf)
137
- target = TTM_PL_FLAG_VRAM;
168
+ target = NOUVEAU_GEM_DOMAIN_VRAM;
138169
139170 ret = nouveau_bo_new(cli, size, 0, target, 0, 0, NULL, NULL,
140171 &chan->push.buffer);
....@@ -149,14 +180,22 @@
149180 return ret;
150181 }
151182
183
+ chan->chan._push.mem.object.parent = cli->base.object.parent;
184
+ chan->chan._push.mem.object.client = &cli->base;
185
+ chan->chan._push.mem.object.name = "chanPush";
186
+ chan->chan._push.mem.object.map.ptr = chan->push.buffer->kmap.virtual;
187
+ chan->chan._push.wait = nouveau_channel_wait;
188
+ chan->chan._push.kick = nouveau_channel_kick;
189
+ chan->chan.push = &chan->chan._push;
190
+
152191 /* create dma object covering the *entire* memory space that the
153192 * pushbuf lives in, this is because the GEM code requires that
154193 * we be able to call out to other (indirect) push buffers
155194 */
156
- chan->push.addr = chan->push.buffer->bo.offset;
195
+ chan->push.addr = chan->push.buffer->offset;
157196
158197 if (device->info.family >= NV_DEVICE_INFO_V0_TESLA) {
159
- ret = nouveau_vma_new(chan->push.buffer, &cli->vmm,
198
+ ret = nouveau_vma_new(chan->push.buffer, chan->vmm,
160199 &chan->push.vma);
161200 if (ret) {
162201 nouveau_channel_del(pchan);
....@@ -171,7 +210,7 @@
171210 args.target = NV_DMA_V0_TARGET_VM;
172211 args.access = NV_DMA_V0_ACCESS_VM;
173212 args.start = 0;
174
- args.limit = cli->vmm.vmm.limit - 1;
213
+ args.limit = chan->vmm->vmm.limit - 1;
175214 } else
176215 if (chan->push.buffer->bo.mem.mem_type == TTM_PL_VRAM) {
177216 if (device->info.family == NV_DEVICE_INFO_V0_TNT) {
....@@ -201,12 +240,13 @@
201240 args.target = NV_DMA_V0_TARGET_VM;
202241 args.access = NV_DMA_V0_ACCESS_RDWR;
203242 args.start = 0;
204
- args.limit = cli->vmm.vmm.limit - 1;
243
+ args.limit = chan->vmm->vmm.limit - 1;
205244 }
206245 }
207246
208
- ret = nvif_object_init(&device->object, 0, NV_DMA_FROM_MEMORY,
209
- &args, sizeof(args), &chan->push.ctxdma);
247
+ ret = nvif_object_ctor(&device->object, "abi16PushCtxDma", 0,
248
+ NV_DMA_FROM_MEMORY, &args, sizeof(args),
249
+ &chan->push.ctxdma);
210250 if (ret) {
211251 nouveau_channel_del(pchan);
212252 return ret;
....@@ -217,10 +257,10 @@
217257
218258 static int
219259 nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device,
220
- u64 runlist, struct nouveau_channel **pchan)
260
+ u64 runlist, bool priv, struct nouveau_channel **pchan)
221261 {
222
- struct nouveau_cli *cli = (void *)device->object.client;
223
- static const u16 oclasses[] = { VOLTA_CHANNEL_GPFIFO_A,
262
+ static const u16 oclasses[] = { TURING_CHANNEL_GPFIFO_A,
263
+ VOLTA_CHANNEL_GPFIFO_A,
224264 PASCAL_CHANNEL_GPFIFO_A,
225265 MAXWELL_CHANNEL_GPFIFO_A,
226266 KEPLER_CHANNEL_GPFIFO_B,
....@@ -234,6 +274,7 @@
234274 struct nv50_channel_gpfifo_v0 nv50;
235275 struct fermi_channel_gpfifo_v0 fermi;
236276 struct kepler_channel_gpfifo_a_v0 kepler;
277
+ struct volta_channel_gpfifo_a_v0 volta;
237278 } args;
238279 struct nouveau_channel *chan;
239280 u32 size;
....@@ -247,39 +288,56 @@
247288
248289 /* create channel object */
249290 do {
291
+ if (oclass[0] >= VOLTA_CHANNEL_GPFIFO_A) {
292
+ args.volta.version = 0;
293
+ args.volta.ilength = 0x02000;
294
+ args.volta.ioffset = 0x10000 + chan->push.addr;
295
+ args.volta.runlist = runlist;
296
+ args.volta.vmm = nvif_handle(&chan->vmm->vmm.object);
297
+ args.volta.priv = priv;
298
+ size = sizeof(args.volta);
299
+ } else
250300 if (oclass[0] >= KEPLER_CHANNEL_GPFIFO_A) {
251301 args.kepler.version = 0;
252302 args.kepler.ilength = 0x02000;
253303 args.kepler.ioffset = 0x10000 + chan->push.addr;
254304 args.kepler.runlist = runlist;
255
- args.kepler.vmm = nvif_handle(&cli->vmm.vmm.object);
305
+ args.kepler.vmm = nvif_handle(&chan->vmm->vmm.object);
306
+ args.kepler.priv = priv;
256307 size = sizeof(args.kepler);
257308 } else
258309 if (oclass[0] >= FERMI_CHANNEL_GPFIFO) {
259310 args.fermi.version = 0;
260311 args.fermi.ilength = 0x02000;
261312 args.fermi.ioffset = 0x10000 + chan->push.addr;
262
- args.fermi.vmm = nvif_handle(&cli->vmm.vmm.object);
313
+ args.fermi.vmm = nvif_handle(&chan->vmm->vmm.object);
263314 size = sizeof(args.fermi);
264315 } else {
265316 args.nv50.version = 0;
266317 args.nv50.ilength = 0x02000;
267318 args.nv50.ioffset = 0x10000 + chan->push.addr;
268319 args.nv50.pushbuf = nvif_handle(&chan->push.ctxdma);
269
- args.nv50.vmm = nvif_handle(&cli->vmm.vmm.object);
320
+ args.nv50.vmm = nvif_handle(&chan->vmm->vmm.object);
270321 size = sizeof(args.nv50);
271322 }
272323
273
- ret = nvif_object_init(&device->object, 0, *oclass++,
274
- &args, size, &chan->user);
324
+ ret = nvif_object_ctor(&device->object, "abi16ChanUser", 0,
325
+ *oclass++, &args, size, &chan->user);
275326 if (ret == 0) {
276
- if (chan->user.oclass >= KEPLER_CHANNEL_GPFIFO_A)
327
+ if (chan->user.oclass >= VOLTA_CHANNEL_GPFIFO_A) {
328
+ chan->chid = args.volta.chid;
329
+ chan->inst = args.volta.inst;
330
+ chan->token = args.volta.token;
331
+ } else
332
+ if (chan->user.oclass >= KEPLER_CHANNEL_GPFIFO_A) {
277333 chan->chid = args.kepler.chid;
278
- else
279
- if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO)
334
+ chan->inst = args.kepler.inst;
335
+ } else
336
+ if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO) {
280337 chan->chid = args.fermi.chid;
281
- else
338
+ } else {
282339 chan->chid = args.nv50.chid;
340
+ }
283341 return ret;
284342 }
285343 } while (*oclass);
....@@ -314,8 +372,9 @@
314372 args.offset = chan->push.addr;
315373
316374 do {
317
- ret = nvif_object_init(&device->object, 0, *oclass++,
318
- &args, sizeof(args), &chan->user);
375
+ ret = nvif_object_ctor(&device->object, "abi16ChanUser", 0,
376
+ *oclass++, &args, sizeof(args),
377
+ &chan->user);
319378 if (ret == 0) {
320379 chan->chid = args.chid;
321380 return ret;
....@@ -330,7 +389,6 @@
330389 nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
331390 {
332391 struct nvif_device *device = chan->device;
333
- struct nouveau_cli *cli = (void *)chan->user.client;
334392 struct nouveau_drm *drm = chan->drm;
335393 struct nv_dma_v0 args = {};
336394 int ret, i;
....@@ -338,7 +396,8 @@
338396 nvif_object_map(&chan->user, NULL, 0);
339397
340398 if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO) {
341
- ret = nvif_notify_init(&chan->user, nouveau_channel_killed,
399
+ ret = nvif_notify_ctor(&chan->user, "abi16ChanKilled",
400
+ nouveau_channel_killed,
342401 true, NV906F_V0_NTFY_KILLED,
343402 NULL, 0, 0, &chan->kill);
344403 if (ret == 0)
....@@ -356,7 +415,7 @@
356415 args.target = NV_DMA_V0_TARGET_VM;
357416 args.access = NV_DMA_V0_ACCESS_VM;
358417 args.start = 0;
359
- args.limit = cli->vmm.vmm.limit - 1;
418
+ args.limit = chan->vmm->vmm.limit - 1;
360419 } else {
361420 args.target = NV_DMA_V0_TARGET_VRAM;
362421 args.access = NV_DMA_V0_ACCESS_RDWR;
....@@ -364,8 +423,9 @@
364423 args.limit = device->info.ram_user - 1;
365424 }
366425
367
- ret = nvif_object_init(&chan->user, vram, NV_DMA_IN_MEMORY,
368
- &args, sizeof(args), &chan->vram);
426
+ ret = nvif_object_ctor(&chan->user, "abi16ChanVramCtxDma", vram,
427
+ NV_DMA_IN_MEMORY, &args, sizeof(args),
428
+ &chan->vram);
369429 if (ret)
370430 return ret;
371431
....@@ -373,7 +433,7 @@
373433 args.target = NV_DMA_V0_TARGET_VM;
374434 args.access = NV_DMA_V0_ACCESS_VM;
375435 args.start = 0;
376
- args.limit = cli->vmm.vmm.limit - 1;
436
+ args.limit = chan->vmm->vmm.limit - 1;
377437 } else
378438 if (chan->drm->agp.bridge) {
379439 args.target = NV_DMA_V0_TARGET_AGP;
....@@ -385,11 +445,12 @@
385445 args.target = NV_DMA_V0_TARGET_VM;
386446 args.access = NV_DMA_V0_ACCESS_RDWR;
387447 args.start = 0;
388
- args.limit = cli->vmm.vmm.limit - 1;
448
+ args.limit = chan->vmm->vmm.limit - 1;
389449 }
390450
391
- ret = nvif_object_init(&chan->user, gart, NV_DMA_IN_MEMORY,
392
- &args, sizeof(args), &chan->gart);
451
+ ret = nvif_object_ctor(&chan->user, "abi16ChanGartCtxDma", gart,
452
+ NV_DMA_IN_MEMORY, &args, sizeof(args),
453
+ &chan->gart);
393454 if (ret)
394455 return ret;
395456 }
....@@ -418,28 +479,27 @@
418479 chan->dma.cur = chan->dma.put;
419480 chan->dma.free = chan->dma.max - chan->dma.cur;
420481
421
- ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS);
482
+ ret = PUSH_WAIT(chan->chan.push, NOUVEAU_DMA_SKIPS);
422483 if (ret)
423484 return ret;
424485
425486 for (i = 0; i < NOUVEAU_DMA_SKIPS; i++)
426
- OUT_RING(chan, 0x00000000);
487
+ PUSH_DATA(chan->chan.push, 0x00000000);
427488
428489 /* allocate software object class (used for fences on <= nv05) */
429490 if (device->info.family < NV_DEVICE_INFO_V0_CELSIUS) {
430
- ret = nvif_object_init(&chan->user, 0x006e,
491
+ ret = nvif_object_ctor(&chan->user, "abi16NvswFence", 0x006e,
431492 NVIF_CLASS_SW_NV04,
432493 NULL, 0, &chan->nvsw);
433494 if (ret)
434495 return ret;
435496
436
- ret = RING_SPACE(chan, 2);
497
+ ret = PUSH_WAIT(chan->chan.push, 2);
437498 if (ret)
438499 return ret;
439500
440
- BEGIN_NV04(chan, NvSubSw, 0x0000, 1);
441
- OUT_RING (chan, chan->nvsw.handle);
442
- FIRE_RING (chan);
501
+ PUSH_NVSQ(chan->chan.push, NV_SW, 0x0000, chan->nvsw.handle);
502
+ PUSH_KICK(chan->chan.push);
443503 }
444504
445505 /* initialise synchronisation */
....@@ -448,7 +508,8 @@
448508
449509 int
450510 nouveau_channel_new(struct nouveau_drm *drm, struct nvif_device *device,
451
- u32 arg0, u32 arg1, struct nouveau_channel **pchan)
511
+ u32 arg0, u32 arg1, bool priv,
512
+ struct nouveau_channel **pchan)
452513 {
453514 struct nouveau_cli *cli = (void *)device->object.client;
454515 bool super;
....@@ -458,7 +519,7 @@
458519 super = cli->base.super;
459520 cli->base.super = true;
460521
461
- ret = nouveau_channel_ind(drm, device, arg0, pchan);
522
+ ret = nouveau_channel_ind(drm, device, arg0, priv, pchan);
462523 if (ret) {
463524 NV_PRINTK(dbg, cli, "ib channel create, %d\n", ret);
464525 ret = nouveau_channel_dma(drm, device, pchan);
....@@ -472,8 +533,13 @@
472533 if (ret) {
473534 NV_PRINTK(err, cli, "channel failed to initialise, %d\n", ret);
474535 nouveau_channel_del(pchan);
536
+ goto done;
475537 }
476538
539
+ ret = nouveau_svmm_join((*pchan)->vmm->svmm, (*pchan)->inst);
540
+ if (ret)
541
+ nouveau_channel_del(pchan);
542
+
477543 done:
478544 cli->base.super = super;
479545 return ret;