[Nouveau] [PATCH 6/7] drm/nv31-nv44/mpeg: inst not available on pre-nv44
Ilia Mirkin
imirkin at alum.mit.edu
Thu Sep 5 01:45:05 PDT 2013
The inst variable (and thus engctx) will not be properly populated for
pre-NV44 cards. The dma setter method didn't need it anyways, so call it
directly instead of the nv_call indirection.
Signed-off-by: Ilia Mirkin <imirkin at alum.mit.edu>
---
An alternative is to move this logic into the nv44 intr handler, but I
don't think that's justified.
drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c | 50 ++++++++++++-------------
1 file changed, 24 insertions(+), 26 deletions(-)
diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
index 30dc047..b966728 100644
--- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
+++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c
@@ -72,11 +72,10 @@ nv31_mpeg_object_ctor(struct nouveau_object *parent,
}
static int
-nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
+nv31_mpeg_mthd_dma(struct nv31_mpeg_priv *priv, u32 mthd, u32 arg)
{
- struct nouveau_instmem *imem = nouveau_instmem(object);
- struct nv31_mpeg_priv *priv = (void *)object->engine;
- u32 inst = *(u32 *)arg << 4;
+ struct nouveau_instmem *imem = nouveau_instmem(priv);
+ u32 inst = arg << 4;
u32 dma0 = nv_ro32(imem, inst + 0);
u32 dma1 = nv_ro32(imem, inst + 4);
u32 dma2 = nv_ro32(imem, inst + 8);
@@ -106,13 +105,16 @@ nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len)
nv_mask(priv, 0x00b300, 0x000c0000, mem_target << 2);
nv_wr32(priv, 0x00b360, base);
nv_wr32(priv, 0x00b364, size);
- } else {
+ } else
+ if (mthd == 0x01b0) {
/* DMA_IMAGE, VRAM only */
if (mem_target)
return -EINVAL;
nv_wr32(priv, 0x00b370, base);
nv_wr32(priv, 0x00b374, size);
+ } else {
+ return -EINVAL;
}
return 0;
@@ -128,17 +130,9 @@ nv31_mpeg_ofuncs = {
.wr32 = _nouveau_gpuobj_wr32,
};
-static struct nouveau_omthds
-nv31_mpeg_omthds[] = {
- { 0x0190, 0x0190, nv31_mpeg_mthd_dma },
- { 0x01a0, 0x01a0, nv31_mpeg_mthd_dma },
- { 0x01b0, 0x01b0, nv31_mpeg_mthd_dma },
- {}
-};
-
struct nouveau_oclass
nv31_mpeg_sclass[] = {
- { 0x3174, &nv31_mpeg_ofuncs, nv31_mpeg_omthds },
+ { 0x3174, &nv31_mpeg_ofuncs },
{}
};
@@ -208,9 +202,8 @@ 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;
+ u32 inst;
u32 stat = nv_rd32(priv, 0x00b100);
u32 type = nv_rd32(priv, 0x00b230);
u32 mthd = nv_rd32(priv, 0x00b234);
@@ -218,9 +211,6 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev)
u32 show = stat;
int chid;
- engctx = nouveau_engctx_get(engine, inst);
- chid = pfifo->chid(pfifo, engctx);
-
if (stat & 0x01000000) {
/* happens on initial binding of the object */
if (type == 0x00000020 && mthd == 0x0000) {
@@ -229,23 +219,31 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev)
}
if (type == 0x00000010) {
- handle = nouveau_handle_get_class(engctx, 0x3174);
- if (handle && !nv_call(handle->object, mthd, data))
+ if (!nv31_mpeg_mthd_dma(priv, mthd, data))
show &= ~0x01000000;
- nouveau_handle_put(handle);
}
}
nv_wr32(priv, 0x00b100, stat);
nv_wr32(priv, 0x00b230, 0x00000001);
- if (show) {
+ if (!show)
+ return;
+
+ if (nv_device(engine)->chipset < 0x44) {
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,
- type, mthd, data);
+ "0x%08x 0x%08x 0x%08x 0x%08x\n",
+ stat, type, mthd, data);
+ return;
}
+ inst = nv_rd32(priv, 0x00b318) & 0x000fffff;
+ engctx = nouveau_engctx_get(engine, inst);
+ chid = pfifo->chid(pfifo, engctx);
+ 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,
+ type, mthd, data);
nouveau_engctx_put(engctx);
}
--
1.8.1.5
More information about the Nouveau
mailing list