diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c | 128 |
1 files changed, 100 insertions, 28 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c index b693127d80e1..1fbbfbe6ca9c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/fifo/base.c +++ b/drivers/gpu/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); } |