diff options
author | Ilia Mirkin <imirkin@alum.mit.edu> | 2013-09-07 21:04:11 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2013-11-08 15:37:42 +1000 |
commit | e6585cab68a71a6025f7b6ace2681ebb866a030e (patch) | |
tree | ecfc4d3841397ab8c66e10db8493e1edada37cd5 /drivers/gpu/drm/nouveau/core/engine/mpeg | |
parent | 912de74c811fa5ba523bf1e525ce8ce45ecfeed4 (diff) | |
download | op-kernel-dev-e6585cab68a71a6025f7b6ace2681ebb866a030e.zip op-kernel-dev-e6585cab68a71a6025f7b6ace2681ebb866a030e.tar.gz |
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>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/engine/mpeg')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c | 27 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h | 9 |
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 2f80b223..9330fc4 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 a488c13..62d04e4 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 |