[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