aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2015-08-20 14:54:18 +1000
committerBen Skeggs <bskeggs@redhat.com>2015-08-28 12:40:39 +1000
commit590801c1a3b19883b0d0e4c60241cbed8a916d47 (patch)
tree98b94cee736ec2cc7ec522222ad440ce5faf227c /drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
parenta65955e19e769e92a0e29cccdc29aea0b19f3809 (diff)
drm/nouveau/mpeg: remove dependence on namedb/engctx lookup
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c')
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c90
1 files changed, 69 insertions, 21 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
index 93936671f39b..1223baddfb9a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/mpeg/nv44.c
@@ -24,24 +24,47 @@
#include <engine/mpeg.h>
#include <core/client.h>
-#include <core/handle.h>
#include <engine/fifo.h>
+struct nv44_mpeg {
+ struct nvkm_mpeg base;
+ struct list_head chan;
+};
+
struct nv44_mpeg_chan {
struct nvkm_mpeg_chan base;
+ struct nvkm_fifo_chan *fifo;
+ u32 inst;
+ struct list_head head;
};
+bool nv40_mpeg_mthd_dma(struct nvkm_device *, u32, u32);
+
/*******************************************************************************
* PMPEG context
******************************************************************************/
+static void
+nv44_mpeg_context_dtor(struct nvkm_object *object)
+{
+ struct nv44_mpeg_chan *chan = (void *)object;
+ struct nv44_mpeg *mpeg = (void *)object->engine;
+ unsigned long flags;
+ spin_lock_irqsave(&mpeg->base.engine.lock, flags);
+ list_del(&chan->head);
+ spin_unlock_irqrestore(&mpeg->base.engine.lock, flags);
+ nvkm_mpeg_context_destroy(&chan->base);
+}
+
static int
nv44_mpeg_context_ctor(struct nvkm_object *parent,
struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{
+ struct nv44_mpeg *mpeg = (void *)engine;
struct nv44_mpeg_chan *chan;
+ unsigned long flags;
int ret;
ret = nvkm_mpeg_context_create(parent, engine, oclass, NULL, 264 * 4,
@@ -50,6 +73,12 @@ nv44_mpeg_context_ctor(struct nvkm_object *parent,
if (ret)
return ret;
+ spin_lock_irqsave(&mpeg->base.engine.lock, flags);
+ chan->fifo = nvkm_fifo_chan(parent);
+ chan->inst = chan->base.base.gpuobj.addr;
+ list_add(&chan->head, &mpeg->chan);
+ spin_unlock_irqrestore(&mpeg->base.engine.lock, flags);
+
nvkm_kmap(&chan->base.base.gpuobj);
nvkm_wo32(&chan->base.base.gpuobj, 0x78, 0x02001ec1);
nvkm_done(&chan->base.base.gpuobj);
@@ -77,7 +106,7 @@ nv44_mpeg_cclass = {
.handle = NV_ENGCTX(MPEG, 0x44),
.ofuncs = &(struct nvkm_ofuncs) {
.ctor = nv44_mpeg_context_ctor,
- .dtor = _nvkm_mpeg_context_dtor,
+ .dtor = nv44_mpeg_context_dtor,
.init = _nvkm_mpeg_context_init,
.fini = nv44_mpeg_context_fini,
.rd32 = _nvkm_mpeg_context_rd32,
@@ -89,25 +118,45 @@ nv44_mpeg_cclass = {
* PMPEG engine/subdev functions
******************************************************************************/
+static bool
+nv44_mpeg_mthd(struct nvkm_device *device, u32 mthd, u32 data)
+{
+ switch (mthd) {
+ case 0x190:
+ case 0x1a0:
+ case 0x1b0:
+ return nv40_mpeg_mthd_dma(device, mthd, data);
+ default:
+ break;
+ }
+ return false;
+}
+
static void
nv44_mpeg_intr(struct nvkm_subdev *subdev)
{
- struct nvkm_mpeg *mpeg = (void *)subdev;
- struct nvkm_device *device = mpeg->engine.subdev.device;
- struct nvkm_fifo *fifo = device->fifo;
- struct nvkm_engine *engine = nv_engine(subdev);
- struct nvkm_object *engctx;
- struct nvkm_handle *handle;
+ struct nv44_mpeg *mpeg = (void *)subdev;
+ struct nv44_mpeg_chan *temp, *chan = NULL;
+ struct nvkm_device *device = mpeg->base.engine.subdev.device;
+ unsigned long flags;
u32 inst = nvkm_rd32(device, 0x00b318) & 0x000fffff;
u32 stat = nvkm_rd32(device, 0x00b100);
u32 type = nvkm_rd32(device, 0x00b230);
u32 mthd = nvkm_rd32(device, 0x00b234);
u32 data = nvkm_rd32(device, 0x00b238);
u32 show = stat;
- int chid;
-
- engctx = nvkm_engctx_get(engine, inst);
- chid = fifo->chid(fifo, engctx);
+ int chid = -1;
+
+ spin_lock_irqsave(&mpeg->base.engine.lock, flags);
+ list_for_each_entry(temp, &mpeg->chan, head) {
+ if (temp->inst >> 4 == inst) {
+ chan = temp;
+ chid = chan->fifo->chid;
+ list_del(&chan->head);
+ list_add(&chan->head, &mpeg->chan);
+ break;
+ }
+ }
if (stat & 0x01000000) {
/* happens on initial binding of the object */
@@ -117,10 +166,8 @@ nv44_mpeg_intr(struct nvkm_subdev *subdev)
}
if (type == 0x00000010) {
- handle = nvkm_handle_get_class(engctx, 0x3174);
- if (handle && !nv_call(handle->object, mthd, data))
+ if (!nv44_mpeg_mthd(subdev->device, mthd, data))
show &= ~0x01000000;
- nvkm_handle_put(handle);
}
}
@@ -128,13 +175,12 @@ nv44_mpeg_intr(struct nvkm_subdev *subdev)
nvkm_wr32(device, 0x00b230, 0x00000001);
if (show) {
- nvkm_error(subdev,
- "ch %d [%08x %s] %08x %08x %08x %08x\n",
- chid, inst << 4, nvkm_client_name(engctx), stat,
- type, mthd, data);
+ nvkm_error(subdev, "ch %d [%08x %s] %08x %08x %08x %08x\n",
+ chid, inst << 4, nvkm_client_name(chan),
+ stat, type, mthd, data);
}
- nvkm_engctx_put(engctx);
+ spin_unlock_irqrestore(&mpeg->base.engine.lock, flags);
}
static void
@@ -158,7 +204,7 @@ nv44_mpeg_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
struct nvkm_oclass *oclass, void *data, u32 size,
struct nvkm_object **pobject)
{
- struct nvkm_mpeg *mpeg;
+ struct nv44_mpeg *mpeg;
int ret;
ret = nvkm_mpeg_create(parent, engine, oclass, &mpeg);
@@ -166,6 +212,8 @@ nv44_mpeg_ctor(struct nvkm_object *parent, struct nvkm_object *engine,
if (ret)
return ret;
+ INIT_LIST_HEAD(&mpeg->chan);
+
nv_subdev(mpeg)->unit = 0x00000002;
nv_subdev(mpeg)->intr = nv44_mpeg_me_intr;
nv_engine(mpeg)->cclass = &nv44_mpeg_cclass;