[PATCH 075/156] drm/nouveau/nvif: rework device "new usermode" api
Ben Skeggs
bskeggs at nvidia.com
Tue Apr 16 23:38:41 UTC 2024
- transition from "ioctl" interface
Signed-off-by: Ben Skeggs <bskeggs at nvidia.com>
---
.../gpu/drm/nouveau/include/nvif/driverif.h | 8 +++++
drivers/gpu/drm/nouveau/include/nvif/user.h | 5 +++-
drivers/gpu/drm/nouveau/nouveau_dma.c | 2 +-
drivers/gpu/drm/nouveau/nouveau_drm.c | 2 +-
drivers/gpu/drm/nouveau/nvif/user.c | 16 ++++++----
drivers/gpu/drm/nouveau/nvkm/device/user.c | 19 ++++++++++--
.../gpu/drm/nouveau/nvkm/subdev/vfn/base.c | 1 -
.../gpu/drm/nouveau/nvkm/subdev/vfn/priv.h | 3 --
.../gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c | 29 +++++++++++++++----
.../gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h | 9 ++++++
10 files changed, 73 insertions(+), 21 deletions(-)
create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h
diff --git a/drivers/gpu/drm/nouveau/include/nvif/driverif.h b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
index 05d69ea0f002..35a5869eb036 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/driverif.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/driverif.h
@@ -4,6 +4,7 @@
struct nvif_client_priv;
struct nvif_device_priv;
struct nvif_control_priv;
+struct nvif_usermode_priv;
struct nvif_driver {
const char *name;
@@ -69,6 +70,10 @@ struct nvif_control_impl {
} pstate;
};
+struct nvif_usermode_impl {
+ void (*del)(struct nvif_usermode_priv *);
+};
+
struct nvif_device_impl {
void (*del)(struct nvif_device_priv *);
@@ -117,6 +122,9 @@ struct nvif_device_impl {
struct {
s32 oclass;
+ int (*new)(struct nvif_device_priv *,
+ const struct nvif_usermode_impl **, struct nvif_usermode_priv **,
+ u64 handle);
} usermode;
struct {
diff --git a/drivers/gpu/drm/nouveau/include/nvif/user.h b/drivers/gpu/drm/nouveau/include/nvif/user.h
index 146986a9fe53..51104955c1e3 100644
--- a/drivers/gpu/drm/nouveau/include/nvif/user.h
+++ b/drivers/gpu/drm/nouveau/include/nvif/user.h
@@ -4,8 +4,11 @@
struct nvif_device;
struct nvif_user {
- const struct nvif_user_func *func;
+ const struct nvif_usermode_impl *impl;
+ struct nvif_usermode_priv *priv;
struct nvif_object object;
+
+ const struct nvif_user_func *func;
};
struct nvif_user_func {
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
index a1f329ef0641..83eb9c9fa67e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
@@ -72,7 +72,7 @@ void
nv50_dma_push(struct nouveau_channel *chan, u64 offset, u32 length,
bool no_prefetch)
{
- struct nvif_user *user = &chan->cli->drm->client.device.user;
+ struct nvif_user *user = &chan->cli->drm->device.user;
struct nouveau_bo *pb = chan->push.buffer;
int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base;
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 76990dde1b6a..a91ad8e65a0f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -474,7 +474,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
/* Volta requires access to a doorbell register for kickoff. */
if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_VOLTA) {
- ret = nvif_user_ctor(device, "drmUsermode");
+ ret = nvif_user_ctor(&drm->device, "drmUsermode");
if (ret)
return;
}
diff --git a/drivers/gpu/drm/nouveau/nvif/user.c b/drivers/gpu/drm/nouveau/nvif/user.c
index d8d37c1c8169..878883aff9c5 100644
--- a/drivers/gpu/drm/nouveau/nvif/user.c
+++ b/drivers/gpu/drm/nouveau/nvif/user.c
@@ -21,6 +21,7 @@
*/
#include <nvif/user.h>
#include <nvif/device.h>
+#include <nvif/driverif.h>
#include <nvif/printf.h>
#include <nvif/class.h>
@@ -28,8 +29,9 @@
void
nvif_user_dtor(struct nvif_device *device)
{
- if (device->user.func) {
- nvif_object_dtor(&device->user.object);
+ if (device->user.impl) {
+ device->user.impl->del(device->user.priv);
+ device->user.impl = NULL;
device->user.func = NULL;
}
}
@@ -53,13 +55,15 @@ nvif_user_ctor(struct nvif_device *device, const char *name)
return -ENODEV;
}
- ret = nvif_object_ctor(&device->object, name ? name : "nvifUsermode",
- 0, oclass, NULL, 0,
- &device->user.object);
+ ret = device->impl->usermode.new(device->priv, &device->user.impl, &device->user.priv,
+ nvif_handle(&device->user.object));
+ NVIF_ERRON(ret, &device->object, "[NEW usermode%04x]", oclass);
if (ret)
return ret;
- nvif_object_map(&device->user.object, NULL, 0);
+ nvif_object_ctor(&device->object, name ?: "nvifUsermode", 0, oclass, &device->user.object);
device->user.func = func;
+
+ nvif_object_map(&device->user.object, NULL, 0);
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/device/user.c b/drivers/gpu/drm/nouveau/nvkm/device/user.c
index 97d54b812165..aadd0c0956ee 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/vfn/uvfn.h>
#include <engine/disp/priv.h>
#include <engine/fifo/ufifo.h>
@@ -39,6 +40,20 @@ struct nvif_device_priv {
struct nvif_device_impl impl;
};
+static int
+nvkm_udevice_usermode_new(struct nvif_device_priv *udev, const struct nvif_usermode_impl **pimpl,
+ struct nvif_usermode_priv **ppriv, u64 handle)
+{
+ struct nvkm_object *object;
+ int ret;
+
+ ret = nvkm_uvfn_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_control_new(struct nvif_device_priv *udev,
const struct nvif_control_impl **pimpl, struct nvif_control_priv **ppriv)
@@ -74,6 +89,7 @@ nvkm_udevice_impl = {
.del = nvkm_udevice_del,
.time = nvkm_udevice_time,
.control.new = nvkm_udevice_control_new,
+ .usermode.new = nvkm_udevice_usermode_new,
};
static int
@@ -154,8 +170,6 @@ nvkm_udevice_child_get(struct nvkm_object *object, int index,
sclass = &device->mmu->user;
else if (device->fault && index-- == 0)
sclass = &device->fault->user;
- else if (device->vfn && index-- == 0)
- sclass = &device->vfn->user;
else
return -EINVAL;
@@ -263,6 +277,7 @@ nvkm_udevice_new(struct nvkm_device *device,
if (device->vfn) {
udev->impl.usermode.oclass = device->vfn->user.base.oclass;
+ udev->impl.usermode.new = nvkm_udevice_usermode_new;
}
if (device->mmu) {
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c
index 62e81d551f44..2215de6c4803 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/base.c
@@ -54,7 +54,6 @@ nvkm_vfn_new_(const struct nvkm_vfn_func *func, struct nvkm_device *device,
return ret;
}
- vfn->user.ctor = nvkm_uvfn_new;
vfn->user.base = func->user.base;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/priv.h
index 3a09781ad032..40245777c600 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/priv.h
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/priv.h
@@ -24,7 +24,4 @@ int nvkm_vfn_new_(const struct nvkm_vfn_func *, struct nvkm_device *, enum nvkm_
u32 addr, struct nvkm_vfn **);
extern const struct nvkm_intr_func tu102_vfn_intr;
-
-int nvkm_uvfn_new(struct nvkm_device *, const struct nvkm_oclass *, void *, u32,
- struct nvkm_object **);
#endif
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c
index fe35024d69ba..6b0ddeb1f568 100644
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.c
@@ -19,6 +19,7 @@
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
+#include "uvfn.h"
#include "priv.h"
#include <core/object.h>
@@ -26,6 +27,8 @@
struct nvif_usermode_priv {
struct nvkm_object object;
struct nvkm_vfn *vfn;
+
+ struct nvif_usermode_impl impl;
};
static int
@@ -41,26 +44,40 @@ nvkm_uvfn_map(struct nvkm_object *object, void *argv, u32 argc,
return 0;
}
+static void
+nvkm_uvfn_del(struct nvif_usermode_priv *uvfn)
+{
+ struct nvkm_object *object = &uvfn->object;
+
+ nvkm_object_del(&object);
+}
+
+static const struct nvif_usermode_impl
+nvkm_uvfn_impl = {
+ .del = nvkm_uvfn_del,
+};
+
static const struct nvkm_object_func
nvkm_uvfn = {
.map = nvkm_uvfn_map,
};
int
-nvkm_uvfn_new(struct nvkm_device *device, const struct nvkm_oclass *oclass,
- void *argv, u32 argc, struct nvkm_object **pobject)
+nvkm_uvfn_new(struct nvkm_device *device, const struct nvif_usermode_impl **pimpl,
+ struct nvif_usermode_priv **ppriv, struct nvkm_object **pobject)
{
struct nvif_usermode_priv *uvfn;
- if (argc != 0)
- return -ENOSYS;
-
if (!(uvfn = kzalloc(sizeof(*uvfn), GFP_KERNEL)))
return -ENOMEM;
- nvkm_object_ctor(&nvkm_uvfn, oclass, &uvfn->object);
+ nvkm_object_ctor(&nvkm_uvfn, &(struct nvkm_oclass) {}, &uvfn->object);
uvfn->vfn = device->vfn;
+ uvfn->impl = nvkm_uvfn_impl;
+
+ *pimpl = &uvfn->impl;
+ *ppriv = uvfn;
*pobject = &uvfn->object;
return 0;
}
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h
new file mode 100644
index 000000000000..23f636eb3b58
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/vfn/uvfn.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: MIT */
+#ifndef __NVKM_UVFN_H__
+#define __NVKM_UVFN_H__
+#include <subdev/vfn.h>
+#include <nvif/driverif.h>
+
+int nvkm_uvfn_new(struct nvkm_device *, const struct nvif_usermode_impl **,
+ struct nvif_usermode_priv **, struct nvkm_object **);
+#endif
--
2.41.0
More information about the Nouveau
mailing list