summaryrefslogtreecommitdiff
path: root/drm/nouveau/nvkm/engine/fifo/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drm/nouveau/nvkm/engine/fifo/base.c')
-rw-r--r--drm/nouveau/nvkm/engine/fifo/base.c128
1 files changed, 100 insertions, 28 deletions
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);
}