drm/nouveau/fifo: add chid allocator
authorBen Skeggs <bskeggs@redhat.com>
Wed, 1 Jun 2022 10:47:23 +0000 (20:47 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 9 Nov 2022 00:44:47 +0000 (10:44 +1000)
We need to be able to allocate TSG IDs as well as channel IDs, also,
Ampere has per-runlist channel IDs.

- holds per-ID private data, which will be used for/to protect lookup
- holds an nvkm_event which will be used for events tied to IDs
- not used yet beyond setup, and switching use of "fifo->nr - 1" for
  channel ID mask to "chid->mask"

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
26 files changed:
drivers/gpu/drm/nouveau/include/nvkm/engine/fifo.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/Kbuild
drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chid.c [new file with mode: 0644]
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chid.h [new file with mode: 0644]
drivers/gpu/drm/nouveau/nvkm/engine/fifo/g84.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gf100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk104.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk110.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk208.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gk20a.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm107.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gm200.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gp100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/gv100.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv04.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv10.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv17.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv40.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/nv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/priv.h
drivers/gpu/drm/nouveau/nvkm/engine/fifo/tu102.c

index 2f2059c..b688121 100644 (file)
@@ -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;
index 76d2bf1..c985736 100644 (file)
@@ -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
 
index 4e099bf..e6b0653 100644 (file)
@@ -23,6 +23,7 @@
  */
 #include "priv.h"
 #include "chan.h"
+#include "chid.h"
 
 #include <core/gpuobj.h>
 #include <subdev/mc.h>
@@ -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,
index 4d4905b..464c956 100644 (file)
 
 #include <nvif/if0020.h>
 
+const struct nvkm_event_func
+nvkm_chan_event = {
+};
+
 struct nvkm_fifo_chan_object {
        struct nvkm_oproxy oproxy;
        struct nvkm_fifo_chan *chan;
index 24fbe6c..a9c0e02 100644 (file)
@@ -4,6 +4,8 @@
 #define nvkm_chan(p) container_of((p), struct nvkm_chan, object) /*FIXME: remove later */
 #include <engine/fifo.h>
 
+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 (file)
index 0000000..7c582bc
--- /dev/null
@@ -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 (file)
index 0000000..d359828
--- /dev/null
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVKM_CHID_H__
+#define __NVKM_CHID_H__
+#include <core/event.h>
+
+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
index 24732d3..dbb9df6 100644 (file)
@@ -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,
index 1a641b1..d8eeca8 100644 (file)
@@ -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,
index 880ddfe..c4fa4fc 100644 (file)
@@ -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,
index 9621877..af6a004 100644 (file)
@@ -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);
index 9dcc54f..b23d50d 100644 (file)
@@ -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,
index 28791ba..1dd937b 100644 (file)
@@ -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,
index b62e3bb..d2e78d2 100644 (file)
@@ -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,
index f996f1c..32ef88a 100644 (file)
@@ -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,
index 8f3da21..7489183 100644 (file)
@@ -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,
index dc59084..c1ad59d 100644 (file)
@@ -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,
index 36c02b5..9e876bd 100644 (file)
@@ -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,
index f9f8371..18fa5b9 100644 (file)
@@ -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,
index 3f23bcd..879c686 100644 (file)
@@ -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
index f07304e..bc25520 100644 (file)
@@ -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,
index 858c8ba..dd254d8 100644 (file)
@@ -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,
index 30f924e..c87d995 100644 (file)
@@ -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,
index 101015a..13c514a 100644 (file)
@@ -22,6 +22,7 @@
  * Authors: Ben Skeggs
  */
 #include "chan.h"
+#include "chid.h"
 
 #include "nv50.h"
 #include "channv50.h"
@@ -89,6 +90,13 @@ nv50_fifo_init(struct nvkm_fifo *base)
 }
 
 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)
 {
        return 128;
@@ -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,
index ba3dbc8..8028084 100644 (file)
@@ -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;
 
index 2740963..fbc67b8 100644 (file)
@@ -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,