summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorIlia Mirkin <imirkin@alum.mit.edu>2013-09-07 21:04:11 -0400
committerBen Skeggs <bskeggs@redhat.com>2013-11-08 15:37:42 +1000
commite6585cab68a71a6025f7b6ace2681ebb866a030e (patch)
treeecfc4d3841397ab8c66e10db8493e1edada37cd5
parent912de74c811fa5ba523bf1e525ce8ce45ecfeed4 (diff)
downloadlinux-e6585cab68a71a6025f7b6ace2681ebb866a030e.tar.gz
linux-e6585cab68a71a6025f7b6ace2681ebb866a030e.tar.bz2
linux-e6585cab68a71a6025f7b6ace2681ebb866a030e.zip
drm/nv31/mpeg: store chan singleton in engine, use it for dispatch
This makes nv31+ able to actually perform the nv_call, since previously the inst was not available. Signed-off-by: Ilia Mirkin <imirkin@alum.mit.edu> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c27
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h9
2 files changed, 21 insertions, 15 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
index 2f80b2232232..9330fc42bd89 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
@@ -147,6 +147,8 @@ nv31_mpeg_context_ctor(struct nouveau_object *parent,
if (ret)
return ret;
+ priv->chan = chan;
+
return 0;
}
@@ -155,8 +157,11 @@ nv31_mpeg_context_dtor(struct nouveau_object *object)
{
struct nv31_mpeg_priv *priv = (void *)object->engine;
struct nv31_mpeg_chan *chan = (void *)object;
- atomic_dec(&priv->refcount);
+
+ WARN_ON(priv->chan != chan);
+ priv->chan = NULL;
nouveau_object_destroy(&chan->base);
+ atomic_dec(&priv->refcount);
}
struct nouveau_oclass
@@ -189,20 +194,19 @@ void
nv31_mpeg_intr(struct nouveau_subdev *subdev)
{
struct nouveau_fifo *pfifo = nouveau_fifo(subdev);
- struct nouveau_engine *engine = nv_engine(subdev);
- struct nouveau_object *engctx;
struct nouveau_handle *handle;
struct nv31_mpeg_priv *priv = (void *)subdev;
- u32 inst = nv_rd32(priv, 0x00b318) & 0x000fffff;
+ struct nouveau_object *engctx = &priv->chan->base;
u32 stat = nv_rd32(priv, 0x00b100);
u32 type = nv_rd32(priv, 0x00b230);
u32 mthd = nv_rd32(priv, 0x00b234);
u32 data = nv_rd32(priv, 0x00b238);
u32 show = stat;
- int chid;
+ int chid = pfifo->chid(pfifo, engctx);
- engctx = nouveau_engctx_get(engine, inst);
- chid = pfifo->chid(pfifo, engctx);
+ if (engctx)
+ if (nouveau_object_inc(engctx))
+ engctx = NULL;
if (stat & 0x01000000) {
/* happens on initial binding of the object */
@@ -211,7 +215,7 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev)
show &= ~0x01000000;
}
- if (type == 0x00000010) {
+ if (type == 0x00000010 && engctx) {
handle = nouveau_handle_get_class(engctx, 0x3174);
if (handle && !nv_call(handle->object, mthd, data))
show &= ~0x01000000;
@@ -224,12 +228,13 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev)
if (show) {
nv_error(priv,
- "ch %d [0x%08x %s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
- chid, inst << 4, nouveau_client_name(engctx), stat,
+ "ch %d [%s] 0x%08x 0x%08x 0x%08x 0x%08x\n",
+ chid, nouveau_client_name(engctx), stat,
type, mthd, data);
}
- nouveau_engctx_put(engctx);
+ if (engctx)
+ WARN_ON(nouveau_object_dec(engctx, false));
}
static int
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h
index a488c13bffd6..62d04e475315 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h
@@ -3,13 +3,14 @@
#include <engine/mpeg.h>
+struct nv31_mpeg_chan {
+ struct nouveau_object base;
+};
+
struct nv31_mpeg_priv {
struct nouveau_mpeg base;
atomic_t refcount;
-};
-
-struct nv31_mpeg_chan {
- struct nouveau_object base;
+ struct nv31_mpeg_chan *chan;
};
#endif