[PATCH 078/156] drm/nouveau/nvif: rework device "new mmu" api

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


- transition from "ioctl" interfaces

Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
 .../gpu/drm/nouveau/include/nvif/driverif.h   | 13 ++++++
 drivers/gpu/drm/nouveau/include/nvif/if0008.h |  7 ---
 drivers/gpu/drm/nouveau/include/nvif/mmu.h    |  8 ++--
 drivers/gpu/drm/nouveau/nouveau_drm.c         |  5 +-
 drivers/gpu/drm/nouveau/nouveau_ttm.c         |  4 +-
 drivers/gpu/drm/nouveau/nvif/mmu.c            | 30 ++++++------
 drivers/gpu/drm/nouveau/nvkm/device/user.c    | 22 +++++++--
 .../gpu/drm/nouveau/nvkm/subdev/mmu/base.c    |  1 -
 .../gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c    | 46 ++++++++++++-------
 .../gpu/drm/nouveau/nvkm/subdev/mmu/ummu.h    | 10 ++--
 10 files changed, 94 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
index cd96e9c36f55..7bba8c79d71e 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
@@ -5,6 +5,7 @@ struct nvif_client_priv;
 struct nvif_device_priv;
 struct nvif_control_priv;
 struct nvif_usermode_priv;
+struct nvif_mmu_priv;
 
 struct nvif_driver {
 	const char *name;
@@ -75,6 +76,16 @@ struct nvif_usermode_impl {
 	struct nvif_mapinfo map;
 };
 
+struct nvif_mmu_impl {
+	void (*del)(struct nvif_mmu_priv *);
+
+	u8 dmabits;
+	u8 heap_nr;
+	u8 type_nr;
+
+	u16 kind_nr;
+};
+
 struct nvif_device_impl {
 	void (*del)(struct nvif_device_priv *);
 
@@ -129,6 +140,8 @@ struct nvif_device_impl {
 
 	struct {
 		s32 oclass;
+		int (*new)(struct nvif_device_priv *, const struct nvif_mmu_impl **,
+			   struct nvif_mmu_priv **, u64 handle);
 	} mmu;
 
 	struct {
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0008.h b/drivers/gpu/drm/nouveau/include/nvif/if0008.h
index c21d09f04f1d..618df13762d3 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/if0008.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/if0008.h
@@ -1,12 +1,5 @@
 #ifndef __NVIF_IF0008_H__
 #define __NVIF_IF0008_H__
-struct nvif_mmu_v0 {
-	__u8  version;
-	__u8  dmabits;
-	__u8  heap_nr;
-	__u8  type_nr;
-	__u16 kind_nr;
-};
 
 #define NVIF_MMU_V0_HEAP                                                   0x00
 #define NVIF_MMU_V0_TYPE                                                   0x01
diff --git a/drivers/gpu/drm/nouveau/include/nvif/mmu.h b/drivers/gpu/drm/nouveau/include/nvif/mmu.h
index 2035ef1d35f5..414caaa2230a 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/mmu.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/mmu.h
@@ -1,10 +1,13 @@
 #ifndef __NVIF_MMU_H__
 #define __NVIF_MMU_H__
 #include <nvif/object.h>
+#include <nvif/driverif.h>
+struct nvif_device;
 
 struct nvif_mmu {
+	const struct nvif_mmu_impl *impl;
+	struct nvif_mmu_priv *priv;
 	struct nvif_object object;
-	u8  dmabits;
 	u8  heap_nr;
 	u8  type_nr;
 	u8  kind_inv;
@@ -31,8 +34,7 @@ struct nvif_mmu {
 	u8 *kind;
 };
 
-int nvif_mmu_ctor(struct nvif_object *, const char *name, s32 oclass,
-		  struct nvif_mmu *);
+int nvif_mmu_ctor(struct nvif_device *, const char *name, struct nvif_mmu *);
 void nvif_mmu_dtor(struct nvif_mmu *);
 
 static inline bool
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index a91ad8e65a0f..1dba64a1e590 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -236,8 +236,7 @@ nouveau_cli_init(struct nouveau_drm *drm, const char *sname,
 
 	cli->device.object.map.ptr = drm->device.object.map.ptr;
 
-	ret = nvif_mmu_ctor(&cli->device.object, "drmMmu", drm->mmu.object.oclass,
-			    &cli->mmu);
+	ret = nvif_mmu_ctor(&cli->device, "drmMmu", &cli->mmu);
 	if (ret) {
 		NV_PRINTK(err, cli, "MMU allocation failed: %d\n", ret);
 		goto done;
@@ -569,7 +568,7 @@ nouveau_drm_device_init(struct drm_device *dev, struct nvkm_device *nvkm)
 		goto fail_nvif;
 	}
 
-	ret = nvif_mmu_ctor(&drm->device.object, "drmMmu", drm->device.impl->mmu.oclass, &drm->mmu);
+	ret = nvif_mmu_ctor(&drm->device, "drmMmu", &drm->mmu);
 	if (ret) {
 		NV_ERROR(drm, "MMU allocation failed: %d\n", ret);
 		goto fail_nvif;
diff --git a/drivers/gpu/drm/nouveau/nouveau_ttm.c b/drivers/gpu/drm/nouveau/nouveau_ttm.c
index 57c7e3ba8e7b..f87ca8a0e6ae 100644
--- a/drivers/gpu/drm/nouveau/nouveau_ttm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_ttm.c
@@ -302,8 +302,8 @@ nouveau_ttm_init(struct nouveau_drm *drm)
 	ret = ttm_device_init(&drm->ttm.bdev, &nouveau_bo_driver, drm->dev->dev,
 				  dev->anon_inode->i_mapping,
 				  dev->vma_offset_manager,
-				  drm_need_swiotlb(drm->client.mmu.dmabits),
-				  drm->client.mmu.dmabits <= 32);
+				  drm_need_swiotlb(drm->mmu.impl->dmabits),
+				  drm->mmu.impl->dmabits <= 32);
 	if (ret) {
 		NV_ERROR(drm, "error initialising bo driver, %d\n", ret);
 		return ret;
diff --git a/drivers/gpu/drm/nouveau/nvif/mmu.c b/drivers/gpu/drm/nouveau/nvif/mmu.c
index c9dd3cff49a0..cc15cf99462c 100644
--- a/drivers/gpu/drm/nouveau/nvif/mmu.c
+++ b/drivers/gpu/drm/nouveau/nvif/mmu.c
@@ -20,6 +20,8 @@
  * OTHER DEALINGS IN THE SOFTWARE.
  */
 #include <nvif/mmu.h>
+#include <nvif/device.h>
+#include <nvif/printf.h>
 
 #include <nvif/class.h>
 #include <nvif/if0008.h>
@@ -27,18 +29,18 @@
 void
 nvif_mmu_dtor(struct nvif_mmu *mmu)
 {
-	if (!nvif_object_constructed(&mmu->object))
+	if (!mmu->impl)
 		return;
 
 	kfree(mmu->kind);
 	kfree(mmu->type);
 	kfree(mmu->heap);
-	nvif_object_dtor(&mmu->object);
+	mmu->impl->del(mmu->priv);
+	mmu->impl = NULL;
 }
 
 int
-nvif_mmu_ctor(struct nvif_object *parent, const char *name, s32 oclass,
-	      struct nvif_mmu *mmu)
+nvif_mmu_ctor(struct nvif_device *device, const char *name, struct nvif_mmu *mmu)
 {
 	static const struct nvif_mclass mems[] = {
 		{ NVIF_CLASS_MEM_GF100, -1 },
@@ -46,23 +48,25 @@ nvif_mmu_ctor(struct nvif_object *parent, const char *name, s32 oclass,
 		{ NVIF_CLASS_MEM_NV04 , -1 },
 		{}
 	};
-	struct nvif_mmu_v0 args;
+	const s32 oclass = device->impl->mmu.oclass;
 	int ret, i;
 
-	args.version = 0;
+	mmu->impl = NULL;
 	mmu->heap = NULL;
 	mmu->type = NULL;
 	mmu->kind = NULL;
 
-	ret = nvif_object_ctor(parent, name ? name : "nvifMmu", 0, oclass,
-			       &args, sizeof(args), &mmu->object);
+	ret = device->impl->mmu.new(device->priv, &mmu->impl, &mmu->priv,
+				    nvif_handle(&mmu->object));
+	NVIF_ERRON(ret, &device->object, "[NEW mmu%08x]", oclass);
 	if (ret)
-		goto done;
+		return ret;
+
+	nvif_object_ctor(&device->object, name ?: "nvifMmu", 0, oclass, &mmu->object);
 
-	mmu->dmabits = args.dmabits;
-	mmu->heap_nr = args.heap_nr;
-	mmu->type_nr = args.type_nr;
-	mmu->kind_nr = args.kind_nr;
+	mmu->heap_nr = mmu->impl->heap_nr;
+	mmu->type_nr = mmu->impl->type_nr;
+	mmu->kind_nr = mmu->impl->kind_nr;
 
 	ret = nvif_mclass(&mmu->object, mems);
 	if (ret < 0)
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/user.c b/drivers/gpu/drm/nouveau/nvkm/device/user.c
index cd126f5b165a..e9486d9da64b 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/user.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/user.c
@@ -29,6 +29,7 @@
 #include <subdev/fb.h>
 #include <subdev/instmem.h>
 #include <subdev/timer.h>
+#include <subdev/mmu/ummu.h>
 #include <subdev/vfn/uvfn.h>
 #include <engine/disp/priv.h>
 #include <engine/fifo/ufifo.h>
@@ -76,6 +77,22 @@ nvkm_udevice_time(struct nvif_device_priv *udev)
 	return nvkm_timer_read(udev->device->timer);
 }
 
+static int
+nvkm_udevice_mmu_new(struct nvif_device_priv *udev,
+		     const struct nvif_mmu_impl **pimpl, struct nvif_mmu_priv **ppriv,
+		     u64 handle)
+{
+	struct nvkm_device *device = udev->device;
+	struct nvkm_object *object;
+	int ret;
+
+	ret = nvkm_ummu_new(device, pimpl, ppriv, &object);
+	if (ret)
+		return ret;
+
+	return nvkm_object_link_rb(udev->object.client, &udev->object, handle, object);
+}
+
 static void
 nvkm_udevice_del(struct nvif_device_priv *udev)
 {
@@ -167,9 +184,7 @@ nvkm_udevice_child_get(struct nvkm_object *object, int index,
 	}
 
 	if (!sclass) {
-		if (device->mmu && index-- == 0)
-			sclass = &device->mmu->user;
-		else if (device->fault && index-- == 0)
+		if (device->fault && index-- == 0)
 			sclass = &device->fault->user;
 		else
 			return -EINVAL;
@@ -283,6 +298,7 @@ nvkm_udevice_new(struct nvkm_device *device,
 
 	if (device->mmu) {
 		udev->impl.mmu.oclass = device->mmu->user.base.oclass;
+		udev->impl.mmu.new = nvkm_udevice_mmu_new;
 	}
 
 	if (device->fault) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
index 7b949a43c372..08ad3ed84631 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/base.c
@@ -426,7 +426,6 @@ nvkm_mmu_ctor(const struct nvkm_mmu_func *func, struct nvkm_device *device,
 	mmu->dma_bits = func->dma_bits;
 	nvkm_mmu_ptc_init(mmu);
 	mutex_init(&mmu->mutex);
-	mmu->user.ctor = nvkm_ummu_new;
 	mmu->user.base = func->mmu.user;
 	spin_lock_init(&mmu->umem_lock);
 	INIT_LIST_HEAD(&mmu->umem);
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c
index 3f008402f451..f97dec6c3309 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.c
@@ -129,6 +129,19 @@ nvkm_ummu_kind(struct nvkm_ummu *ummu, void *argv, u32 argc)
 	return 0;
 }
 
+static void
+nvkm_ummu_del(struct nvif_mmu_priv *ummu)
+{
+	struct nvkm_object *object = &ummu->object;
+
+	nvkm_object_del(&object);
+}
+
+static const struct nvif_mmu_impl
+nvkm_ummu_impl = {
+	.del = nvkm_ummu_del,
+};
+
 static int
 nvkm_ummu_mthd(struct nvkm_object *object, u32 mthd, void *argv, u32 argc)
 {
@@ -150,32 +163,31 @@ nvkm_ummu = {
 };
 
 int
-nvkm_ummu_new(struct nvkm_device *device, const struct nvkm_oclass *oclass,
-	      void *argv, u32 argc, struct nvkm_object **pobject)
+nvkm_ummu_new(struct nvkm_device *device, const struct nvif_mmu_impl **pimpl,
+	      struct nvif_mmu_priv **ppriv, struct nvkm_object **pobject)
 {
-	union {
-		struct nvif_mmu_v0 v0;
-	} *args = argv;
 	struct nvkm_mmu *mmu = device->mmu;
 	struct nvif_mmu_priv *ummu;
-	int ret = -ENOSYS, kinds = 0;
+	int kinds = 0;
 	u8 unused = 0;
 
+	if (!(ummu = kzalloc(sizeof(*ummu), GFP_KERNEL)))
+		return -ENOMEM;
+
+	nvkm_object_ctor(&nvkm_ummu, &(struct nvkm_oclass) {}, &ummu->object);
+	ummu->mmu = mmu;
+	ummu->impl = nvkm_ummu_impl;
+
 	if (mmu->func->kind)
 		mmu->func->kind(mmu, &kinds, &unused);
 
-	if (!(ret = nvif_unpack(ret, &argv, &argc, args->v0, 0, 0, false))) {
-		args->v0.dmabits = mmu->dma_bits;
-		args->v0.heap_nr = mmu->heap_nr;
-		args->v0.type_nr = mmu->type_nr;
-		args->v0.kind_nr = kinds;
-	} else
-		return ret;
+	ummu->impl.dmabits = mmu->dma_bits;
+	ummu->impl.heap_nr = mmu->heap_nr;
+	ummu->impl.type_nr = mmu->type_nr;
+	ummu->impl.kind_nr = kinds;
 
-	if (!(ummu = kzalloc(sizeof(*ummu), GFP_KERNEL)))
-		return -ENOMEM;
-	nvkm_object_ctor(&nvkm_ummu, oclass, &ummu->object);
-	ummu->mmu = mmu;
+	*pimpl = &ummu->impl;
+	*ppriv = ummu;
 	*pobject = &ummu->object;
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.h
index 35ae48758017..c03563aa4cae 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/ummu.h
@@ -1,15 +1,19 @@
 #ifndef __NVKM_UMMU_H__
 #define __NVKM_UMMU_H__
 #include <core/object.h>
-#include "priv.h"
+struct nvkm_device;
+
+#include <nvif/driverif.h>
 
 #define nvkm_ummu nvif_mmu_priv
 
 struct nvif_mmu_priv {
 	struct nvkm_object object;
 	struct nvkm_mmu *mmu;
+
+	struct nvif_mmu_impl impl;
 };
 
-int nvkm_ummu_new(struct nvkm_device *, const struct nvkm_oclass *,
-		  void *argv, u32 argc, struct nvkm_object **);
+int nvkm_ummu_new(struct nvkm_device *, const struct nvif_mmu_impl **, struct nvif_mmu_priv **,
+		  struct nvkm_object **);
 #endif
-- 
2.41.0



More information about the Nouveau mailing list