|
@@ -24,75 +24,232 @@
|
|
|
#include <core/object.h>
|
|
|
#include <core/engine.h>
|
|
|
|
|
|
+int
|
|
|
+nvkm_object_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size)
|
|
|
+{
|
|
|
+ if (object->oclass) {
|
|
|
+ if (object->oclass->ofuncs->mthd)
|
|
|
+ return object->oclass->ofuncs->mthd(object, mthd, data, size);
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
+ if (likely(object->func->mthd))
|
|
|
+ return object->func->mthd(object, mthd, data, size);
|
|
|
+ return -ENODEV;
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+nvkm_object_ntfy(struct nvkm_object *object, u32 mthd,
|
|
|
+ struct nvkm_event **pevent)
|
|
|
+{
|
|
|
+ if (object->oclass) {
|
|
|
+ if (object->oclass->ofuncs->ntfy)
|
|
|
+ return object->oclass->ofuncs->ntfy(object, mthd, pevent);
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
+ if (likely(object->func->ntfy))
|
|
|
+ return object->func->ntfy(object, mthd, pevent);
|
|
|
+ return -ENODEV;
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+nvkm_object_map(struct nvkm_object *object, u64 *addr, u32 *size)
|
|
|
+{
|
|
|
+ if (object->oclass) {
|
|
|
+ if (object->oclass->ofuncs->map)
|
|
|
+ return object->oclass->ofuncs->map(object, addr, size);
|
|
|
+ return -ENODEV;
|
|
|
+ }
|
|
|
+ if (likely(object->func->map))
|
|
|
+ return object->func->map(object, addr, size);
|
|
|
+ return -ENODEV;
|
|
|
+}
|
|
|
+
|
|
|
int
|
|
|
nvkm_object_rd08(struct nvkm_object *object, u64 addr, u8 *data)
|
|
|
{
|
|
|
- const struct nvkm_oclass *oclass = object->oclass;
|
|
|
- if (oclass->ofuncs && oclass->ofuncs->rd08) {
|
|
|
- *data = oclass->ofuncs->rd08(object, addr);
|
|
|
- return 0;
|
|
|
+ if (object->oclass) {
|
|
|
+ if (object->oclass->ofuncs->rd08) {
|
|
|
+ *data = object->oclass->ofuncs->rd08(object, addr);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ *data = 0x00;
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
- *data = 0x00;
|
|
|
+ if (likely(object->func->rd08))
|
|
|
+ return object->func->rd08(object, addr, data);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
int
|
|
|
nvkm_object_rd16(struct nvkm_object *object, u64 addr, u16 *data)
|
|
|
{
|
|
|
- const struct nvkm_oclass *oclass = object->oclass;
|
|
|
- if (oclass->ofuncs && oclass->ofuncs->rd16) {
|
|
|
- *data = oclass->ofuncs->rd16(object, addr);
|
|
|
- return 0;
|
|
|
+ if (object->oclass) {
|
|
|
+ if (object->oclass->ofuncs->rd16) {
|
|
|
+ *data = object->oclass->ofuncs->rd16(object, addr);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ *data = 0x0000;
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
- *data = 0x0000;
|
|
|
+ if (likely(object->func->rd16))
|
|
|
+ return object->func->rd16(object, addr, data);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
int
|
|
|
nvkm_object_rd32(struct nvkm_object *object, u64 addr, u32 *data)
|
|
|
{
|
|
|
- const struct nvkm_oclass *oclass = object->oclass;
|
|
|
- if (oclass->ofuncs && oclass->ofuncs->rd32) {
|
|
|
- *data = oclass->ofuncs->rd32(object, addr);
|
|
|
- return 0;
|
|
|
+ if (object->oclass) {
|
|
|
+ if (object->oclass->ofuncs->rd32) {
|
|
|
+ *data = object->oclass->ofuncs->rd32(object, addr);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ *data = 0x00000000;
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
- *data = 0x0000;
|
|
|
+ if (likely(object->func->rd32))
|
|
|
+ return object->func->rd32(object, addr, data);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
int
|
|
|
nvkm_object_wr08(struct nvkm_object *object, u64 addr, u8 data)
|
|
|
{
|
|
|
- const struct nvkm_oclass *oclass = object->oclass;
|
|
|
- if (oclass->ofuncs && oclass->ofuncs->wr08) {
|
|
|
- oclass->ofuncs->wr08(object, addr, data);
|
|
|
- return 0;
|
|
|
+ if (object->oclass) {
|
|
|
+ if (object->oclass->ofuncs->wr08) {
|
|
|
+ object->oclass->ofuncs->wr08(object, addr, data);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
+ if (likely(object->func->wr08))
|
|
|
+ return object->func->wr08(object, addr, data);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
int
|
|
|
nvkm_object_wr16(struct nvkm_object *object, u64 addr, u16 data)
|
|
|
{
|
|
|
- const struct nvkm_oclass *oclass = object->oclass;
|
|
|
- if (oclass->ofuncs && oclass->ofuncs->wr16) {
|
|
|
- oclass->ofuncs->wr16(object, addr, data);
|
|
|
- return 0;
|
|
|
+ if (object->oclass) {
|
|
|
+ if (object->oclass->ofuncs->wr16) {
|
|
|
+ object->oclass->ofuncs->wr16(object, addr, data);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
+ if (likely(object->func->wr16))
|
|
|
+ return object->func->wr16(object, addr, data);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
int
|
|
|
nvkm_object_wr32(struct nvkm_object *object, u64 addr, u32 data)
|
|
|
{
|
|
|
- const struct nvkm_oclass *oclass = object->oclass;
|
|
|
- if (oclass->ofuncs && oclass->ofuncs->wr32) {
|
|
|
- oclass->ofuncs->wr32(object, addr, data);
|
|
|
- return 0;
|
|
|
+ if (object->oclass) {
|
|
|
+ if (object->oclass->ofuncs->wr32) {
|
|
|
+ object->oclass->ofuncs->wr32(object, addr, data);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return -ENODEV;
|
|
|
}
|
|
|
+ if (likely(object->func->wr32))
|
|
|
+ return object->func->wr32(object, addr, data);
|
|
|
return -ENODEV;
|
|
|
}
|
|
|
|
|
|
+int
|
|
|
+nvkm_object_bind(struct nvkm_object *object, struct nvkm_gpuobj *gpuobj,
|
|
|
+ int align, struct nvkm_gpuobj **pgpuobj)
|
|
|
+{
|
|
|
+ if (object->oclass)
|
|
|
+ return -ENODEV;
|
|
|
+ if (object->func->bind)
|
|
|
+ return object->func->bind(object, gpuobj, align, pgpuobj);
|
|
|
+ return -ENODEV;
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+nvkm_object_fini(struct nvkm_object *object, bool suspend)
|
|
|
+{
|
|
|
+ if (object->oclass)
|
|
|
+ return object->oclass->ofuncs->fini(object, suspend);
|
|
|
+ if (object->func->fini)
|
|
|
+ return object->func->fini(object, suspend);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+nvkm_object_init(struct nvkm_object *object)
|
|
|
+{
|
|
|
+ if (object->oclass)
|
|
|
+ return object->oclass->ofuncs->init(object);
|
|
|
+ if (object->func->init)
|
|
|
+ return object->func->init(object);
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void
|
|
|
+nvkm_object_del(struct nvkm_object **pobject)
|
|
|
+{
|
|
|
+ struct nvkm_object *object = *pobject;
|
|
|
+
|
|
|
+ if (object && object->oclass) {
|
|
|
+ object->oclass->ofuncs->dtor(object);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (object && !WARN_ON(!object->func)) {
|
|
|
+ if (object->func->dtor)
|
|
|
+ *pobject = object->func->dtor(object);
|
|
|
+ kfree(*pobject);
|
|
|
+ *pobject = NULL;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void
|
|
|
+nvkm_object_ctor(const struct nvkm_object_func *func,
|
|
|
+ const struct nvkm_oclass *oclass, struct nvkm_object *object)
|
|
|
+{
|
|
|
+ object->func = func;
|
|
|
+ object->client = oclass->client;
|
|
|
+ object->engine = oclass->engine;
|
|
|
+ object->oclass_name = oclass->base.oclass;
|
|
|
+ object->handle = oclass->handle;
|
|
|
+ object->parent = oclass->parent;
|
|
|
+ atomic_set(&object->refcount, 1);
|
|
|
+ atomic_set(&object->usecount, 0);
|
|
|
+#ifdef NVKM_OBJECT_MAGIC
|
|
|
+ object->_magic = NVKM_OBJECT_MAGIC;
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
+int
|
|
|
+nvkm_object_new_(const struct nvkm_object_func *func,
|
|
|
+ const struct nvkm_oclass *oclass, void *data, u32 size,
|
|
|
+ struct nvkm_object **pobject)
|
|
|
+{
|
|
|
+ if (size == 0) {
|
|
|
+ if (!(*pobject = kzalloc(sizeof(**pobject), GFP_KERNEL)))
|
|
|
+ return -ENOMEM;
|
|
|
+ nvkm_object_ctor(func, oclass, *pobject);
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return -ENOSYS;
|
|
|
+}
|
|
|
+
|
|
|
+static const struct nvkm_object_func
|
|
|
+nvkm_object_func = {
|
|
|
+};
|
|
|
+
|
|
|
+int
|
|
|
+nvkm_object_new(const struct nvkm_oclass *oclass, void *data, u32 size,
|
|
|
+ struct nvkm_object **pobject)
|
|
|
+{
|
|
|
+ const struct nvkm_object_func *func =
|
|
|
+ oclass->base.func ? oclass->base.func : &nvkm_object_func;
|
|
|
+ return nvkm_object_new_(func, oclass, data, size, pobject);
|
|
|
+}
|
|
|
+
|
|
|
int
|
|
|
nvkm_object_create_(struct nvkm_object *parent, struct nvkm_object *engine,
|
|
|
struct nvkm_oclass *oclass, u32 pclass,
|
|
@@ -182,12 +339,6 @@ nvkm_object_old(struct nvkm_object *parent, struct nvkm_object *engine,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-static void
|
|
|
-nvkm_object_dtor(struct nvkm_object *object)
|
|
|
-{
|
|
|
- nv_ofuncs(object)->dtor(object);
|
|
|
-}
|
|
|
-
|
|
|
void
|
|
|
nvkm_object_ref(struct nvkm_object *obj, struct nvkm_object **ref)
|
|
|
{
|
|
@@ -198,7 +349,7 @@ nvkm_object_ref(struct nvkm_object *obj, struct nvkm_object **ref)
|
|
|
if (*ref) {
|
|
|
int dead = atomic_dec_and_test(&(*ref)->refcount);
|
|
|
if (dead)
|
|
|
- nvkm_object_dtor(*ref);
|
|
|
+ nvkm_object_del(ref);
|
|
|
}
|
|
|
|
|
|
*ref = obj;
|
|
@@ -227,7 +378,7 @@ nvkm_object_inc(struct nvkm_object *object)
|
|
|
goto fail_engine;
|
|
|
}
|
|
|
|
|
|
- ret = nv_ofuncs(object)->init(object);
|
|
|
+ ret = nvkm_object_init(object);
|
|
|
atomic_set(&object->usecount, 1);
|
|
|
if (ret)
|
|
|
goto fail_self;
|
|
@@ -251,7 +402,7 @@ fail_parent:
|
|
|
static int
|
|
|
nvkm_object_decf(struct nvkm_object *object)
|
|
|
{
|
|
|
- nv_ofuncs(object)->fini(object, false);
|
|
|
+ nvkm_object_fini(object, false);
|
|
|
atomic_set(&object->usecount, 0);
|
|
|
|
|
|
if (object->engine) {
|
|
@@ -271,7 +422,7 @@ nvkm_object_decs(struct nvkm_object *object)
|
|
|
{
|
|
|
int ret;
|
|
|
|
|
|
- ret = nv_ofuncs(object)->fini(object, true);
|
|
|
+ ret = nvkm_object_fini(object, true);
|
|
|
atomic_set(&object->usecount, 0);
|
|
|
if (ret)
|
|
|
return ret;
|
|
@@ -300,7 +451,7 @@ fail_parent:
|
|
|
}
|
|
|
|
|
|
fail_engine:
|
|
|
- nv_ofuncs(object)->init(object);
|
|
|
+ nvkm_object_init(object);
|
|
|
|
|
|
return ret;
|
|
|
}
|