drm/nv50-/disp: share channel creation between nv50/gf110 impls
authorBen Skeggs <bskeggs@redhat.com>
Sat, 9 Aug 2014 18:10:25 +0000 (04:10 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Sat, 9 Aug 2014 19:28:06 +0000 (05:28 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/core/engine/disp/gm107.c
drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c

index a9681df..f93d76e 100644 (file)
 
 static struct nouveau_oclass
 gm107_disp_sclass[] = {
-       { GM107_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs },
-       { GM107_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs },
-       { GM107_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs },
-       { GM107_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs },
-       { GM107_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs },
+       { GM107_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs.base },
+       { GM107_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs.base },
+       { GM107_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs.base },
+       { GM107_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs.base },
+       { GM107_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs.base },
        {}
 };
 
index ca8ce9c..4f1ed89 100644 (file)
  * EVO channel base class
  ******************************************************************************/
 
-int
+static int
 nv50_disp_chan_create_(struct nouveau_object *parent,
                       struct nouveau_object *engine,
-                      struct nouveau_oclass *oclass, int chid,
+                      struct nouveau_oclass *oclass, int head,
                       int length, void **pobject)
 {
+       const struct nv50_disp_chan_impl *impl = (void *)oclass->ofuncs;
        struct nv50_disp_base *base = (void *)parent;
        struct nv50_disp_chan *chan;
+       int chid = impl->chid + head;
        int ret;
 
        if (base->chan & (1 << chid))
@@ -63,12 +65,14 @@ nv50_disp_chan_create_(struct nouveau_object *parent,
        chan = *pobject;
        if (ret)
                return ret;
-
        chan->chid = chid;
+
+       nv_parent(chan)->object_attach = impl->attach;
+       nv_parent(chan)->object_detach = impl->detach;
        return 0;
 }
 
-void
+static void
 nv50_disp_chan_destroy(struct nv50_disp_chan *chan)
 {
        struct nv50_disp_base *base = (void *)nv_object(chan)->parent;
@@ -115,16 +119,16 @@ nv50_disp_dmac_object_detach(struct nouveau_object *parent, int cookie)
        nouveau_ramht_remove(base->ramht, cookie);
 }
 
-int
+static int
 nv50_disp_dmac_create_(struct nouveau_object *parent,
                       struct nouveau_object *engine,
-                      struct nouveau_oclass *oclass, u32 pushbuf, int chid,
+                      struct nouveau_oclass *oclass, u32 pushbuf, int head,
                       int length, void **pobject)
 {
        struct nv50_disp_dmac *dmac;
        int ret;
 
-       ret = nv50_disp_chan_create_(parent, engine, oclass, chid,
+       ret = nv50_disp_chan_create_(parent, engine, oclass, head,
                                     length, pobject);
        dmac = *pobject;
        if (ret)
@@ -397,7 +401,7 @@ nv50_disp_mast_mthd_chan = {
        }
 };
 
-static int
+int
 nv50_disp_mast_ctor(struct nouveau_object *parent,
                    struct nouveau_object *engine,
                    struct nouveau_oclass *oclass, void *data, u32 size,
@@ -416,8 +420,6 @@ nv50_disp_mast_ctor(struct nouveau_object *parent,
        if (ret)
                return ret;
 
-       nv_parent(mast)->object_attach = nv50_disp_dmac_object_attach;
-       nv_parent(mast)->object_detach = nv50_disp_dmac_object_detach;
        return 0;
 }
 
@@ -479,14 +481,17 @@ nv50_disp_mast_fini(struct nouveau_object *object, bool suspend)
        return nv50_disp_chan_fini(&mast->base, suspend);
 }
 
-struct nouveau_ofuncs
+struct nv50_disp_chan_impl
 nv50_disp_mast_ofuncs = {
-       .ctor = nv50_disp_mast_ctor,
-       .dtor = nv50_disp_dmac_dtor,
-       .init = nv50_disp_mast_init,
-       .fini = nv50_disp_mast_fini,
-       .rd32 = nv50_disp_chan_rd32,
-       .wr32 = nv50_disp_chan_wr32,
+       .base.ctor = nv50_disp_mast_ctor,
+       .base.dtor = nv50_disp_dmac_dtor,
+       .base.init = nv50_disp_mast_init,
+       .base.fini = nv50_disp_mast_fini,
+       .base.rd32 = nv50_disp_chan_rd32,
+       .base.wr32 = nv50_disp_chan_wr32,
+       .chid = 0,
+       .attach = nv50_disp_dmac_object_attach,
+       .detach = nv50_disp_dmac_object_detach,
 };
 
 /*******************************************************************************
@@ -543,39 +548,40 @@ nv50_disp_sync_mthd_chan = {
        }
 };
 
-static int
+int
 nv50_disp_sync_ctor(struct nouveau_object *parent,
                    struct nouveau_object *engine,
                    struct nouveau_oclass *oclass, void *data, u32 size,
                    struct nouveau_object **pobject)
 {
        struct nv50_display_sync_class *args = data;
+       struct nv50_disp_priv *priv = (void *)engine;
        struct nv50_disp_dmac *dmac;
        int ret;
 
-       if (size < sizeof(*args) || args->head > 1)
+       if (size < sizeof(*args) || args->head >= priv->head.nr)
                return -EINVAL;
 
        ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf,
-                                    1 + args->head, sizeof(*dmac),
-                                    (void **)&dmac);
+                                    args->head, sizeof(*dmac), (void **)&dmac);
        *pobject = nv_object(dmac);
        if (ret)
                return ret;
 
-       nv_parent(dmac)->object_attach = nv50_disp_dmac_object_attach;
-       nv_parent(dmac)->object_detach = nv50_disp_dmac_object_detach;
        return 0;
 }
 
-struct nouveau_ofuncs
+struct nv50_disp_chan_impl
 nv50_disp_sync_ofuncs = {
-       .ctor = nv50_disp_sync_ctor,
-       .dtor = nv50_disp_dmac_dtor,
-       .init = nv50_disp_dmac_init,
-       .fini = nv50_disp_dmac_fini,
-       .rd32 = nv50_disp_chan_rd32,
-       .wr32 = nv50_disp_chan_wr32,
+       .base.ctor = nv50_disp_sync_ctor,
+       .base.dtor = nv50_disp_dmac_dtor,
+       .base.init = nv50_disp_dmac_init,
+       .base.fini = nv50_disp_dmac_fini,
+       .base.rd32 = nv50_disp_chan_rd32,
+       .base.wr32 = nv50_disp_chan_wr32,
+       .chid = 1,
+       .attach = nv50_disp_dmac_object_attach,
+       .detach = nv50_disp_dmac_object_detach,
 };
 
 /*******************************************************************************
@@ -620,39 +626,40 @@ nv50_disp_ovly_mthd_chan = {
        }
 };
 
-static int
+int
 nv50_disp_ovly_ctor(struct nouveau_object *parent,
                    struct nouveau_object *engine,
                    struct nouveau_oclass *oclass, void *data, u32 size,
                    struct nouveau_object **pobject)
 {
        struct nv50_display_ovly_class *args = data;
+       struct nv50_disp_priv *priv = (void *)engine;
        struct nv50_disp_dmac *dmac;
        int ret;
 
-       if (size < sizeof(*args) || args->head > 1)
+       if (size < sizeof(*args) || args->head >= priv->head.nr)
                return -EINVAL;
 
        ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf,
-                                    3 + args->head, sizeof(*dmac),
-                                    (void **)&dmac);
+                                    args->head, sizeof(*dmac), (void **)&dmac);
        *pobject = nv_object(dmac);
        if (ret)
                return ret;
 
-       nv_parent(dmac)->object_attach = nv50_disp_dmac_object_attach;
-       nv_parent(dmac)->object_detach = nv50_disp_dmac_object_detach;
        return 0;
 }
 
-struct nouveau_ofuncs
+struct nv50_disp_chan_impl
 nv50_disp_ovly_ofuncs = {
-       .ctor = nv50_disp_ovly_ctor,
-       .dtor = nv50_disp_dmac_dtor,
-       .init = nv50_disp_dmac_init,
-       .fini = nv50_disp_dmac_fini,
-       .rd32 = nv50_disp_chan_rd32,
-       .wr32 = nv50_disp_chan_wr32,
+       .base.ctor = nv50_disp_ovly_ctor,
+       .base.dtor = nv50_disp_dmac_dtor,
+       .base.init = nv50_disp_dmac_init,
+       .base.fini = nv50_disp_dmac_fini,
+       .base.rd32 = nv50_disp_chan_rd32,
+       .base.wr32 = nv50_disp_chan_wr32,
+       .chid = 3,
+       .attach = nv50_disp_dmac_object_attach,
+       .detach = nv50_disp_dmac_object_detach,
 };
 
 /*******************************************************************************
@@ -662,14 +669,14 @@ nv50_disp_ovly_ofuncs = {
 static int
 nv50_disp_pioc_create_(struct nouveau_object *parent,
                       struct nouveau_object *engine,
-                      struct nouveau_oclass *oclass, int chid,
+                      struct nouveau_oclass *oclass, int head,
                       int length, void **pobject)
 {
-       return nv50_disp_chan_create_(parent, engine, oclass, chid,
+       return nv50_disp_chan_create_(parent, engine, oclass, head,
                                      length, pobject);
 }
 
-static void
+void
 nv50_disp_pioc_dtor(struct nouveau_object *object)
 {
        struct nv50_disp_pioc *pioc = (void *)object;
@@ -727,20 +734,21 @@ nv50_disp_pioc_fini(struct nouveau_object *object, bool suspend)
  * EVO immediate overlay channel objects
  ******************************************************************************/
 
-static int
+int
 nv50_disp_oimm_ctor(struct nouveau_object *parent,
                    struct nouveau_object *engine,
                    struct nouveau_oclass *oclass, void *data, u32 size,
                    struct nouveau_object **pobject)
 {
        struct nv50_display_oimm_class *args = data;
+       struct nv50_disp_priv *priv = (void *)engine;
        struct nv50_disp_pioc *pioc;
        int ret;
 
-       if (size < sizeof(*args) || args->head > 1)
+       if (size < sizeof(*args) || args->head >= priv->head.nr)
                return -EINVAL;
 
-       ret = nv50_disp_pioc_create_(parent, engine, oclass, 5 + args->head,
+       ret = nv50_disp_pioc_create_(parent, engine, oclass, args->head,
                                     sizeof(*pioc), (void **)&pioc);
        *pobject = nv_object(pioc);
        if (ret)
@@ -749,34 +757,36 @@ nv50_disp_oimm_ctor(struct nouveau_object *parent,
        return 0;
 }
 
-struct nouveau_ofuncs
+struct nv50_disp_chan_impl
 nv50_disp_oimm_ofuncs = {
-       .ctor = nv50_disp_oimm_ctor,
-       .dtor = nv50_disp_pioc_dtor,
-       .init = nv50_disp_pioc_init,
-       .fini = nv50_disp_pioc_fini,
-       .rd32 = nv50_disp_chan_rd32,
-       .wr32 = nv50_disp_chan_wr32,
+       .base.ctor = nv50_disp_oimm_ctor,
+       .base.dtor = nv50_disp_pioc_dtor,
+       .base.init = nv50_disp_pioc_init,
+       .base.fini = nv50_disp_pioc_fini,
+       .base.rd32 = nv50_disp_chan_rd32,
+       .base.wr32 = nv50_disp_chan_wr32,
+       .chid = 5,
 };
 
 /*******************************************************************************
  * EVO cursor channel objects
  ******************************************************************************/
 
-static int
+int
 nv50_disp_curs_ctor(struct nouveau_object *parent,
                    struct nouveau_object *engine,
                    struct nouveau_oclass *oclass, void *data, u32 size,
                    struct nouveau_object **pobject)
 {
        struct nv50_display_curs_class *args = data;
+       struct nv50_disp_priv *priv = (void *)engine;
        struct nv50_disp_pioc *pioc;
        int ret;
 
-       if (size < sizeof(*args) || args->head > 1)
+       if (size < sizeof(*args) || args->head >= priv->head.nr)
                return -EINVAL;
 
-       ret = nv50_disp_pioc_create_(parent, engine, oclass, 7 + args->head,
+       ret = nv50_disp_pioc_create_(parent, engine, oclass, args->head,
                                     sizeof(*pioc), (void **)&pioc);
        *pobject = nv_object(pioc);
        if (ret)
@@ -785,14 +795,15 @@ nv50_disp_curs_ctor(struct nouveau_object *parent,
        return 0;
 }
 
-struct nouveau_ofuncs
+struct nv50_disp_chan_impl
 nv50_disp_curs_ofuncs = {
-       .ctor = nv50_disp_curs_ctor,
-       .dtor = nv50_disp_pioc_dtor,
-       .init = nv50_disp_pioc_init,
-       .fini = nv50_disp_pioc_fini,
-       .rd32 = nv50_disp_chan_rd32,
-       .wr32 = nv50_disp_chan_wr32,
+       .base.ctor = nv50_disp_curs_ctor,
+       .base.dtor = nv50_disp_pioc_dtor,
+       .base.init = nv50_disp_pioc_init,
+       .base.fini = nv50_disp_pioc_fini,
+       .base.rd32 = nv50_disp_chan_rd32,
+       .base.wr32 = nv50_disp_chan_wr32,
+       .chid = 7,
 };
 
 /*******************************************************************************
@@ -966,11 +977,11 @@ nv50_disp_base_oclass[] = {
 
 static struct nouveau_oclass
 nv50_disp_sclass[] = {
-       { NV50_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
-       { NV50_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
-       { NV50_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
-       { NV50_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
-       { NV50_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
+       { NV50_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs.base },
+       { NV50_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs.base },
+       { NV50_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs.base },
+       { NV50_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs.base },
+       { NV50_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs.base },
        {}
 };
 
index c0e8b79..a1ec6a5 100644 (file)
@@ -104,14 +104,18 @@ struct nv50_disp_base {
        u32 chan;
 };
 
+struct nv50_disp_chan_impl {
+       struct nouveau_ofuncs base;
+       int chid;
+       int  (*attach)(struct nouveau_object *, struct nouveau_object *, u32);
+       void (*detach)(struct nouveau_object *, int);
+};
+
 struct nv50_disp_chan {
        struct nouveau_namedb base;
        int chid;
 };
 
-int  nv50_disp_chan_create_(struct nouveau_object *, struct nouveau_object *,
-                           struct nouveau_oclass *, int, int, void **);
-void nv50_disp_chan_destroy(struct nv50_disp_chan *);
 u32  nv50_disp_chan_rd32(struct nouveau_object *, u64);
 void nv50_disp_chan_wr32(struct nouveau_object *, u64, u32);
 
@@ -120,20 +124,20 @@ void nv50_disp_chan_wr32(struct nouveau_object *, u64, u32);
 #define nv50_disp_chan_fini(a,b)                                               \
        nouveau_namedb_fini(&(a)->base, (b))
 
-int  nv50_disp_dmac_create_(struct nouveau_object *, struct nouveau_object *,
-                           struct nouveau_oclass *, u32, int, int, void **);
-void nv50_disp_dmac_dtor(struct nouveau_object *);
-
 struct nv50_disp_dmac {
        struct nv50_disp_chan base;
        struct nouveau_dmaobj *pushdma;
        u32 push;
 };
 
+void nv50_disp_dmac_dtor(struct nouveau_object *);
+
 struct nv50_disp_pioc {
        struct nv50_disp_chan base;
 };
 
+void nv50_disp_pioc_dtor(struct nouveau_object *);
+
 struct nv50_disp_mthd_list {
        u32 mthd;
        u32 addr;
@@ -154,16 +158,31 @@ struct nv50_disp_mthd_chan {
        } data[];
 };
 
-extern struct nouveau_ofuncs nv50_disp_mast_ofuncs;
+extern struct nv50_disp_chan_impl nv50_disp_mast_ofuncs;
+int nv50_disp_mast_ctor(struct nouveau_object *, struct nouveau_object *,
+                       struct nouveau_oclass *, void *, u32,
+                       struct nouveau_object **);
 extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_base;
 extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_sor;
 extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_pior;
-extern struct nouveau_ofuncs nv50_disp_sync_ofuncs;
+extern struct nv50_disp_chan_impl nv50_disp_sync_ofuncs;
+int nv50_disp_sync_ctor(struct nouveau_object *, struct nouveau_object *,
+                       struct nouveau_oclass *, void *, u32,
+                       struct nouveau_object **);
 extern const struct nv50_disp_mthd_list nv50_disp_sync_mthd_image;
-extern struct nouveau_ofuncs nv50_disp_ovly_ofuncs;
+extern struct nv50_disp_chan_impl nv50_disp_ovly_ofuncs;
+int nv50_disp_ovly_ctor(struct nouveau_object *, struct nouveau_object *,
+                       struct nouveau_oclass *, void *, u32,
+                       struct nouveau_object **);
 extern const struct nv50_disp_mthd_list nv50_disp_ovly_mthd_base;
-extern struct nouveau_ofuncs nv50_disp_oimm_ofuncs;
-extern struct nouveau_ofuncs nv50_disp_curs_ofuncs;
+extern struct nv50_disp_chan_impl nv50_disp_oimm_ofuncs;
+int nv50_disp_oimm_ctor(struct nouveau_object *, struct nouveau_object *,
+                       struct nouveau_oclass *, void *, u32,
+                       struct nouveau_object **);
+extern struct nv50_disp_chan_impl nv50_disp_curs_ofuncs;
+int nv50_disp_curs_ctor(struct nouveau_object *, struct nouveau_object *,
+                       struct nouveau_oclass *, void *, u32,
+                       struct nouveau_object **);
 extern struct nouveau_ofuncs nv50_disp_base_ofuncs;
 int  nv50_disp_base_ctor(struct nouveau_object *, struct nouveau_object *,
                         struct nouveau_oclass *, void *, u32,
@@ -185,16 +204,16 @@ extern struct nouveau_omthds nv84_disp_base_omthds[];
 
 extern const struct nv50_disp_mthd_chan nv94_disp_mast_mthd_chan;
 
-extern struct nouveau_ofuncs nvd0_disp_mast_ofuncs;
+extern struct nv50_disp_chan_impl nvd0_disp_mast_ofuncs;
 extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_base;
 extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_dac;
 extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_sor;
 extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_pior;
-extern struct nouveau_ofuncs nvd0_disp_sync_ofuncs;
-extern struct nouveau_ofuncs nvd0_disp_ovly_ofuncs;
+extern struct nv50_disp_chan_impl nvd0_disp_sync_ofuncs;
+extern struct nv50_disp_chan_impl nvd0_disp_ovly_ofuncs;
 extern const struct nv50_disp_mthd_chan nvd0_disp_sync_mthd_chan;
-extern struct nouveau_ofuncs nvd0_disp_oimm_ofuncs;
-extern struct nouveau_ofuncs nvd0_disp_curs_ofuncs;
+extern struct nv50_disp_chan_impl nvd0_disp_oimm_ofuncs;
+extern struct nv50_disp_chan_impl nvd0_disp_curs_ofuncs;
 extern struct nouveau_omthds nvd0_disp_base_omthds[];
 extern struct nouveau_ofuncs nvd0_disp_base_ofuncs;
 extern struct nouveau_oclass nvd0_disp_cclass;
index dd59774..43ef1fa 100644 (file)
@@ -204,11 +204,11 @@ nv84_disp_ovly_mthd_chan = {
 
 static struct nouveau_oclass
 nv84_disp_sclass[] = {
-       { NV84_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
-       { NV84_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
-       { NV84_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
-       { NV84_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
-       { NV84_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
+       { NV84_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs.base },
+       { NV84_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs.base },
+       { NV84_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs.base },
+       { NV84_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs.base },
+       { NV84_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs.base },
        {}
 };
 
index 03a6b25..2e38a79 100644 (file)
@@ -63,11 +63,11 @@ nv94_disp_mast_mthd_chan = {
 
 static struct nouveau_oclass
 nv94_disp_sclass[] = {
-       { NV94_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
-       { NV94_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
-       { NV94_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
-       { NV94_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
-       { NV94_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
+       { NV94_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs.base },
+       { NV94_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs.base },
+       { NV94_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs.base },
+       { NV94_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs.base },
+       { NV94_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs.base },
        {}
 };
 
index ea1b5a7..bfd5cf1 100644 (file)
@@ -80,11 +80,11 @@ nva0_disp_ovly_mthd_chan = {
 
 static struct nouveau_oclass
 nva0_disp_sclass[] = {
-       { NVA0_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
-       { NVA0_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
-       { NVA0_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
-       { NVA0_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
-       { NVA0_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
+       { NVA0_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs.base },
+       { NVA0_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs.base },
+       { NVA0_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs.base },
+       { NVA0_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs.base },
+       { NVA0_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs.base },
        {}
 };
 
index 00f38a3..4b601c8 100644 (file)
 
 static struct nouveau_oclass
 nva3_disp_sclass[] = {
-       { NVA3_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs },
-       { NVA3_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs },
-       { NVA3_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs },
-       { NVA3_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs },
-       { NVA3_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs },
+       { NVA3_DISP_MAST_CLASS, &nv50_disp_mast_ofuncs.base },
+       { NVA3_DISP_SYNC_CLASS, &nv50_disp_sync_ofuncs.base },
+       { NVA3_DISP_OVLY_CLASS, &nv50_disp_ovly_ofuncs.base },
+       { NVA3_DISP_OIMM_CLASS, &nv50_disp_oimm_ofuncs.base },
+       { NVA3_DISP_CURS_CLASS, &nv50_disp_curs_ofuncs.base },
        {}
 };
 
index 1ab2169..57d6cb3 100644 (file)
@@ -264,30 +264,6 @@ nvd0_disp_mast_mthd_chan = {
        }
 };
 
-static int
-nvd0_disp_mast_ctor(struct nouveau_object *parent,
-                   struct nouveau_object *engine,
-                   struct nouveau_oclass *oclass, void *data, u32 size,
-                   struct nouveau_object **pobject)
-{
-       struct nv50_display_mast_class *args = data;
-       struct nv50_disp_dmac *mast;
-       int ret;
-
-       if (size < sizeof(*args))
-               return -EINVAL;
-
-       ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf,
-                                    0, sizeof(*mast), (void **)&mast);
-       *pobject = nv_object(mast);
-       if (ret)
-               return ret;
-
-       nv_parent(mast)->object_attach = nvd0_disp_dmac_object_attach;
-       nv_parent(mast)->object_detach = nvd0_disp_dmac_object_detach;
-       return 0;
-}
-
 static int
 nvd0_disp_mast_init(struct nouveau_object *object)
 {
@@ -342,14 +318,17 @@ nvd0_disp_mast_fini(struct nouveau_object *object, bool suspend)
        return nv50_disp_chan_fini(&mast->base, suspend);
 }
 
-struct nouveau_ofuncs
+struct nv50_disp_chan_impl
 nvd0_disp_mast_ofuncs = {
-       .ctor = nvd0_disp_mast_ctor,
-       .dtor = nv50_disp_dmac_dtor,
-       .init = nvd0_disp_mast_init,
-       .fini = nvd0_disp_mast_fini,
-       .rd32 = nv50_disp_chan_rd32,
-       .wr32 = nv50_disp_chan_wr32,
+       .base.ctor = nv50_disp_mast_ctor,
+       .base.dtor = nv50_disp_dmac_dtor,
+       .base.init = nvd0_disp_mast_init,
+       .base.fini = nvd0_disp_mast_fini,
+       .base.rd32 = nv50_disp_chan_rd32,
+       .base.wr32 = nv50_disp_chan_wr32,
+       .chid = 0,
+       .attach = nvd0_disp_dmac_object_attach,
+       .detach = nvd0_disp_dmac_object_detach,
 };
 
 /*******************************************************************************
@@ -431,40 +410,17 @@ nvd0_disp_sync_mthd_chan = {
        }
 };
 
-static int
-nvd0_disp_sync_ctor(struct nouveau_object *parent,
-                   struct nouveau_object *engine,
-                   struct nouveau_oclass *oclass, void *data, u32 size,
-                   struct nouveau_object **pobject)
-{
-       struct nv50_display_sync_class *args = data;
-       struct nv50_disp_priv *priv = (void *)engine;
-       struct nv50_disp_dmac *dmac;
-       int ret;
-
-       if (size < sizeof(*args) || args->head >= priv->head.nr)
-               return -EINVAL;
-
-       ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf,
-                                    1 + args->head, sizeof(*dmac),
-                                    (void **)&dmac);
-       *pobject = nv_object(dmac);
-       if (ret)
-               return ret;
-
-       nv_parent(dmac)->object_attach = nvd0_disp_dmac_object_attach;
-       nv_parent(dmac)->object_detach = nvd0_disp_dmac_object_detach;
-       return 0;
-}
-
-struct nouveau_ofuncs
+struct nv50_disp_chan_impl
 nvd0_disp_sync_ofuncs = {
-       .ctor = nvd0_disp_sync_ctor,
-       .dtor = nv50_disp_dmac_dtor,
-       .init = nvd0_disp_dmac_init,
-       .fini = nvd0_disp_dmac_fini,
-       .rd32 = nv50_disp_chan_rd32,
-       .wr32 = nv50_disp_chan_wr32,
+       .base.ctor = nv50_disp_sync_ctor,
+       .base.dtor = nv50_disp_dmac_dtor,
+       .base.init = nvd0_disp_dmac_init,
+       .base.fini = nvd0_disp_dmac_fini,
+       .base.rd32 = nv50_disp_chan_rd32,
+       .base.wr32 = nv50_disp_chan_wr32,
+       .chid = 1,
+       .attach = nvd0_disp_dmac_object_attach,
+       .detach = nvd0_disp_dmac_object_detach,
 };
 
 /*******************************************************************************
@@ -533,63 +489,23 @@ nvd0_disp_ovly_mthd_chan = {
        }
 };
 
-static int
-nvd0_disp_ovly_ctor(struct nouveau_object *parent,
-                   struct nouveau_object *engine,
-                   struct nouveau_oclass *oclass, void *data, u32 size,
-                   struct nouveau_object **pobject)
-{
-       struct nv50_display_ovly_class *args = data;
-       struct nv50_disp_priv *priv = (void *)engine;
-       struct nv50_disp_dmac *dmac;
-       int ret;
-
-       if (size < sizeof(*args) || args->head >= priv->head.nr)
-               return -EINVAL;
-
-       ret = nv50_disp_dmac_create_(parent, engine, oclass, args->pushbuf,
-                                    5 + args->head, sizeof(*dmac),
-                                    (void **)&dmac);
-       *pobject = nv_object(dmac);
-       if (ret)
-               return ret;
-
-       nv_parent(dmac)->object_attach = nvd0_disp_dmac_object_attach;
-       nv_parent(dmac)->object_detach = nvd0_disp_dmac_object_detach;
-       return 0;
-}
-
-struct nouveau_ofuncs
+struct nv50_disp_chan_impl
 nvd0_disp_ovly_ofuncs = {
-       .ctor = nvd0_disp_ovly_ctor,
-       .dtor = nv50_disp_dmac_dtor,
-       .init = nvd0_disp_dmac_init,
-       .fini = nvd0_disp_dmac_fini,
-       .rd32 = nv50_disp_chan_rd32,
-       .wr32 = nv50_disp_chan_wr32,
+       .base.ctor = nv50_disp_ovly_ctor,
+       .base.dtor = nv50_disp_dmac_dtor,
+       .base.init = nvd0_disp_dmac_init,
+       .base.fini = nvd0_disp_dmac_fini,
+       .base.rd32 = nv50_disp_chan_rd32,
+       .base.wr32 = nv50_disp_chan_wr32,
+       .chid = 5,
+       .attach = nvd0_disp_dmac_object_attach,
+       .detach = nvd0_disp_dmac_object_detach,
 };
 
 /*******************************************************************************
  * EVO PIO channel base class
  ******************************************************************************/
 
-static int
-nvd0_disp_pioc_create_(struct nouveau_object *parent,
-                      struct nouveau_object *engine,
-                      struct nouveau_oclass *oclass, int chid,
-                      int length, void **pobject)
-{
-       return nv50_disp_chan_create_(parent, engine, oclass, chid,
-                                     length, pobject);
-}
-
-static void
-nvd0_disp_pioc_dtor(struct nouveau_object *object)
-{
-       struct nv50_disp_pioc *pioc = (void *)object;
-       nv50_disp_chan_destroy(&pioc->base);
-}
-
 static int
 nvd0_disp_pioc_init(struct nouveau_object *object)
 {
@@ -643,74 +559,30 @@ nvd0_disp_pioc_fini(struct nouveau_object *object, bool suspend)
  * EVO immediate overlay channel objects
  ******************************************************************************/
 
-static int
-nvd0_disp_oimm_ctor(struct nouveau_object *parent,
-                   struct nouveau_object *engine,
-                   struct nouveau_oclass *oclass, void *data, u32 size,
-                   struct nouveau_object **pobject)
-{
-       struct nv50_display_oimm_class *args = data;
-       struct nv50_disp_priv *priv = (void *)engine;
-       struct nv50_disp_pioc *pioc;
-       int ret;
-
-       if (size < sizeof(*args) || args->head >= priv->head.nr)
-               return -EINVAL;
-
-       ret = nvd0_disp_pioc_create_(parent, engine, oclass, 9 + args->head,
-                                    sizeof(*pioc), (void **)&pioc);
-       *pobject = nv_object(pioc);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-struct nouveau_ofuncs
+struct nv50_disp_chan_impl
 nvd0_disp_oimm_ofuncs = {
-       .ctor = nvd0_disp_oimm_ctor,
-       .dtor = nvd0_disp_pioc_dtor,
-       .init = nvd0_disp_pioc_init,
-       .fini = nvd0_disp_pioc_fini,
-       .rd32 = nv50_disp_chan_rd32,
-       .wr32 = nv50_disp_chan_wr32,
+       .base.ctor = nv50_disp_oimm_ctor,
+       .base.dtor = nv50_disp_pioc_dtor,
+       .base.init = nvd0_disp_pioc_init,
+       .base.fini = nvd0_disp_pioc_fini,
+       .base.rd32 = nv50_disp_chan_rd32,
+       .base.wr32 = nv50_disp_chan_wr32,
+       .chid = 9,
 };
 
 /*******************************************************************************
  * EVO cursor channel objects
  ******************************************************************************/
 
-static int
-nvd0_disp_curs_ctor(struct nouveau_object *parent,
-                   struct nouveau_object *engine,
-                   struct nouveau_oclass *oclass, void *data, u32 size,
-                   struct nouveau_object **pobject)
-{
-       struct nv50_display_curs_class *args = data;
-       struct nv50_disp_priv *priv = (void *)engine;
-       struct nv50_disp_pioc *pioc;
-       int ret;
-
-       if (size < sizeof(*args) || args->head >= priv->head.nr)
-               return -EINVAL;
-
-       ret = nvd0_disp_pioc_create_(parent, engine, oclass, 13 + args->head,
-                                    sizeof(*pioc), (void **)&pioc);
-       *pobject = nv_object(pioc);
-       if (ret)
-               return ret;
-
-       return 0;
-}
-
-struct nouveau_ofuncs
+struct nv50_disp_chan_impl
 nvd0_disp_curs_ofuncs = {
-       .ctor = nvd0_disp_curs_ctor,
-       .dtor = nvd0_disp_pioc_dtor,
-       .init = nvd0_disp_pioc_init,
-       .fini = nvd0_disp_pioc_fini,
-       .rd32 = nv50_disp_chan_rd32,
-       .wr32 = nv50_disp_chan_wr32,
+       .base.ctor = nv50_disp_curs_ctor,
+       .base.dtor = nv50_disp_pioc_dtor,
+       .base.init = nvd0_disp_pioc_init,
+       .base.fini = nvd0_disp_pioc_fini,
+       .base.rd32 = nv50_disp_chan_rd32,
+       .base.wr32 = nv50_disp_chan_wr32,
+       .chid = 13,
 };
 
 /*******************************************************************************
@@ -860,11 +732,11 @@ nvd0_disp_base_oclass[] = {
 
 static struct nouveau_oclass
 nvd0_disp_sclass[] = {
-       { NVD0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs },
-       { NVD0_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs },
-       { NVD0_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs },
-       { NVD0_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs },
-       { NVD0_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs },
+       { NVD0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs.base },
+       { NVD0_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs.base },
+       { NVD0_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs.base },
+       { NVD0_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs.base },
+       { NVD0_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs.base },
        {}
 };
 
index 1e5a79a..49ab742 100644 (file)
@@ -200,11 +200,11 @@ nve0_disp_ovly_mthd_chan = {
 
 static struct nouveau_oclass
 nve0_disp_sclass[] = {
-       { NVE0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs },
-       { NVE0_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs },
-       { NVE0_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs },
-       { NVE0_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs },
-       { NVE0_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs },
+       { NVE0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs.base },
+       { NVE0_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs.base },
+       { NVE0_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs.base },
+       { NVE0_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs.base },
+       { NVE0_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs.base },
        {}
 };
 
index 198bc4b..448dc91 100644 (file)
 
 static struct nouveau_oclass
 nvf0_disp_sclass[] = {
-       { NVF0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs },
-       { NVF0_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs },
-       { NVF0_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs },
-       { NVF0_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs },
-       { NVF0_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs },
+       { NVF0_DISP_MAST_CLASS, &nvd0_disp_mast_ofuncs.base },
+       { NVF0_DISP_SYNC_CLASS, &nvd0_disp_sync_ofuncs.base },
+       { NVF0_DISP_OVLY_CLASS, &nvd0_disp_ovly_ofuncs.base },
+       { NVF0_DISP_OIMM_CLASS, &nvd0_disp_oimm_ofuncs.base },
+       { NVF0_DISP_CURS_CLASS, &nvd0_disp_curs_ofuncs.base },
        {}
 };