]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
drm/nouveau/core/object: allow arguments to be passed to map function
authorBen Skeggs <bskeggs@redhat.com>
Tue, 31 Oct 2017 17:56:19 +0000 (03:56 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 2 Nov 2017 03:32:16 +0000 (13:32 +1000)
MMU will be needing this to specify kind info on BAR mappings.

We have no userspace currently using these interfaces, so break the ABI
instead of supporting both.  NVIF version bump so any future use can be
guarded.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
13 files changed:
drivers/gpu/drm/nouveau/dispnv04/disp.c
drivers/gpu/drm/nouveau/include/nvif/ioctl.h
drivers/gpu/drm/nouveau/include/nvif/object.h
drivers/gpu/drm/nouveau/include/nvkm/core/object.h
drivers/gpu/drm/nouveau/nouveau_chan.c
drivers/gpu/drm/nouveau/nv50_display.c
drivers/gpu/drm/nouveau/nvif/object.c
drivers/gpu/drm/nouveau/nvkm/core/ioctl.c
drivers/gpu/drm/nouveau/nvkm/core/object.c
drivers/gpu/drm/nouveau/nvkm/core/oproxy.c
drivers/gpu/drm/nouveau/nvkm/engine/device/user.c
drivers/gpu/drm/nouveau/nvkm/engine/disp/channv50.c
drivers/gpu/drm/nouveau/nvkm/engine/fifo/chan.c

index 5b9d549aa791f5d02d1abef5e1c96e1aaf4bf2c6..501d2d290e9c6c49072c8a57d9a3643dd286b731 100644 (file)
@@ -48,7 +48,7 @@ nv04_display_create(struct drm_device *dev)
        if (!disp)
                return -ENOMEM;
 
-       nvif_object_map(&drm->client.device.object);
+       nvif_object_map(&drm->client.device.object, NULL, 0);
 
        nouveau_display(dev)->priv = disp;
        nouveau_display(dev)->dtor = nv04_display_destroy;
index c5f5eb83a59449c1a55918588dcd4d0edc83546f..1886366457f18cdd83db32c70d5154995b957ca6 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __NVIF_IOCTL_H__
 #define __NVIF_IOCTL_H__
 
-#define NVIF_VERSION_LATEST                               0x0000000000000000ULL
+#define NVIF_VERSION_LATEST                               0x0000000000000100ULL
 
 struct nvif_ioctl_v0 {
        __u8  version;
@@ -83,9 +83,13 @@ struct nvif_ioctl_wr_v0 {
 struct nvif_ioctl_map_v0 {
        /* nvif_ioctl ... */
        __u8  version;
-       __u8  pad01[3];
-       __u32 length;
+#define NVIF_IOCTL_MAP_V0_IO                                               0x00
+#define NVIF_IOCTL_MAP_V0_VA                                               0x01
+       __u8  type;
+       __u8  pad02[6];
        __u64 handle;
+       __u64 length;
+       __u8  data[];
 };
 
 struct nvif_ioctl_unmap {
index 9e58b305b020380ac3f033d535e216485c09d05a..0b54261bdefe5609949c793f9bfe4eb7944061c2 100644 (file)
@@ -16,7 +16,7 @@ struct nvif_object {
        void *priv; /*XXX: hack */
        struct {
                void __iomem *ptr;
-               u32 size;
+               u64 size;
        } map;
 };
 
@@ -29,7 +29,10 @@ void nvif_object_sclass_put(struct nvif_sclass **);
 u32  nvif_object_rd(struct nvif_object *, int, u64);
 void nvif_object_wr(struct nvif_object *, int, u64, u32);
 int  nvif_object_mthd(struct nvif_object *, u32, void *, u32);
-int  nvif_object_map(struct nvif_object *);
+int  nvif_object_map_handle(struct nvif_object *, void *, u32,
+                           u64 *handle, u64 *length);
+void nvif_object_unmap_handle(struct nvif_object *);
+int  nvif_object_map(struct nvif_object *, void *, u32);
 void nvif_object_unmap(struct nvif_object *);
 
 #define nvif_handle(a) (unsigned long)(void *)(a)
index 5a092ffb5abf87da45db7b297e61425ea1ac943d..4797577d52ce381e7177902d5b6b6be0f2e9eb0d 100644 (file)
@@ -19,13 +19,19 @@ struct nvkm_object {
        struct rb_node node;
 };
 
+enum nvkm_object_map {
+       NVKM_OBJECT_MAP_IO,
+       NVKM_OBJECT_MAP_VA
+};
+
 struct nvkm_object_func {
        void *(*dtor)(struct nvkm_object *);
        int (*init)(struct nvkm_object *);
        int (*fini)(struct nvkm_object *, bool suspend);
        int (*mthd)(struct nvkm_object *, u32 mthd, void *data, u32 size);
        int (*ntfy)(struct nvkm_object *, u32 mthd, struct nvkm_event **);
-       int (*map)(struct nvkm_object *, u64 *addr, u32 *size);
+       int (*map)(struct nvkm_object *, void *argv, u32 argc,
+                  enum nvkm_object_map *, u64 *addr, u64 *size);
        int (*rd08)(struct nvkm_object *, u64 addr, u8 *data);
        int (*rd16)(struct nvkm_object *, u64 addr, u16 *data);
        int (*rd32)(struct nvkm_object *, u64 addr, u32 *data);
@@ -50,7 +56,8 @@ int nvkm_object_init(struct nvkm_object *);
 int nvkm_object_fini(struct nvkm_object *, bool suspend);
 int nvkm_object_mthd(struct nvkm_object *, u32 mthd, void *data, u32 size);
 int nvkm_object_ntfy(struct nvkm_object *, u32 mthd, struct nvkm_event **);
-int nvkm_object_map(struct nvkm_object *, u64 *addr, u32 *size);
+int nvkm_object_map(struct nvkm_object *, void *argv, u32 argc,
+                   enum nvkm_object_map *, u64 *addr, u64 *size);
 int nvkm_object_rd08(struct nvkm_object *, u64 addr, u8  *data);
 int nvkm_object_rd16(struct nvkm_object *, u64 addr, u16 *data);
 int nvkm_object_rd32(struct nvkm_object *, u64 addr, u32 *data);
index dbc41fa86ee8bf8f36666dfbb27ebc4daf2884d6..4af09e9be93041069a086436056404f2b5ac17eb 100644 (file)
@@ -318,7 +318,7 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
        struct nv_dma_v0 args = {};
        int ret, i;
 
-       nvif_object_map(&chan->user);
+       nvif_object_map(&chan->user, NULL, 0);
 
        if (chan->user.oclass >= FERMI_CHANNEL_GPFIFO) {
                ret = nvif_notify_init(&chan->user, nouveau_channel_killed,
index 9cd5a53f85fa7a6bc32d6bc70de5751b39985e59..1f3872f438c97b44979d6fb89c2176a2c6a719a0 100644 (file)
@@ -318,7 +318,7 @@ nv50_chan_create(struct nvif_device *device, struct nvif_object *disp,
                                ret = nvif_object_init(disp, 0, oclass[0],
                                                       data, size, &chan->user);
                                if (ret == 0)
-                                       nvif_object_map(&chan->user);
+                                       nvif_object_map(&chan->user, NULL, 0);
                                nvif_object_sclass_put(&sclass);
                                return ret;
                        }
index c3fb6a20f567d1454bfb49ffd19b151470eb6b90..40adfe9b334b3c45f899f543d161b2a2ee6cdf51 100644 (file)
@@ -166,46 +166,77 @@ nvif_object_mthd(struct nvif_object *object, u32 mthd, void *data, u32 size)
 }
 
 void
-nvif_object_unmap(struct nvif_object *object)
+nvif_object_unmap_handle(struct nvif_object *object)
+{
+       struct {
+               struct nvif_ioctl_v0 ioctl;
+               struct nvif_ioctl_unmap unmap;
+       } args = {
+               .ioctl.type = NVIF_IOCTL_V0_UNMAP,
+       };
+
+       nvif_object_ioctl(object, &args, sizeof(args), NULL);
+}
+
+int
+nvif_object_map_handle(struct nvif_object *object, void *argv, u32 argc,
+                      u64 *handle, u64 *length)
 {
-       if (object->map.size) {
-               struct nvif_client *client = object->client;
-               struct {
-                       struct nvif_ioctl_v0 ioctl;
-                       struct nvif_ioctl_unmap unmap;
-               } args = {
-                       .ioctl.type = NVIF_IOCTL_V0_UNMAP,
-               };
+       struct {
+               struct nvif_ioctl_v0 ioctl;
+               struct nvif_ioctl_map_v0 map;
+       } *args;
+       u32 argn = sizeof(*args) + argc;
+       int ret, maptype;
+
+       if (!(args = kzalloc(argn, GFP_KERNEL)))
+               return -ENOMEM;
+       args->ioctl.type = NVIF_IOCTL_V0_MAP;
+       memcpy(args->map.data, argv, argc);
 
-               if (object->map.ptr) {
+       ret = nvif_object_ioctl(object, args, argn, NULL);
+       *handle = args->map.handle;
+       *length = args->map.length;
+       maptype = args->map.type;
+       kfree(args);
+       return ret ? ret : (maptype == NVIF_IOCTL_MAP_V0_IO);
+}
+
+void
+nvif_object_unmap(struct nvif_object *object)
+{
+       struct nvif_client *client = object->client;
+       if (object->map.ptr) {
+               if (object->map.size) {
                        client->driver->unmap(client, object->map.ptr,
                                                      object->map.size);
-                       object->map.ptr = NULL;
+                       object->map.size = 0;
                }
-
-               nvif_object_ioctl(object, &args, sizeof(args), NULL);
-               object->map.size = 0;
+               object->map.ptr = NULL;
+               nvif_object_unmap_handle(object);
        }
 }
 
 int
-nvif_object_map(struct nvif_object *object)
+nvif_object_map(struct nvif_object *object, void *argv, u32 argc)
 {
        struct nvif_client *client = object->client;
-       struct {
-               struct nvif_ioctl_v0 ioctl;
-               struct nvif_ioctl_map_v0 map;
-       } args = {
-               .ioctl.type = NVIF_IOCTL_V0_MAP,
-       };
-       int ret = nvif_object_ioctl(object, &args, sizeof(args), NULL);
-       if (ret == 0) {
-               object->map.size = args.map.length;
-               object->map.ptr = client->driver->map(client, args.map.handle,
-                                                     object->map.size);
-               if (ret = -ENOMEM, object->map.ptr)
+       u64 handle, length;
+       int ret = nvif_object_map_handle(object, argv, argc, &handle, &length);
+       if (ret >= 0) {
+               if (ret) {
+                       object->map.ptr = client->driver->map(client,
+                                                             handle,
+                                                             length);
+                       if (ret = -ENOMEM, object->map.ptr) {
+                               object->map.size = length;
+                               return 0;
+                       }
+               } else {
+                       object->map.ptr = (void *)(unsigned long)handle;
                        return 0;
-               nvif_object_unmap(object);
+               }
+               nvif_object_unmap_handle(object);
        }
        return ret;
 }
index be19bbe56bba8d81ab47cd688724f580dfb86c46..bf2507f17baa5063f2e9fe19f6d8e11b3a916b62 100644 (file)
@@ -257,13 +257,19 @@ nvkm_ioctl_map(struct nvkm_client *client,
        union {
                struct nvif_ioctl_map_v0 v0;
        } *args = data;
+       enum nvkm_object_map type;
        int ret = -ENOSYS;
 
        nvif_ioctl(object, "map size %d\n", size);
-       if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, false))) {
+       if (!(ret = nvif_unpack(ret, &data, &size, args->v0, 0, 0, true))) {
                nvif_ioctl(object, "map vers %d\n", args->v0.version);
-               ret = nvkm_object_map(object, &args->v0.handle,
-                                             &args->v0.length);
+               ret = nvkm_object_map(object, data, size, &type,
+                                     &args->v0.handle,
+                                     &args->v0.length);
+               if (type == NVKM_OBJECT_MAP_IO)
+                       args->v0.type = NVIF_IOCTL_MAP_V0_IO;
+               else
+                       args->v0.type = NVIF_IOCTL_MAP_V0_VA;
        }
 
        return ret;
index acd76fd4f6d85eab1fe6fea719a888f93725c575..516e73a52665079ef83285b17000005a04646769 100644 (file)
@@ -102,10 +102,11 @@ nvkm_object_ntfy(struct nvkm_object *object, u32 mthd,
 }
 
 int
-nvkm_object_map(struct nvkm_object *object, u64 *addr, u32 *size)
+nvkm_object_map(struct nvkm_object *object, void *argv, u32 argc,
+               enum nvkm_object_map *type, u64 *addr, u64 *size)
 {
        if (likely(object->func->map))
-               return object->func->map(object, addr, size);
+               return object->func->map(object, argv, argc, type, addr, size);
        return -ENODEV;
 }
 
index e31a0479add0d6930dcf932da30f4402b3350df8..e7dd15b97721748266afd43e23b2a3b3a5d07590 100644 (file)
@@ -37,9 +37,11 @@ nvkm_oproxy_ntfy(struct nvkm_object *object, u32 mthd,
 }
 
 static int
-nvkm_oproxy_map(struct nvkm_object *object, u64 *addr, u32 *size)
+nvkm_oproxy_map(struct nvkm_object *object, void *argv, u32 argc,
+               enum nvkm_object_map *type, u64 *addr, u64 *size)
 {
-       return nvkm_object_map(nvkm_oproxy(object)->object, addr, size);
+       struct nvkm_oproxy *oproxy = nvkm_oproxy(object);
+       return nvkm_object_map(oproxy->object, argv, argc, type, addr, size);
 }
 
 static int
index 513ee6b79553df3f459c9dad0ca2dcc62b63c6fe..e9b90e40f27464540ec420355ff04f4df83a7265 100644 (file)
@@ -206,10 +206,12 @@ nvkm_udevice_wr32(struct nvkm_object *object, u64 addr, u32 data)
 }
 
 static int
-nvkm_udevice_map(struct nvkm_object *object, u64 *addr, u32 *size)
+nvkm_udevice_map(struct nvkm_object *object, void *argv, u32 argc,
+                enum nvkm_object_map *type, u64 *addr, u64 *size)
 {
        struct nvkm_udevice *udev = nvkm_udevice(object);
        struct nvkm_device *device = udev->device;
+       *type = NVKM_OBJECT_MAP_IO;
        *addr = device->func->resource_addr(device, 0);
        *size = device->func->resource_size(device, 0);
        return 0;
index 0c0310498afdb99e59459b5e70873bc7ad6a5f55..723dcbde2ac2fae44de8a30a09d12fb3e2b84ce6 100644 (file)
@@ -191,11 +191,13 @@ nv50_disp_chan_ntfy(struct nvkm_object *object, u32 type,
 }
 
 static int
-nv50_disp_chan_map(struct nvkm_object *object, u64 *addr, u32 *size)
+nv50_disp_chan_map(struct nvkm_object *object, void *argv, u32 argc,
+                  enum nvkm_object_map *type, u64 *addr, u64 *size)
 {
        struct nv50_disp_chan *chan = nv50_disp_chan(object);
        struct nv50_disp *disp = chan->root->disp;
        struct nvkm_device *device = disp->base.engine.subdev.device;
+       *type = NVKM_OBJECT_MAP_IO;
        *addr = device->func->resource_addr(device, 0) +
                0x640000 + (chan->chid.user * 0x1000);
        *size = 0x001000;
index fab760ae922fbe4784084d0cbc77f5496e2997bf..7aea0a8692aee3e080f62f4ef99f2513d8d80e27 100644 (file)
@@ -253,9 +253,11 @@ nvkm_fifo_chan_ntfy(struct nvkm_object *object, u32 type,
 }
 
 static int
-nvkm_fifo_chan_map(struct nvkm_object *object, u64 *addr, u32 *size)
+nvkm_fifo_chan_map(struct nvkm_object *object, void *argv, u32 argc,
+                  enum nvkm_object_map *type, u64 *addr, u64 *size)
 {
        struct nvkm_fifo_chan *chan = nvkm_fifo_chan(object);
+       *type = NVKM_OBJECT_MAP_IO;
        *addr = chan->addr;
        *size = chan->size;
        return 0;