diff --git a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h index 2f2059c5d4c9eff84b44d3ec7c477b8276de64b3..b688121f1a91e16ace1eed96bb7437e16f527dfa 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h @@ -37,6 +37,9 @@ struct nvkm_fifo { const struct nvkm_fifo_func *func; struct nvkm_engine engine; + struct nvkm_chid *chid; + struct nvkm_chid *cgid; + DECLARE_BITMAP(mask, NVKM_FIFO_CHID_NR); int nr; struct list_head chan; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild index 76d2bf1f6d8b4a858cf330525dd98dacf1951e0f..c985736bff2c4c65204408aefaa630eaa2331afb 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild @@ -1,5 +1,8 @@ # SPDX-License-Identifier: MIT nvkm-y += nvkm/engine/fifo/base.o +nvkm-y += nvkm/engine/fifo/chan.o +nvkm-y += nvkm/engine/fifo/chid.o + nvkm-y += nvkm/engine/fifo/nv04.o nvkm-y += nvkm/engine/fifo/nv10.o nvkm-y += nvkm/engine/fifo/nv17.o @@ -18,7 +21,6 @@ nvkm-y += nvkm/engine/fifo/gv100.o nvkm-y += nvkm/engine/fifo/tu102.o nvkm-y += nvkm/engine/fifo/ga102.o -nvkm-y += nvkm/engine/fifo/chan.o nvkm-y += nvkm/engine/fifo/channv50.o nvkm-y += nvkm/engine/fifo/chang84.o diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c index 4e099bf0a3fa91ed15cff3b953906a26a056223a..e6b0653625f5a782e511350c7824e6fb8e7b668b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c @@ -23,6 +23,7 @@ */ #include "priv.h" #include "chan.h" +#include "chid.h" #include #include @@ -218,13 +219,15 @@ static int nvkm_fifo_info(struct nvkm_engine *engine, u64 mthd, u64 *data) { struct nvkm_fifo *fifo = nvkm_fifo(engine); + switch (mthd) { - case NV_DEVICE_HOST_CHANNELS: *data = fifo->nr; return 0; + case NV_DEVICE_HOST_CHANNELS: *data = fifo->chid ? fifo->chid->nr : 0; return 0; default: if (fifo->func->info) return fifo->func->info(fifo, mthd, data); break; } + return -ENOSYS; } @@ -232,8 +235,18 @@ static int nvkm_fifo_oneinit(struct nvkm_engine *engine) { struct nvkm_fifo *fifo = nvkm_fifo(engine); + int ret; + + /* Initialise CHID/CGID allocator(s) on GPUs where they aren't per-runlist. */ + if (fifo->func->chid_nr) { + ret = fifo->func->chid_ctor(fifo, fifo->func->chid_nr(fifo)); + if (ret) + return ret; + } + if (fifo->func->oneinit) return fifo->func->oneinit(fifo); + return 0; } @@ -248,6 +261,10 @@ nvkm_fifo_dtor(struct nvkm_engine *engine) { struct nvkm_fifo *fifo = nvkm_fifo(engine); void *data = fifo; + + nvkm_chid_unref(&fifo->cgid); + nvkm_chid_unref(&fifo->chid); + if (fifo->func->dtor) data = fifo->func->dtor(fifo); nvkm_event_fini(&fifo->kevent); @@ -289,7 +306,6 @@ nvkm_fifo_ctor(const struct nvkm_fifo_func *func, struct nvkm_device *device, fifo->nr = NVKM_FIFO_CHID_NR; else fifo->nr = nr; - bitmap_clear(fifo->mask, 0, fifo->nr); if (func->uevent_init) { ret = nvkm_event_init(&nvkm_fifo_uevent_func, &fifo->engine.subdev, 1, 1, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c index 4d4905be4b92b1aa47fa5e977a2d15e3c760805d..464c956aaca9dc13be628181855a9ac4038bbfe2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c @@ -32,6 +32,10 @@ #include +const struct nvkm_event_func +nvkm_chan_event = { +}; + struct nvkm_fifo_chan_object { struct nvkm_oproxy oproxy; struct nvkm_fifo_chan *chan; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h index 24fbe6cf70e1b9f1d0a8580665344206d4c17e50..a9c0e02b6f9f421cb77b35fce6fd6dcb56dc5e4f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h @@ -4,6 +4,8 @@ #define nvkm_chan(p) container_of((p), struct nvkm_chan, object) /*FIXME: remove later */ #include +extern const struct nvkm_event_func nvkm_chan_event; + struct nvkm_chan_func { void *(*dtor)(struct nvkm_fifo_chan *); void (*init)(struct nvkm_fifo_chan *); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chid.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chid.c new file mode 100644 index 0000000000000000000000000000000000000000..7c582bce7e24502a3274675729e266346a089546 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chid.c @@ -0,0 +1,82 @@ +/* + * Copyright 2020 Red Hat Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "chid.h" + +static void +nvkm_chid_del(struct kref *kref) +{ + struct nvkm_chid *chid = container_of(kref, typeof(*chid), kref); + + nvkm_event_fini(&chid->event); + + kvfree(chid->data); + kfree(chid); +} + +void +nvkm_chid_unref(struct nvkm_chid **pchid) +{ + struct nvkm_chid *chid = *pchid; + + if (!chid) + return; + + kref_put(&chid->kref, nvkm_chid_del); + *pchid = NULL; +} + +struct nvkm_chid * +nvkm_chid_ref(struct nvkm_chid *chid) +{ + if (chid) + kref_get(&chid->kref); + + return chid; +} + +int +nvkm_chid_new(const struct nvkm_event_func *func, struct nvkm_subdev *subdev, + int nr, int first, int count, struct nvkm_chid **pchid) +{ + struct nvkm_chid *chid; + int id; + + if (!(chid = *pchid = kzalloc(struct_size(chid, used, nr), GFP_KERNEL))) + return -ENOMEM; + + kref_init(&chid->kref); + chid->nr = nr; + chid->mask = chid->nr - 1; + spin_lock_init(&chid->lock); + + if (!(chid->data = kvzalloc(sizeof(*chid->data) * nr, GFP_KERNEL))) { + nvkm_chid_unref(pchid); + return -ENOMEM; + } + + for (id = 0; id < first; id++) + __set_bit(id, chid->used); + for (id = first + count; id < nr; id++) + __set_bit(id, chid->used); + + return nvkm_event_init(func, subdev, 1, nr, &chid->event); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chid.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chid.h new file mode 100644 index 0000000000000000000000000000000000000000..d359828dde8099ad356f70398995b087a1187022 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/chid.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: MIT */ +#ifndef __NVKM_CHID_H__ +#define __NVKM_CHID_H__ +#include + +struct nvkm_chid { + struct kref kref; + int nr; + u32 mask; + + struct nvkm_event event; + + void **data; + + spinlock_t lock; + unsigned long used[]; +}; + +int nvkm_chid_new(const struct nvkm_event_func *, struct nvkm_subdev *, + int nr, int first, int count, struct nvkm_chid **pchid); +struct nvkm_chid *nvkm_chid_ref(struct nvkm_chid *); +void nvkm_chid_unref(struct nvkm_chid **); +#endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c index 24732d355c8315f6ebf8db761021c5b9d5b3e3fd..dbb9df6f8eb51273cdcdb8a661ddab4b5339fb06 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c @@ -119,6 +119,7 @@ g84_fifo = { .dtor = nv50_fifo_dtor, .oneinit = nv50_fifo_oneinit, .chid_nr = nv50_fifo_chid_nr, + .chid_ctor = nv50_fifo_chid_ctor, .init = nv50_fifo_init, .intr = nv04_fifo_intr, .engine_id = g84_fifo_engine_id, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c index 1a641b1fdfbf1c110a4e4129657ec6e4494b01d7..d8eeca81863728ba4b6a3e595c91a85bc817ab6e 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "chan.h" +#include "chid.h" #include "gf100.h" #include "changf100.h" @@ -624,6 +625,12 @@ gf100_fifo_init(struct nvkm_fifo *base) nvkm_wr32(device, 0x002628, 0x00000001); /* ENGINE_INTR_EN */ } +int +gf100_fifo_chid_ctor(struct nvkm_fifo *fifo, int nr) +{ + return nvkm_chid_new(&nvkm_chan_event, &fifo->engine.subdev, nr, 0, nr, &fifo->chid); +} + static int gf100_fifo_oneinit(struct nvkm_fifo *base) { @@ -681,6 +688,7 @@ gf100_fifo = { .dtor = gf100_fifo_dtor, .oneinit = gf100_fifo_oneinit, .chid_nr = nv50_fifo_chid_nr, + .chid_ctor = gf100_fifo_chid_ctor, .init = gf100_fifo_init, .fini = gf100_fifo_fini, .intr = gf100_fifo_intr, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c index 880ddfec22f7ae765cfbe3d2573a2f91472a87fa..c4fa4fc68d467f5ab8502eab131455d9491e1804 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "chan.h" +#include "chid.h" #include "gk104.h" #include "cgrp.h" @@ -1193,6 +1194,7 @@ gk104_fifo = { .dtor = gk104_fifo_dtor, .oneinit = gk104_fifo_oneinit, .chid_nr = gk104_fifo_chid_nr, + .chid_ctor = gf100_fifo_chid_ctor, .info = gk104_fifo_info, .init = gk104_fifo_init, .fini = gk104_fifo_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h index 962187740010655c0ee08f0c774b6a000e356a8c..af6a004a62670587f53dca4632888335ac82344a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h @@ -74,7 +74,7 @@ void gk104_fifo_intr_pbdma_1(struct gk104_fifo *fifo, int unit); void gk104_fifo_intr_runlist(struct gk104_fifo *fifo); void gk104_fifo_intr_engine(struct gk104_fifo *fifo); void *gk104_fifo_dtor(struct nvkm_fifo *base); -int gk104_fifo_oneinit(struct nvkm_fifo *base); +int gk104_fifo_oneinit(struct nvkm_fifo *); int gk104_fifo_info(struct nvkm_fifo *base, u64 mthd, u64 *data); void gk104_fifo_init(struct nvkm_fifo *base); void gk104_fifo_fini(struct nvkm_fifo *base); diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c index 9dcc54f1d016b325a90ab3af536a9ab5d308231c..b23d50d1b351f971e652adf745f0e0f0487ef6e7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c @@ -23,6 +23,7 @@ */ #include "cgrp.h" #include "chan.h" +#include "chid.h" #include "gk104.h" #include "changk104.h" @@ -56,11 +57,24 @@ gk110_fifo_runlist = { .commit = gk104_fifo_runlist_commit, }; +int +gk110_fifo_chid_ctor(struct nvkm_fifo *fifo, int nr) +{ + int ret; + + ret = nvkm_chid_new(&nvkm_chan_event, &fifo->engine.subdev, nr, 0, nr, &fifo->cgid); + if (ret) + return ret; + + return gf100_fifo_chid_ctor(fifo, nr); +} + static const struct nvkm_fifo_func gk110_fifo = { .dtor = gk104_fifo_dtor, .oneinit = gk104_fifo_oneinit, .chid_nr = gk104_fifo_chid_nr, + .chid_ctor = gk110_fifo_chid_ctor, .info = gk104_fifo_info, .init = gk104_fifo_init, .fini = gk104_fifo_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c index 28791baf77f8ae29d0e70eb455efbfd8b7f72be0..1dd937bdbbae04d6c5b383cbd37e6a42db91c0e0 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c @@ -54,6 +54,7 @@ gk208_fifo = { .dtor = gk104_fifo_dtor, .oneinit = gk104_fifo_oneinit, .chid_nr = gk208_fifo_chid_nr, + .chid_ctor = gk110_fifo_chid_ctor, .info = gk104_fifo_info, .init = gk104_fifo_init, .fini = gk104_fifo_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c index b62e3bb0294cad96a39250049b6434eefeb1fd65..d2e78d2a868a581dfbd88e959441c9ca624b4c91 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c @@ -29,6 +29,7 @@ gk20a_fifo = { .dtor = gk104_fifo_dtor, .oneinit = gk104_fifo_oneinit, .chid_nr = nv50_fifo_chid_nr, + .chid_ctor = gk110_fifo_chid_ctor, .info = gk104_fifo_info, .init = gk104_fifo_init, .fini = gk104_fifo_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c index f996f1c1141a02c2671110b8e105f897d5de90fb..32ef88a90d1e8c0698bed497ee66eb4dda6263ba 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c @@ -114,6 +114,7 @@ gm107_fifo = { .dtor = gk104_fifo_dtor, .oneinit = gk104_fifo_oneinit, .chid_nr = gm107_fifo_chid_nr, + .chid_ctor = gk110_fifo_chid_ctor, .info = gk104_fifo_info, .init = gk104_fifo_init, .fini = gk104_fifo_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c index 8f3da21ce1e763db0c60f8191e1f1db528a829f1..74891833926e0a6c5d0c46ebb5a79712dcf9a9b7 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c @@ -51,6 +51,7 @@ gm200_fifo = { .dtor = gk104_fifo_dtor, .oneinit = gk104_fifo_oneinit, .chid_nr = gm200_fifo_chid_nr, + .chid_ctor = gk110_fifo_chid_ctor, .info = gk104_fifo_info, .init = gk104_fifo_init, .fini = gk104_fifo_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c index dc590848c25c7eac69687f3bc015db9f694d5cff..c1ad59d1223b3111dd191fb3743404b388881492 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c @@ -86,6 +86,7 @@ gp100_fifo = { .dtor = gk104_fifo_dtor, .oneinit = gk104_fifo_oneinit, .chid_nr = gm200_fifo_chid_nr, + .chid_ctor = gk110_fifo_chid_ctor, .info = gk104_fifo_info, .init = gk104_fifo_init, .fini = gk104_fifo_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c index 36c02b5aac0f96dd12a4755a11f1614664c9ae48..9e876bd871bb4cc0bcb0b6f5762e5a0064f94c0a 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c @@ -301,6 +301,7 @@ gv100_fifo = { .dtor = gk104_fifo_dtor, .oneinit = gk104_fifo_oneinit, .chid_nr = gm200_fifo_chid_nr, + .chid_ctor = gk110_fifo_chid_ctor, .info = gk104_fifo_info, .init = gk104_fifo_init, .fini = gk104_fifo_fini, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c index f9f8371d375656a5e8a817e414e5d6e47e25e512..18fa5b933e9ef871d2113bdfbfe46016cd9ae4a4 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c @@ -23,6 +23,7 @@ */ #include "cgrp.h" #include "chan.h" +#include "chid.h" #include "nv04.h" #include "channv04.h" @@ -58,7 +59,6 @@ nv04_fifo_dma_fini(struct nvkm_fifo_chan *base) struct nvkm_memory *fctx = device->imem->ramfc; const struct nv04_fifo_ramfc *c; unsigned long flags; - u32 mask = fifo->base.nr - 1; u32 data = chan->ramfc; u32 chid; @@ -67,7 +67,7 @@ nv04_fifo_dma_fini(struct nvkm_fifo_chan *base) nvkm_wr32(device, NV03_PFIFO_CACHES, 0); /* if this channel is active, replace it with a null context */ - chid = nvkm_rd32(device, NV03_PFIFO_CACHE1_PUSH1) & mask; + chid = nvkm_rd32(device, NV03_PFIFO_CACHE1_PUSH1) & fifo->base.chid->mask; if (chid == chan->base.chid) { nvkm_mask(device, NV04_PFIFO_CACHE1_DMA_PUSH, 0x00000001, 0); nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH0, 0); @@ -91,7 +91,7 @@ nv04_fifo_dma_fini(struct nvkm_fifo_chan *base) nvkm_wr32(device, NV03_PFIFO_CACHE1_GET, 0); nvkm_wr32(device, NV03_PFIFO_CACHE1_PUT, 0); - nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH1, mask); + nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH1, fifo->base.chid->mask); nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH0, 1); nvkm_wr32(device, NV04_PFIFO_CACHE1_PULL0, 1); } @@ -360,7 +360,7 @@ nv04_fifo_intr(struct nvkm_fifo *base) reassign = nvkm_rd32(device, NV03_PFIFO_CACHES) & 1; nvkm_wr32(device, NV03_PFIFO_CACHES, 0); - chid = nvkm_rd32(device, NV03_PFIFO_CACHE1_PUSH1) & (fifo->base.nr - 1); + chid = nvkm_rd32(device, NV03_PFIFO_CACHE1_PUSH1) & fifo->base.chid->mask; get = nvkm_rd32(device, NV03_PFIFO_CACHE1_GET); if (stat & NV_PFIFO_INTR_CACHE_ERROR) { @@ -407,10 +407,9 @@ nv04_fifo_intr(struct nvkm_fifo *base) } void -nv04_fifo_init(struct nvkm_fifo *base) +nv04_fifo_init(struct nvkm_fifo *fifo) { - struct nv04_fifo *fifo = nv04_fifo(base); - struct nvkm_device *device = fifo->base.engine.subdev.device; + struct nvkm_device *device = fifo->engine.subdev.device; struct nvkm_instmem *imem = device->imem; struct nvkm_ramht *ramht = imem->ramht; struct nvkm_memory *ramro = imem->ramro; @@ -425,7 +424,7 @@ nv04_fifo_init(struct nvkm_fifo *base) nvkm_wr32(device, NV03_PFIFO_RAMRO, nvkm_memory_addr(ramro) >> 8); nvkm_wr32(device, NV03_PFIFO_RAMFC, nvkm_memory_addr(ramfc) >> 8); - nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH1, fifo->base.nr - 1); + nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH1, fifo->chid->mask); nvkm_wr32(device, NV03_PFIFO_INTR_0, 0xffffffff); nvkm_wr32(device, NV03_PFIFO_INTR_EN_0, 0xffffffff); @@ -435,6 +434,13 @@ nv04_fifo_init(struct nvkm_fifo *base) nvkm_wr32(device, NV03_PFIFO_CACHES, 1); } +int +nv04_fifo_chid_ctor(struct nvkm_fifo *fifo, int nr) +{ + /* The last CHID is reserved by HW as a "channel invalid" marker. */ + return nvkm_chid_new(&nvkm_chan_event, &fifo->engine.subdev, nr, 0, nr - 1, &fifo->chid); +} + static int nv04_fifo_chid_nr(struct nvkm_fifo *fifo) { @@ -465,6 +471,7 @@ nv04_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device, static const struct nvkm_fifo_func nv04_fifo = { .chid_nr = nv04_fifo_chid_nr, + .chid_ctor = nv04_fifo_chid_ctor, .init = nv04_fifo_init, .intr = nv04_fifo_intr, .engine_id = nv04_fifo_engine_id, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h index 3f23bcde4a540cc3c9a4384744f675120d08a023..879c686675d66ffe5eb08e6bd7998cfc76d2d900 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h @@ -19,5 +19,4 @@ struct nv04_fifo { int nv04_fifo_new_(const struct nvkm_fifo_func *, struct nvkm_device *, enum nvkm_subdev_type, int, int nr, const struct nv04_fifo_ramfc *, struct nvkm_fifo **); -void nv04_fifo_init(struct nvkm_fifo *); #endif diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c index f07304e4b8c50e0d9585b238d2bbafab860a0b22..bc25520cb39b4660e44dd9c44ec66e0d4ba0faf2 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c @@ -56,6 +56,7 @@ nv10_fifo_chid_nr(struct nvkm_fifo *fifo) static const struct nvkm_fifo_func nv10_fifo = { .chid_nr = nv10_fifo_chid_nr, + .chid_ctor = nv04_fifo_chid_ctor, .init = nv04_fifo_init, .intr = nv04_fifo_intr, .engine_id = nv04_fifo_engine_id, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c index 858c8ba158c94e0d50b602d79eac44e47b9fa8af..dd254d88d008fbb7c2390c556f6b213f492e4255 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "chan.h" +#include "chid.h" #include "nv04.h" #include "channv04.h" @@ -56,10 +57,9 @@ nv17_chan = { }; static void -nv17_fifo_init(struct nvkm_fifo *base) +nv17_fifo_init(struct nvkm_fifo *fifo) { - struct nv04_fifo *fifo = nv04_fifo(base); - struct nvkm_device *device = fifo->base.engine.subdev.device; + struct nvkm_device *device = fifo->engine.subdev.device; struct nvkm_instmem *imem = device->imem; struct nvkm_ramht *ramht = imem->ramht; struct nvkm_memory *ramro = imem->ramro; @@ -75,7 +75,7 @@ nv17_fifo_init(struct nvkm_fifo *base) nvkm_wr32(device, NV03_PFIFO_RAMFC, nvkm_memory_addr(ramfc) >> 8 | 0x00010000); - nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH1, fifo->base.nr - 1); + nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH1, fifo->chid->mask); nvkm_wr32(device, NV03_PFIFO_INTR_0, 0xffffffff); nvkm_wr32(device, NV03_PFIFO_INTR_EN_0, 0xffffffff); @@ -88,6 +88,7 @@ nv17_fifo_init(struct nvkm_fifo *base) static const struct nvkm_fifo_func nv17_fifo = { .chid_nr = nv10_fifo_chid_nr, + .chid_ctor = nv04_fifo_chid_ctor, .init = nv17_fifo_init, .intr = nv04_fifo_intr, .engine_id = nv04_fifo_engine_id, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c index 30f924e3da3c87a7d9a6e3a8cf0881d4fd078a36..c87d995e4fd1eb4dc6b303209e4b9b00495839f6 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "chan.h" +#include "chid.h" #include "nv04.h" #include "channv04.h" @@ -65,10 +66,9 @@ nv40_chan = { }; static void -nv40_fifo_init(struct nvkm_fifo *base) +nv40_fifo_init(struct nvkm_fifo *fifo) { - struct nv04_fifo *fifo = nv04_fifo(base); - struct nvkm_device *device = fifo->base.engine.subdev.device; + struct nvkm_device *device = fifo->engine.subdev.device; struct nvkm_fb *fb = device->fb; struct nvkm_instmem *imem = device->imem; struct nvkm_ramht *ramht = imem->ramht; @@ -106,7 +106,7 @@ nv40_fifo_init(struct nvkm_fifo *base) break; } - nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH1, fifo->base.nr - 1); + nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH1, fifo->chid->mask); nvkm_wr32(device, NV03_PFIFO_INTR_0, 0xffffffff); nvkm_wr32(device, NV03_PFIFO_INTR_EN_0, 0xffffffff); @@ -119,6 +119,7 @@ nv40_fifo_init(struct nvkm_fifo *base) static const struct nvkm_fifo_func nv40_fifo = { .chid_nr = nv10_fifo_chid_nr, + .chid_ctor = nv04_fifo_chid_ctor, .init = nv40_fifo_init, .intr = nv04_fifo_intr, .engine_id = nv04_fifo_engine_id, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c index 101015a1a7e94a1844b0dac44940c706c6aefb1e..13c514acc9d72cf1212a71d7c71fe87a993f0a76 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c @@ -22,6 +22,7 @@ * Authors: Ben Skeggs */ #include "chan.h" +#include "chid.h" #include "nv50.h" #include "channv50.h" @@ -88,6 +89,13 @@ nv50_fifo_init(struct nvkm_fifo *base) nvkm_wr32(device, 0x002500, 0x00000001); } +int +nv50_fifo_chid_ctor(struct nvkm_fifo *fifo, int nr) +{ + /* CHID 0 is unusable (some kind of PIO channel?), 127 is "channel invalid". */ + return nvkm_chid_new(&nvkm_chan_event, &fifo->engine.subdev, nr, 1, nr - 2, &fifo->chid); +} + int nv50_fifo_chid_nr(struct nvkm_fifo *fifo) { @@ -144,6 +152,7 @@ nv50_fifo = { .dtor = nv50_fifo_dtor, .oneinit = nv50_fifo_oneinit, .chid_nr = nv50_fifo_chid_nr, + .chid_ctor = nv50_fifo_chid_ctor, .init = nv50_fifo_init, .intr = nv04_fifo_intr, .engine_id = nv04_fifo_engine_id, diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h index ba3dbc86435e4b2f9d2da5f0595f9c03d832743c..80280841cf814c9fe2531db1e236c07756851edd 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h @@ -21,6 +21,7 @@ struct nvkm_fifo_func { int (*oneinit)(struct nvkm_fifo *); int (*chid_nr)(struct nvkm_fifo *); + int (*chid_ctor)(struct nvkm_fifo *, int nr); int (*info)(struct nvkm_fifo *, u64 mthd, u64 *data); void (*init)(struct nvkm_fifo *); @@ -86,6 +87,8 @@ struct nvkm_fifo_func { int nvkm_fifo_ctor(const struct nvkm_fifo_func *, struct nvkm_device *, enum nvkm_subdev_type, int, struct nvkm_fifo *); +int nv04_fifo_chid_ctor(struct nvkm_fifo *, int); +void nv04_fifo_init(struct nvkm_fifo *); void nv04_fifo_intr(struct nvkm_fifo *); int nv04_fifo_engine_id(struct nvkm_fifo *, struct nvkm_engine *); struct nvkm_engine *nv04_fifo_id_engine(struct nvkm_fifo *, int); @@ -96,9 +99,11 @@ extern const struct nvkm_cgrp_func nv04_cgrp; int nv10_fifo_chid_nr(struct nvkm_fifo *); int nv50_fifo_chid_nr(struct nvkm_fifo *); +int nv50_fifo_chid_ctor(struct nvkm_fifo *, int); extern const struct nvkm_chan_func g84_chan; +int gf100_fifo_chid_ctor(struct nvkm_fifo *, int); void gf100_fifo_intr_mmu_fault_unit(struct nvkm_fifo *, int); int gk104_fifo_chid_nr(struct nvkm_fifo *); @@ -109,6 +114,7 @@ void gk104_fifo_recover_chan(struct nvkm_fifo *, int); int gk104_fifo_engine_id(struct nvkm_fifo *, struct nvkm_engine *); struct nvkm_engine *gk104_fifo_id_engine(struct nvkm_fifo *, int); +int gk110_fifo_chid_ctor(struct nvkm_fifo *, int); extern const struct nvkm_cgrp_func gk110_cgrp; extern const struct nvkm_chan_func gk110_chan; diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c index 274096316a1b12cb2a1ed0b2111e2a028e4d65ac..fbc67b84a8b10cf7f2a2ef0c10a949d093cd710b 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c @@ -442,6 +442,7 @@ tu102_fifo = { .dtor = gk104_fifo_dtor, .oneinit = gk104_fifo_oneinit, .chid_nr = gm200_fifo_chid_nr, + .chid_ctor = gk110_fifo_chid_ctor, .info = gk104_fifo_info, .init = gk104_fifo_init, .fini = gk104_fifo_fini,