drm/nouveau/kms/nv50-: modify cursor allocation so the code can be split
authorBen Skeggs <bskeggs@redhat.com>
Tue, 8 May 2018 10:39:47 +0000 (20:39 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Fri, 18 May 2018 05:01:27 +0000 (15:01 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/dispnv50/disp.c

index 26caca2..33cb358 100644 (file)
@@ -617,12 +617,14 @@ struct nv50_wndw_func {
        void (*image_set)(struct nv50_wndw *, struct nv50_wndw_atom *);
        void (*image_clr)(struct nv50_wndw *);
        void (*lut)(struct nv50_wndw *, struct nv50_wndw_atom *);
-       void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *);
 
        u32 (*update)(struct nv50_wndw *, u32 interlock);
 };
 
 struct nv50_wimm_func {
+       void (*point)(struct nv50_wndw *, struct nv50_wndw_atom *);
+
+       u32 (*update)(struct nv50_wndw *, u32 interlock);
 };
 
 static void
@@ -728,9 +730,12 @@ nv50_wndw_flush_set(struct nv50_wndw *wndw, u32 interlock,
        if (asyw->set.ntfy ) wndw->func->ntfy_set (wndw, asyw);
        if (asyw->set.image) wndw->func->image_set(wndw, asyw);
        if (asyw->set.lut  ) wndw->func->lut      (wndw, asyw);
-       if (asyw->set.point) wndw->func->point    (wndw, asyw);
+       if (asyw->set.point) {
+               wndw->immd->point(wndw, asyw);
+               wndw->immd->update(wndw, interlock);
+       }
 
-       return wndw->func->update(wndw, interlock);
+       return wndw->func->update ? wndw->func->update(wndw, interlock) : 0;
 }
 
 static void
@@ -1181,28 +1186,26 @@ nv50_ovly_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
 /******************************************************************************
  * Cursor plane
  *****************************************************************************/
-#define nv50_curs(p) container_of((p), struct nv50_curs, wndw)
-
-struct nv50_curs {
-       struct nv50_wndw wndw;
-       struct nvif_object chan;
-};
-
 static u32
 nv50_curs_update(struct nv50_wndw *wndw, u32 interlock)
 {
-       struct nv50_curs *curs = nv50_curs(wndw);
-       nvif_wr32(&curs->chan, 0x0080, 0x00000000);
+       nvif_wr32(&wndw->wimm.base.user, 0x0080, 0x00000000);
        return 0;
 }
 
 static void
 nv50_curs_point(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw)
 {
-       struct nv50_curs *curs = nv50_curs(wndw);
-       nvif_wr32(&curs->chan, 0x0084, (asyw->point.y << 16) | asyw->point.x);
+       nvif_wr32(&wndw->wimm.base.user, 0x0084, (asyw->point.y << 16) |
+                                                 asyw->point.x);
 }
 
+static const struct nv50_wimm_func
+curs507a = {
+       .point = nv50_curs_point,
+       .update = nv50_curs_update,
+};
+
 static void
 nv50_curs_prepare(struct nv50_wndw *wndw, struct nv50_head_atom *asyh,
                  struct nv50_wndw_atom *asyw)
@@ -1257,77 +1260,82 @@ nv50_curs_acquire(struct nv50_wndw *wndw, struct nv50_wndw_atom *asyw,
        return 0;
 }
 
-static void *
-nv50_curs_dtor(struct nv50_wndw *wndw)
-{
-       struct nv50_curs *curs = nv50_curs(wndw);
-       nvif_object_fini(&curs->chan);
-       return curs;
-}
-
 static const u32
 nv50_curs_format[] = {
        DRM_FORMAT_ARGB8888,
+       0
 };
 
 static const struct nv50_wndw_func
 nv50_curs = {
-       .dtor = nv50_curs_dtor,
        .acquire = nv50_curs_acquire,
        .release = nv50_curs_release,
        .prepare = nv50_curs_prepare,
-       .point = nv50_curs_point,
-       .update = nv50_curs_update,
 };
 
 static int
-nv50_curs_new(struct nouveau_drm *drm, struct nv50_head *head,
-             struct nv50_curs **pcurs)
-{
-       static const struct nvif_mclass curses[] = {
-               { GK104_DISP_CURSOR, 0 },
-               { GF110_DISP_CURSOR, 0 },
-               { GT214_DISP_CURSOR, 0 },
-               {   G82_DISP_CURSOR, 0 },
-               {  NV50_DISP_CURSOR, 0 },
-               {}
-       };
+curs507a_new_(const struct nv50_wimm_func *func, struct nouveau_drm *drm,
+             int head, s32 oclass, struct nv50_wndw **pwndw)
+{
        struct nv50_disp_cursor_v0 args = {
-               .head = head->base.index,
+               .head = head,
        };
        struct nv50_disp *disp = nv50_disp(drm->dev);
-       struct nv50_curs *curs;
-       int cid, ret;
-
-       cid = nvif_mclass(&disp->disp->object, curses);
-       if (cid < 0) {
-               NV_ERROR(drm, "No supported cursor immediate class\n");
-               return cid;
-       }
-
-       if (!(curs = *pcurs = kzalloc(sizeof(*curs), GFP_KERNEL)))
-               return -ENOMEM;
+       struct nv50_wndw *wndw;
+       int ret;
 
-       ret = nv50_wndw_ctor(&nv50_curs, drm->dev, DRM_PLANE_TYPE_CURSOR,
-                            "curs", head->base.index, &disp->mast.base,
-                            nv50_curs_format, ARRAY_SIZE(nv50_curs_format),
-                            &curs->wndw);
-       if (ret) {
-               kfree(curs);
+       ret = nv50_wndw_new_(&nv50_curs, drm->dev, DRM_PLANE_TYPE_CURSOR,
+                            "curs", head, nv50_curs_format, &wndw);
+       if (*pwndw = wndw, ret)
                return ret;
-       }
 
-       ret = nvif_object_init(&disp->disp->object, 0, curses[cid].oclass,
-                              &args, sizeof(args), &curs->chan);
+       ret = nvif_object_init(&disp->disp->object, 0, oclass, &args,
+                              sizeof(args), &wndw->wimm.base.user);
        if (ret) {
-               NV_ERROR(drm, "curs%04x allocation failed: %d\n",
-                        curses[cid].oclass, ret);
+               NV_ERROR(drm, "curs%04x allocation failed: %d\n", oclass, ret);
                return ret;
        }
 
+       nvif_object_map(&wndw->wimm.base.user, NULL, 0);
+       wndw->immd = func;
+       wndw->ctxdma.parent = &disp->mast.base.base.user;
        return 0;
 }
 
+static int
+curs507a_new(struct nouveau_drm *drm, int head, s32 oclass,
+            struct nv50_wndw **pwndw)
+{
+       return curs507a_new_(&curs507a, drm, head, oclass, pwndw);
+}
+
+static int
+nv50_curs_new(struct nouveau_drm *drm, int head, struct nv50_wndw **pwndw)
+{
+       struct {
+               s32 oclass;
+               int version;
+               int (*new)(struct nouveau_drm *, int, s32, struct nv50_wndw **);
+       } curses[] = {
+               { GK104_DISP_CURSOR, 0, curs507a_new },
+               { GF110_DISP_CURSOR, 0, curs507a_new },
+               { GT214_DISP_CURSOR, 0, curs507a_new },
+               {   G82_DISP_CURSOR, 0, curs507a_new },
+               {  NV50_DISP_CURSOR, 0, curs507a_new },
+               {}
+       };
+       struct nv50_disp *disp = nv50_disp(drm->dev);
+       int cid;
+
+       cid = nvif_mclass(&disp->disp->object, curses);
+       if (cid < 0) {
+               NV_ERROR(drm, "No supported cursor immediate class\n");
+               return cid;
+       }
+
+       return curses[cid].new(drm, head, curses[cid].oclass, pwndw);
+}
+
 /******************************************************************************
  * Primary plane
  *****************************************************************************/
@@ -2464,8 +2472,7 @@ nv50_head_create(struct drm_device *dev, int index)
        struct nouveau_drm *drm = nouveau_drm(dev);
        struct nv50_head *head;
        struct nv50_base *base;
-       struct nv50_curs *curs;
-       struct nv50_wndw *wndw;
+       struct nv50_wndw *curs, *wndw;
        struct drm_crtc *crtc;
        int ret, i;
 
@@ -2476,16 +2483,15 @@ nv50_head_create(struct drm_device *dev, int index)
        head->base.index = index;
        ret = nv50_base_new(drm, head, &base);
        if (ret == 0)
-               ret = nv50_curs_new(drm, head, &curs);
+               ret = nv50_curs_new(drm, head->base.index, &curs);
        if (ret) {
                kfree(head);
                return ret;
        }
 
        crtc = &head->base.base;
-       drm_crtc_init_with_planes(dev, crtc, &base->wndw.plane,
-                                 &curs->wndw.plane, &nv50_head_func,
-                                 "head-%d", head->base.index);
+       drm_crtc_init_with_planes(dev, crtc, &base->wndw.plane, &curs->plane,
+                                 &nv50_head_func, "head-%d", head->base.index);
        drm_crtc_helper_add(crtc, &nv50_head_help);
        drm_mode_crtc_set_gamma_size(crtc, 256);