Simplifies the GPU-specific code, completing the switch to newer HALs.
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Reviewed-by: Lyude Paul <lyude@redhat.com>
nvkm_chan_event = {
};
-struct nvkm_fifo_chan_object {
- struct nvkm_oproxy oproxy;
- struct nvkm_fifo_chan *chan;
- int hash;
-};
-
-static void
-nvkm_fifo_chan_child_del(struct nvkm_oproxy *base)
-{
- struct nvkm_fifo_chan_object *object =
- container_of(base, typeof(*object), oproxy);
- struct nvkm_fifo_chan *chan = object->chan;
-
- if (chan->func->object_dtor)
- chan->func->object_dtor(chan, object->hash);
-}
-
-static const struct nvkm_oproxy_func
-nvkm_fifo_chan_child_func = {
- .dtor[0] = nvkm_fifo_chan_child_del,
-};
-
-int
-nvkm_fifo_chan_child_new(const struct nvkm_oclass *oclass, void *data, u32 size,
- struct nvkm_object **pobject)
-{
- struct nvkm_engine *engine = oclass->engine;
- struct nvkm_fifo_chan *chan = nvkm_fifo_chan(oclass->parent);
- struct nvkm_ectx *engn = nvkm_list_find(engn, &chan->cgrp->ectxs, head,
- engn->engn->engine == engine);
- struct nvkm_fifo_chan_object *object;
- int ret = 0;
-
- if (!(object = kzalloc(sizeof(*object), GFP_KERNEL)))
- return -ENOMEM;
- nvkm_oproxy_ctor(&nvkm_fifo_chan_child_func, oclass, &object->oproxy);
- object->chan = chan;
- *pobject = &object->oproxy.base;
-
-
- ret = oclass->base.ctor(&(const struct nvkm_oclass) {
- .base = oclass->base,
- .engn = oclass->engn,
- .handle = oclass->handle,
- .object = oclass->object,
- .client = oclass->client,
- .parent = engn->object ?
- engn->object :
- oclass->parent,
- .engine = engine,
- }, data, size, &object->oproxy.object);
- if (ret)
- return ret;
-
- if (chan->func->object_ctor) {
- object->hash =
- chan->func->object_ctor(chan, object->oproxy.object);
- if (object->hash < 0)
- return object->hash;
- }
-
- return 0;
-}
-
void
nvkm_chan_cctx_bind(struct nvkm_chan *chan, struct nvkm_engn *engn, struct nvkm_cctx *cctx)
{
*func = *fifo->func->chan.func;
func->dtor = fn->dtor;
- func->object_ctor = fn->object_ctor;
- func->object_dtor = fn->object_dtor;
chan->func = func;
chan->id = -1;
u32 (*doorbell_handle)(struct nvkm_chan *);
void *(*dtor)(struct nvkm_fifo_chan *);
- int (*object_ctor)(struct nvkm_fifo_chan *, struct nvkm_object *);
- void (*object_dtor)(struct nvkm_fifo_chan *, int);
};
int nvkm_fifo_chan_ctor(const struct nvkm_fifo_chan_func *, struct nvkm_fifo *,
#define CHAN_PRINT(c,l,p,f,a...) CGRP_PRINT((c)->cgrp, l, p, "%04x:"f, (c)->id, ##a)
#define CHAN_ERROR(c,f,a...) CHAN_PRCLI((c), ERROR, err, " "f"\n", ##a)
#define CHAN_TRACE(c,f,a...) CHAN_PRINT((c), TRACE, info, " "f"\n", ##a)
-
-int nvkm_fifo_chan_child_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
#endif
#include <nvif/cl826e.h>
-static int
-g84_fifo_chan_object_ctor(struct nvkm_fifo_chan *base,
- struct nvkm_object *object)
-{
- struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
- u32 handle = object->handle;
- u32 context;
-
- switch (object->engine->subdev.type) {
- case NVKM_ENGINE_DMAOBJ:
- case NVKM_ENGINE_SW : context = 0x00000000; break;
- case NVKM_ENGINE_GR : context = 0x00100000; break;
- case NVKM_ENGINE_MPEG :
- case NVKM_ENGINE_MSPPP : context = 0x00200000; break;
- case NVKM_ENGINE_ME :
- case NVKM_ENGINE_CE : context = 0x00300000; break;
- case NVKM_ENGINE_VP :
- case NVKM_ENGINE_MSPDEC: context = 0x00400000; break;
- case NVKM_ENGINE_CIPHER:
- case NVKM_ENGINE_SEC :
- case NVKM_ENGINE_VIC : context = 0x00500000; break;
- case NVKM_ENGINE_BSP :
- case NVKM_ENGINE_MSVLD : context = 0x00600000; break;
- default:
- WARN_ON(1);
- return -EINVAL;
- }
-
- return nvkm_ramht_insert(chan->ramht, object, 0, 4, handle, context);
-}
-
static const struct nvkm_fifo_chan_func
g84_fifo_chan_func = {
.dtor = nv50_fifo_chan_dtor,
- .object_ctor = g84_fifo_chan_object_ctor,
- .object_dtor = nv50_fifo_chan_object_dtor,
};
int
BIT(G84_FIFO_ENGN_MSVLD) |
BIT(G84_FIFO_ENGN_DMA),
0, 0xc00000, 0x2000, oclass, &chan->base);
- chan->fifo = fifo;
return ret;
}
struct gf100_fifo_chan {
struct nvkm_fifo_chan base;
- struct gf100_fifo *fifo;
#define GF100_FIFO_ENGN_GR 0
#define GF100_FIFO_ENGN_MSPDEC 1
struct gk104_fifo_chan {
struct nvkm_fifo_chan base;
- struct gk104_fifo *fifo;
int runl;
#define GK104_FIFO_ENGN_SW 15
struct nv04_fifo_chan {
struct nvkm_fifo_chan base;
- struct nv04_fifo *fifo;
#define NV04_FIFO_ENGN_SW 0
#define NV04_FIFO_ENGN_GR 1
#define NV04_FIFO_ENGN_MPEG 2
extern const struct nvkm_fifo_chan_func nv04_fifo_dma_func;
void *nv04_fifo_dma_dtor(struct nvkm_fifo_chan *);
-void nv04_fifo_dma_object_dtor(struct nvkm_fifo_chan *, int);
extern const struct nvkm_fifo_chan_oclass nv04_fifo_dma_oclass;
extern const struct nvkm_fifo_chan_oclass nv10_fifo_dma_oclass;
#include <subdev/mmu.h>
#include <subdev/timer.h>
-void
-nv50_fifo_chan_object_dtor(struct nvkm_fifo_chan *base, int cookie)
-{
- struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
- nvkm_ramht_remove(chan->ramht, cookie);
-}
-
-static int
-nv50_fifo_chan_object_ctor(struct nvkm_fifo_chan *base,
- struct nvkm_object *object)
-{
- struct nv50_fifo_chan *chan = nv50_fifo_chan(base);
- u32 handle = object->handle;
- u32 context;
-
- switch (object->engine->subdev.type) {
- case NVKM_ENGINE_DMAOBJ:
- case NVKM_ENGINE_SW : context = 0x00000000; break;
- case NVKM_ENGINE_GR : context = 0x00100000; break;
- case NVKM_ENGINE_MPEG : context = 0x00200000; break;
- default:
- WARN_ON(1);
- return -EINVAL;
- }
-
- return nvkm_ramht_insert(chan->ramht, object, 0, 4, handle, context);
-}
-
void *
nv50_fifo_chan_dtor(struct nvkm_fifo_chan *base)
{
static const struct nvkm_fifo_chan_func
nv50_fifo_chan_func = {
.dtor = nv50_fifo_chan_dtor,
- .object_ctor = nv50_fifo_chan_object_ctor,
- .object_dtor = nv50_fifo_chan_object_dtor,
};
int
BIT(NV50_FIFO_ENGN_MPEG) |
BIT(NV50_FIFO_ENGN_DMA),
0, 0xc00000, 0x2000, oclass, &chan->base);
- chan->fifo = fifo;
return ret;
}
#include "nv50.h"
struct nv50_fifo_chan {
- struct nv50_fifo *fifo;
struct nvkm_fifo_chan base;
- struct nvkm_ramht *ramht;
-
#define NV50_FIFO_ENGN_SW 0
#define NV50_FIFO_ENGN_GR 1
#define NV50_FIFO_ENGN_MPEG 2
int nv50_fifo_chan_ctor(struct nv50_fifo *, u64 vmm, u64 push,
const struct nvkm_oclass *, struct nv50_fifo_chan *);
void *nv50_fifo_chan_dtor(struct nvkm_fifo_chan *);
-void nv50_fifo_chan_object_dtor(struct nvkm_fifo_chan *, int);
int g84_fifo_chan_ctor(struct nv50_fifo *, u64 vmm, u64 push,
const struct nvkm_oclass *, struct nv50_fifo_chan *);
#include <nvif/cl006b.h>
#include <nvif/unpack.h>
-void
-nv04_fifo_dma_object_dtor(struct nvkm_fifo_chan *base, int cookie)
-{
- struct nv04_fifo_chan *chan = nv04_fifo_chan(base);
- struct nvkm_instmem *imem = chan->fifo->base.engine.subdev.device->imem;
-
- mutex_lock(&chan->fifo->base.mutex);
- nvkm_ramht_remove(imem->ramht, cookie);
- mutex_unlock(&chan->fifo->base.mutex);
-}
-
-static int
-nv04_fifo_dma_object_ctor(struct nvkm_fifo_chan *base,
- struct nvkm_object *object)
-{
- struct nv04_fifo_chan *chan = nv04_fifo_chan(base);
- struct nvkm_instmem *imem = chan->fifo->base.engine.subdev.device->imem;
- u32 context = 0x80000000 | chan->base.chid << 24;
- u32 handle = object->handle;
- int hash;
-
- switch (object->engine->subdev.type) {
- case NVKM_ENGINE_DMAOBJ:
- case NVKM_ENGINE_SW : context |= 0x00000000; break;
- case NVKM_ENGINE_GR : context |= 0x00010000; break;
- case NVKM_ENGINE_MPEG : context |= 0x00020000; break;
- default:
- WARN_ON(1);
- return -EINVAL;
- }
-
- mutex_lock(&chan->fifo->base.mutex);
- hash = nvkm_ramht_insert(imem->ramht, object, chan->base.chid, 4,
- handle, context);
- mutex_unlock(&chan->fifo->base.mutex);
- return hash;
-}
-
void *
nv04_fifo_dma_dtor(struct nvkm_fifo_chan *base)
{
const struct nvkm_fifo_chan_func
nv04_fifo_dma_func = {
.dtor = nv04_fifo_dma_dtor,
- .object_ctor = nv04_fifo_dma_object_ctor,
- .object_dtor = nv04_fifo_dma_object_dtor,
};
static int
BIT(NV04_FIFO_ENGN_GR) |
BIT(NV04_FIFO_ENGN_DMA),
0, 0x800000, 0x10000, oclass, &chan->base);
- chan->fifo = fifo;
if (ret)
return ret;
BIT(NV04_FIFO_ENGN_GR) |
BIT(NV04_FIFO_ENGN_DMA),
0, 0x800000, 0x10000, oclass, &chan->base);
- chan->fifo = fifo;
if (ret)
return ret;
BIT(NV04_FIFO_ENGN_MPEG) | /* NV31- */
BIT(NV04_FIFO_ENGN_DMA),
0, 0x800000, 0x10000, oclass, &chan->base);
- chan->fifo = fifo;
if (ret)
return ret;
#include <nvif/cl006b.h>
#include <nvif/unpack.h>
-static int
-nv40_fifo_dma_object_ctor(struct nvkm_fifo_chan *base,
- struct nvkm_object *object)
-{
- struct nv04_fifo_chan *chan = nv04_fifo_chan(base);
- struct nvkm_instmem *imem = chan->fifo->base.engine.subdev.device->imem;
- u32 context = chan->base.chid << 23;
- u32 handle = object->handle;
- int hash;
-
- switch (object->engine->subdev.type) {
- case NVKM_ENGINE_DMAOBJ:
- case NVKM_ENGINE_SW : context |= 0x00000000; break;
- case NVKM_ENGINE_GR : context |= 0x00100000; break;
- case NVKM_ENGINE_MPEG : context |= 0x00200000; break;
- default:
- WARN_ON(1);
- return -EINVAL;
- }
-
- mutex_lock(&chan->fifo->base.mutex);
- hash = nvkm_ramht_insert(imem->ramht, object, chan->base.chid, 4,
- handle, context);
- mutex_unlock(&chan->fifo->base.mutex);
- return hash;
-}
-
static const struct nvkm_fifo_chan_func
nv40_fifo_dma_func = {
- .dtor = nv04_fifo_dma_dtor,
- .object_ctor = nv40_fifo_dma_object_ctor,
- .object_dtor = nv04_fifo_dma_object_dtor,
};
static int
BIT(NV04_FIFO_ENGN_MPEG) |
BIT(NV04_FIFO_ENGN_DMA),
0, 0xc00000, 0x1000, oclass, &chan->base);
- chan->fifo = fifo;
if (ret)
return ret;
if (ret)
return ret;
- nv50_fifo_chan(chan)->ramht = chan->ramht;
-
nvkm_kmap(chan->ramfc);
nvkm_wo32(chan->ramfc, 0x3c, 0x403f6078);
nvkm_wo32(chan->ramfc, 0x44, 0x01003fff);
const struct nvkm_engn_func
g84_engn = {
.bind = g84_ectx_bind,
+ .ramht_add = nv50_eobj_ramht_add,
+ .ramht_del = nv50_eobj_ramht_del,
};
static void
if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
return -ENOMEM;
*pobject = &chan->base.object;
- chan->fifo = fifo;
ret = nvkm_fifo_chan_ctor(&gf100_fifo_gpfifo_func, &fifo->base,
0x1000, 0x1000, true, args->v0.vmm, 0,
if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
return -ENOMEM;
*pobject = &chan->base.object;
- chan->fifo = fifo;
chan->runl = runlist;
ret = nvkm_fifo_chan_ctor(&gk104_fifo_gpfifo_func, &fifo->base,
if (!(chan = kzalloc(sizeof(*chan), GFP_KERNEL)))
return -ENOMEM;
*pobject = &chan->base.object;
- chan->fifo = fifo;
chan->runl = runlist;
ret = nvkm_fifo_chan_ctor(func, &fifo->base, 0x1000, 0x1000, true, vmm,
nv04_cgrp = {
};
+void
+nv04_eobj_ramht_del(struct nvkm_chan *chan, int hash)
+{
+ struct nvkm_fifo *fifo = chan->cgrp->runl->fifo;
+ struct nvkm_instmem *imem = fifo->engine.subdev.device->imem;
+
+ mutex_lock(&fifo->mutex);
+ nvkm_ramht_remove(imem->ramht, hash);
+ mutex_unlock(&fifo->mutex);
+}
+
+static int
+nv04_eobj_ramht_add(struct nvkm_engn *engn, struct nvkm_object *eobj, struct nvkm_chan *chan)
+{
+ struct nvkm_fifo *fifo = chan->cgrp->runl->fifo;
+ struct nvkm_instmem *imem = fifo->engine.subdev.device->imem;
+ u32 context = 0x80000000 | chan->id << 24 | engn->id << 16;
+ int hash;
+
+ mutex_lock(&fifo->mutex);
+ hash = nvkm_ramht_insert(imem->ramht, eobj, chan->id, 4, eobj->handle, context);
+ mutex_unlock(&fifo->mutex);
+ return hash;
+}
+
const struct nvkm_engn_func
nv04_engn = {
+ .ramht_add = nv04_eobj_ramht_add,
+ .ramht_del = nv04_eobj_ramht_del,
};
void
.stop = nv04_chan_stop,
};
+static int
+nv40_eobj_ramht_add(struct nvkm_engn *engn, struct nvkm_object *eobj, struct nvkm_chan *chan)
+{
+ struct nvkm_fifo *fifo = chan->cgrp->runl->fifo;
+ struct nvkm_instmem *imem = fifo->engine.subdev.device->imem;
+ u32 context = chan->id << 23 | engn->id << 20;
+ int hash;
+
+ mutex_lock(&fifo->mutex);
+ hash = nvkm_ramht_insert(imem->ramht, eobj, chan->id, 4, eobj->handle, context);
+ mutex_unlock(&fifo->mutex);
+ return hash;
+}
+
static void
nv40_ectx_bind(struct nvkm_engn *engn, struct nvkm_cctx *cctx, struct nvkm_chan *chan)
{
static const struct nvkm_engn_func
nv40_engn = {
.bind = nv40_ectx_bind,
+ .ramht_add = nv40_eobj_ramht_add,
+ .ramht_del = nv04_eobj_ramht_del,
};
static const struct nvkm_engn_func
nv40_engn_sw = {
+ .ramht_add = nv40_eobj_ramht_add,
+ .ramht_del = nv04_eobj_ramht_del,
};
static void
#include <nvif/class.h>
+void
+nv50_eobj_ramht_del(struct nvkm_chan *chan, int hash)
+{
+ nvkm_ramht_remove(chan->ramht, hash);
+}
+
+int
+nv50_eobj_ramht_add(struct nvkm_engn *engn, struct nvkm_object *eobj, struct nvkm_chan *chan)
+{
+ return nvkm_ramht_insert(chan->ramht, eobj, 0, 4, eobj->handle, engn->id << 20);
+}
+
void
nv50_chan_stop(struct nvkm_chan *chan)
{
if (ret)
return ret;
- nv50_fifo_chan(chan)->ramht = chan->ramht;
-
nvkm_kmap(chan->ramfc);
nvkm_wo32(chan->ramfc, 0x3c, 0x403f6078);
nvkm_wo32(chan->ramfc, 0x44, 0x01003fff);
static const struct nvkm_engn_func
nv50_engn = {
.bind = nv50_ectx_bind,
+ .ramht_add = nv50_eobj_ramht_add,
+ .ramht_del = nv50_eobj_ramht_del,
};
const struct nvkm_engn_func
nv50_engn_sw = {
+ .ramht_add = nv50_eobj_ramht_add,
+ .ramht_del = nv50_eobj_ramht_del,
};
static bool
void nv04_chan_ramfc_clear(struct nvkm_chan *);
void nv04_chan_start(struct nvkm_chan *);
void nv04_chan_stop(struct nvkm_chan *);
+void nv04_eobj_ramht_del(struct nvkm_chan *, int);
int nv10_fifo_chid_nr(struct nvkm_fifo *);
void nv50_chan_start(struct nvkm_chan *);
void nv50_chan_stop(struct nvkm_chan *);
void nv50_chan_preempt(struct nvkm_chan *);
+int nv50_eobj_ramht_add(struct nvkm_engn *, struct nvkm_object *, struct nvkm_chan *);
+void nv50_eobj_ramht_del(struct nvkm_chan *, int);
extern const struct nvkm_event_func g84_fifo_nonstall;
extern const struct nvkm_engn_func g84_engn;
struct nvkm_cgrp;
struct nvkm_chan;
struct nvkm_memory;
+struct nvkm_object;
struct nvkm_vctx;
enum nvkm_subdev_type;
bool (*mmu_fault_triggered)(struct nvkm_engn *);
int (*ctor)(struct nvkm_engn *, struct nvkm_vctx *);
void (*bind)(struct nvkm_engn *, struct nvkm_cctx *, struct nvkm_chan *);
+ int (*ramht_add)(struct nvkm_engn *, struct nvkm_object *, struct nvkm_chan *);
+ void (*ramht_del)(struct nvkm_chan *, int hash);
} *func;
struct nvkm_runl *runl;
int id;
struct nvkm_oproxy oproxy;
struct nvkm_chan *chan;
struct nvkm_cctx *cctx;
+ int hash;
};
static int
nvkm_uchan_object_dtor(struct nvkm_oproxy *oproxy)
{
struct nvkm_uobj *uobj = container_of(oproxy, typeof(*uobj), oproxy);
+ struct nvkm_engn *engn;
if (!uobj->cctx)
return;
+ engn = uobj->cctx->vctx->ectx->engn;
+ if (engn->func->ramht_del)
+ engn->func->ramht_del(uobj->chan, uobj->hash);
+
nvkm_chan_cctx_put(uobj->chan, &uobj->cctx);
}
struct nvkm_cgrp *cgrp = chan->cgrp;
struct nvkm_engn *engn;
struct nvkm_uobj *uobj;
- struct nvkm_oclass _oclass;
int ret;
/* Lookup host engine state for target engine. */
return ret;
/* Allocate HW object. */
- _oclass = *oclass;
- _oclass.parent = &chan->object;
- return nvkm_fifo_chan_child_new(&_oclass, argv, argc, &uobj->oproxy.object);
+ ret = oclass->base.ctor(&(const struct nvkm_oclass) {
+ .base = oclass->base,
+ .engn = oclass->engn,
+ .handle = oclass->handle,
+ .object = oclass->object,
+ .client = oclass->client,
+ .parent = uobj->cctx->vctx->ectx->object ?: oclass->parent,
+ .engine = engn->engine,
+ }, argv, argc, &uobj->oproxy.object);
+ if (ret)
+ return ret;
+
+ if (engn->func->ramht_add) {
+ uobj->hash = engn->func->ramht_add(engn, uobj->oproxy.object, uobj->chan);
+ if (uobj->hash < 0)
+ return uobj->hash;
+ }
+
+ return 0;
}
static int