[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