From 867920f8c920bcaa5a6fa5ebad4596669b82ba80 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Sun, 10 Aug 2014 04:10:25 +1000 Subject: [PATCH] drm/nouveau/fifo: implement nvif event source Signed-off-by: Ben Skeggs --- .../gpu/drm/nouveau/core/engine/fifo/base.c | 44 +++++++++++++++++++ .../gpu/drm/nouveau/core/engine/fifo/nv04.c | 3 +- .../gpu/drm/nouveau/core/engine/fifo/nv10.c | 1 + .../gpu/drm/nouveau/core/engine/fifo/nv17.c | 1 + .../gpu/drm/nouveau/core/engine/fifo/nv40.c | 1 + .../gpu/drm/nouveau/core/engine/fifo/nv50.c | 2 + .../gpu/drm/nouveau/core/engine/fifo/nv84.c | 16 ++----- .../gpu/drm/nouveau/core/engine/fifo/nvc0.c | 17 ++----- .../gpu/drm/nouveau/core/engine/fifo/nve0.c | 17 ++----- .../drm/nouveau/core/include/engine/fifo.h | 5 +++ drivers/gpu/drm/nouveau/nouveau_fence.c | 23 ++++++---- drivers/gpu/drm/nouveau/nvif/class.h | 1 + drivers/gpu/drm/nouveau/nvif/event.h | 8 ++++ 13 files changed, 89 insertions(+), 50 deletions(-) diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c index 0def249b1b43..0f999fc45ab9 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -168,6 +169,49 @@ _nouveau_fifo_channel_wr32(struct nouveau_object *object, u64 addr, u32 data) iowrite32_native(data, chan->user + addr); } +int +nouveau_fifo_uevent_ctor(void *data, u32 size, struct nvkm_notify *notify) +{ + union { + struct nvif_notify_uevent_req none; + } *req = data; + int ret; + + if (nvif_unvers(req->none)) { + notify->size = sizeof(struct nvif_notify_uevent_rep); + notify->types = 1; + notify->index = 0; + } + + return ret; +} + +void +nouveau_fifo_uevent(struct nouveau_fifo *fifo) +{ + struct nvif_notify_uevent_rep rep = { + }; + nvkm_event_send(&fifo->uevent, 1, 0, &rep, sizeof(rep)); +} + +int +_nouveau_fifo_channel_ntfy(struct nouveau_object *object, u32 type, + struct nvkm_event **event) +{ + struct nouveau_fifo *fifo = (void *)object->engine; + switch (type) { + case G82_CHANNEL_DMA_V0_NTFY_UEVENT: + if (nv_mclass(object) >= G82_CHANNEL_DMA) { + *event = &fifo->uevent; + return 0; + } + break; + default: + break; + } + return -EINVAL; +} + static int nouveau_fifo_chid(struct nouveau_fifo *priv, struct nouveau_object *object) { diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c index 347b381e2dcf..5ae6a43893b5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c @@ -255,6 +255,7 @@ nv04_fifo_ofuncs = { .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass @@ -550,7 +551,7 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) } if (status & 0x40000000) { - nvkm_event_send(&priv->base.uevent, 1, 0, NULL, 0); + nouveau_fifo_uevent(&priv->base); nv_wr32(priv, 0x002100, 0x40000000); status &= ~0x40000000; } diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c index d8dac2fc6a3b..2a32add51c81 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c @@ -113,6 +113,7 @@ nv10_fifo_ofuncs = { .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c index c424aab0e041..12d76c8adb23 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c @@ -120,6 +120,7 @@ nv17_fifo_ofuncs = { .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c index 17d14d9e02ca..9f49c3a24dc6 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c @@ -239,6 +239,7 @@ nv40_fifo_ofuncs = { .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c index 2db67a207b4a..5d1e86bc244c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c @@ -366,6 +366,7 @@ nv50_fifo_ofuncs_dma = { .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_ofuncs @@ -377,6 +378,7 @@ nv50_fifo_ofuncs_ind = { .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c index a2acf3f78b56..1f42996b354a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c @@ -327,6 +327,7 @@ nv84_fifo_ofuncs_dma = { .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_ofuncs @@ -338,6 +339,7 @@ nv84_fifo_ofuncs_ind = { .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass @@ -424,21 +426,9 @@ nv84_fifo_uevent_fini(struct nvkm_event *event, int type, int index) nv_mask(fifo, 0x002140, 0x40000000, 0x00000000); } -static int -nv84_fifo_uevent_ctor(void *data, u32 size, struct nvkm_notify *notify) -{ - if (size == 0) { - notify->size = 0; - notify->types = 1; - notify->index = 0; - return 0; - } - return -ENOSYS; -} - static const struct nvkm_event_func nv84_fifo_uevent_func = { - .ctor = nv84_fifo_uevent_ctor, + .ctor = nouveau_fifo_uevent_ctor, .init = nv84_fifo_uevent_init, .fini = nv84_fifo_uevent_fini, }; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index f76ed10d8db0..1fe1f8fbda0c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c @@ -305,6 +305,7 @@ nvc0_fifo_ofuncs = { .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass @@ -742,7 +743,7 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn) for (unkn = 0; unkn < 8; unkn++) { u32 ints = (intr >> (unkn * 0x04)) & inte; if (ints & 0x1) { - nvkm_event_send(&priv->base.uevent, 1, 0, NULL, 0); + nouveau_fifo_uevent(&priv->base); ints &= ~1; } if (ints) { @@ -852,21 +853,9 @@ nvc0_fifo_uevent_fini(struct nvkm_event *event, int type, int index) nv_mask(fifo, 0x002140, 0x80000000, 0x00000000); } -static int -nvc0_fifo_uevent_ctor(void *data, u32 size, struct nvkm_notify *notify) -{ - if (size == 0) { - notify->size = 0; - notify->types = 1; - notify->index = 0; - return 0; - } - return -ENOSYS; -} - static const struct nvkm_event_func nvc0_fifo_uevent_func = { - .ctor = nvc0_fifo_uevent_ctor, + .ctor = nouveau_fifo_uevent_ctor, .init = nvc0_fifo_uevent_init, .fini = nvc0_fifo_uevent_fini, }; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index ef730b52ce0d..d2f0fd39c145 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c @@ -339,6 +339,7 @@ nve0_fifo_ofuncs = { .map = _nouveau_fifo_channel_map, .rd32 = _nouveau_fifo_channel_rd32, .wr32 = _nouveau_fifo_channel_wr32, + .ntfy = _nouveau_fifo_channel_ntfy }; static struct nouveau_oclass @@ -871,7 +872,7 @@ nve0_fifo_intr_runlist(struct nve0_fifo_priv *priv) static void nve0_fifo_intr_engine(struct nve0_fifo_priv *priv) { - nvkm_event_send(&priv->base.uevent, 1, 0, NULL, 0); + nouveau_fifo_uevent(&priv->base); } static void @@ -977,21 +978,9 @@ nve0_fifo_uevent_fini(struct nvkm_event *event, int type, int index) nv_mask(fifo, 0x002140, 0x80000000, 0x00000000); } -static int -nve0_fifo_uevent_ctor(void *data, u32 size, struct nvkm_notify *notify) -{ - if (size == 0) { - notify->size = 0; - notify->types = 1; - notify->index = 0; - return 0; - } - return -ENOSYS; -} - static const struct nvkm_event_func nve0_fifo_uevent_func = { - .ctor = nve0_fifo_uevent_ctor, + .ctor = nouveau_fifo_uevent_ctor, .init = nve0_fifo_uevent_init, .fini = nve0_fifo_uevent_fini, }; diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h index b53f9d8022fe..e5e4d930b2c2 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h @@ -4,6 +4,7 @@ #include #include #include +#include struct nouveau_fifo_chan { struct nouveau_namedb base; @@ -44,6 +45,7 @@ void _nouveau_fifo_channel_dtor(struct nouveau_object *); int _nouveau_fifo_channel_map(struct nouveau_object *, u64 *, u32 *); u32 _nouveau_fifo_channel_rd32(struct nouveau_object *, u64); void _nouveau_fifo_channel_wr32(struct nouveau_object *, u64, u32); +int _nouveau_fifo_channel_ntfy(struct nouveau_object *, u32, struct nvkm_event **); struct nouveau_fifo_base { struct nouveau_gpuobj base; @@ -114,6 +116,9 @@ extern struct nouveau_oclass *nve0_fifo_oclass; extern struct nouveau_oclass *gk20a_fifo_oclass; extern struct nouveau_oclass *nv108_fifo_oclass; +int nouveau_fifo_uevent_ctor(void *, u32, struct nvkm_notify *); +void nouveau_fifo_uevent(struct nouveau_fifo *); + void nv04_fifo_intr(struct nouveau_subdev *); int nv04_fifo_context_attach(struct nouveau_object *, struct nouveau_object *); diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index ace42ec92a72..0a93114158cd 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -29,6 +29,9 @@ #include #include +#include +#include + #include "nouveau_drm.h" #include "nouveau_dma.h" #include "nouveau_fence.h" @@ -165,16 +168,16 @@ nouveau_fence_done(struct nouveau_fence *fence) struct nouveau_fence_wait { struct nouveau_fence_priv *priv; - struct nvkm_notify notify; + struct nvif_notify notify; }; static int -nouveau_fence_wait_uevent_handler(struct nvkm_notify *notify) +nouveau_fence_wait_uevent_handler(struct nvif_notify *notify) { struct nouveau_fence_wait *wait = container_of(notify, typeof(*wait), notify); wake_up_all(&wait->priv->waiting); - return NVKM_NOTIFY_KEEP; + return NVIF_NOTIFY_KEEP; } static int @@ -182,18 +185,22 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) { struct nouveau_channel *chan = fence->channel; - struct nouveau_fifo *pfifo = nvkm_fifo(chan->device); struct nouveau_fence_priv *priv = chan->drm->fence; struct nouveau_fence_wait wait = { .priv = priv }; int ret = 0; - ret = nvkm_notify_init(&pfifo->uevent, + ret = nvif_notify_init(chan->object, NULL, nouveau_fence_wait_uevent_handler, false, - NULL, 0, 0, &wait.notify); + G82_CHANNEL_DMA_V0_NTFY_UEVENT, + &(struct nvif_notify_uevent_req) { + }, + sizeof(struct nvif_notify_uevent_req), + sizeof(struct nvif_notify_uevent_rep), + &wait.notify); if (ret) return ret; - nvkm_notify_get(&wait.notify); + nvif_notify_get(&wait.notify); if (fence->timeout) { unsigned long timeout = fence->timeout - jiffies; @@ -225,7 +232,7 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) } } - nvkm_notify_fini(&wait.notify); + nvif_notify_fini(&wait.notify); if (unlikely(ret < 0)) return ret; diff --git a/drivers/gpu/drm/nouveau/nvif/class.h b/drivers/gpu/drm/nouveau/nvif/class.h index 476d57a1ed6e..50c5413ff523 100644 --- a/drivers/gpu/drm/nouveau/nvif/class.h +++ b/drivers/gpu/drm/nouveau/nvif/class.h @@ -258,6 +258,7 @@ struct nv03_channel_dma_v0 { __u64 offset; }; +#define G82_CHANNEL_DMA_V0_NTFY_UEVENT 0x00 /******************************************************************************* * GPFIFO channels diff --git a/drivers/gpu/drm/nouveau/nvif/event.h b/drivers/gpu/drm/nouveau/nvif/event.h index cef3ef103be5..21764499b4be 100644 --- a/drivers/gpu/drm/nouveau/nvif/event.h +++ b/drivers/gpu/drm/nouveau/nvif/event.h @@ -51,4 +51,12 @@ struct nvif_notify_conn_rep_v0 { __u8 pad02[6]; }; +struct nvif_notify_uevent_req { + /* nvif_notify_req ... */ +}; + +struct nvif_notify_uevent_rep { + /* nvif_notify_rep ... */ +}; + #endif -- 2.20.1