- transition from "ioctl" interface Signed-off-by: Ben Skeggs <bskeggs@xxxxxxxxxx> --- drivers/gpu/drm/nouveau/include/nvif/device.h | 2 + .../gpu/drm/nouveau/include/nvif/driverif.h | 11 +++++ drivers/gpu/drm/nouveau/include/nvif/object.h | 8 ++++ drivers/gpu/drm/nouveau/nvif/device.c | 5 +- drivers/gpu/drm/nouveau/nvif/object.c | 46 +++++++++++++++++++ drivers/gpu/drm/nouveau/nvkm/device/user.c | 16 ++----- 6 files changed, 74 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/nouveau/include/nvif/device.h b/drivers/gpu/drm/nouveau/include/nvif/device.h index c0f8920f0e08..27526d5811cf 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/device.h +++ b/drivers/gpu/drm/nouveau/include/nvif/device.h @@ -10,6 +10,8 @@ struct nvif_device { const struct nvif_device_impl *impl; struct nvif_device_priv *priv; struct nvif_object object; + struct nvif_map map; + struct nv_device_info_v0 info; struct nvif_fifo_runlist { diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h index 9ac4857714c7..03c4803f6492 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h +++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h @@ -13,9 +13,20 @@ struct nvif_driver { void (*unmap)(struct nvif_client_priv *, void __iomem *ptr, u32 size); }; +struct nvif_mapinfo { + enum nvif_map_type { + NVIF_MAP_IO, + NVIF_MAP_VA, + } type; + u64 handle; + u64 length; +}; + struct nvif_device_impl { void (*del)(struct nvif_device_priv *); + struct nvif_mapinfo map; + struct { s32 oclass; } usermode; diff --git a/drivers/gpu/drm/nouveau/include/nvif/object.h b/drivers/gpu/drm/nouveau/include/nvif/object.h index a84cdb423471..b3e66425f310 100644 --- a/drivers/gpu/drm/nouveau/include/nvif/object.h +++ b/drivers/gpu/drm/nouveau/include/nvif/object.h @@ -22,6 +22,12 @@ struct nvif_object { } map; }; +struct nvif_map { + const struct nvif_mapinfo *impl; + struct nvif_object *object; + void __iomem *ptr; +}; + static inline bool nvif_object_constructed(struct nvif_object *object) { @@ -43,6 +49,8 @@ int nvif_object_ioctl(struct nvif_object *, void *, u32, void **); int nvif_object_sclass_get(struct nvif_object *, struct nvif_sclass **); void nvif_object_sclass_put(struct nvif_sclass **); int nvif_object_mthd(struct nvif_object *, u32, void *, u32); +int nvif_object_map_cpu(struct nvif_object *, const struct nvif_mapinfo *, struct nvif_map *); +int nvif_object_unmap_cpu(struct nvif_map *); int nvif_object_map_handle(struct nvif_object *, void *, u32, u64 *handle, u64 *length); void nvif_object_unmap_handle(struct nvif_object *); diff --git a/drivers/gpu/drm/nouveau/nvif/device.c b/drivers/gpu/drm/nouveau/nvif/device.c index bb95e80f1c81..a0bc047ae28d 100644 --- a/drivers/gpu/drm/nouveau/nvif/device.c +++ b/drivers/gpu/drm/nouveau/nvif/device.c @@ -42,7 +42,7 @@ nvif_device_time(struct nvif_device *device) int nvif_device_map(struct nvif_device *device) { - return nvif_object_map(&device->object, NULL, 0); + return nvif_object_map_cpu(&device->object, &device->impl->map, &device->map); } void @@ -52,9 +52,12 @@ nvif_device_dtor(struct nvif_device *device) return; nvif_user_dtor(device); + kfree(device->runlist); device->runlist = NULL; + nvif_object_unmap_cpu(&device->map); + device->impl->del(device->priv); device->impl = NULL; } diff --git a/drivers/gpu/drm/nouveau/nvif/object.c b/drivers/gpu/drm/nouveau/nvif/object.c index f172f632979b..d0f4ddca085e 100644 --- a/drivers/gpu/drm/nouveau/nvif/object.c +++ b/drivers/gpu/drm/nouveau/nvif/object.c @@ -178,6 +178,52 @@ nvif_object_unmap(struct nvif_object *object) } } +int +nvif_object_unmap_cpu(struct nvif_map *map) +{ + struct nvif_client *client; + + if (!map->ptr || map->impl->type == NVIF_MAP_VA) + return 0; + if (map->impl->type != NVIF_MAP_IO) + return -EINVAL; + + client = map->object->client; + client->driver->unmap(client->priv, map->ptr, map->impl->length); + map->ptr = NULL; + return 0; +} + +int +nvif_object_map_cpu(struct nvif_object *object, + const struct nvif_mapinfo *impl, struct nvif_map *map) +{ + struct nvif_client *client = object->client; + void *ptr = NULL; + + switch (impl->type) { + case NVIF_MAP_IO: + ptr = client->driver->map(client->priv, impl->handle, impl->length); + break; + case NVIF_MAP_VA: + ptr = (void **)(unsigned long)impl->handle; + break; + default: + WARN_ON(1); + return -EINVAL; + } + + if (!ptr) + return -EFAULT; + + map->object = object; + map->impl = impl; + map->ptr = ptr; + + object->map.ptr = map->ptr; /*FIXME: needed by nvif_rd/wr */ + return 0; +} + int nvif_object_map(struct nvif_object *object, void *argv, u32 argc) { diff --git a/drivers/gpu/drm/nouveau/nvkm/device/user.c b/drivers/gpu/drm/nouveau/nvkm/device/user.c index f55088849a0c..229245b03719 100644 --- a/drivers/gpu/drm/nouveau/nvkm/device/user.c +++ b/drivers/gpu/drm/nouveau/nvkm/device/user.c @@ -222,18 +222,6 @@ nvkm_udevice_mthd(struct nvkm_object *object, u32 mthd, void *data, u32 size) return -EINVAL; } -static int -nvkm_udevice_map(struct nvkm_object *object, void *argv, u32 argc, - enum nvkm_object_map *type, u64 *addr, u64 *size) -{ - struct nvif_device_priv *udev = container_of(object, typeof(*udev), 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; -} - static int nvkm_udevice_fini(struct nvkm_object *object, bool suspend) { @@ -333,7 +321,6 @@ nvkm_udevice = { .init = nvkm_udevice_init, .fini = nvkm_udevice_fini, .mthd = nvkm_udevice_mthd, - .map = nvkm_udevice_map, .sclass = nvkm_udevice_child_get, }; @@ -356,6 +343,9 @@ nvkm_udevice_new(struct nvkm_device *device, goto done; udev->impl = nvkm_udevice_impl; + udev->impl.map.type = NVIF_MAP_IO; + udev->impl.map.handle = device->func->resource_addr(device, 0); + udev->impl.map.length = device->func->resource_size(device, 0); if (device->vfn) { udev->impl.usermode.oclass = device->vfn->user.base.oclass; -- 2.41.0