summaryrefslogtreecommitdiff
path: root/drm/nouveau/nvkm/engine/fifo
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2015-08-20 14:54:22 +1000
committerBen Skeggs <bskeggs@redhat.com>2015-08-28 12:37:43 +1000
commite103ae8e49c69eb2e7a343c0d36e7beb20e0f580 (patch)
treed924862b740fcdd51eb685d123aedb9c507a99c9 /drm/nouveau/nvkm/engine/fifo
parent2a030fbd0be8d91441321ec149307dccf9a9b453 (diff)
downloadnouveau-e103ae8e49c69eb2e7a343c0d36e7beb20e0f580.tar.gz
fifo: convert to new-style nvkm_engine
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drm/nouveau/nvkm/engine/fifo')
-rw-r--r--drm/nouveau/nvkm/engine/fifo/Kbuild2
-rw-r--r--drm/nouveau/nvkm/engine/fifo/base.c128
-rw-r--r--drm/nouveau/nvkm/engine/fifo/chan.c1
-rw-r--r--drm/nouveau/nvkm/engine/fifo/chan.h1
-rw-r--r--drm/nouveau/nvkm/engine/fifo/dmanv04.c8
-rw-r--r--drm/nouveau/nvkm/engine/fifo/dmanv10.c1
-rw-r--r--drm/nouveau/nvkm/engine/fifo/dmanv17.c1
-rw-r--r--drm/nouveau/nvkm/engine/fifo/g84.c71
-rw-r--r--drm/nouveau/nvkm/engine/fifo/gf100.c162
-rw-r--r--drm/nouveau/nvkm/engine/fifo/gk104.c198
-rw-r--r--drm/nouveau/nvkm/engine/fifo/gk104.h24
-rw-r--r--drm/nouveau/nvkm/engine/fifo/gk208.c30
-rw-r--r--drm/nouveau/nvkm/engine/fifo/gk20a.c30
-rw-r--r--drm/nouveau/nvkm/engine/fifo/gm204.c32
-rw-r--r--drm/nouveau/nvkm/engine/fifo/gm20b.c30
-rw-r--r--drm/nouveau/nvkm/engine/fifo/gpfifogf100.c1
-rw-r--r--drm/nouveau/nvkm/engine/fifo/gpfifogk104.c1
-rw-r--r--drm/nouveau/nvkm/engine/fifo/nv04.c92
-rw-r--r--drm/nouveau/nvkm/engine/fifo/nv04.h10
-rw-r--r--drm/nouveau/nvkm/engine/fifo/nv10.c45
-rw-r--r--drm/nouveau/nvkm/engine/fifo/nv17.c57
-rw-r--r--drm/nouveau/nvkm/engine/fifo/nv40.c59
-rw-r--r--drm/nouveau/nvkm/engine/fifo/nv50.c103
-rw-r--r--drm/nouveau/nvkm/engine/fifo/nv50.h8
-rw-r--r--drm/nouveau/nvkm/engine/fifo/priv.h19
25 files changed, 526 insertions, 588 deletions
diff --git a/drm/nouveau/nvkm/engine/fifo/Kbuild b/drm/nouveau/nvkm/engine/fifo/Kbuild
index 4525b0159..74993c144 100644
--- a/drm/nouveau/nvkm/engine/fifo/Kbuild
+++ b/drm/nouveau/nvkm/engine/fifo/Kbuild
@@ -7,8 +7,8 @@ nvkm-y += nvkm/engine/fifo/nv50.o
nvkm-y += nvkm/engine/fifo/g84.o
nvkm-y += nvkm/engine/fifo/gf100.o
nvkm-y += nvkm/engine/fifo/gk104.o
-nvkm-y += nvkm/engine/fifo/gk20a.o
nvkm-y += nvkm/engine/fifo/gk208.o
+nvkm-y += nvkm/engine/fifo/gk20a.o
nvkm-y += nvkm/engine/fifo/gm204.o
nvkm-y += nvkm/engine/fifo/gm20b.o
diff --git a/drm/nouveau/nvkm/engine/fifo/base.c b/drm/nouveau/nvkm/engine/fifo/base.c
index b693127d8..1fbbfbe6c 100644
--- a/drm/nouveau/nvkm/engine/fifo/base.c
+++ b/drm/nouveau/nvkm/engine/fifo/base.c
@@ -25,12 +25,25 @@
#include "chan.h"
#include <core/client.h>
+#include <core/gpuobj.h>
#include <core/notify.h>
#include <nvif/event.h>
#include <nvif/unpack.h>
void
+nvkm_fifo_pause(struct nvkm_fifo *fifo, unsigned long *flags)
+{
+ return fifo->func->pause(fifo, flags);
+}
+
+void
+nvkm_fifo_start(struct nvkm_fifo *fifo, unsigned long *flags)
+{
+ return fifo->func->start(fifo, flags);
+}
+
+void
nvkm_fifo_chan_put(struct nvkm_fifo *fifo, unsigned long flags,
struct nvkm_fifo_chan **pchan)
{
@@ -95,7 +108,21 @@ nvkm_fifo_event_func = {
.ctor = nvkm_fifo_event_ctor,
};
-int
+static void
+nvkm_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
+{
+ struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
+ fifo->func->uevent_fini(fifo);
+}
+
+static void
+nvkm_fifo_uevent_init(struct nvkm_event *event, int type, int index)
+{
+ struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
+ fifo->func->uevent_init(fifo);
+}
+
+static int
nvkm_fifo_uevent_ctor(struct nvkm_object *object, void *data, u32 size,
struct nvkm_notify *notify)
{
@@ -113,6 +140,13 @@ nvkm_fifo_uevent_ctor(struct nvkm_object *object, void *data, u32 size,
return ret;
}
+static const struct nvkm_event_func
+nvkm_fifo_uevent_func = {
+ .ctor = nvkm_fifo_uevent_ctor,
+ .init = nvkm_fifo_uevent_init,
+ .fini = nvkm_fifo_uevent_fini,
+};
+
void
nvkm_fifo_uevent(struct nvkm_fifo *fifo)
{
@@ -156,50 +190,88 @@ nvkm_fifo_class_get(struct nvkm_oclass *oclass, int index,
return c;
}
-void
-nvkm_fifo_destroy(struct nvkm_fifo *fifo)
+static void
+nvkm_fifo_intr(struct nvkm_engine *engine)
{
- nvkm_event_fini(&fifo->uevent);
+ struct nvkm_fifo *fifo = nvkm_fifo(engine);
+ fifo->func->intr(fifo);
+}
+
+static int
+nvkm_fifo_fini(struct nvkm_engine *engine, bool suspend)
+{
+ struct nvkm_fifo *fifo = nvkm_fifo(engine);
+ if (fifo->func->fini)
+ fifo->func->fini(fifo);
+ return 0;
+}
+
+static int
+nvkm_fifo_oneinit(struct nvkm_engine *engine)
+{
+ struct nvkm_fifo *fifo = nvkm_fifo(engine);
+ if (fifo->func->oneinit)
+ return fifo->func->oneinit(fifo);
+ return 0;
+}
+
+static int
+nvkm_fifo_init(struct nvkm_engine *engine)
+{
+ struct nvkm_fifo *fifo = nvkm_fifo(engine);
+ fifo->func->init(fifo);
+ return 0;
+}
+
+static void *
+nvkm_fifo_dtor(struct nvkm_engine *engine)
+{
+ struct nvkm_fifo *fifo = nvkm_fifo(engine);
+ void *data = fifo;
+ if (fifo->func->dtor)
+ data = fifo->func->dtor(fifo);
nvkm_event_fini(&fifo->cevent);
- nvkm_engine_destroy(&fifo->engine);
+ nvkm_event_fini(&fifo->uevent);
+ return data;
}
static const struct nvkm_engine_func
-nvkm_fifo_func = {
+nvkm_fifo = {
+ .dtor = nvkm_fifo_dtor,
+ .oneinit = nvkm_fifo_oneinit,
+ .init = nvkm_fifo_init,
+ .fini = nvkm_fifo_fini,
+ .intr = nvkm_fifo_intr,
.base.sclass = nvkm_fifo_class_get,
};
int
-nvkm_fifo_create_(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass,
- int min, int max, int length, void **pobject)
+nvkm_fifo_ctor(const struct nvkm_fifo_func *func, struct nvkm_device *device,
+ int index, int nr, struct nvkm_fifo *fifo)
{
- struct nvkm_fifo *fifo;
- int nr = max + 1;
- int cnt = nr - min;
int ret;
- ret = nvkm_engine_create_(parent, engine, oclass, true, "PFIFO",
- "fifo", length, pobject);
- fifo = *pobject;
- if (ret)
- return ret;
-
- fifo->engine.func = &nvkm_fifo_func;
+ fifo->func = func;
INIT_LIST_HEAD(&fifo->chan);
+ spin_lock_init(&fifo->lock);
- fifo->nr = nr;
- if (WARN_ON(fifo->nr > NVKM_FIFO_CHID_NR)) {
+ if (WARN_ON(fifo->nr > NVKM_FIFO_CHID_NR))
fifo->nr = NVKM_FIFO_CHID_NR;
- cnt = fifo->nr - min;
- }
- bitmap_fill(fifo->mask, NVKM_FIFO_CHID_NR);
- bitmap_clear(fifo->mask, min, cnt);
+ else
+ fifo->nr = nr;
+ bitmap_clear(fifo->mask, 0, fifo->nr);
- ret = nvkm_event_init(&nvkm_fifo_event_func, 1, 1, &fifo->cevent);
+ ret = nvkm_engine_ctor(&nvkm_fifo, device, index, 0x00000100,
+ true, &fifo->engine);
if (ret)
return ret;
- spin_lock_init(&fifo->lock);
- return 0;
+ if (func->uevent_init) {
+ ret = nvkm_event_init(&nvkm_fifo_uevent_func, 1, 1,
+ &fifo->uevent);
+ if (ret)
+ return ret;
+ }
+
+ return nvkm_event_init(&nvkm_fifo_event_func, 1, 1, &fifo->cevent);
}
diff --git a/drm/nouveau/nvkm/engine/fifo/chan.c b/drm/nouveau/nvkm/engine/fifo/chan.c
index a02c60f34..4ed06abdc 100644
--- a/drm/nouveau/nvkm/engine/fifo/chan.c
+++ b/drm/nouveau/nvkm/engine/fifo/chan.c
@@ -24,6 +24,7 @@
#include "chan.h"
#include <core/client.h>
+#include <core/gpuobj.h>
#include <core/oproxy.h>
#include <subdev/mmu.h>
#include <engine/dma.h>
diff --git a/drm/nouveau/nvkm/engine/fifo/chan.h b/drm/nouveau/nvkm/engine/fifo/chan.h
index bfec12dbf..55dc415c5 100644
--- a/drm/nouveau/nvkm/engine/fifo/chan.h
+++ b/drm/nouveau/nvkm/engine/fifo/chan.h
@@ -1,5 +1,6 @@
#ifndef __NVKM_FIFO_CHAN_H__
#define __NVKM_FIFO_CHAN_H__
+#define nvkm_fifo_chan(p) container_of((p), struct nvkm_fifo_chan, object)
#include "priv.h"
struct nvkm_fifo_chan_func {
diff --git a/drm/nouveau/nvkm/engine/fifo/dmanv04.c b/drm/nouveau/nvkm/engine/fifo/dmanv04.c
index eafa87886..52cbc4b47 100644
--- a/drm/nouveau/nvkm/engine/fifo/dmanv04.c
+++ b/drm/nouveau/nvkm/engine/fifo/dmanv04.c
@@ -73,7 +73,7 @@ nv04_fifo_dma_fini(struct nvkm_fifo_chan *base)
struct nv04_fifo *fifo = chan->fifo;
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_memory *fctx = device->imem->ramfc;
- struct ramfc_desc *c;
+ const struct nv04_fifo_ramfc *c;
unsigned long flags;
u32 mask = fifo->base.nr - 1;
u32 data = chan->ramfc;
@@ -90,7 +90,7 @@ nv04_fifo_dma_fini(struct nvkm_fifo_chan *base)
nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH0, 0);
nvkm_mask(device, NV04_PFIFO_CACHE1_PULL0, 0x00000001, 0);
- c = fifo->ramfc_desc;
+ c = fifo->ramfc;
do {
u32 rm = ((1ULL << c->bits) - 1) << c->regs;
u32 cm = ((1ULL << c->bits) - 1) << c->ctxs;
@@ -99,7 +99,7 @@ nv04_fifo_dma_fini(struct nvkm_fifo_chan *base)
nvkm_wo32(fctx, c->ctxp + data, cv | (rv << c->ctxs));
} while ((++c)->bits);
- c = fifo->ramfc_desc;
+ c = fifo->ramfc;
do {
nvkm_wr32(device, c->regp, 0x00000000);
} while ((++c)->bits);
@@ -136,7 +136,7 @@ nv04_fifo_dma_dtor(struct nvkm_fifo_chan *base)
struct nv04_fifo_chan *chan = nv04_fifo_chan(base);
struct nv04_fifo *fifo = chan->fifo;
struct nvkm_instmem *imem = fifo->base.engine.subdev.device->imem;
- struct ramfc_desc *c = fifo->ramfc_desc;
+ const struct nv04_fifo_ramfc *c = fifo->ramfc;
nvkm_kmap(imem->ramfc);
do {
diff --git a/drm/nouveau/nvkm/engine/fifo/dmanv10.c b/drm/nouveau/nvkm/engine/fifo/dmanv10.c
index 1ad162053..d8e4d5570 100644
--- a/drm/nouveau/nvkm/engine/fifo/dmanv10.c
+++ b/drm/nouveau/nvkm/engine/fifo/dmanv10.c
@@ -25,6 +25,7 @@
#include "regsnv04.h"
#include <core/client.h>
+#include <core/gpuobj.h>
#include <subdev/instmem.h>
#include <nvif/class.h>
diff --git a/drm/nouveau/nvkm/engine/fifo/dmanv17.c b/drm/nouveau/nvkm/engine/fifo/dmanv17.c
index 2fbb9d4f0..1424dd9b6 100644
--- a/drm/nouveau/nvkm/engine/fifo/dmanv17.c
+++ b/drm/nouveau/nvkm/engine/fifo/dmanv17.c
@@ -25,6 +25,7 @@
#include "regsnv04.h"
#include <core/client.h>
+#include <core/gpuobj.h>
#include <subdev/instmem.h>
#include <nvif/class.h>
diff --git a/drm/nouveau/nvkm/engine/fifo/g84.c b/drm/nouveau/nvkm/engine/fifo/g84.c
index 00fa9d3ef..ff7b52976 100644
--- a/drm/nouveau/nvkm/engine/fifo/g84.c
+++ b/drm/nouveau/nvkm/engine/fifo/g84.c
@@ -25,30 +25,29 @@
#include "channv50.h"
static void
-g84_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
+g84_fifo_uevent_fini(struct nvkm_fifo *fifo)
{
- struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
struct nvkm_device *device = fifo->engine.subdev.device;
nvkm_mask(device, 0x002140, 0x40000000, 0x00000000);
}
static void
-g84_fifo_uevent_init(struct nvkm_event *event, int type, int index)
+g84_fifo_uevent_init(struct nvkm_fifo *fifo)
{
- struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
struct nvkm_device *device = fifo->engine.subdev.device;
nvkm_mask(device, 0x002140, 0x40000000, 0x40000000);
}
-static const struct nvkm_event_func
-g84_fifo_uevent_func = {
- .ctor = nvkm_fifo_uevent_ctor,
- .init = g84_fifo_uevent_init,
- .fini = g84_fifo_uevent_fini,
-};
-
static const struct nvkm_fifo_func
-g84_fifo_func = {
+g84_fifo = {
+ .dtor = nv50_fifo_dtor,
+ .oneinit = nv50_fifo_oneinit,
+ .init = nv50_fifo_init,
+ .intr = nv04_fifo_intr,
+ .pause = nv04_fifo_pause,
+ .start = nv04_fifo_start,
+ .uevent_init = g84_fifo_uevent_init,
+ .uevent_fini = g84_fifo_uevent_fini,
.chan = {
&g84_fifo_dma_oclass,
&g84_fifo_gpfifo_oclass,
@@ -56,50 +55,8 @@ g84_fifo_func = {
},
};
-static int
-g84_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
+int
+g84_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
{
- struct nvkm_device *device = (void *)parent;
- struct nv50_fifo *fifo;
- int ret;
-
- ret = nvkm_fifo_create(parent, engine, oclass, 1, 127, &fifo);
- *pobject = nv_object(fifo);
- if (ret)
- return ret;
-
- fifo->base.func = &g84_fifo_func;
-
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 128 * 4, 0x1000,
- false, &fifo->runlist[0]);
- if (ret)
- return ret;
-
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 128 * 4, 0x1000,
- false, &fifo->runlist[1]);
- if (ret)
- return ret;
-
- ret = nvkm_event_init(&g84_fifo_uevent_func, 1, 1, &fifo->base.uevent);
- if (ret)
- return ret;
-
- nv_subdev(fifo)->unit = 0x00000100;
- nv_subdev(fifo)->intr = nv04_fifo_intr;
- fifo->base.pause = nv04_fifo_pause;
- fifo->base.start = nv04_fifo_start;
- return 0;
+ return nv50_fifo_new_(&g84_fifo, device, index, pfifo);
}
-
-struct nvkm_oclass *
-g84_fifo_oclass = &(struct nvkm_oclass) {
- .handle = NV_ENGINE(FIFO, 0x84),
- .ofuncs = &(struct nvkm_ofuncs) {
- .ctor = g84_fifo_ctor,
- .dtor = nv50_fifo_dtor,
- .init = nv50_fifo_init,
- .fini = _nvkm_fifo_fini,
- },
-};
diff --git a/drm/nouveau/nvkm/engine/fifo/gf100.c b/drm/nouveau/nvkm/engine/fifo/gf100.c
index e8598fc44..bc094223f 100644
--- a/drm/nouveau/nvkm/engine/fifo/gf100.c
+++ b/drm/nouveau/nvkm/engine/fifo/gf100.c
@@ -26,6 +26,7 @@
#include <core/client.h>
#include <core/enum.h>
+#include <core/gpuobj.h>
#include <core/handle.h>
#include <subdev/bar.h>
#include <engine/sw.h>
@@ -33,28 +34,19 @@
#include <nvif/class.h>
static void
-gf100_fifo_uevent_init(struct nvkm_event *event, int type, int index)
+gf100_fifo_uevent_init(struct nvkm_fifo *fifo)
{
- struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
struct nvkm_device *device = fifo->engine.subdev.device;
nvkm_mask(device, 0x002140, 0x80000000, 0x80000000);
}
static void
-gf100_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
+gf100_fifo_uevent_fini(struct nvkm_fifo *fifo)
{
- struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
struct nvkm_device *device = fifo->engine.subdev.device;
nvkm_mask(device, 0x002140, 0x80000000, 0x00000000);
}
-static const struct nvkm_event_func
-gf100_fifo_uevent_func = {
- .ctor = nvkm_fifo_uevent_ctor,
- .init = gf100_fifo_uevent_init,
- .fini = gf100_fifo_uevent_fini,
-};
-
void
gf100_fifo_runlist_update(struct gf100_fifo *fifo)
{
@@ -64,7 +56,7 @@ gf100_fifo_runlist_update(struct gf100_fifo *fifo)
struct nvkm_memory *cur;
int nr = 0;
- mutex_lock(&nv_subdev(fifo)->mutex);
+ mutex_lock(&subdev->mutex);
cur = fifo->runlist.mem[fifo->runlist.active];
fifo->runlist.active = !fifo->runlist.active;
@@ -83,7 +75,7 @@ gf100_fifo_runlist_update(struct gf100_fifo *fifo)
!(nvkm_rd32(device, 0x00227c) & 0x00100000),
msecs_to_jiffies(2000)) == 0)
nvkm_error(subdev, "runlist update timeout\n");
- mutex_unlock(&nv_subdev(fifo)->mutex);
+ mutex_unlock(&subdev->mutex);
}
static inline int
@@ -106,6 +98,8 @@ gf100_fifo_engidx(struct gf100_fifo *fifo, u32 engn)
static inline struct nvkm_engine *
gf100_fifo_engine(struct gf100_fifo *fifo, u32 engn)
{
+ struct nvkm_device *device = fifo->base.engine.subdev.device;
+
switch (engn) {
case 0: engn = NVDEV_ENGINE_GR; break;
case 1: engn = NVDEV_ENGINE_MSVLD; break;
@@ -117,7 +111,7 @@ gf100_fifo_engine(struct gf100_fifo *fifo, u32 engn)
return NULL;
}
- return nvkm_engine(fifo, engn);
+ return nvkm_device_engine(device, engn);
}
static void
@@ -167,7 +161,7 @@ gf100_fifo_recover(struct gf100_fifo *fifo, struct nvkm_engine *engine,
list_del_init(&chan->head);
chan->killed = true;
- fifo->mask |= 1ULL << nv_engidx(engine);
+ fifo->mask |= 1ULL << engine->subdev.index;
schedule_work(&fifo->fault);
}
@@ -333,7 +327,7 @@ gf100_fifo_intr_fault(struct gf100_fifo *fifo, int unit)
nvkm_mask(device, 0x001718, 0x00000000, 0x00000000);
break;
default:
- engine = nvkm_engine(fifo, eu->data2);
+ engine = nvkm_device_engine(device, eu->data2);
break;
}
}
@@ -457,10 +451,11 @@ gf100_fifo_intr_engine(struct gf100_fifo *fifo)
}
static void
-gf100_fifo_intr(struct nvkm_subdev *subdev)
+gf100_fifo_intr(struct nvkm_fifo *base)
{
- struct gf100_fifo *fifo = (void *)subdev;
- struct nvkm_device *device = fifo->base.engine.subdev.device;
+ struct gf100_fifo *fifo = gf100_fifo(base);
+ struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
+ struct nvkm_device *device = subdev->device;
u32 mask = nvkm_rd32(device, 0x002140);
u32 stat = nvkm_rd32(device, 0x002100) & mask;
@@ -531,17 +526,52 @@ gf100_fifo_intr(struct nvkm_subdev *subdev)
}
static int
-gf100_fifo_init(struct nvkm_object *object)
+gf100_fifo_oneinit(struct nvkm_fifo *base)
{
- struct gf100_fifo *fifo = (void *)object;
- struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
- struct nvkm_device *device = subdev->device;
- int ret, i;
+ struct gf100_fifo *fifo = gf100_fifo(base);
+ struct nvkm_device *device = fifo->base.engine.subdev.device;
+ int ret;
- ret = nvkm_fifo_init(&fifo->base);
+ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000,
+ false, &fifo->runlist.mem[0]);
+ if (ret)
+ return ret;
+
+ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000,
+ false, &fifo->runlist.mem[1]);
if (ret)
return ret;
+ init_waitqueue_head(&fifo->runlist.wait);
+
+ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 128 * 0x1000,
+ 0x1000, false, &fifo->user.mem);
+ if (ret)
+ return ret;
+
+ ret = nvkm_bar_umap(device->bar, 128 * 0x1000, 12, &fifo->user.bar);
+ if (ret)
+ return ret;
+
+ nvkm_memory_map(fifo->user.mem, &fifo->user.bar, 0);
+ return 0;
+}
+
+static void
+gf100_fifo_fini(struct nvkm_fifo *base)
+{
+ struct gf100_fifo *fifo = gf100_fifo(base);
+ flush_work(&fifo->fault);
+}
+
+static void
+gf100_fifo_init(struct nvkm_fifo *base)
+{
+ struct gf100_fifo *fifo = gf100_fifo(base);
+ struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
+ struct nvkm_device *device = subdev->device;
+ int i;
+
nvkm_wr32(device, 0x000204, 0xffffffff);
nvkm_wr32(device, 0x002204, 0xffffffff);
@@ -571,90 +601,44 @@ gf100_fifo_init(struct nvkm_object *object)
nvkm_wr32(device, 0x002100, 0xffffffff);
nvkm_wr32(device, 0x002140, 0x7fffffff);
nvkm_wr32(device, 0x002628, 0x00000001); /* ENGINE_INTR_EN */
- return 0;
}
-static void
-gf100_fifo_dtor(struct nvkm_object *object)
+static void *
+gf100_fifo_dtor(struct nvkm_fifo *base)
{
- struct gf100_fifo *fifo = (void *)object;
-
+ struct gf100_fifo *fifo = gf100_fifo(base);
nvkm_vm_put(&fifo->user.bar);
nvkm_memory_del(&fifo->user.mem);
nvkm_memory_del(&fifo->runlist.mem[0]);
nvkm_memory_del(&fifo->runlist.mem[1]);
-
- nvkm_fifo_destroy(&fifo->base);
+ return fifo;
}
static const struct nvkm_fifo_func
-gf100_fifo_func = {
+gf100_fifo = {
+ .dtor = gf100_fifo_dtor,
+ .oneinit = gf100_fifo_oneinit,
+ .init = gf100_fifo_init,
+ .fini = gf100_fifo_fini,
+ .intr = gf100_fifo_intr,
+ .uevent_init = gf100_fifo_uevent_init,
+ .uevent_fini = gf100_fifo_uevent_fini,
.chan = {
&gf100_fifo_gpfifo_oclass,
NULL
},
};
-static int
-gf100_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
+int
+gf100_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
{
- struct nvkm_device *device = (void *)parent;
- struct nvkm_bar *bar = device->bar;
struct gf100_fifo *fifo;
- int ret;
-
- ret = nvkm_fifo_create(parent, engine, oclass, 0, 127, &fifo);
- *pobject = nv_object(fifo);
- if (ret)
- return ret;
-
- fifo->base.func = &gf100_fifo_func;
+ if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
+ return -ENOMEM;
INIT_LIST_HEAD(&fifo->chan);
INIT_WORK(&fifo->fault, gf100_fifo_recover_work);
+ *pfifo = &fifo->base;
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000,
- false, &fifo->runlist.mem[0]);
- if (ret)
- return ret;
-
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000,
- false, &fifo->runlist.mem[1]);
- if (ret)
- return ret;
-
- init_waitqueue_head(&fifo->runlist.wait);
-
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 128 * 0x1000,
- 0x1000, false, &fifo->user.mem);
- if (ret)
- return ret;
-
- ret = nvkm_bar_umap(bar, 128 * 0x1000, 12, &fifo->user.bar);
- if (ret)
- return ret;
-
- nvkm_memory_map(fifo->user.mem, &fifo->user.bar, 0);
-
- ret = nvkm_event_init(&gf100_fifo_uevent_func, 1, 1, &fifo->base.uevent);
- if (ret)
- return ret;
-
- nv_subdev(fifo)->unit = 0x00000100;
- nv_subdev(fifo)->intr = gf100_fifo_intr;
- return 0;
+ return nvkm_fifo_ctor(&gf100_fifo, device, index, 128, &fifo->base);
}
-
-
-struct nvkm_oclass *
-gf100_fifo_oclass = &(struct nvkm_oclass) {
- .handle = NV_ENGINE(FIFO, 0xc0),
- .ofuncs = &(struct nvkm_ofuncs) {
- .ctor = gf100_fifo_ctor,
- .dtor = gf100_fifo_dtor,
- .init = gf100_fifo_init,
- .fini = _nvkm_fifo_fini,
- },
-};
diff --git a/drm/nouveau/nvkm/engine/fifo/gk104.c b/drm/nouveau/nvkm/engine/fifo/gk104.c
index a69f61f3e..465b52dee 100644
--- a/drm/nouveau/nvkm/engine/fifo/gk104.c
+++ b/drm/nouveau/nvkm/engine/fifo/gk104.c
@@ -26,35 +26,27 @@
#include <core/client.h>
#include <core/enum.h>
+#include <core/gpuobj.h>
#include <core/handle.h>
#include <subdev/bar.h>
#include <engine/sw.h>
#include <nvif/class.h>
-static void
-gk104_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
+void
+gk104_fifo_uevent_fini(struct nvkm_fifo *fifo)
{
- struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
struct nvkm_device *device = fifo->engine.subdev.device;
nvkm_mask(device, 0x002140, 0x80000000, 0x00000000);
}
-static void
-gk104_fifo_uevent_init(struct nvkm_event *event, int type, int index)
+void
+gk104_fifo_uevent_init(struct nvkm_fifo *fifo)
{
- struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent);
struct nvkm_device *device = fifo->engine.subdev.device;
nvkm_mask(device, 0x002140, 0x80000000, 0x80000000);
}
-static const struct nvkm_event_func
-gk104_fifo_uevent_func = {
- .ctor = nvkm_fifo_uevent_ctor,
- .init = gk104_fifo_uevent_init,
- .fini = gk104_fifo_uevent_fini,
-};
-
void
gk104_fifo_runlist_update(struct gk104_fifo *fifo, u32 engine)
{
@@ -65,7 +57,7 @@ gk104_fifo_runlist_update(struct gk104_fifo *fifo, u32 engine)
struct nvkm_memory *cur;
int nr = 0;
- mutex_lock(&nv_subdev(fifo)->mutex);
+ mutex_lock(&subdev->mutex);
cur = engn->runlist[engn->cur_runlist];
engn->cur_runlist = !engn->cur_runlist;
@@ -84,15 +76,16 @@ gk104_fifo_runlist_update(struct gk104_fifo *fifo, u32 engine)
(engine * 0x08)) & 0x00100000),
msecs_to_jiffies(2000)) == 0)
nvkm_error(subdev, "runlist %d update timeout\n", engine);
- mutex_unlock(&nv_subdev(fifo)->mutex);
+ mutex_unlock(&subdev->mutex);
}
static inline struct nvkm_engine *
gk104_fifo_engine(struct gk104_fifo *fifo, u32 engn)
{
+ struct nvkm_device *device = fifo->base.engine.subdev.device;
u64 subdevs = gk104_fifo_engine_subdev(engn);
if (subdevs)
- return nvkm_engine(fifo, __ffs(subdevs));
+ return nvkm_device_engine(device, __ffs(subdevs));
return NULL;
}
@@ -136,14 +129,14 @@ gk104_fifo_recover(struct gk104_fifo *fifo, struct nvkm_engine *engine,
u32 chid = chan->base.chid;
nvkm_error(subdev, "%s engine fault on channel %d, recovering...\n",
- nvkm_subdev_name[nv_subdev(engine)->index], chid);
+ nvkm_subdev_name[engine->subdev.index], chid);
assert_spin_locked(&fifo->base.lock);
nvkm_mask(device, 0x800004 + (chid * 0x08), 0x00000800, 0x00000800);
list_del_init(&chan->head);
chan->killed = true;
- fifo->mask |= 1ULL << nv_engidx(engine);
+ fifo->mask |= 1ULL << engine->subdev.index;
schedule_work(&fifo->fault);
}
@@ -399,7 +392,7 @@ gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit)
nvkm_mask(device, 0x001718, 0x00000000, 0x00000000);
break;
default:
- engine = nvkm_engine(fifo, eu->data2);
+ engine = nvkm_device_engine(device, eu->data2);
break;
}
}
@@ -542,11 +535,12 @@ gk104_fifo_intr_engine(struct gk104_fifo *fifo)
nvkm_fifo_uevent(&fifo->base);
}
-static void
-gk104_fifo_intr(struct nvkm_subdev *subdev)
+void
+gk104_fifo_intr(struct nvkm_fifo *base)
{
- struct gk104_fifo *fifo = (void *)subdev;
- struct nvkm_device *device = fifo->base.engine.subdev.device;
+ struct gk104_fifo *fifo = gk104_fifo(base);
+ struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
+ struct nvkm_device *device = subdev->device;
u32 mask = nvkm_rd32(device, 0x002140);
u32 stat = nvkm_rd32(device, 0x002100) & mask;
@@ -633,33 +627,62 @@ gk104_fifo_intr(struct nvkm_subdev *subdev)
}
}
+void
+gk104_fifo_fini(struct nvkm_fifo *base)
+{
+ struct gk104_fifo *fifo = gk104_fifo(base);
+ struct nvkm_device *device = fifo->base.engine.subdev.device;
+ flush_work(&fifo->fault);
+ /* allow mmu fault interrupts, even when we're not using fifo */
+ nvkm_mask(device, 0x002140, 0x10000000, 0x10000000);
+}
+
int
-gk104_fifo_fini(struct nvkm_object *object, bool suspend)
+gk104_fifo_oneinit(struct nvkm_fifo *base)
{
- struct gk104_fifo *fifo = (void *)object;
+ struct gk104_fifo *fifo = gk104_fifo(base);
struct nvkm_device *device = fifo->base.engine.subdev.device;
- int ret;
+ int ret, i;
- ret = nvkm_fifo_fini(&fifo->base, suspend);
+ for (i = 0; i < ARRAY_SIZE(fifo->engine); i++) {
+ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
+ 0x8000, 0x1000, false,
+ &fifo->engine[i].runlist[0]);
+ if (ret)
+ return ret;
+
+ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
+ 0x8000, 0x1000, false,
+ &fifo->engine[i].runlist[1]);
+ if (ret)
+ return ret;
+
+ init_waitqueue_head(&fifo->engine[i].wait);
+ INIT_LIST_HEAD(&fifo->engine[i].chan);
+ }
+
+ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
+ fifo->base.nr * 0x200, 0x1000, true,
+ &fifo->user.mem);
if (ret)
return ret;
- /* allow mmu fault interrupts, even when we're not using fifo */
- nvkm_mask(device, 0x002140, 0x10000000, 0x10000000);
+ ret = nvkm_bar_umap(device->bar, fifo->base.nr * 0x200, 12,
+ &fifo->user.bar);
+ if (ret)
+ return ret;
+
+ nvkm_memory_map(fifo->user.mem, &fifo->user.bar, 0);
return 0;
}
-int
-gk104_fifo_init(struct nvkm_object *object)
+void
+gk104_fifo_init(struct nvkm_fifo *base)
{
- struct gk104_fifo *fifo = (void *)object;
+ struct gk104_fifo *fifo = gk104_fifo(base);
struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
- int ret, i;
-
- ret = nvkm_fifo_init(&fifo->base);
- if (ret)
- return ret;
+ int i;
/* enable all available PBDMA units */
nvkm_wr32(device, 0x000204, 0xffffffff);
@@ -683,13 +706,12 @@ gk104_fifo_init(struct nvkm_object *object)
nvkm_wr32(device, 0x002100, 0xffffffff);
nvkm_wr32(device, 0x002140, 0x7fffffff);
- return 0;
}
-void
-gk104_fifo_dtor(struct nvkm_object *object)
+void *
+gk104_fifo_dtor(struct nvkm_fifo *base)
{
- struct gk104_fifo *fifo = (void *)object;
+ struct gk104_fifo *fifo = gk104_fifo(base);
int i;
nvkm_vm_put(&fifo->user.bar);
@@ -700,11 +722,32 @@ gk104_fifo_dtor(struct nvkm_object *object)
nvkm_memory_del(&fifo->engine[i].runlist[0]);
}
- nvkm_fifo_destroy(&fifo->base);
+ return fifo;
+}
+
+int
+gk104_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device,
+ int index, int nr, struct nvkm_fifo **pfifo)
+{
+ struct gk104_fifo *fifo;
+
+ if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
+ return -ENOMEM;
+ INIT_WORK(&fifo->fault, gk104_fifo_recover_work);
+ *pfifo = &fifo->base;
+
+ return nvkm_fifo_ctor(func, device, index, nr, &fifo->base);
}
static const struct nvkm_fifo_func
-gk104_fifo_func = {
+gk104_fifo = {
+ .dtor = gk104_fifo_dtor,
+ .oneinit = gk104_fifo_oneinit,
+ .init = gk104_fifo_init,
+ .fini = gk104_fifo_fini,
+ .intr = gk104_fifo_intr,
+ .uevent_init = gk104_fifo_uevent_init,
+ .uevent_fini = gk104_fifo_uevent_fini,
.chan = {
&gk104_fifo_gpfifo_oclass,
NULL
@@ -712,72 +755,7 @@ gk104_fifo_func = {
};
int
-gk104_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
+gk104_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
{
- struct nvkm_device *device = (void *)parent;
- struct nvkm_bar *bar = device->bar;
- struct gk104_fifo_impl *impl = (void *)oclass;
- struct gk104_fifo *fifo;
- int ret, i;
-
- ret = nvkm_fifo_create(parent, engine, oclass, 0,
- impl->channels - 1, &fifo);
- *pobject = nv_object(fifo);
- if (ret)
- return ret;
-
- fifo->base.func = &gk104_fifo_func;
-
- INIT_WORK(&fifo->fault, gk104_fifo_recover_work);
-
- for (i = 0; i < ARRAY_SIZE(fifo->engine); i++) {
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
- 0x8000, 0x1000, false,
- &fifo->engine[i].runlist[0]);
- if (ret)
- return ret;
-
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
- 0x8000, 0x1000, false,
- &fifo->engine[i].runlist[1]);
- if (ret)
- return ret;
-
- init_waitqueue_head(&fifo->engine[i].wait);
- INIT_LIST_HEAD(&fifo->engine[i].chan);
- }
-
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
- impl->channels * 0x200, 0x1000,
- true, &fifo->user.mem);
- if (ret)
- return ret;
-
- ret = nvkm_bar_umap(bar, impl->channels * 0x200, 12, &fifo->user.bar);
- if (ret)
- return ret;
-
- nvkm_memory_map(fifo->user.mem, &fifo->user.bar, 0);
-
- ret = nvkm_event_init(&gk104_fifo_uevent_func, 1, 1, &fifo->base.uevent);
- if (ret)
- return ret;
-
- nv_subdev(fifo)->unit = 0x00000100;
- nv_subdev(fifo)->intr = gk104_fifo_intr;
- return 0;
+ return gk104_fifo_new_(&gk104_fifo, device, index, 4096, pfifo);
}
-
-struct nvkm_oclass *
-gk104_fifo_oclass = &(struct gk104_fifo_impl) {
- .base.handle = NV_ENGINE(FIFO, 0xe0),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = gk104_fifo_ctor,
- .dtor = gk104_fifo_dtor,
- .init = gk104_fifo_init,
- .fini = gk104_fifo_fini,
- },
- .channels = 4096,
-}.base;
diff --git a/drm/nouveau/nvkm/engine/fifo/gk104.h b/drm/nouveau/nvkm/engine/fifo/gk104.h
index 1103e6b1e..7a5c544a5 100644
--- a/drm/nouveau/nvkm/engine/fifo/gk104.h
+++ b/drm/nouveau/nvkm/engine/fifo/gk104.h
@@ -26,23 +26,17 @@ struct gk104_fifo {
int spoon_nr;
};
-struct gk104_fifo_impl {
- struct nvkm_oclass base;
- u32 channels;
-};
-
-int gk104_fifo_ctor(struct nvkm_object *, struct nvkm_object *,
- struct nvkm_oclass *, void *, u32,
- struct nvkm_object **);
-void gk104_fifo_dtor(struct nvkm_object *);
-int gk104_fifo_init(struct nvkm_object *);
-int gk104_fifo_fini(struct nvkm_object *, bool);
+int gk104_fifo_new_(const struct nvkm_fifo_func *, struct nvkm_device *,
+ int index, int nr, struct nvkm_fifo **);
+void *gk104_fifo_dtor(struct nvkm_fifo *);
+int gk104_fifo_oneinit(struct nvkm_fifo *);
+void gk104_fifo_init(struct nvkm_fifo *);
+void gk104_fifo_fini(struct nvkm_fifo *);
+void gk104_fifo_intr(struct nvkm_fifo *);
+void gk104_fifo_uevent_init(struct nvkm_fifo *);
+void gk104_fifo_uevent_fini(struct nvkm_fifo *);
void gk104_fifo_runlist_update(struct gk104_fifo *, u32 engine);
-int gm204_fifo_ctor(struct nvkm_object *, struct nvkm_object *,
- struct nvkm_oclass *, void *, u32,
- struct nvkm_object **);
-
static inline u64
gk104_fifo_engine_subdev(int engine)
{
diff --git a/drm/nouveau/nvkm/engine/fifo/gk208.c b/drm/nouveau/nvkm/engine/fifo/gk208.c
index 927092217..ce01c1a7d 100644
--- a/drm/nouveau/nvkm/engine/fifo/gk208.c
+++ b/drm/nouveau/nvkm/engine/fifo/gk208.c
@@ -22,15 +22,25 @@
* Authors: Ben Skeggs
*/
#include "gk104.h"
+#include "changk104.h"
-struct nvkm_oclass *
-gk208_fifo_oclass = &(struct gk104_fifo_impl) {
- .base.handle = NV_ENGINE(FIFO, 0x08),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = gk104_fifo_ctor,
- .dtor = gk104_fifo_dtor,
- .init = gk104_fifo_init,
- .fini = _nvkm_fifo_fini,
+static const struct nvkm_fifo_func
+gk208_fifo = {
+ .dtor = gk104_fifo_dtor,
+ .oneinit = gk104_fifo_oneinit,
+ .init = gk104_fifo_init,
+ .fini = gk104_fifo_fini,
+ .intr = gk104_fifo_intr,
+ .uevent_init = gk104_fifo_uevent_init,
+ .uevent_fini = gk104_fifo_uevent_fini,
+ .chan = {
+ &gk104_fifo_gpfifo_oclass,
+ NULL
},
- .channels = 1024,
-}.base;
+};
+
+int
+gk208_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
+{
+ return gk104_fifo_new_(&gk208_fifo, device, index, 1024, pfifo);
+}
diff --git a/drm/nouveau/nvkm/engine/fifo/gk20a.c b/drm/nouveau/nvkm/engine/fifo/gk20a.c
index b30dc87a1..b47fe98f4 100644
--- a/drm/nouveau/nvkm/engine/fifo/gk20a.c
+++ b/drm/nouveau/nvkm/engine/fifo/gk20a.c
@@ -20,15 +20,25 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "gk104.h"
+#include "changk104.h"
-struct nvkm_oclass *
-gk20a_fifo_oclass = &(struct gk104_fifo_impl) {
- .base.handle = NV_ENGINE(FIFO, 0xea),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = gk104_fifo_ctor,
- .dtor = gk104_fifo_dtor,
- .init = gk104_fifo_init,
- .fini = gk104_fifo_fini,
+static const struct nvkm_fifo_func
+gk20a_fifo = {
+ .dtor = gk104_fifo_dtor,
+ .oneinit = gk104_fifo_oneinit,
+ .init = gk104_fifo_init,
+ .fini = gk104_fifo_fini,
+ .intr = gk104_fifo_intr,
+ .uevent_init = gk104_fifo_uevent_init,
+ .uevent_fini = gk104_fifo_uevent_fini,
+ .chan = {
+ &gk104_fifo_gpfifo_oclass,
+ NULL
},
- .channels = 128,
-}.base;
+};
+
+int
+gk20a_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
+{
+ return gk104_fifo_new_(&gk20a_fifo, device, index, 128, pfifo);
+}
diff --git a/drm/nouveau/nvkm/engine/fifo/gm204.c b/drm/nouveau/nvkm/engine/fifo/gm204.c
index 18c68ac74..2db629f1b 100644
--- a/drm/nouveau/nvkm/engine/fifo/gm204.c
+++ b/drm/nouveau/nvkm/engine/fifo/gm204.c
@@ -25,7 +25,14 @@
#include "changk104.h"
static const struct nvkm_fifo_func
-gm204_fifo_func = {
+gm204_fifo = {
+ .dtor = gk104_fifo_dtor,
+ .oneinit = gk104_fifo_oneinit,
+ .init = gk104_fifo_init,
+ .fini = gk104_fifo_fini,
+ .intr = gk104_fifo_intr,
+ .uevent_init = gk104_fifo_uevent_init,
+ .uevent_fini = gk104_fifo_uevent_fini,
.chan = {
&gm204_fifo_gpfifo_oclass,
NULL
@@ -33,26 +40,7 @@ gm204_fifo_func = {
};
int
-gm204_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
+gm204_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
{
- int ret = gk104_fifo_ctor(parent, engine, oclass, data, size, pobject);
- if (ret == 0) {
- struct gk104_fifo *fifo = (void *)*pobject;
- fifo->base.func = &gm204_fifo_func;
- }
- return ret;
+ return gk104_fifo_new_(&gm204_fifo, device, index, 4096, pfifo);
}
-
-struct nvkm_oclass *
-gm204_fifo_oclass = &(struct gk104_fifo_impl) {
- .base.handle = NV_ENGINE(FIFO, 0x24),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = gm204_fifo_ctor,
- .dtor = gk104_fifo_dtor,
- .init = gk104_fifo_init,
- .fini = _nvkm_fifo_fini,
- },
- .channels = 4096,
-}.base;
diff --git a/drm/nouveau/nvkm/engine/fifo/gm20b.c b/drm/nouveau/nvkm/engine/fifo/gm20b.c
index 4abf547c3..ae6375d97 100644
--- a/drm/nouveau/nvkm/engine/fifo/gm20b.c
+++ b/drm/nouveau/nvkm/engine/fifo/gm20b.c
@@ -20,15 +20,25 @@
* DEALINGS IN THE SOFTWARE.
*/
#include "gk104.h"
+#include "changk104.h"
-struct nvkm_oclass *
-gm20b_fifo_oclass = &(struct gk104_fifo_impl) {
- .base.handle = NV_ENGINE(FIFO, 0x2b),
- .base.ofuncs = &(struct nvkm_ofuncs) {
- .ctor = gm204_fifo_ctor,
- .dtor = gk104_fifo_dtor,
- .init = gk104_fifo_init,
- .fini = gk104_fifo_fini,
+static const struct nvkm_fifo_func
+gm20b_fifo = {
+ .dtor = gk104_fifo_dtor,
+ .oneinit = gk104_fifo_oneinit,
+ .init = gk104_fifo_init,
+ .fini = gk104_fifo_fini,
+ .intr = gk104_fifo_intr,
+ .uevent_init = gk104_fifo_uevent_init,
+ .uevent_fini = gk104_fifo_uevent_fini,
+ .chan = {
+ &gm204_fifo_gpfifo_oclass,
+ NULL
},
- .channels = 512,
-}.base;
+};
+
+int
+gm20b_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
+{
+ return gk104_fifo_new_(&gm20b_fifo, device, index, 512, pfifo);
+}
diff --git a/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c b/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
index eb9195a6f..5d76c3013 100644
--- a/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
+++ b/drm/nouveau/nvkm/engine/fifo/gpfifogf100.c
@@ -24,6 +24,7 @@
#include "changf100.h"
#include <core/client.h>
+#include <core/gpuobj.h>
#include <subdev/fb.h>
#include <subdev/timer.h>
diff --git a/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c b/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
index 2595cf92f..fe3998191 100644
--- a/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
+++ b/drm/nouveau/nvkm/engine/fifo/gpfifogk104.c
@@ -24,6 +24,7 @@
#include "changk104.h"
#include <core/client.h>
+#include <core/gpuobj.h>
#include <subdev/fb.h>
#include <subdev/mmu.h>
#include <subdev/timer.h>
diff --git a/drm/nouveau/nvkm/engine/fifo/nv04.c b/drm/nouveau/nvkm/engine/fifo/nv04.c
index d1ad3fa72..e6f04e871 100644
--- a/drm/nouveau/nvkm/engine/fifo/nv04.c
+++ b/drm/nouveau/nvkm/engine/fifo/nv04.c
@@ -32,8 +32,8 @@
#include <subdev/timer.h>
#include <engine/sw.h>
-static struct ramfc_desc
-nv04_ramfc[] = {
+static const struct nv04_fifo_ramfc
+nv04_fifo_ramfc[] = {
{ 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
{ 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
{ 16, 0, 0x08, 0, NV04_PFIFO_CACHE1_DMA_INSTANCE },
@@ -46,10 +46,10 @@ nv04_ramfc[] = {
};
void
-nv04_fifo_pause(struct nvkm_fifo *obj, unsigned long *pflags)
+nv04_fifo_pause(struct nvkm_fifo *base, unsigned long *pflags)
__acquires(fifo->base.lock)
{
- struct nv04_fifo *fifo = container_of(obj, typeof(*fifo), base);
+ struct nv04_fifo *fifo = nv04_fifo(base);
struct nvkm_device *device = fifo->base.engine.subdev.device;
unsigned long flags;
@@ -82,10 +82,10 @@ __acquires(fifo->base.lock)
}
void
-nv04_fifo_start(struct nvkm_fifo *obj, unsigned long *pflags)
+nv04_fifo_start(struct nvkm_fifo *base, unsigned long *pflags)
__releases(fifo->base.lock)
{
- struct nv04_fifo *fifo = container_of(obj, typeof(*fifo), base);
+ struct nv04_fifo *fifo = nv04_fifo(base);
struct nvkm_device *device = fifo->base.engine.subdev.device;
unsigned long flags = *pflags;
@@ -236,10 +236,11 @@ nv04_fifo_dma_pusher(struct nv04_fifo *fifo, u32 chid)
}
void
-nv04_fifo_intr(struct nvkm_subdev *subdev)
+nv04_fifo_intr(struct nvkm_fifo *base)
{
+ struct nv04_fifo *fifo = nv04_fifo(base);
+ struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
struct nvkm_device *device = subdev->device;
- struct nv04_fifo *fifo = (void *)subdev;
u32 mask = nvkm_rd32(device, NV03_PFIFO_INTR_EN_0);
u32 stat = nvkm_rd32(device, NV03_PFIFO_INTR_0) & mask;
u32 reassign, chid, get, sem;
@@ -293,20 +294,15 @@ nv04_fifo_intr(struct nvkm_subdev *subdev)
nvkm_wr32(device, NV03_PFIFO_CACHES, reassign);
}
-int
-nv04_fifo_init(struct nvkm_object *object)
+void
+nv04_fifo_init(struct nvkm_fifo *base)
{
- struct nv04_fifo *fifo = (void *)object;
+ struct nv04_fifo *fifo = nv04_fifo(base);
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_instmem *imem = device->imem;
struct nvkm_ramht *ramht = imem->ramht;
struct nvkm_memory *ramro = imem->ramro;
struct nvkm_memory *ramfc = imem->ramfc;
- int ret;
-
- ret = nvkm_fifo_init(&fifo->base);
- if (ret)
- return ret;
nvkm_wr32(device, NV04_PFIFO_DELAY_0, 0x000000ff);
nvkm_wr32(device, NV04_PFIFO_DMA_TIMESLICE, 0x0101ffff);
@@ -325,54 +321,44 @@ nv04_fifo_init(struct nvkm_object *object)
nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH0, 1);
nvkm_wr32(device, NV04_PFIFO_CACHE1_PULL0, 1);
nvkm_wr32(device, NV03_PFIFO_CACHES, 1);
- return 0;
}
-void
-nv04_fifo_dtor(struct nvkm_object *object)
-{
- struct nv04_fifo *fifo = (void *)object;
- nvkm_fifo_destroy(&fifo->base);
-}
-
-static const struct nvkm_fifo_func
-nv04_fifo_func = {
- .chan = {
- &nv04_fifo_dma_oclass,
- NULL
- },
-};
-
-static int
-nv04_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
+int
+nv04_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device,
+ int index, int nr, const struct nv04_fifo_ramfc *ramfc,
+ struct nvkm_fifo **pfifo)
{
struct nv04_fifo *fifo;
int ret;
- ret = nvkm_fifo_create(parent, engine, oclass, 0, 15, &fifo);
- *pobject = nv_object(fifo);
+ if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
+ return -ENOMEM;
+ fifo->ramfc = ramfc;
+ *pfifo = &fifo->base;
+
+ ret = nvkm_fifo_ctor(func, device, index, nr, &fifo->base);
if (ret)
return ret;
- fifo->base.func = &nv04_fifo_func;
-
- nv_subdev(fifo)->unit = 0x00000100;
- nv_subdev(fifo)->intr = nv04_fifo_intr;
- fifo->base.pause = nv04_fifo_pause;
- fifo->base.start = nv04_fifo_start;
- fifo->ramfc_desc = nv04_ramfc;
+ set_bit(nr - 1, fifo->base.mask); /* inactive channel */
return 0;
}
-struct nvkm_oclass *
-nv04_fifo_oclass = &(struct nvkm_oclass) {
- .handle = NV_ENGINE(FIFO, 0x04),
- .ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv04_fifo_ctor,
- .dtor = nv04_fifo_dtor,
- .init = nv04_fifo_init,
- .fini = _nvkm_fifo_fini,
+static const struct nvkm_fifo_func
+nv04_fifo = {
+ .init = nv04_fifo_init,
+ .intr = nv04_fifo_intr,
+ .pause = nv04_fifo_pause,
+ .start = nv04_fifo_start,
+ .chan = {
+ &nv04_fifo_dma_oclass,
+ NULL
},
};
+
+int
+nv04_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
+{
+ return nv04_fifo_new_(&nv04_fifo, device, index, 16,
+ nv04_fifo_ramfc, pfifo);
+}
diff --git a/drm/nouveau/nvkm/engine/fifo/nv04.h b/drm/nouveau/nvkm/engine/fifo/nv04.h
index c33dc56f8..03f60004b 100644
--- a/drm/nouveau/nvkm/engine/fifo/nv04.h
+++ b/drm/nouveau/nvkm/engine/fifo/nv04.h
@@ -3,7 +3,7 @@
#define nv04_fifo(p) container_of((p), struct nv04_fifo, base)
#include "priv.h"
-struct ramfc_desc {
+struct nv04_fifo_ramfc {
unsigned bits:6;
unsigned ctxs:5;
unsigned ctxp:8;
@@ -13,9 +13,11 @@ struct ramfc_desc {
struct nv04_fifo {
struct nvkm_fifo base;
- struct ramfc_desc *ramfc_desc;
+ const struct nv04_fifo_ramfc *ramfc;
};
-void nv04_fifo_dtor(struct nvkm_object *);
-int nv04_fifo_init(struct nvkm_object *);
+int nv04_fifo_new_(const struct nvkm_fifo_func *, struct nvkm_device *,
+ int index, int nr, const struct nv04_fifo_ramfc *,
+ struct nvkm_fifo **);
+void nv04_fifo_init(struct nvkm_fifo *);
#endif
diff --git a/drm/nouveau/nvkm/engine/fifo/nv10.c b/drm/nouveau/nvkm/engine/fifo/nv10.c
index d7fab9598..f9a87deb2 100644
--- a/drm/nouveau/nvkm/engine/fifo/nv10.c
+++ b/drm/nouveau/nvkm/engine/fifo/nv10.c
@@ -25,8 +25,8 @@
#include "channv04.h"
#include "regsnv04.h"
-static struct ramfc_desc
-nv10_ramfc[] = {
+static const struct nv04_fifo_ramfc
+nv10_fifo_ramfc[] = {
{ 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
{ 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
{ 32, 0, 0x08, 0, NV10_PFIFO_CACHE1_REF_CNT },
@@ -40,43 +40,20 @@ nv10_ramfc[] = {
};
static const struct nvkm_fifo_func
-nv10_fifo_func = {
+nv10_fifo = {
+ .init = nv04_fifo_init,
+ .intr = nv04_fifo_intr,
+ .pause = nv04_fifo_pause,
+ .start = nv04_fifo_start,
.chan = {
&nv10_fifo_dma_oclass,
NULL
},
};
-static int
-nv10_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
+int
+nv10_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
{
- struct nv04_fifo *fifo;
- int ret;
-
- ret = nvkm_fifo_create(parent, engine, oclass, 0, 31, &fifo);
- *pobject = nv_object(fifo);
- if (ret)
- return ret;
-
- fifo->base.func = &nv10_fifo_func;
-
- nv_subdev(fifo)->unit = 0x00000100;
- nv_subdev(fifo)->intr = nv04_fifo_intr;
- fifo->base.pause = nv04_fifo_pause;
- fifo->base.start = nv04_fifo_start;
- fifo->ramfc_desc = nv10_ramfc;
- return 0;
+ return nv04_fifo_new_(&nv10_fifo, device, index, 32,
+ nv10_fifo_ramfc, pfifo);
}
-
-struct nvkm_oclass *
-nv10_fifo_oclass = &(struct nvkm_oclass) {
- .handle = NV_ENGINE(FIFO, 0x10),
- .ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv10_fifo_ctor,
- .dtor = nv04_fifo_dtor,
- .init = nv04_fifo_init,
- .fini = _nvkm_fifo_fini,
- },
-};
diff --git a/drm/nouveau/nvkm/engine/fifo/nv17.c b/drm/nouveau/nvkm/engine/fifo/nv17.c
index a8e28fc24..f6d383a21 100644
--- a/drm/nouveau/nvkm/engine/fifo/nv17.c
+++ b/drm/nouveau/nvkm/engine/fifo/nv17.c
@@ -28,8 +28,8 @@
#include <core/ramht.h>
#include <subdev/instmem.h>
-static struct ramfc_desc
-nv17_ramfc[] = {
+static const struct nv04_fifo_ramfc
+nv17_fifo_ramfc[] = {
{ 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
{ 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
{ 32, 0, 0x08, 0, NV10_PFIFO_CACHE1_REF_CNT },
@@ -47,20 +47,15 @@ nv17_ramfc[] = {
{}
};
-static int
-nv17_fifo_init(struct nvkm_object *object)
+static void
+nv17_fifo_init(struct nvkm_fifo *base)
{
- struct nv04_fifo *fifo = (void *)object;
+ struct nv04_fifo *fifo = nv04_fifo(base);
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_instmem *imem = device->imem;
struct nvkm_ramht *ramht = imem->ramht;
struct nvkm_memory *ramro = imem->ramro;
struct nvkm_memory *ramfc = imem->ramfc;
- int ret;
-
- ret = nvkm_fifo_init(&fifo->base);
- if (ret)
- return ret;
nvkm_wr32(device, NV04_PFIFO_DELAY_0, 0x000000ff);
nvkm_wr32(device, NV04_PFIFO_DMA_TIMESLICE, 0x0101ffff);
@@ -80,47 +75,23 @@ nv17_fifo_init(struct nvkm_object *object)
nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH0, 1);
nvkm_wr32(device, NV04_PFIFO_CACHE1_PULL0, 1);
nvkm_wr32(device, NV03_PFIFO_CACHES, 1);
- return 0;
}
static const struct nvkm_fifo_func
-nv17_fifo_func = {
+nv17_fifo = {
+ .init = nv17_fifo_init,
+ .intr = nv04_fifo_intr,
+ .pause = nv04_fifo_pause,
+ .start = nv04_fifo_start,
.chan = {
&nv17_fifo_dma_oclass,
NULL
},
};
-static int
-nv17_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
+int
+nv17_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
{
- struct nv04_fifo *fifo;
- int ret;
-
- ret = nvkm_fifo_create(parent, engine, oclass, 0, 31, &fifo);
- *pobject = nv_object(fifo);
- if (ret)
- return ret;
-
- fifo->base.func = &nv17_fifo_func;
-
- nv_subdev(fifo)->unit = 0x00000100;
- nv_subdev(fifo)->intr = nv04_fifo_intr;
- fifo->base.pause = nv04_fifo_pause;
- fifo->base.start = nv04_fifo_start;
- fifo->ramfc_desc = nv17_ramfc;
- return 0;
+ return nv04_fifo_new_(&nv17_fifo, device, index, 32,
+ nv17_fifo_ramfc, pfifo);
}
-
-struct nvkm_oclass *
-nv17_fifo_oclass = &(struct nvkm_oclass) {
- .handle = NV_ENGINE(FIFO, 0x17),
- .ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv17_fifo_ctor,
- .dtor = nv04_fifo_dtor,
- .init = nv17_fifo_init,
- .fini = _nvkm_fifo_fini,
- },
-};
diff --git a/drm/nouveau/nvkm/engine/fifo/nv40.c b/drm/nouveau/nvkm/engine/fifo/nv40.c
index aca146377..8c7ba3276 100644
--- a/drm/nouveau/nvkm/engine/fifo/nv40.c
+++ b/drm/nouveau/nvkm/engine/fifo/nv40.c
@@ -29,8 +29,8 @@
#include <subdev/fb.h>
#include <subdev/instmem.h>
-static struct ramfc_desc
-nv40_ramfc[] = {
+static const struct nv04_fifo_ramfc
+nv40_fifo_ramfc[] = {
{ 32, 0, 0x00, 0, NV04_PFIFO_CACHE1_DMA_PUT },
{ 32, 0, 0x04, 0, NV04_PFIFO_CACHE1_DMA_GET },
{ 32, 0, 0x08, 0, NV10_PFIFO_CACHE1_REF_CNT },
@@ -56,21 +56,16 @@ nv40_ramfc[] = {
{}
};
-static int
-nv40_fifo_init(struct nvkm_object *object)
+static void
+nv40_fifo_init(struct nvkm_fifo *base)
{
- struct nv04_fifo *fifo = (void *)object;
+ struct nv04_fifo *fifo = nv04_fifo(base);
struct nvkm_device *device = fifo->base.engine.subdev.device;
struct nvkm_fb *fb = device->fb;
struct nvkm_instmem *imem = device->imem;
struct nvkm_ramht *ramht = imem->ramht;
struct nvkm_memory *ramro = imem->ramro;
struct nvkm_memory *ramfc = imem->ramfc;
- int ret;
-
- ret = nvkm_fifo_init(&fifo->base);
- if (ret)
- return ret;
nvkm_wr32(device, 0x002040, 0x000000ff);
nvkm_wr32(device, 0x002044, 0x2101ffff);
@@ -81,7 +76,7 @@ nv40_fifo_init(struct nvkm_object *object)
(ramht->gpuobj->addr >> 8));
nvkm_wr32(device, NV03_PFIFO_RAMRO, nvkm_memory_addr(ramro) >> 8);
- switch (nv_device(fifo)->chipset) {
+ switch (device->chipset) {
case 0x47:
case 0x49:
case 0x4b:
@@ -110,47 +105,23 @@ nv40_fifo_init(struct nvkm_object *object)
nvkm_wr32(device, NV03_PFIFO_CACHE1_PUSH0, 1);
nvkm_wr32(device, NV04_PFIFO_CACHE1_PULL0, 1);
nvkm_wr32(device, NV03_PFIFO_CACHES, 1);
- return 0;
}
static const struct nvkm_fifo_func
-nv40_fifo_func = {
+nv40_fifo = {
+ .init = nv40_fifo_init,
+ .intr = nv04_fifo_intr,
+ .pause = nv04_fifo_pause,
+ .start = nv04_fifo_start,
.chan = {
&nv40_fifo_dma_oclass,
NULL
},
};
-static int
-nv40_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
+int
+nv40_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
{
- struct nv04_fifo *fifo;
- int ret;
-
- ret = nvkm_fifo_create(parent, engine, oclass, 0, 31, &fifo);
- *pobject = nv_object(fifo);
- if (ret)
- return ret;
-
- fifo->base.func = &nv40_fifo_func;
-
- nv_subdev(fifo)->unit = 0x00000100;
- nv_subdev(fifo)->intr = nv04_fifo_intr;
- fifo->base.pause = nv04_fifo_pause;
- fifo->base.start = nv04_fifo_start;
- fifo->ramfc_desc = nv40_ramfc;
- return 0;
+ return nv04_fifo_new_(&nv40_fifo, device, index, 32,
+ nv40_fifo_ramfc, pfifo);
}
-
-struct nvkm_oclass *
-nv40_fifo_oclass = &(struct nvkm_oclass) {
- .handle = NV_ENGINE(FIFO, 0x40),
- .ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv40_fifo_ctor,
- .dtor = nv04_fifo_dtor,
- .init = nv40_fifo_init,
- .fini = _nvkm_fifo_fini,
- },
-};
diff --git a/drm/nouveau/nvkm/engine/fifo/nv50.c b/drm/nouveau/nvkm/engine/fifo/nv50.c
index ad653e9c4..66eb12c2b 100644
--- a/drm/nouveau/nvkm/engine/fifo/nv50.c
+++ b/drm/nouveau/nvkm/engine/fifo/nv50.c
@@ -24,6 +24,8 @@
#include "nv50.h"
#include "channv50.h"
+#include <core/gpuobj.h>
+
static void
nv50_fifo_runlist_update_locked(struct nv50_fifo *fifo)
{
@@ -49,22 +51,34 @@ nv50_fifo_runlist_update_locked(struct nv50_fifo *fifo)
void
nv50_fifo_runlist_update(struct nv50_fifo *fifo)
{
- mutex_lock(&nv_subdev(fifo)->mutex);
+ mutex_lock(&fifo->base.engine.subdev.mutex);
nv50_fifo_runlist_update_locked(fifo);
- mutex_unlock(&nv_subdev(fifo)->mutex);
+ mutex_unlock(&fifo->base.engine.subdev.mutex);
}
int
-nv50_fifo_init(struct nvkm_object *object)
+nv50_fifo_oneinit(struct nvkm_fifo *base)
{
- struct nv50_fifo *fifo = (void *)object;
+ struct nv50_fifo *fifo = nv50_fifo(base);
struct nvkm_device *device = fifo->base.engine.subdev.device;
- int ret, i;
+ int ret;
- ret = nvkm_fifo_init(&fifo->base);
+ ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 128 * 4, 0x1000,
+ false, &fifo->runlist[0]);
if (ret)
return ret;
+ return nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 128 * 4, 0x1000,
+ false, &fifo->runlist[1]);
+}
+
+void
+nv50_fifo_init(struct nvkm_fifo *base)
+{
+ struct nv50_fifo *fifo = nv50_fifo(base);
+ struct nvkm_device *device = fifo->base.engine.subdev.device;
+ int i;
+
nvkm_mask(device, 0x000200, 0x00000100, 0x00000000);
nvkm_mask(device, 0x000200, 0x00000100, 0x00000100);
nvkm_wr32(device, 0x00250c, 0x6f3cfc34);
@@ -80,69 +94,54 @@ nv50_fifo_init(struct nvkm_object *object)
nvkm_wr32(device, 0x003200, 0x00000001);
nvkm_wr32(device, 0x003250, 0x00000001);
nvkm_wr32(device, 0x002500, 0x00000001);
- return 0;
}
-void
-nv50_fifo_dtor(struct nvkm_object *object)
+void *
+nv50_fifo_dtor(struct nvkm_fifo *base)
{
- struct nv50_fifo *fifo = (void *)object;
-
+ struct nv50_fifo *fifo = nv50_fifo(base);
nvkm_memory_del(&fifo->runlist[1]);
nvkm_memory_del(&fifo->runlist[0]);
-
- nvkm_fifo_destroy(&fifo->base);
+ return fifo;
}
-static const struct nvkm_fifo_func
-nv50_fifo_func = {
- .chan = {
- &nv50_fifo_dma_oclass,
- &nv50_fifo_gpfifo_oclass,
- NULL
- },
-};
-
-static int
-nv50_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
- struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
+int
+nv50_fifo_new_(const struct nvkm_fifo_func *func, struct nvkm_device *device,
+ int index, struct nvkm_fifo **pfifo)
{
- struct nvkm_device *device = (void *)parent;
struct nv50_fifo *fifo;
int ret;
- ret = nvkm_fifo_create(parent, engine, oclass, 1, 127, &fifo);
- *pobject = nv_object(fifo);
- if (ret)
- return ret;
-
- fifo->base.func = &nv50_fifo_func;
-
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 128 * 4, 0x1000,
- false, &fifo->runlist[0]);
- if (ret)
- return ret;
+ if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
+ return -ENOMEM;
+ *pfifo = &fifo->base;
- ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 128 * 4, 0x1000,
- false, &fifo->runlist[1]);
+ ret = nvkm_fifo_ctor(func, device, index, 128, &fifo->base);
if (ret)
return ret;
- nv_subdev(fifo)->unit = 0x00000100;
- nv_subdev(fifo)->intr = nv04_fifo_intr;
- fifo->base.pause = nv04_fifo_pause;
- fifo->base.start = nv04_fifo_start;
+ set_bit(0, fifo->base.mask); /* PIO channel */
+ set_bit(127, fifo->base.mask); /* inactive channel */
return 0;
}
-struct nvkm_oclass *
-nv50_fifo_oclass = &(struct nvkm_oclass) {
- .handle = NV_ENGINE(FIFO, 0x50),
- .ofuncs = &(struct nvkm_ofuncs) {
- .ctor = nv50_fifo_ctor,
- .dtor = nv50_fifo_dtor,
- .init = nv50_fifo_init,
- .fini = _nvkm_fifo_fini,
+static const struct nvkm_fifo_func
+nv50_fifo = {
+ .dtor = nv50_fifo_dtor,
+ .oneinit = nv50_fifo_oneinit,
+ .init = nv50_fifo_init,
+ .intr = nv04_fifo_intr,
+ .pause = nv04_fifo_pause,
+ .start = nv04_fifo_start,
+ .chan = {
+ &nv50_fifo_dma_oclass,
+ &nv50_fifo_gpfifo_oclass,
+ NULL
},
};
+
+int
+nv50_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
+{
+ return nv50_fifo_new_(&nv50_fifo, device, index, pfifo);
+}
diff --git a/drm/nouveau/nvkm/engine/fifo/nv50.h b/drm/nouveau/nvkm/engine/fifo/nv50.h
index a7d5dba12..8ab53948c 100644
--- a/drm/nouveau/nvkm/engine/fifo/nv50.h
+++ b/drm/nouveau/nvkm/engine/fifo/nv50.h
@@ -9,7 +9,11 @@ struct nv50_fifo {
int cur_runlist;
};
-void nv50_fifo_dtor(struct nvkm_object *);
-int nv50_fifo_init(struct nvkm_object *);
+int nv50_fifo_new_(const struct nvkm_fifo_func *, struct nvkm_device *,
+ int index, struct nvkm_fifo **);
+
+void *nv50_fifo_dtor(struct nvkm_fifo *);
+int nv50_fifo_oneinit(struct nvkm_fifo *);
+void nv50_fifo_init(struct nvkm_fifo *);
void nv50_fifo_runlist_update(struct nv50_fifo *);
#endif
diff --git a/drm/nouveau/nvkm/engine/fifo/priv.h b/drm/nouveau/nvkm/engine/fifo/priv.h
index a30d160f3..cb1432e9b 100644
--- a/drm/nouveau/nvkm/engine/fifo/priv.h
+++ b/drm/nouveau/nvkm/engine/fifo/priv.h
@@ -1,7 +1,26 @@
#ifndef __NVKM_FIFO_PRIV_H__
#define __NVKM_FIFO_PRIV_H__
+#define nvkm_fifo(p) container_of((p), struct nvkm_fifo, engine)
#include <engine/fifo.h>
+int nvkm_fifo_ctor(const struct nvkm_fifo_func *, struct nvkm_device *,
+ int index, int nr, struct nvkm_fifo *);
+void nvkm_fifo_uevent(struct nvkm_fifo *);
+
+struct nvkm_fifo_func {
+ void *(*dtor)(struct nvkm_fifo *);
+ int (*oneinit)(struct nvkm_fifo *);
+ void (*init)(struct nvkm_fifo *);
+ void (*fini)(struct nvkm_fifo *);
+ void (*intr)(struct nvkm_fifo *);
+ void (*pause)(struct nvkm_fifo *, unsigned long *);
+ void (*start)(struct nvkm_fifo *, unsigned long *);
+ void (*uevent_init)(struct nvkm_fifo *);
+ void (*uevent_fini)(struct nvkm_fifo *);
+ const struct nvkm_fifo_chan_oclass *chan[];
+};
+
+void nv04_fifo_intr(struct nvkm_fifo *);
void nv04_fifo_pause(struct nvkm_fifo *, unsigned long *);
void nv04_fifo_start(struct nvkm_fifo *, unsigned long *);
#endif