diff options
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/base.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c | 24 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/engine/fifo.h | 2 |
4 files changed, 56 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c index ca1057a..7341ebe 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/base.c @@ -25,6 +25,7 @@ #include <core/client.h> #include <core/object.h> #include <core/handle.h> +#include <core/event.h> #include <core/class.h> #include <engine/dmaobj.h> @@ -165,6 +166,7 @@ void nouveau_fifo_destroy(struct nouveau_fifo *priv) { kfree(priv->channel); + nouveau_event_destroy(&priv->uevent); nouveau_engine_destroy(&priv->base); } @@ -189,6 +191,10 @@ nouveau_fifo_create_(struct nouveau_object *parent, if (!priv->channel) return -ENOMEM; + ret = nouveau_event_create(1, &priv->uevent); + if (ret) + return ret; + priv->chid = nouveau_fifo_chid; spin_lock_init(&priv->lock); return 0; diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index 2a9919b..bf86f40 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c @@ -27,6 +27,7 @@ #include <core/namedb.h> #include <core/gpuobj.h> #include <core/engctx.h> +#include <core/event.h> #include <core/class.h> #include <core/math.h> #include <core/enum.h> @@ -583,7 +584,8 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev) if (stat & 0x80000000) { u32 intr = nv_mask(priv, 0x0025a8, 0x00000000, 0x00000000); - nv_warn(priv, "INTR 0x80000000: 0x%08x\n", intr); + nouveau_event_trigger(priv->base.uevent, 0); + nv_debug(priv, "INTR 0x80000000: 0x%08x\n", intr); stat &= ~0x80000000; } @@ -594,6 +596,20 @@ nvc0_fifo_intr(struct nouveau_subdev *subdev) } } +static void +nvc0_fifo_uevent_enable(struct nouveau_event *event, int index) +{ + struct nvc0_fifo_priv *priv = event->priv; + nv_mask(priv, 0x002140, 0x80000000, 0x80000000); +} + +static void +nvc0_fifo_uevent_disable(struct nouveau_event *event, int index) +{ + struct nvc0_fifo_priv *priv = event->priv; + nv_mask(priv, 0x002140, 0x80000000, 0x00000000); +} + static int nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -627,6 +643,10 @@ nvc0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; + priv->base.uevent->enable = nvc0_fifo_uevent_enable; + priv->base.uevent->disable = nvc0_fifo_uevent_disable; + priv->base.uevent->priv = priv; + nv_subdev(priv)->unit = 0x00000100; nv_subdev(priv)->intr = nvc0_fifo_intr; nv_engine(priv)->cclass = &nvc0_fifo_cclass; @@ -685,7 +705,7 @@ nvc0_fifo_init(struct nouveau_object *object) nv_wr32(priv, 0x002a00, 0xffffffff); /* clears PFIFO.INTR bit 30 */ nv_wr32(priv, 0x002100, 0xffffffff); - nv_wr32(priv, 0x002140, 0xbfffffff); + nv_wr32(priv, 0x002140, 0x3fffffff); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 410c6e2..4419e40 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c @@ -27,6 +27,7 @@ #include <core/namedb.h> #include <core/gpuobj.h> #include <core/engctx.h> +#include <core/event.h> #include <core/class.h> #include <core/math.h> #include <core/enum.h> @@ -554,6 +555,12 @@ nve0_fifo_intr(struct nouveau_subdev *subdev) stat &= ~0x40000000; } + if (stat & 0x80000000) { + nouveau_event_trigger(priv->base.uevent, 0); + nv_wr32(priv, 0x002100, 0x80000000); + stat &= ~0x80000000; + } + if (stat) { nv_fatal(priv, "unhandled status 0x%08x\n", stat); nv_wr32(priv, 0x002100, stat); @@ -561,6 +568,20 @@ nve0_fifo_intr(struct nouveau_subdev *subdev) } } +static void +nve0_fifo_uevent_enable(struct nouveau_event *event, int index) +{ + struct nve0_fifo_priv *priv = event->priv; + nv_mask(priv, 0x002140, 0x80000000, 0x80000000); +} + +static void +nve0_fifo_uevent_disable(struct nouveau_event *event, int index) +{ + struct nve0_fifo_priv *priv = event->priv; + nv_mask(priv, 0x002140, 0x80000000, 0x00000000); +} + static int nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -584,6 +605,10 @@ nve0_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; + priv->base.uevent->enable = nve0_fifo_uevent_enable; + priv->base.uevent->disable = nve0_fifo_uevent_disable; + priv->base.uevent->priv = priv; + nv_subdev(priv)->unit = 0x00000100; nv_subdev(priv)->intr = nve0_fifo_intr; nv_engine(priv)->cclass = &nve0_fifo_cclass; @@ -634,7 +659,7 @@ nve0_fifo_init(struct nouveau_object *object) nv_wr32(priv, 0x002a00, 0xffffffff); nv_wr32(priv, 0x002100, 0xffffffff); - nv_wr32(priv, 0x002140, 0xbfffffff); + nv_wr32(priv, 0x002140, 0x3fffffff); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h index 543e4ef..b46c197 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h @@ -65,6 +65,8 @@ struct nouveau_fifo_base { struct nouveau_fifo { struct nouveau_engine base; + struct nouveau_event *uevent; + struct nouveau_object **channel; spinlock_t lock; u16 min; |