summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c')
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c73
1 files changed, 32 insertions, 41 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
index b04d4572603c..2472c6b7489f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
@@ -30,22 +30,43 @@
#include "priv.h"
static int
-nouveau_dmaobj_ctor(struct nouveau_object *parent,
+nvkm_dmaobj_bind(struct nouveau_dmaobj *dmaobj, struct nouveau_object *parent,
+ struct nouveau_gpuobj **pgpuobj)
+{
+ const struct nvkm_dmaeng_impl *impl = (void *)
+ nv_oclass(nv_object(dmaobj)->engine);
+ int ret = 0;
+
+ if (nv_object(dmaobj) == parent) { /* ctor bind */
+ if (nv_mclass(parent->parent) == NV_DEVICE) {
+ /* delayed, or no, binding */
+ return 0;
+ }
+ ret = impl->bind(dmaobj, parent, pgpuobj);
+ if (ret == 0)
+ nouveau_object_ref(NULL, &parent);
+ return ret;
+ }
+
+ return impl->bind(dmaobj, parent, pgpuobj);
+}
+
+int
+nvkm_dmaobj_create_(struct nouveau_object *parent,
struct nouveau_object *engine,
- struct nouveau_oclass *oclass, void *data, u32 size,
- struct nouveau_object **pobject)
+ struct nouveau_oclass *oclass, void **pdata, u32 *psize,
+ int length, void **pobject)
{
- struct nouveau_dmaeng *dmaeng = (void *)engine;
+ struct nv_dma_class *args = *pdata;
struct nouveau_dmaobj *dmaobj;
- struct nouveau_gpuobj *gpuobj;
- struct nv_dma_class *args = data;
int ret;
- if (size < sizeof(*args))
+ if (*psize < sizeof(*args))
return -EINVAL;
+ *pdata = &args->conf0;
- ret = nouveau_object_create(parent, engine, oclass, 0, &dmaobj);
- *pobject = nv_object(dmaobj);
+ ret = nouveau_object_create_(parent, engine, oclass, 0, length, pobject);
+ dmaobj = *pobject;
if (ret)
return ret;
@@ -87,39 +108,9 @@ nouveau_dmaobj_ctor(struct nouveau_object *parent,
dmaobj->start = args->start;
dmaobj->limit = args->limit;
dmaobj->conf0 = args->conf0;
-
- switch (nv_mclass(parent)) {
- case NV_DEVICE:
- /* delayed, or no, binding */
- break;
- default:
- ret = dmaeng->bind(dmaeng, *pobject, dmaobj, &gpuobj);
- if (ret == 0) {
- nouveau_object_ref(NULL, pobject);
- *pobject = nv_object(gpuobj);
- }
- break;
- }
-
return ret;
}
-static struct nouveau_ofuncs
-nouveau_dmaobj_ofuncs = {
- .ctor = nouveau_dmaobj_ctor,
- .dtor = nouveau_object_destroy,
- .init = nouveau_object_init,
- .fini = nouveau_object_fini,
-};
-
-static struct nouveau_oclass
-nouveau_dmaobj_sclass[] = {
- { NV_DMA_FROM_MEMORY_CLASS, &nouveau_dmaobj_ofuncs },
- { NV_DMA_TO_MEMORY_CLASS, &nouveau_dmaobj_ofuncs },
- { NV_DMA_IN_MEMORY_CLASS, &nouveau_dmaobj_ofuncs },
- {}
-};
-
int
_nvkm_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
struct nouveau_oclass *oclass, void *data, u32 size,
@@ -135,7 +126,7 @@ _nvkm_dmaeng_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
if (ret)
return ret;
- nv_engine(dmaeng)->sclass = nouveau_dmaobj_sclass;
- dmaeng->bind = impl->bind;
+ nv_engine(dmaeng)->sclass = impl->sclass;
+ dmaeng->bind = nvkm_dmaobj_bind;
return 0;
}