[PATCH 066/156] drm/nouveau/nvif: rework device "map" api

Ben Skeggs bskeggs at nvidia.com
Tue Apr 16 23:38:32 UTC 2024


- transition from "ioctl" interface

Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
 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



More information about the Nouveau mailing list