summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2014-08-10 04:10:25 +1000
committerBen Skeggs <bskeggs@redhat.com>2014-08-10 05:26:57 +1000
commit5f297946df6d87ea788462e20b2e28fc03ea79a5 (patch)
tree4c940d5116761cdee41821a92c3314fa50f0d254
parentfea516ed2a9a198bca882615ec5e23e1b770fbfb (diff)
downloadnouveau-5f297946df6d87ea788462e20b2e28fc03ea79a5.tar.gz
fifo: implement nvif event source
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drm/nouveau_fence.c23
-rw-r--r--nvif/class.h1
-rw-r--r--nvif/event.h8
-rw-r--r--nvkm/engine/fifo/base.c44
-rw-r--r--nvkm/engine/fifo/nv04.c3
-rw-r--r--nvkm/engine/fifo/nv10.c1
-rw-r--r--nvkm/engine/fifo/nv17.c1
-rw-r--r--nvkm/engine/fifo/nv40.c1
-rw-r--r--nvkm/engine/fifo/nv50.c2
-rw-r--r--nvkm/engine/fifo/nv84.c16
-rw-r--r--nvkm/engine/fifo/nvc0.c17
-rw-r--r--nvkm/engine/fifo/nve0.c17
-rw-r--r--nvkm/include/engine/fifo.h5
13 files changed, 89 insertions, 50 deletions
diff --git a/drm/nouveau_fence.c b/drm/nouveau_fence.c
index ace42ec92..0a9311415 100644
--- a/drm/nouveau_fence.c
+++ b/drm/nouveau_fence.c
@@ -29,6 +29,9 @@
#include <linux/ktime.h>
#include <linux/hrtimer.h>
+#include <nvif/notify.h>
+#include <nvif/event.h>
+
#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/nvif/class.h b/nvif/class.h
index 476d57a1e..50c5413ff 100644
--- a/nvif/class.h
+++ b/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/nvif/event.h b/nvif/event.h
index cef3ef103..21764499b 100644
--- a/nvif/event.h
+++ b/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
diff --git a/nvkm/engine/fifo/base.c b/nvkm/engine/fifo/base.c
index 0def249b1..0f999fc45 100644
--- a/nvkm/engine/fifo/base.c
+++ b/nvkm/engine/fifo/base.c
@@ -28,6 +28,7 @@
#include <core/event.h>
#include <nvif/unpack.h>
#include <nvif/class.h>
+#include <nvif/event.h>
#include <engine/dmaobj.h>
#include <engine/fifo.h>
@@ -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/nvkm/engine/fifo/nv04.c b/nvkm/engine/fifo/nv04.c
index 347b381e2..5ae6a4389 100644
--- a/nvkm/engine/fifo/nv04.c
+++ b/nvkm/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/nvkm/engine/fifo/nv10.c b/nvkm/engine/fifo/nv10.c
index d8dac2fc6..2a32add51 100644
--- a/nvkm/engine/fifo/nv10.c
+++ b/nvkm/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/nvkm/engine/fifo/nv17.c b/nvkm/engine/fifo/nv17.c
index c424aab0e..12d76c8ad 100644
--- a/nvkm/engine/fifo/nv17.c
+++ b/nvkm/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/nvkm/engine/fifo/nv40.c b/nvkm/engine/fifo/nv40.c
index 17d14d9e0..9f49c3a24 100644
--- a/nvkm/engine/fifo/nv40.c
+++ b/nvkm/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/nvkm/engine/fifo/nv50.c b/nvkm/engine/fifo/nv50.c
index 2db67a207..5d1e86bc2 100644
--- a/nvkm/engine/fifo/nv50.c
+++ b/nvkm/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/nvkm/engine/fifo/nv84.c b/nvkm/engine/fifo/nv84.c
index a2acf3f78..1f42996b3 100644
--- a/nvkm/engine/fifo/nv84.c
+++ b/nvkm/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/nvkm/engine/fifo/nvc0.c b/nvkm/engine/fifo/nvc0.c
index f76ed10d8..1fe1f8fbd 100644
--- a/nvkm/engine/fifo/nvc0.c
+++ b/nvkm/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/nvkm/engine/fifo/nve0.c b/nvkm/engine/fifo/nve0.c
index ef730b52c..d2f0fd39c 100644
--- a/nvkm/engine/fifo/nve0.c
+++ b/nvkm/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/nvkm/include/engine/fifo.h b/nvkm/include/engine/fifo.h
index b53f9d802..e5e4d930b 100644
--- a/nvkm/include/engine/fifo.h
+++ b/nvkm/include/engine/fifo.h
@@ -4,6 +4,7 @@
#include <core/namedb.h>
#include <core/gpuobj.h>
#include <core/engine.h>
+#include <core/event.h>
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 *);