Commit 6c1689a0 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/dmaobj: move parent class check to bind() method

Otherwise when nvc0- gains a bind() method (disp needs it), the fifo
engine will attempt to create a dma object for the push buffer, which
is unnecessary on fermi.

The only sane place to put these checks is in the bind method itself,
and have it unconditionally called from wherever it might be needed.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent f86770aa
...@@ -88,21 +88,15 @@ nouveau_dmaobj_ctor(struct nouveau_object *parent, ...@@ -88,21 +88,15 @@ nouveau_dmaobj_ctor(struct nouveau_object *parent,
switch (nv_mclass(parent)) { switch (nv_mclass(parent)) {
case NV_DEVICE_CLASS: case NV_DEVICE_CLASS:
/* delayed, or no, binding */
break; break;
case NV03_CHANNEL_DMA_CLASS: default:
case NV10_CHANNEL_DMA_CLASS:
case NV17_CHANNEL_DMA_CLASS:
case NV40_CHANNEL_DMA_CLASS:
case NV50_CHANNEL_DMA_CLASS:
case NV84_CHANNEL_DMA_CLASS:
case NV50_CHANNEL_IND_CLASS:
case NV84_CHANNEL_IND_CLASS:
ret = dmaeng->bind(dmaeng, *pobject, dmaobj, &gpuobj); ret = dmaeng->bind(dmaeng, *pobject, dmaobj, &gpuobj);
nouveau_object_ref(NULL, pobject); if (ret == 0) {
*pobject = nv_object(gpuobj); nouveau_object_ref(NULL, pobject);
*pobject = nv_object(gpuobj);
}
break; break;
default:
return -EINVAL;
} }
return ret; return ret;
......
...@@ -49,6 +49,18 @@ nv04_dmaobj_bind(struct nouveau_dmaeng *dmaeng, ...@@ -49,6 +49,18 @@ nv04_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
u32 length = dmaobj->limit - dmaobj->start; u32 length = dmaobj->limit - dmaobj->start;
int ret; int ret;
if (!nv_iclass(parent, NV_ENGCTX_CLASS)) {
switch (nv_mclass(parent->parent)) {
case NV03_CHANNEL_DMA_CLASS:
case NV10_CHANNEL_DMA_CLASS:
case NV17_CHANNEL_DMA_CLASS:
case NV40_CHANNEL_DMA_CLASS:
break;
default:
return -EINVAL;
}
}
if (dmaobj->target == NV_MEM_TARGET_VM) { if (dmaobj->target == NV_MEM_TARGET_VM) {
if (nv_object(vmm)->oclass == &nv04_vmmgr_oclass) { if (nv_object(vmm)->oclass == &nv04_vmmgr_oclass) {
struct nouveau_gpuobj *pgt = vmm->vm->pgt[0].obj[0]; struct nouveau_gpuobj *pgt = vmm->vm->pgt[0].obj[0];
......
...@@ -41,6 +41,18 @@ nv50_dmaobj_bind(struct nouveau_dmaeng *dmaeng, ...@@ -41,6 +41,18 @@ nv50_dmaobj_bind(struct nouveau_dmaeng *dmaeng,
u32 flags = nv_mclass(dmaobj); u32 flags = nv_mclass(dmaobj);
int ret; int ret;
if (!nv_iclass(parent, NV_ENGCTX_CLASS)) {
switch (nv_mclass(parent->parent)) {
case NV50_CHANNEL_DMA_CLASS:
case NV84_CHANNEL_DMA_CLASS:
case NV50_CHANNEL_IND_CLASS:
case NV84_CHANNEL_IND_CLASS:
break;
default:
return -EINVAL;
}
}
switch (dmaobj->target) { switch (dmaobj->target) {
case NV_MEM_TARGET_VM: case NV_MEM_TARGET_VM:
flags |= 0x00000000; flags |= 0x00000000;
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <core/object.h> #include <core/object.h>
#include <core/handle.h> #include <core/handle.h>
#include <core/class.h>
#include <engine/dmaobj.h> #include <engine/dmaobj.h>
#include <engine/fifo.h> #include <engine/fifo.h>
...@@ -56,15 +57,16 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent, ...@@ -56,15 +57,16 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent,
dmaeng = (void *)chan->pushdma->base.engine; dmaeng = (void *)chan->pushdma->base.engine;
switch (chan->pushdma->base.oclass->handle) { switch (chan->pushdma->base.oclass->handle) {
case 0x0002: case NV_DMA_FROM_MEMORY_CLASS:
case 0x003d: case NV_DMA_IN_MEMORY_CLASS:
break; break;
default: default:
return -EINVAL; return -EINVAL;
} }
if (dmaeng->bind) { if (dmaeng->bind) {
ret = dmaeng->bind(dmaeng, parent, chan->pushdma, &chan->pushgpu); ret = dmaeng->bind(dmaeng, parent, chan->pushdma,
&chan->pushgpu);
if (ret) if (ret)
return ret; return ret;
} }
......
...@@ -16,8 +16,12 @@ struct nouveau_dmaobj { ...@@ -16,8 +16,12 @@ struct nouveau_dmaobj {
struct nouveau_dmaeng { struct nouveau_dmaeng {
struct nouveau_engine base; struct nouveau_engine base;
int (*bind)(struct nouveau_dmaeng *, struct nouveau_object *parent,
struct nouveau_dmaobj *, struct nouveau_gpuobj **); /* creates a "physical" dma object from a struct nouveau_dmaobj */
int (*bind)(struct nouveau_dmaeng *dmaeng,
struct nouveau_object *parent,
struct nouveau_dmaobj *dmaobj,
struct nouveau_gpuobj **);
}; };
#define nouveau_dmaeng_create(p,e,c,d) \ #define nouveau_dmaeng_create(p,e,c,d) \
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment