[PATCH 135/156] drm/nouveau/nvif: rework device "new ctxdma" api

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


- transition from "ioctl" interface

Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
 drivers/gpu/drm/nouveau/include/nvif/device.h |  4 ++
 .../gpu/drm/nouveau/include/nvif/driverif.h   |  6 +++
 drivers/gpu/drm/nouveau/nouveau_chan.c        | 11 +++--
 drivers/gpu/drm/nouveau/nouveau_chan.h        |  3 +-
 drivers/gpu/drm/nouveau/nvif/device.c         | 17 ++++++++
 drivers/gpu/drm/nouveau/nvkm/device/user.c    | 41 ++++++++++++++++++-
 6 files changed, 73 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/include/nvif/device.h b/drivers/gpu/drm/nouveau/include/nvif/device.h
index fa8402e575da..5fb71e6da7cd 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/device.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/device.h
@@ -5,6 +5,7 @@
 #include <nvif/cl0080.h>
 #include <nvif/driverif.h>
 #include <nvif/user.h>
+struct nvif_ctxdma;
 
 struct nvif_device {
 	const struct nvif_device_impl *impl;
@@ -22,6 +23,9 @@ void nvif_device_dtor(struct nvif_device *);
 int  nvif_device_map(struct nvif_device *);
 u64  nvif_device_time(struct nvif_device *);
 
+int nvif_device_ctxdma_ctor(struct nvif_device *, const char *name, s32 oclass,
+			    void *argv, u32 argc, struct nvif_ctxdma *);
+
 /*XXX*/
 #include <subdev/bios.h>
 #include <subdev/fb.h>
diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
index 75168621427a..c1971b85d927 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
@@ -507,6 +507,12 @@ struct nvif_device_impl {
 			   const struct nvif_disp_impl **, struct nvif_disp_priv **);
 	} disp;
 
+	struct {
+		int (*new)(struct nvif_device_priv *, s32 oclass, void *argv, u32 argc,
+			   const struct nvif_ctxdma_impl **, struct nvif_ctxdma_priv **,
+			   u64 handle);
+	} ctxdma;
+
 	struct nvif_device_impl_fifo {
 		u8  engine_nr;
 		u8  runl_nr;
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c
index 771a4b4b3f1d..7c57bc48a8af 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.c
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
@@ -106,7 +106,7 @@ nouveau_channel_del(struct nouveau_channel **pchan)
 		nvif_object_unmap_cpu(&chan->userd.map);
 		nvif_object_dtor(&chan->user);
 		nvif_mem_dtor(&chan->userd.mem);
-		nvif_object_dtor(&chan->push.ctxdma);
+		nvif_ctxdma_dtor(&chan->push.ctxdma);
 		nouveau_vma_del(&chan->push.vma);
 		nouveau_bo_unmap(chan->push.buffer);
 		if (chan->push.buffer && chan->push.buffer->bo.pin_count)
@@ -242,9 +242,8 @@ nouveau_channel_prep(struct nouveau_cli *cli,
 		}
 	}
 
-	ret = nvif_object_ctor(&device->object, "abi16PushCtxDma", 0,
-			       NV_DMA_FROM_MEMORY, &args, sizeof(args),
-			       &chan->push.ctxdma);
+	ret = nvif_device_ctxdma_ctor(device, "abi16PushCtxDma", NV_DMA_FROM_MEMORY,
+				      &args, sizeof(args), &chan->push.ctxdma);
 	if (ret) {
 		nouveau_channel_del(pchan);
 		return ret;
@@ -315,13 +314,13 @@ nouveau_channel_ctor(struct nouveau_cli *cli, bool priv, u64 runm,
 	args.chan.devm = BIT(0);
 	if (oclass < NV50_CHANNEL_GPFIFO) {
 		args.chan.vmm = 0;
-		args.chan.ctxdma = nvif_handle(&chan->push.ctxdma);
+		args.chan.ctxdma = nvif_handle(&chan->push.ctxdma.object);
 		args.chan.offset = chan->push.addr;
 		args.chan.length = 0;
 	} else {
 		args.chan.vmm = nvif_handle(&chan->vmm->vmm.object);
 		if (oclass < FERMI_CHANNEL_GPFIFO)
-			args.chan.ctxdma = nvif_handle(&chan->push.ctxdma);
+			args.chan.ctxdma = nvif_handle(&chan->push.ctxdma.object);
 		else
 			args.chan.ctxdma = 0;
 		args.chan.offset = ioffset + chan->push.addr;
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h
index 811271ae6fe1..786c929843d1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.h
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.h
@@ -2,6 +2,7 @@
 #ifndef __NOUVEAU_CHAN_H__
 #define __NOUVEAU_CHAN_H__
 #include <nvif/object.h>
+#include <nvif/ctxdma.h>
 #include <nvif/event.h>
 #include <nvif/push.h>
 struct nvif_device;
@@ -31,7 +32,7 @@ struct nouveau_channel {
 	struct {
 		struct nouveau_bo *buffer;
 		struct nouveau_vma *vma;
-		struct nvif_object ctxdma;
+		struct nvif_ctxdma ctxdma;
 		u64 addr;
 	} push;
 
diff --git a/drivers/gpu/drm/nouveau/nvif/device.c b/drivers/gpu/drm/nouveau/nvif/device.c
index 7d057691600f..555c63e96660 100644
--- a/drivers/gpu/drm/nouveau/nvif/device.c
+++ b/drivers/gpu/drm/nouveau/nvif/device.c
@@ -23,8 +23,25 @@
  */
 #include <nvif/device.h>
 #include <nvif/client.h>
+#include <nvif/ctxdma.h>
 #include <nvif/printf.h>
 
+int
+nvif_device_ctxdma_ctor(struct nvif_device *device, const char *name, s32 oclass,
+			void *argv, u32 argc, struct nvif_ctxdma *ctxdma)
+{
+	int ret;
+
+	ret = device->impl->ctxdma.new(device->priv, oclass, argv, argc,
+				       &ctxdma->impl, &ctxdma->priv, nvif_handle(&ctxdma->object));
+	NVIF_ERRON(ret, &device->object, "[NEW ctxdma%04x]", oclass);
+	if (ret)
+		return ret;
+
+	nvif_ctxdma_ctor(&device->object, name ?: "nvifDeviceCtxDma", 0, oclass, ctxdma);
+	return 0;
+}
+
 u64
 nvif_device_time(struct nvif_device *device)
 {
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/user.c b/drivers/gpu/drm/nouveau/nvkm/device/user.c
index f76861945cd0..fc81d595bdb7 100644
--- a/drivers/gpu/drm/nouveau/nvkm/device/user.c
+++ b/drivers/gpu/drm/nouveau/nvkm/device/user.c
@@ -111,6 +111,42 @@ nvkm_udevice_cgrp_new(struct nvif_device_priv *udev, u8 runl, struct nvif_vmm_pr
 	return 0;
 }
 
+#include <engine/dma/priv.h>
+
+static void
+nvkm_udevice_ctxdma_del(struct nvif_ctxdma_priv *priv)
+{
+	struct nvkm_dmaobj *dmaobj = (void *)priv;
+	struct nvkm_object *object = &dmaobj->object;
+
+	nvkm_object_del(&object);
+}
+
+static const struct nvif_ctxdma_impl
+nvkm_udevice_ctxdma_impl = {
+	.del = nvkm_udevice_ctxdma_del
+};
+
+static int
+nvkm_udevice_ctxdma_new(struct nvif_device_priv *udev, s32 oclass, void *argv, u32 argc,
+			const struct nvif_ctxdma_impl **pimpl, struct nvif_ctxdma_priv **ppriv,
+			u64 handle)
+{
+	struct nvkm_dma *dma = udev->device->dma;
+	struct nvkm_dmaobj *dmaobj;
+	int ret;
+
+	ret = dma->func->class_new(dma, &(struct nvkm_oclass) { .base.oclass = oclass },
+				   argv, argc, &dmaobj);
+	if (ret)
+		return ret;
+
+	*pimpl = &nvkm_udevice_ctxdma_impl;
+	*ppriv = (void *)dmaobj;
+
+	return nvkm_object_link_rb(udev->object.client, &udev->object, handle, &dmaobj->object);
+}
+
 static int
 nvkm_udevice_disp_new(struct nvif_device_priv *udev,
 		      const struct nvif_disp_impl **pimpl, struct nvif_disp_priv **ppriv)
@@ -217,8 +253,7 @@ nvkm_udevice_child_get(struct nvkm_object *object, int index,
 	struct nvif_device_priv *udev = container_of(object, typeof(*udev), object);
 	struct nvkm_device *device = udev->device;
 	struct nvkm_engine *engine;
-	u64 mask = (1ULL << NVKM_ENGINE_DMAOBJ) |
-		   (1ULL << NVKM_ENGINE_FIFO);
+	u64 mask = (1ULL << NVKM_ENGINE_FIFO);
 	const struct nvkm_device_oclass *sclass = NULL;
 	int i;
 
@@ -353,6 +388,8 @@ nvkm_udevice_new(struct nvkm_device *device,
 	}
 
 	if (device->fifo) {
+		udev->impl.ctxdma.new = nvkm_udevice_ctxdma_new;
+
 		if (!WARN_ON(nvkm_subdev_oneinit(&device->fifo->engine.subdev))) {
 			nvkm_ufifo_ctor(device->fifo, &udev->impl.fifo);
 
-- 
2.41.0



More information about the Nouveau mailing list