- transition from "ioctl" interface Signed-off-by: Ben Skeggs <bskeggs@xxxxxxxxxx> --- 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