drm/nouveau/dmaobj: move parent class check to bind() method
authorBen Skeggs <bskeggs@redhat.com>
Mon, 8 Oct 2012 02:58:23 +0000 (12:58 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Wed, 28 Nov 2012 23:56:38 +0000 (09:56 +1000)
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: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/engine/dmaobj/base.c
drivers/gpu/drm/nouveau/core/engine/dmaobj/nv04.c
drivers/gpu/drm/nouveau/core/engine/dmaobj/nv50.c
drivers/gpu/drm/nouveau/core/engine/fifo/base.c
drivers/gpu/drm/nouveau/core/include/engine/dmaobj.h

index 9ca90613306afa4cc4bd392933c98f09a0c63f3e..325b79dd619acafaf3517a116b769e0e0701e264 100644 (file)
@@ -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;
index 892387327667a33800d29f9bcd3eec67fcf540de..027d8217c0faf18aa0819d223b024c2b21331b2c 100644 (file)
@@ -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];
index 58876f53b3a43d9856c03c4e4eba528fccc1c104..3dab016b6fe4181ac14d8721a99f3e2d820824e6 100644 (file)
@@ -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;
index 0d45e845a8f8bddd4b973d129ed57f67d01e05cf..ca4050c6ea5fa278c90f7dffd728dd908fad799a 100644 (file)
@@ -24,6 +24,7 @@
 
 #include <core/object.h>
 #include <core/handle.h>
+#include <core/class.h>
 
 #include <engine/dmaobj.h>
 #include <engine/fifo.h>
@@ -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;
        }
index f61d1a8f5c17066ce269c999766a5ee2df2be4a7..a0b102680d81f85001555d3b7d8c0a4907978645 100644 (file)
@@ -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)                                         \