[PATCH 099/156] drm/nouveau/nvif: rework device "new disp" api

Ben Skeggs bskeggs at nvidia.com
Tue Apr 16 23:39:05 UTC 2024


- transition from "ioctl" interface

Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
 drivers/gpu/drm/nouveau/include/nvif/disp.h   |  5 ++
 .../gpu/drm/nouveau/include/nvif/driverif.h   | 20 ++++++++
 drivers/gpu/drm/nouveau/include/nvif/if0010.h | 14 -----
 drivers/gpu/drm/nouveau/include/nvif/object.h | 16 ------
 drivers/gpu/drm/nouveau/nvif/disp.c           | 26 +++++-----
 drivers/gpu/drm/nouveau/nvkm/device/user.c    | 20 +++++++-
 .../gpu/drm/nouveau/nvkm/engine/disp/base.c   | 27 ----------
 .../gpu/drm/nouveau/nvkm/engine/disp/priv.h   |  1 -
 .../gpu/drm/nouveau/nvkm/engine/disp/udisp.c  | 51 +++++++++++++------
 .../gpu/drm/nouveau/nvkm/engine/disp/udisp.h  |  6 +++
 10 files changed, 97 insertions(+), 89 deletions(-)
 delete mode 100644 drivers/gpu/drm/nouveau/include/nvif/if0010.h

diff --git a/drivers/gpu/drm/nouveau/include/nvif/disp.h b/drivers/gpu/drm/nouveau/include/nvif/disp.h
index c4f428f268ea..06f56cc63893 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/disp.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/disp.h
@@ -4,7 +4,12 @@
 struct nvif_device;
 
 struct nvif_disp {
+	const struct nvif_disp_impl *impl;
+	struct nvif_disp_priv *priv;
 	struct nvif_object object;
+
+	struct nvif_device *device;
+
 	unsigned long conn_mask;
 	unsigned long outp_mask;
 	unsigned long head_mask;
diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
index 42e6324ddfe3..e479e8114605 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
@@ -10,6 +10,7 @@ struct nvif_mmu_priv;
 struct nvif_mem_priv;
 struct nvif_vmm_priv;
 struct nvif_faultbuf_priv;
+struct nvif_disp_priv;
 
 struct nvif_driver {
 	const char *name;
@@ -216,6 +217,22 @@ struct nvif_faultbuf_impl {
 	} event;
 };
 
+struct nvif_disp_impl {
+	void (*del)(struct nvif_disp_priv *);
+
+	struct {
+		u32 mask;
+	} conn;
+
+	struct {
+		u32 mask;
+	} outp;
+
+	struct {
+		u32 mask;
+	} head;
+};
+
 struct nvif_device_impl {
 	void (*del)(struct nvif_device_priv *);
 
@@ -282,6 +299,9 @@ struct nvif_device_impl {
 
 	struct {
 		s32 oclass;
+		int (*new)(struct nvif_device_priv *,
+			   const struct nvif_disp_impl **, struct nvif_disp_priv **,
+			   u64 handle);
 	} disp;
 
 	struct nvif_device_impl_fifo {
diff --git a/drivers/gpu/drm/nouveau/include/nvif/if0010.h b/drivers/gpu/drm/nouveau/include/nvif/if0010.h
deleted file mode 100644
index 4c835bbe6fe3..000000000000
--- a/drivers/gpu/drm/nouveau/include/nvif/if0010.h
+++ /dev/null
@@ -1,14 +0,0 @@
-/* SPDX-License-Identifier: MIT */
-#ifndef __NVIF_IF0010_H__
-#define __NVIF_IF0010_H__
-
-union nvif_disp_args {
-	struct nvif_disp_v0 {
-		__u8 version;
-		__u8 pad01[3];
-		__u32 conn_mask;
-		__u32 outp_mask;
-		__u32 head_mask;
-	} v0;
-};
-#endif
diff --git a/drivers/gpu/drm/nouveau/include/nvif/object.h b/drivers/gpu/drm/nouveau/include/nvif/object.h
index b3e66425f310..819ae1c9729d 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/object.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/object.h
@@ -111,22 +111,6 @@ struct nvif_mclass {
 	ret;                                                                   \
 })
 
-#define nvif_sclass(o,m,u) ({                                                  \
-	const typeof(m[0]) *_mclass = (m);                                     \
-	s32 _oclass = (u);                                                     \
-	int _cid;                                                              \
-	if (_oclass) {                                                         \
-		for (_cid = 0; _mclass[_cid].oclass; _cid++) {                 \
-			if (_mclass[_cid].oclass == _oclass)                   \
-				break;                                         \
-		}                                                              \
-		_cid = _mclass[_cid].oclass ? _cid : -ENOSYS;                  \
-	} else {                                                               \
-		_cid = nvif_mclass((o), _mclass);                              \
-	}                                                                      \
-	_cid;                                                                  \
-})
-
 #define NVIF_RD32_(p,o,dr)   nvif_rd32((p), (o) + (dr))
 #define NVIF_WR32_(p,o,dr,f) nvif_wr32((p), (o) + (dr), (f))
 #define NVIF_RD32(p,A...) DRF_RD(NVIF_RD32_,                  (p), 0, ##A)
diff --git a/drivers/gpu/drm/nouveau/nvif/disp.c b/drivers/gpu/drm/nouveau/nvif/disp.c
index 875c63877468..f3c425daf7d5 100644
--- a/drivers/gpu/drm/nouveau/nvif/disp.c
+++ b/drivers/gpu/drm/nouveau/nvif/disp.c
@@ -24,23 +24,23 @@
 #include <nvif/printf.h>
 
 #include <nvif/class.h>
-#include <nvif/if0010.h>
 
 void
 nvif_disp_dtor(struct nvif_disp *disp)
 {
-	nvif_object_dtor(&disp->object);
+	if (!disp->impl)
+		return;
+
+	disp->impl->del(disp->priv);
+	disp->impl = NULL;
 }
 
 int
 nvif_disp_ctor(struct nvif_device *device, const char *name, struct nvif_disp *disp)
 {
 	const u32 oclass = device->impl->disp.oclass;
-	struct nvif_disp_v0 args;
 	int ret;
 
-	disp->object.client = NULL;
-
 	switch (oclass) {
 	case AD102_DISP:
 	case GA102_DISP:
@@ -65,18 +65,16 @@ nvif_disp_ctor(struct nvif_device *device, const char *name, struct nvif_disp *d
 		return -ENODEV;
 	}
 
-	args.version = 0;
-
-	ret = nvif_object_ctor(&device->object, name ?: "nvifDisp", 0,
-			       oclass, &args, sizeof(args), &disp->object);
+	ret = device->impl->disp.new(device->priv, &disp->impl, &disp->priv,
+				     nvif_handle(&disp->object));
 	NVIF_ERRON(ret, &device->object, "[NEW disp%04x]", oclass);
 	if (ret)
 		return ret;
 
-	NVIF_DEBUG(&disp->object, "[NEW] conn_mask:%08x outp_mask:%08x head_mask:%08x",
-		   args.conn_mask, args.outp_mask, args.head_mask);
-	disp->conn_mask = args.conn_mask;
-	disp->outp_mask = args.outp_mask;
-	disp->head_mask = args.head_mask;
+	nvif_object_ctor(&device->object, name ?: "nvifDisp", 0, oclass, &disp->object);
+	disp->device = device;
+	disp->conn_mask = disp->impl->conn.mask;
+	disp->outp_mask = disp->impl->outp.mask;
+	disp->head_mask = disp->impl->head.mask;
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/user.c b/drivers/gpu/drm/nouveau/nvkm/device/user.c
index eb33ab81d7e1..3c7c0d1e6adb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/user.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/user.c
@@ -33,6 +33,7 @@
 #include <subdev/mmu/ummu.h>
 #include <subdev/vfn/uvfn.h>
 #include <engine/disp/priv.h>
+#include <engine/disp/udisp.h>
 #include <engine/fifo/ufifo.h>
 
 struct nvif_device_priv {
@@ -93,6 +94,21 @@ nvkm_udevice_time(struct nvif_device_priv *udev)
 	return nvkm_timer_read(udev->device->timer);
 }
 
+static int
+nvkm_udevice_disp_new(struct nvif_device_priv *udev,
+		      const struct nvif_disp_impl **pimpl, struct nvif_disp_priv **ppriv,
+		      u64 handle)
+{
+	struct nvkm_object *object;
+	int ret;
+
+	ret = nvkm_udisp_new(udev->device, pimpl, ppriv, &object);
+	if (ret)
+		return ret;
+
+	return nvkm_object_link_rb(udev->object.client, &udev->object, handle, object);
+}
+
 static int
 nvkm_udevice_mmu_new(struct nvif_device_priv *udev,
 		     const struct nvif_mmu_impl **pimpl, struct nvif_mmu_priv **ppriv)
@@ -185,8 +201,7 @@ nvkm_udevice_child_get(struct nvkm_object *object, int index,
 	struct nvkm_device *device = udev->device;
 	struct nvkm_engine *engine;
 	u64 mask = (1ULL << NVKM_ENGINE_DMAOBJ) |
-		   (1ULL << NVKM_ENGINE_FIFO) |
-		   (1ULL << NVKM_ENGINE_DISP);
+		   (1ULL << NVKM_ENGINE_FIFO);
 	const struct nvkm_device_oclass *sclass = NULL;
 	int i;
 
@@ -317,6 +332,7 @@ nvkm_udevice_new(struct nvkm_device *device,
 
 	if (device->disp) {
 		udev->impl.disp.oclass = device->disp->func->user.root.oclass;
+		udev->impl.disp.new = nvkm_udevice_disp_new;
 	}
 
 	if (device->fifo) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
index 6850c703ff2d..dab603f17e2d 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/base.c
@@ -65,32 +65,6 @@ nvkm_disp_vblank(struct nvkm_disp *disp, int head)
 	nvkm_event_ntfy(&disp->vblank, head, NVKM_DISP_HEAD_EVENT_VBLANK);
 }
 
-static int
-nvkm_disp_class_new(struct nvkm_device *device,
-		    const struct nvkm_oclass *oclass, void *data, u32 size,
-		    struct nvkm_object **pobject)
-{
-	return nvkm_udisp_new(oclass, data, size, pobject);
-}
-
-static const struct nvkm_device_oclass
-nvkm_disp_sclass = {
-	.ctor = nvkm_disp_class_new,
-};
-
-static int
-nvkm_disp_class_get(struct nvkm_oclass *oclass, int index,
-		    const struct nvkm_device_oclass **class)
-{
-	struct nvkm_disp *disp = nvkm_disp(oclass->engine);
-	if (index == 0) {
-		oclass->base = (struct nvkm_sclass) { 0, 0, disp->func->user.root.oclass };
-		*class = &nvkm_disp_sclass;
-		return 0;
-	}
-	return 1;
-}
-
 static void
 nvkm_disp_intr(struct nvkm_engine *engine)
 {
@@ -222,7 +196,6 @@ nvkm_disp = {
 	.init = nvkm_disp_init,
 	.fini = nvkm_disp_fini,
 	.intr = nvkm_disp_intr,
-	.base.sclass = nvkm_disp_class_get,
 };
 
 int
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
index 82b16cc9212a..324a7971a0eb 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/priv.h
@@ -90,7 +90,6 @@ void nv50_disp_chan_uevent_send(struct nvkm_disp *, int);
 extern const struct nvkm_event_func gf119_disp_chan_uevent;
 extern const struct nvkm_event_func gv100_disp_chan_uevent;
 
-int nvkm_udisp_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
 int nvkm_uconn_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
 int nvkm_uoutp_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
 int nvkm_uhead_new(const struct nvkm_oclass *, void *, u32, struct nvkm_object **);
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c
index 750db6a1eb44..06e465edf3e9 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.c
@@ -26,7 +26,6 @@
 #include "outp.h"
 
 #include <nvif/class.h>
-#include <nvif/if0010.h>
 
 static int
 nvkm_udisp_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *sclass)
@@ -102,15 +101,32 @@ nvkm_udisp_sclass(struct nvkm_object *object, int index, struct nvkm_oclass *scl
 	return -EINVAL;
 }
 
+static void
+nvkm_udisp_del(struct nvif_disp_priv *udisp)
+{
+	struct nvkm_object *object = &udisp->object;
+
+	nvkm_object_fini(object, false);
+	nvkm_object_del(&object);
+}
+
+static const struct nvif_disp_impl
+nvkm_udisp_impl = {
+	.del = nvkm_udisp_del,
+};
+
 static void *
 nvkm_udisp_dtor(struct nvkm_object *object)
 {
 	struct nvif_disp_priv *udisp = container_of(object, typeof(*udisp), object);
 	struct nvkm_disp *disp = udisp->disp;
+	struct nvkm_engine *engine = &disp->engine;
 
 	spin_lock(&disp->user.lock);
 	disp->user.allocated = false;
 	spin_unlock(&disp->user.lock);
+
+	nvkm_engine_unref(&engine);
 	return udisp;
 }
 
@@ -121,46 +137,51 @@ nvkm_udisp = {
 };
 
 int
-nvkm_udisp_new(const struct nvkm_oclass *oclass, void *argv, u32 argc, struct nvkm_object **pobject)
+nvkm_udisp_new(struct nvkm_device *device, const struct nvif_disp_impl **pimpl,
+	       struct nvif_disp_priv **ppriv, struct nvkm_object **pobject)
 {
-	struct nvkm_disp *disp = nvkm_disp(oclass->engine);
+	struct nvkm_disp *disp = device->disp;
 	struct nvkm_conn *conn;
 	struct nvkm_outp *outp;
 	struct nvkm_head *head;
-	union nvif_disp_args *args = argv;
 	struct nvif_disp_priv *udisp;
-
-	if (argc != sizeof(args->v0) || args->v0.version != 0)
-		return -ENOSYS;
+	struct nvkm_engine *engine;
 
 	udisp = kzalloc(sizeof(*udisp), GFP_KERNEL);
 	if (!udisp)
 		return -ENOMEM;
 
+	engine = nvkm_engine_ref(&disp->engine);
+	if (IS_ERR(engine)) {
+		kfree(udisp);
+		return PTR_ERR(engine);
+	}
+
 	spin_lock(&disp->user.lock);
 	if (disp->user.allocated) {
 		spin_unlock(&disp->user.lock);
+		nvkm_engine_unref(&engine);
 		kfree(udisp);
 		return -EBUSY;
 	}
 	disp->user.allocated = true;
 	spin_unlock(&disp->user.lock);
 
-	nvkm_object_ctor(&nvkm_udisp, oclass, &udisp->object);
+	nvkm_object_ctor(&nvkm_udisp, &(struct nvkm_oclass) {}, &udisp->object);
 	udisp->disp = disp;
-	*pobject = &udisp->object;
+	udisp->impl = nvkm_udisp_impl;
 
-	args->v0.conn_mask = 0;
 	list_for_each_entry(conn, &disp->conns, head)
-		args->v0.conn_mask |= BIT(conn->index);
+		udisp->impl.conn.mask |= BIT(conn->index);
 
-	args->v0.outp_mask = 0;
 	list_for_each_entry(outp, &disp->outps, head)
-		args->v0.outp_mask |= BIT(outp->index);
+		udisp->impl.outp.mask |= BIT(outp->index);
 
-	args->v0.head_mask = 0;
 	list_for_each_entry(head, &disp->heads, head)
-		args->v0.head_mask |= BIT(head->id);
+		udisp->impl.head.mask |= BIT(head->id);
 
+	*pimpl = &udisp->impl;
+	*ppriv = udisp;
+	*pobject = &udisp->object;
 	return 0;
 }
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.h
index 2918ecbca5d3..5baf1fe35f88 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/udisp.h
@@ -3,9 +3,15 @@
 #define __NVKM_UDISP_H__
 #include <core/object.h>
 #include "priv.h"
+#include <nvif/driverif.h>
 
 struct nvif_disp_priv {
 	struct nvkm_object object;
 	struct nvkm_disp *disp;
+
+	struct nvif_disp_impl impl;
 };
+
+int nvkm_udisp_new(struct nvkm_device *, const struct nvif_disp_impl **, struct nvif_disp_priv **,
+		   struct nvkm_object **);
 #endif
-- 
2.41.0



More information about the Nouveau mailing list