diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c index 9ca90613306afa4cc4bd392933c98f09a0c63f3e..325b79dd619acafaf3517a116b769e0e0701e264 100644 --- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c @@ -88,21 +88,15 @@ nouveau_dmaobj_ctor(struct nouveau_object *parent, switch (nv_mclass(parent)) { case NV_DEVICE_CLASS: + /* delayed, or no, binding */ break; - case NV03_CHANNEL_DMA_CLASS: - 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: + default: ret = dmaeng->bind(dmaeng, *pobject, dmaobj, &gpuobj); - nouveau_object_ref(NULL, pobject); - *pobject = nv_object(gpuobj); + if (ret == 0) { + nouveau_object_ref(NULL, pobject); + *pobject = nv_object(gpuobj); + } break; - default: - return -EINVAL; } return ret; diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c index 892387327667a33800d29f9bcd3eec67fcf540de..027d8217c0faf18aa0819d223b024c2b21331b2c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c @@ -49,6 +49,18 @@ nv04_dmaobj_bind(struct nouveau_dmaeng *dmaeng, u32 length = dmaobj->limit - dmaobj->start; 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 (nv_object(vmm)->oclass == &nv04_vmmgr_oclass) { struct nouveau_gpuobj *pgt = vmm->vm->pgt[0].obj[0]; diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c index 58876f53b3a43d9856c03c4e4eba528fccc1c104..3dab016b6fe4181ac14d8721a99f3e2d820824e6 100644 --- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c @@ -41,6 +41,18 @@ nv50_dmaobj_bind(struct nouveau_dmaeng *dmaeng, u32 flags = nv_mclass(dmaobj); 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) { case NV_MEM_TARGET_VM: flags |= 0x00000000; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c index 0d45e845a8f8bddd4b973d129ed57f67d01e05cf..ca4050c6ea5fa278c90f7dffd728dd908fad799a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c @@ -24,6 +24,7 @@ #include #include +#include #include #include @@ -56,15 +57,16 @@ nouveau_fifo_channel_create_(struct nouveau_object *parent, dmaeng = (void *)chan->pushdma->base.engine; switch (chan->pushdma->base.oclass->handle) { - case 0x0002: - case 0x003d: + case NV_DMA_FROM_MEMORY_CLASS: + case NV_DMA_IN_MEMORY_CLASS: break; default: return -EINVAL; } if (dmaeng->bind) { - ret = dmaeng->bind(dmaeng, parent, chan->pushdma, &chan->pushgpu); + ret = dmaeng->bind(dmaeng, parent, chan->pushdma, + &chan->pushgpu); if (ret) return ret; } diff --git a/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h b/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h index f61d1a8f5c17066ce269c999766a5ee2df2be4a7..a0b102680d81f85001555d3b7d8c0a4907978645 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h @@ -16,8 +16,12 @@ struct nouveau_dmaobj { struct nouveau_dmaeng { 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) \