diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2022-06-01 20:47:38 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2022-11-09 10:44:50 +1000 |
commit | 06db7fded6dec88772a65c5a39af12ba4dc2ad38 (patch) | |
tree | d00ff73679dd75931c7625880903e1b301184600 | |
parent | 7ac293328122075a2afc40a4089e7afc6cbc26eb (diff) | |
download | linux-06db7fded6dec88772a65c5a39af12ba4dc2ad38.tar.gz linux-06db7fded6dec88772a65c5a39af12ba4dc2ad38.tar.bz2 linux-06db7fded6dec88772a65c5a39af12ba4dc2ad38.zip |
drm/nouveau/fifo: add new channel classes
Exposes a bunch of the new features that became possible as a result
of the earlier commits. DRM will build on this in the future to add
support for features such as SCG ("async compute") and multi-device
rendering, as part of the work necessary to be able to write a half-
decent vulkan driver - finally.
For the moment, this just crudely ports DRM to the API changes.
- channel class interfaces now the same for all HW classes
- channel group class exposed (SCG)
- channel runqueue selector exposed (SCG)
- channel sub-device id control exposed (multi-device rendering)
- channel names in logging will reflect creating process, not fd owner
- explicit USERD allocation required by VOLTA_CHANNEL_GPFIFO_A and newer
- drm is smarter about determining the appropriate channel class to use
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
63 files changed, 524 insertions, 1763 deletions
diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl006b.h b/drivers/gpu/drm/nouveau/include/nvif/cl006b.h deleted file mode 100644 index c960c449e430..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvif/cl006b.h +++ /dev/null @@ -1,12 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVIF_CL006B_H__ -#define __NVIF_CL006B_H__ - -struct nv03_channel_dma_v0 { - __u8 version; - __u8 chid; - __u8 pad02[2]; - __u32 offset; - __u64 pushbuf; -}; -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl506e.h b/drivers/gpu/drm/nouveau/include/nvif/cl506e.h deleted file mode 100644 index 9df289c7a84f..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvif/cl506e.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVIF_CL506E_H__ -#define __NVIF_CL506E_H__ - -struct nv50_channel_dma_v0 { - __u8 version; - __u8 chid; - __u8 pad02[6]; - __u64 vmm; - __u64 pushbuf; - __u64 offset; -}; -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl506f.h b/drivers/gpu/drm/nouveau/include/nvif/cl506f.h deleted file mode 100644 index 327c96a994bb..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvif/cl506f.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVIF_CL506F_H__ -#define __NVIF_CL506F_H__ - -struct nv50_channel_gpfifo_v0 { - __u8 version; - __u8 chid; - __u8 pad02[2]; - __u32 ilength; - __u64 ioffset; - __u64 pushbuf; - __u64 vmm; -}; -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl826e.h b/drivers/gpu/drm/nouveau/include/nvif/cl826e.h deleted file mode 100644 index ef3033b836f0..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvif/cl826e.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVIF_CL826E_H__ -#define __NVIF_CL826E_H__ - -struct g82_channel_dma_v0 { - __u8 version; - __u8 chid; - __u8 pad02[6]; - __u64 vmm; - __u64 pushbuf; - __u64 offset; -}; -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl826f.h b/drivers/gpu/drm/nouveau/include/nvif/cl826f.h deleted file mode 100644 index c5d5e56b04cc..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvif/cl826f.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVIF_CL826F_H__ -#define __NVIF_CL826F_H__ - -struct g82_channel_gpfifo_v0 { - __u8 version; - __u8 chid; - __u8 pad02[2]; - __u32 ilength; - __u64 ioffset; - __u64 pushbuf; - __u64 vmm; -}; -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/cl906f.h b/drivers/gpu/drm/nouveau/include/nvif/cl906f.h deleted file mode 100644 index 5ccc8fd8c458..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvif/cl906f.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVIF_CL906F_H__ -#define __NVIF_CL906F_H__ - -struct fermi_channel_gpfifo_v0 { - __u8 version; - __u8 chid; - __u8 pad02[2]; - __u32 ilength; - __u64 ioffset; - __u64 vmm; -}; -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/cla06f.h b/drivers/gpu/drm/nouveau/include/nvif/cla06f.h deleted file mode 100644 index 10449accd3e8..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvif/cla06f.h +++ /dev/null @@ -1,15 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVIF_CLA06F_H__ -#define __NVIF_CLA06F_H__ - -struct kepler_channel_gpfifo_a_v0 { - __u8 version; - __u8 priv; - __u16 chid; - __u32 ilength; - __u64 ioffset; - __u64 runlist; - __u64 vmm; - __u64 inst; -}; -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/class.h b/drivers/gpu/drm/nouveau/include/nvif/class.h index e9d9f314a744..ceea074b064b 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/class.h +++ b/drivers/gpu/drm/nouveau/include/nvif/class.h @@ -70,23 +70,23 @@ #define MAXWELL_FAULT_BUFFER_A /* clb069.h */ 0x0000b069 #define VOLTA_FAULT_BUFFER_A /* clb069.h */ 0x0000c369 -#define NV03_CHANNEL_DMA /* cl506b.h */ 0x0000006b -#define NV10_CHANNEL_DMA /* cl506b.h */ 0x0000006e -#define NV17_CHANNEL_DMA /* cl506b.h */ 0x0000176e -#define NV40_CHANNEL_DMA /* cl506b.h */ 0x0000406e +#define NV03_CHANNEL_DMA /* if0020.h */ 0x0000006b +#define NV10_CHANNEL_DMA /* if0020.h */ 0x0000006e +#define NV17_CHANNEL_DMA /* if0020.h */ 0x0000176e +#define NV40_CHANNEL_DMA /* if0020.h */ 0x0000406e #define KEPLER_CHANNEL_GROUP_A /* if0021.h */ 0x0000a06c -#define NV50_CHANNEL_GPFIFO /* cl506f.h */ 0x0000506f -#define G82_CHANNEL_GPFIFO /* cl826f.h */ 0x0000826f -#define FERMI_CHANNEL_GPFIFO /* cl906f.h */ 0x0000906f -#define KEPLER_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000a06f -#define KEPLER_CHANNEL_GPFIFO_B /* cla06f.h */ 0x0000a16f -#define MAXWELL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000b06f -#define PASCAL_CHANNEL_GPFIFO_A /* cla06f.h */ 0x0000c06f -#define VOLTA_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c36f -#define TURING_CHANNEL_GPFIFO_A /* clc36f.h */ 0x0000c46f -#define AMPERE_CHANNEL_GPFIFO_B /* clc36f.h */ 0x0000c76f +#define NV50_CHANNEL_GPFIFO /* if0020.h */ 0x0000506f +#define G82_CHANNEL_GPFIFO /* if0020.h */ 0x0000826f +#define FERMI_CHANNEL_GPFIFO /* if0020.h */ 0x0000906f +#define KEPLER_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000a06f +#define KEPLER_CHANNEL_GPFIFO_B /* if0020.h */ 0x0000a16f +#define MAXWELL_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000b06f +#define PASCAL_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000c06f +#define VOLTA_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000c36f +#define TURING_CHANNEL_GPFIFO_A /* if0020.h */ 0x0000c46f +#define AMPERE_CHANNEL_GPFIFO_B /* if0020.h */ 0x0000c76f #define NV50_DISP /* if0010.h */ 0x00005070 #define G82_DISP /* if0010.h */ 0x00008270 diff --git a/drivers/gpu/drm/nouveau/include/nvif/clc36f.h b/drivers/gpu/drm/nouveau/include/nvif/clc36f.h deleted file mode 100644 index cdf6708e1d9a..000000000000 --- a/drivers/gpu/drm/nouveau/include/nvif/clc36f.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -#ifndef __NVIF_CLC36F_H__ -#define __NVIF_CLC36F_H__ - -struct volta_channel_gpfifo_a_v0 { - __u8 version; - __u8 priv; - __u16 chid; - __u32 ilength; - __u64 ioffset; - __u64 runlist; - __u64 vmm; - __u64 inst; - __u32 token; -}; -#endif diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0020.h b/drivers/gpu/drm/nouveau/include/nvif/if0020.h index 1893b8aa0abb..085e0ae8a450 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/if0020.h +++ b/drivers/gpu/drm/nouveau/include/nvif/if0020.h @@ -2,6 +2,38 @@ #ifndef __NVIF_IF0020_H__ #define __NVIF_IF0020_H__ +union nvif_chan_args { + struct nvif_chan_v0 { + __u8 version; + __u8 namelen; + __u8 runlist; + __u8 runq; + __u8 priv; + __u8 pad05; + __u16 devm; + __u64 vmm; + + __u64 ctxdma; + __u64 offset; + __u64 length; + + __u64 huserd; + __u64 ouserd; + + __u32 token; + __u16 chid; + __u8 pad3e; +#define NVIF_CHAN_V0_INST_APER_VRAM 0 +#define NVIF_CHAN_V0_INST_APER_HOST 1 +#define NVIF_CHAN_V0_INST_APER_NCOH 2 +#define NVIF_CHAN_V0_INST_APER_INST 0xff + __u8 aper; + __u64 inst; + + __u8 name[]; + } v0; +}; + union nvif_chan_event_args { struct nvif_chan_event_v0 { __u8 version; diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0021.h b/drivers/gpu/drm/nouveau/include/nvif/if0021.h new file mode 100644 index 000000000000..5013def90455 --- /dev/null +++ b/drivers/gpu/drm/nouveau/include/nvif/if0021.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVIF_IF0021_H__ +#define __NVIF_IF0021_H__ + +union nvif_cgrp_args { + struct nvif_cgrp_v0 { + __u8 version; + __u8 namelen; + __u8 runlist; + __u8 pad03[3]; + __u16 cgid; + __u64 vmm; + __u8 name[]; + } v0; +}; +#endif diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h index da8abcbeb965..c71f412bbb7f 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h @@ -16,7 +16,8 @@ struct nvkm_chan { struct nvkm_gpuobj *inst; struct nvkm_vmm *vmm; - union { int id; int chid; }; /*FIXME: remove later */ + struct nvkm_gpuobj *push; + int id; struct { struct nvkm_memory *mem; @@ -35,11 +36,7 @@ struct nvkm_chan { atomic_t errored; struct list_head cctxs; - - struct nvkm_object object; - struct list_head head; - struct nvkm_gpuobj *push; }; struct nvkm_chan *nvkm_chan_get_chid(struct nvkm_engine *, int id, unsigned long *irqflags); diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 9237ef328b9f..82dab51d8aeb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -27,7 +27,6 @@ #include <nvif/ioctl.h> #include <nvif/class.h> #include <nvif/cl0002.h> -#include <nvif/cla06f.h> #include <nvif/unpack.h> #include "nouveau_drv.h" diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index 5b7042d94e80..efd6cf46921b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -25,13 +25,7 @@ #include <nvif/class.h> #include <nvif/cl0002.h> -#include <nvif/cl006b.h> -#include <nvif/cl506f.h> -#include <nvif/cl906f.h> -#include <nvif/cla06f.h> -#include <nvif/clc36f.h> #include <nvif/if0020.h> -#include <nvif/ioctl.h> #include "nouveau_drv.h" #include "nouveau_dma.h" @@ -101,6 +95,7 @@ nouveau_channel_del(struct nouveau_channel **pchan) nvif_object_dtor(&chan->vram); nvif_event_dtor(&chan->kill); nvif_object_dtor(&chan->user); + nvif_mem_dtor(&chan->mem_userd); nvif_object_dtor(&chan->push.ctxdma); nouveau_vma_del(&chan->push.vma); nouveau_bo_unmap(chan->push.buffer); @@ -250,134 +245,112 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nvif_device *device, } static int -nouveau_channel_ind(struct nouveau_drm *drm, struct nvif_device *device, - u64 runlist, bool priv, struct nouveau_channel **pchan) +nouveau_channel_ctor(struct nouveau_drm *drm, struct nvif_device *device, bool priv, u64 runm, + struct nouveau_channel **pchan) { - static const u16 oclasses[] = { AMPERE_CHANNEL_GPFIFO_B, - TURING_CHANNEL_GPFIFO_A, - VOLTA_CHANNEL_GPFIFO_A, - PASCAL_CHANNEL_GPFIFO_A, - MAXWELL_CHANNEL_GPFIFO_A, - KEPLER_CHANNEL_GPFIFO_B, - KEPLER_CHANNEL_GPFIFO_A, - FERMI_CHANNEL_GPFIFO, - G82_CHANNEL_GPFIFO, - NV50_CHANNEL_GPFIFO, - 0 }; - const u16 *oclass = oclasses; - union { - struct nv50_channel_gpfifo_v0 nv50; - struct fermi_channel_gpfifo_v0 fermi; - struct kepler_channel_gpfifo_a_v0 kepler; - struct volta_channel_gpfifo_a_v0 volta; + static const struct { + s32 oclass; + int version; + } hosts[] = { + { AMPERE_CHANNEL_GPFIFO_B, 0 }, + { TURING_CHANNEL_GPFIFO_A, 0 }, + { VOLTA_CHANNEL_GPFIFO_A, 0 }, + { PASCAL_CHANNEL_GPFIFO_A, 0 }, + { MAXWELL_CHANNEL_GPFIFO_A, 0 }, + { KEPLER_CHANNEL_GPFIFO_B, 0 }, + { KEPLER_CHANNEL_GPFIFO_A, 0 }, + { FERMI_CHANNEL_GPFIFO , 0 }, + { G82_CHANNEL_GPFIFO , 0 }, + { NV50_CHANNEL_GPFIFO , 0 }, + { NV40_CHANNEL_DMA , 0 }, + { NV17_CHANNEL_DMA , 0 }, + { NV10_CHANNEL_DMA , 0 }, + { NV03_CHANNEL_DMA , 0 }, + {} + }; + struct { + struct nvif_chan_v0 chan; + char name[TASK_COMM_LEN+16]; } args; + struct nouveau_cli *cli = (void *)device->object.client; struct nouveau_channel *chan; - u32 size; - int ret; + const u64 plength = 0x10000; + const u64 ioffset = plength; + const u64 ilength = 0x02000; + char name[TASK_COMM_LEN]; + int cid, ret; + u64 size; + + cid = nvif_mclass(&device->object, hosts); + if (cid < 0) + return cid; + + if (hosts[cid].oclass < NV50_CHANNEL_GPFIFO) + size = plength; + else + size = ioffset + ilength; /* allocate dma push buffer */ - ret = nouveau_channel_prep(drm, device, 0x12000, &chan); + ret = nouveau_channel_prep(drm, device, size, &chan); *pchan = chan; if (ret) return ret; /* create channel object */ - do { - if (oclass[0] >= VOLTA_CHANNEL_GPFIFO_A) { - args.volta.version = 0; - args.volta.ilength = 0x02000; - args.volta.ioffset = 0x10000 + chan->push.addr; - args.volta.runlist = runlist; - args.volta.vmm = nvif_handle(&chan->vmm->vmm.object); - args.volta.priv = priv; - size = sizeof(args.volta); - } else - if (oclass[0] >= KEPLER_CHANNEL_GPFIFO_A) { - args.kepler.version = 0; - args.kepler.ilength = 0x02000; - args.kepler.ioffset = 0x10000 + chan->push.addr; - args.kepler.runlist = runlist; - args.kepler.vmm = nvif_handle(&chan->vmm->vmm.object); - args.kepler.priv = priv; - size = sizeof(args.kepler); - } else - if (oclass[0] >= FERMI_CHANNEL_GPFIFO) { - args.fermi.version = 0; - args.fermi.ilength = 0x02000; - args.fermi.ioffset = 0x10000 + chan->push.addr; - args.fermi.vmm = nvif_handle(&chan->vmm->vmm.object); - size = sizeof(args.fermi); - } else { - args.nv50.version = 0; - args.nv50.ilength = 0x02000; - args.nv50.ioffset = 0x10000 + chan->push.addr; - args.nv50.pushbuf = nvif_handle(&chan->push.ctxdma); - args.nv50.vmm = nvif_handle(&chan->vmm->vmm.object); - size = sizeof(args.nv50); - } - - ret = nvif_object_ctor(&device->object, "abi16ChanUser", 0, - *oclass++, &args, size, &chan->user); - if (ret == 0) { - if (chan->user.oclass >= VOLTA_CHANNEL_GPFIFO_A) { - chan->chid = args.volta.chid; - chan->inst = args.volta.inst; - chan->token = args.volta.token; - } else - if (chan->user.oclass >= KEPLER_CHANNEL_GPFIFO_A) { - chan->chid = args.kepler.chid; - chan->inst = args.kepler.inst; - } else - if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO) { - chan->chid = args.fermi.chid; - } else { - chan->chid = args.nv50.chid; - } + args.chan.version = 0; + args.chan.namelen = sizeof(args.name); + args.chan.runlist = __ffs64(runm); + args.chan.runq = 0; + args.chan.priv = priv; + args.chan.devm = BIT(0); + if (hosts[cid].oclass < NV50_CHANNEL_GPFIFO) { + args.chan.vmm = 0; + args.chan.ctxdma = nvif_handle(&chan->push.ctxdma); + args.chan.offset = chan->push.addr; + args.chan.length = 0; + } else { + args.chan.vmm = nvif_handle(&chan->vmm->vmm.object); + if (hosts[cid].oclass < FERMI_CHANNEL_GPFIFO) + args.chan.ctxdma = nvif_handle(&chan->push.ctxdma); + else + args.chan.ctxdma = 0; + args.chan.offset = ioffset + chan->push.addr; + args.chan.length = ilength; + } + args.chan.huserd = 0; + args.chan.ouserd = 0; + + /* allocate userd */ + if (hosts[cid].oclass >= VOLTA_CHANNEL_GPFIFO_A) { + ret = nvif_mem_ctor(&cli->mmu, "abi16ChanUSERD", NVIF_CLASS_MEM_GF100, + NVIF_MEM_VRAM | NVIF_MEM_COHERENT | NVIF_MEM_MAPPABLE, + 0, PAGE_SIZE, NULL, 0, &chan->mem_userd); + if (ret) return ret; - } - } while (*oclass); - nouveau_channel_del(pchan); - return ret; -} + args.chan.huserd = nvif_handle(&chan->mem_userd.object); + args.chan.ouserd = 0; -static int -nouveau_channel_dma(struct nouveau_drm *drm, struct nvif_device *device, - struct nouveau_channel **pchan) -{ - static const u16 oclasses[] = { NV40_CHANNEL_DMA, - NV17_CHANNEL_DMA, - NV10_CHANNEL_DMA, - NV03_CHANNEL_DMA, - 0 }; - const u16 *oclass = oclasses; - struct nv03_channel_dma_v0 args; - struct nouveau_channel *chan; - int ret; + chan->userd = &chan->mem_userd.object; |