Skip to content

Commit

Permalink
drm/nouveau/fifo/nvc0-: use interrupt 31 as an event trigger
Browse files Browse the repository at this point in the history
Generated if you try and use fifo method 0x20 on any subchannel, appears
that it can be safely masked off without stalling the whole GPU.

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
  • Loading branch information
Ben Skeggs committed Feb 20, 2013
1 parent 1d7c71a commit 9bd2ddb
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 3 deletions.
6 changes: 6 additions & 0 deletions drivers/gpu/drm/nouveau/core/engine/fifo/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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);
}

Expand All @@ -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;
Expand Down
24 changes: 22 additions & 2 deletions drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
}

Expand All @@ -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,
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
27 changes: 26 additions & 1 deletion drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -554,13 +555,33 @@ 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);
nv_wr32(priv, 0x002140, 0);
}
}

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,
Expand All @@ -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;
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/nouveau/core/include/engine/fifo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 9bd2ddb

Please sign in to comment.