Commit 867920f8 authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/fifo: implement nvif event source

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 6c6ae061
...@@ -28,6 +28,7 @@ ...@@ -28,6 +28,7 @@
#include <core/event.h> #include <core/event.h>
#include <nvif/unpack.h> #include <nvif/unpack.h>
#include <nvif/class.h> #include <nvif/class.h>
#include <nvif/event.h>
#include <engine/dmaobj.h> #include <engine/dmaobj.h>
#include <engine/fifo.h> #include <engine/fifo.h>
...@@ -168,6 +169,49 @@ _nouveau_fifo_channel_wr32(struct nouveau_object *object, u64 addr, u32 data) ...@@ -168,6 +169,49 @@ _nouveau_fifo_channel_wr32(struct nouveau_object *object, u64 addr, u32 data)
iowrite32_native(data, chan->user + addr); 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 static int
nouveau_fifo_chid(struct nouveau_fifo *priv, struct nouveau_object *object) nouveau_fifo_chid(struct nouveau_fifo *priv, struct nouveau_object *object)
{ {
......
...@@ -255,6 +255,7 @@ nv04_fifo_ofuncs = { ...@@ -255,6 +255,7 @@ nv04_fifo_ofuncs = {
.map = _nouveau_fifo_channel_map, .map = _nouveau_fifo_channel_map,
.rd32 = _nouveau_fifo_channel_rd32, .rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32, .wr32 = _nouveau_fifo_channel_wr32,
.ntfy = _nouveau_fifo_channel_ntfy
}; };
static struct nouveau_oclass static struct nouveau_oclass
...@@ -550,7 +551,7 @@ nv04_fifo_intr(struct nouveau_subdev *subdev) ...@@ -550,7 +551,7 @@ nv04_fifo_intr(struct nouveau_subdev *subdev)
} }
if (status & 0x40000000) { if (status & 0x40000000) {
nvkm_event_send(&priv->base.uevent, 1, 0, NULL, 0); nouveau_fifo_uevent(&priv->base);
nv_wr32(priv, 0x002100, 0x40000000); nv_wr32(priv, 0x002100, 0x40000000);
status &= ~0x40000000; status &= ~0x40000000;
} }
......
...@@ -113,6 +113,7 @@ nv10_fifo_ofuncs = { ...@@ -113,6 +113,7 @@ nv10_fifo_ofuncs = {
.map = _nouveau_fifo_channel_map, .map = _nouveau_fifo_channel_map,
.rd32 = _nouveau_fifo_channel_rd32, .rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32, .wr32 = _nouveau_fifo_channel_wr32,
.ntfy = _nouveau_fifo_channel_ntfy
}; };
static struct nouveau_oclass static struct nouveau_oclass
......
...@@ -120,6 +120,7 @@ nv17_fifo_ofuncs = { ...@@ -120,6 +120,7 @@ nv17_fifo_ofuncs = {
.map = _nouveau_fifo_channel_map, .map = _nouveau_fifo_channel_map,
.rd32 = _nouveau_fifo_channel_rd32, .rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32, .wr32 = _nouveau_fifo_channel_wr32,
.ntfy = _nouveau_fifo_channel_ntfy
}; };
static struct nouveau_oclass static struct nouveau_oclass
......
...@@ -239,6 +239,7 @@ nv40_fifo_ofuncs = { ...@@ -239,6 +239,7 @@ nv40_fifo_ofuncs = {
.map = _nouveau_fifo_channel_map, .map = _nouveau_fifo_channel_map,
.rd32 = _nouveau_fifo_channel_rd32, .rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32, .wr32 = _nouveau_fifo_channel_wr32,
.ntfy = _nouveau_fifo_channel_ntfy
}; };
static struct nouveau_oclass static struct nouveau_oclass
......
...@@ -366,6 +366,7 @@ nv50_fifo_ofuncs_dma = { ...@@ -366,6 +366,7 @@ nv50_fifo_ofuncs_dma = {
.map = _nouveau_fifo_channel_map, .map = _nouveau_fifo_channel_map,
.rd32 = _nouveau_fifo_channel_rd32, .rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32, .wr32 = _nouveau_fifo_channel_wr32,
.ntfy = _nouveau_fifo_channel_ntfy
}; };
static struct nouveau_ofuncs static struct nouveau_ofuncs
...@@ -377,6 +378,7 @@ nv50_fifo_ofuncs_ind = { ...@@ -377,6 +378,7 @@ nv50_fifo_ofuncs_ind = {
.map = _nouveau_fifo_channel_map, .map = _nouveau_fifo_channel_map,
.rd32 = _nouveau_fifo_channel_rd32, .rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32, .wr32 = _nouveau_fifo_channel_wr32,
.ntfy = _nouveau_fifo_channel_ntfy
}; };
static struct nouveau_oclass static struct nouveau_oclass
......
...@@ -327,6 +327,7 @@ nv84_fifo_ofuncs_dma = { ...@@ -327,6 +327,7 @@ nv84_fifo_ofuncs_dma = {
.map = _nouveau_fifo_channel_map, .map = _nouveau_fifo_channel_map,
.rd32 = _nouveau_fifo_channel_rd32, .rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32, .wr32 = _nouveau_fifo_channel_wr32,
.ntfy = _nouveau_fifo_channel_ntfy
}; };
static struct nouveau_ofuncs static struct nouveau_ofuncs
...@@ -338,6 +339,7 @@ nv84_fifo_ofuncs_ind = { ...@@ -338,6 +339,7 @@ nv84_fifo_ofuncs_ind = {
.map = _nouveau_fifo_channel_map, .map = _nouveau_fifo_channel_map,
.rd32 = _nouveau_fifo_channel_rd32, .rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32, .wr32 = _nouveau_fifo_channel_wr32,
.ntfy = _nouveau_fifo_channel_ntfy
}; };
static struct nouveau_oclass static struct nouveau_oclass
...@@ -424,21 +426,9 @@ nv84_fifo_uevent_fini(struct nvkm_event *event, int type, int index) ...@@ -424,21 +426,9 @@ nv84_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
nv_mask(fifo, 0x002140, 0x40000000, 0x00000000); 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 static const struct nvkm_event_func
nv84_fifo_uevent_func = { nv84_fifo_uevent_func = {
.ctor = nv84_fifo_uevent_ctor, .ctor = nouveau_fifo_uevent_ctor,
.init = nv84_fifo_uevent_init, .init = nv84_fifo_uevent_init,
.fini = nv84_fifo_uevent_fini, .fini = nv84_fifo_uevent_fini,
}; };
......
...@@ -305,6 +305,7 @@ nvc0_fifo_ofuncs = { ...@@ -305,6 +305,7 @@ nvc0_fifo_ofuncs = {
.map = _nouveau_fifo_channel_map, .map = _nouveau_fifo_channel_map,
.rd32 = _nouveau_fifo_channel_rd32, .rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32, .wr32 = _nouveau_fifo_channel_wr32,
.ntfy = _nouveau_fifo_channel_ntfy
}; };
static struct nouveau_oclass static struct nouveau_oclass
...@@ -742,7 +743,7 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn) ...@@ -742,7 +743,7 @@ nvc0_fifo_intr_engine_unit(struct nvc0_fifo_priv *priv, int engn)
for (unkn = 0; unkn < 8; unkn++) { for (unkn = 0; unkn < 8; unkn++) {
u32 ints = (intr >> (unkn * 0x04)) & inte; u32 ints = (intr >> (unkn * 0x04)) & inte;
if (ints & 0x1) { if (ints & 0x1) {
nvkm_event_send(&priv->base.uevent, 1, 0, NULL, 0); nouveau_fifo_uevent(&priv->base);
ints &= ~1; ints &= ~1;
} }
if (ints) { if (ints) {
...@@ -852,21 +853,9 @@ nvc0_fifo_uevent_fini(struct nvkm_event *event, int type, int index) ...@@ -852,21 +853,9 @@ nvc0_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
nv_mask(fifo, 0x002140, 0x80000000, 0x00000000); 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 static const struct nvkm_event_func
nvc0_fifo_uevent_func = { nvc0_fifo_uevent_func = {
.ctor = nvc0_fifo_uevent_ctor, .ctor = nouveau_fifo_uevent_ctor,
.init = nvc0_fifo_uevent_init, .init = nvc0_fifo_uevent_init,
.fini = nvc0_fifo_uevent_fini, .fini = nvc0_fifo_uevent_fini,
}; };
......
...@@ -339,6 +339,7 @@ nve0_fifo_ofuncs = { ...@@ -339,6 +339,7 @@ nve0_fifo_ofuncs = {
.map = _nouveau_fifo_channel_map, .map = _nouveau_fifo_channel_map,
.rd32 = _nouveau_fifo_channel_rd32, .rd32 = _nouveau_fifo_channel_rd32,
.wr32 = _nouveau_fifo_channel_wr32, .wr32 = _nouveau_fifo_channel_wr32,
.ntfy = _nouveau_fifo_channel_ntfy
}; };
static struct nouveau_oclass static struct nouveau_oclass
...@@ -871,7 +872,7 @@ nve0_fifo_intr_runlist(struct nve0_fifo_priv *priv) ...@@ -871,7 +872,7 @@ nve0_fifo_intr_runlist(struct nve0_fifo_priv *priv)
static void static void
nve0_fifo_intr_engine(struct nve0_fifo_priv *priv) 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 static void
...@@ -977,21 +978,9 @@ nve0_fifo_uevent_fini(struct nvkm_event *event, int type, int index) ...@@ -977,21 +978,9 @@ nve0_fifo_uevent_fini(struct nvkm_event *event, int type, int index)
nv_mask(fifo, 0x002140, 0x80000000, 0x00000000); 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 static const struct nvkm_event_func
nve0_fifo_uevent_func = { nve0_fifo_uevent_func = {
.ctor = nve0_fifo_uevent_ctor, .ctor = nouveau_fifo_uevent_ctor,
.init = nve0_fifo_uevent_init, .init = nve0_fifo_uevent_init,
.fini = nve0_fifo_uevent_fini, .fini = nve0_fifo_uevent_fini,
}; };
......
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
#include <core/namedb.h> #include <core/namedb.h>
#include <core/gpuobj.h> #include <core/gpuobj.h>
#include <core/engine.h> #include <core/engine.h>
#include <core/event.h>
struct nouveau_fifo_chan { struct nouveau_fifo_chan {
struct nouveau_namedb base; struct nouveau_namedb base;
...@@ -44,6 +45,7 @@ void _nouveau_fifo_channel_dtor(struct nouveau_object *); ...@@ -44,6 +45,7 @@ void _nouveau_fifo_channel_dtor(struct nouveau_object *);
int _nouveau_fifo_channel_map(struct nouveau_object *, u64 *, u32 *); int _nouveau_fifo_channel_map(struct nouveau_object *, u64 *, u32 *);
u32 _nouveau_fifo_channel_rd32(struct nouveau_object *, u64); u32 _nouveau_fifo_channel_rd32(struct nouveau_object *, u64);
void _nouveau_fifo_channel_wr32(struct nouveau_object *, u64, u32); 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_fifo_base {
struct nouveau_gpuobj base; struct nouveau_gpuobj base;
...@@ -114,6 +116,9 @@ extern struct nouveau_oclass *nve0_fifo_oclass; ...@@ -114,6 +116,9 @@ extern struct nouveau_oclass *nve0_fifo_oclass;
extern struct nouveau_oclass *gk20a_fifo_oclass; extern struct nouveau_oclass *gk20a_fifo_oclass;
extern struct nouveau_oclass *nv108_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 *); void nv04_fifo_intr(struct nouveau_subdev *);
int nv04_fifo_context_attach(struct nouveau_object *, struct nouveau_object *); int nv04_fifo_context_attach(struct nouveau_object *, struct nouveau_object *);
......
...@@ -29,6 +29,9 @@ ...@@ -29,6 +29,9 @@
#include <linux/ktime.h> #include <linux/ktime.h>
#include <linux/hrtimer.h> #include <linux/hrtimer.h>
#include <nvif/notify.h>
#include <nvif/event.h>
#include "nouveau_drm.h" #include "nouveau_drm.h"
#include "nouveau_dma.h" #include "nouveau_dma.h"
#include "nouveau_fence.h" #include "nouveau_fence.h"
...@@ -165,16 +168,16 @@ nouveau_fence_done(struct nouveau_fence *fence) ...@@ -165,16 +168,16 @@ nouveau_fence_done(struct nouveau_fence *fence)
struct nouveau_fence_wait { struct nouveau_fence_wait {
struct nouveau_fence_priv *priv; struct nouveau_fence_priv *priv;
struct nvkm_notify notify; struct nvif_notify notify;
}; };
static int 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 = struct nouveau_fence_wait *wait =
container_of(notify, typeof(*wait), notify); container_of(notify, typeof(*wait), notify);
wake_up_all(&wait->priv->waiting); wake_up_all(&wait->priv->waiting);
return NVKM_NOTIFY_KEEP; return NVIF_NOTIFY_KEEP;
} }
static int static int
...@@ -182,18 +185,22 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) ...@@ -182,18 +185,22 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr)
{ {
struct nouveau_channel *chan = fence->channel; 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_priv *priv = chan->drm->fence;
struct nouveau_fence_wait wait = { .priv = priv }; struct nouveau_fence_wait wait = { .priv = priv };
int ret = 0; int ret = 0;
ret = nvkm_notify_init(&pfifo->uevent, ret = nvif_notify_init(chan->object, NULL,
nouveau_fence_wait_uevent_handler, false, 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) if (ret)
return ret; return ret;
nvkm_notify_get(&wait.notify); nvif_notify_get(&wait.notify);
if (fence->timeout) { if (fence->timeout) {
unsigned long timeout = fence->timeout - jiffies; unsigned long timeout = fence->timeout - jiffies;
...@@ -225,7 +232,7 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) ...@@ -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)) if (unlikely(ret < 0))
return ret; return ret;
......
...@@ -258,6 +258,7 @@ struct nv03_channel_dma_v0 { ...@@ -258,6 +258,7 @@ struct nv03_channel_dma_v0 {
__u64 offset; __u64 offset;
}; };
#define G82_CHANNEL_DMA_V0_NTFY_UEVENT 0x00
/******************************************************************************* /*******************************************************************************
* GPFIFO channels * GPFIFO channels
......
...@@ -51,4 +51,12 @@ struct nvif_notify_conn_rep_v0 { ...@@ -51,4 +51,12 @@ struct nvif_notify_conn_rep_v0 {
__u8 pad02[6]; __u8 pad02[6];
}; };
struct nvif_notify_uevent_req {
/* nvif_notify_req ... */
};
struct nvif_notify_uevent_rep {
/* nvif_notify_rep ... */
};
#endif #endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment