aboutsummaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-08-06 18:16:37 +1000
committerBen Skeggs <bskeggs@redhat.com>2012-10-03 13:13:01 +1000
commitdbff2dee9f8561710fcfe7f6623dd272ddca5a27 (patch)
tree69efde69340d08fdbe02e48e8d753263a14f54b7 /drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
parent43b1e9c9899ece92c1f68d45ae0d7b98d009f5d0 (diff)
downloadvexpress-lsk-dbff2dee9f8561710fcfe7f6623dd272ddca5a27.tar.gz
drm/nve0/fifo: support engine selection when creating fifo channels
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c')
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c45
1 files changed, 39 insertions, 6 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
index aaff086dfd2..c3f4955fef5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
@@ -38,6 +38,22 @@
#include <engine/dmaobj.h>
#include <engine/fifo.h>
+#define _(a,b) { (a), ((1 << (a)) | (b)) }
+static const struct {
+ int subdev;
+ u32 mask;
+} fifo_engine[] = {
+ _(NVDEV_ENGINE_GR , (1 << NVDEV_ENGINE_SW)),
+ _(NVDEV_ENGINE_VP , 0),
+ _(NVDEV_ENGINE_PPP , 0),
+ _(NVDEV_ENGINE_BSP , 0),
+ _(NVDEV_ENGINE_COPY0 , 0),
+ _(NVDEV_ENGINE_COPY1 , 0),
+ _(NVDEV_ENGINE_VENC , 0),
+};
+#undef _
+#define FIFO_ENGINE_NR ARRAY_SIZE(fifo_engine)
+
struct nve0_fifo_engn {
struct nouveau_gpuobj *playlist[2];
int cur_playlist;
@@ -45,7 +61,7 @@ struct nve0_fifo_engn {
struct nve0_fifo_priv {
struct nouveau_fifo base;
- struct nve0_fifo_engn engine[16];
+ struct nve0_fifo_engn engine[FIFO_ENGINE_NR];
struct {
struct nouveau_gpuobj *mem;
struct nouveau_vma bar;
@@ -119,7 +135,9 @@ nve0_fifo_context_attach(struct nouveau_object *parent,
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0;
- case NVDEV_ENGINE_GR : addr = 0x0210; break;
+ case NVDEV_ENGINE_GR :
+ case NVDEV_ENGINE_COPY0:
+ case NVDEV_ENGINE_COPY1: addr = 0x0210; break;
default:
return -EINVAL;
}
@@ -149,7 +167,9 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0;
- case NVDEV_ENGINE_GR : addr = 0x0210; break;
+ case NVDEV_ENGINE_GR :
+ case NVDEV_ENGINE_COPY0:
+ case NVDEV_ENGINE_COPY1: addr = 0x0210; break;
default:
return -EINVAL;
}
@@ -178,24 +198,36 @@ nve0_fifo_chan_ctor(struct nouveau_object *parent,
struct nve0_fifo_priv *priv = (void *)engine;
struct nve0_fifo_base *base = (void *)parent;
struct nve0_fifo_chan *chan;
- struct nv_channel_ind_class *args = data;
+ struct nve0_channel_ind_class *args = data;
u64 usermem, ioffset, ilength;
int ret, i;
if (size < sizeof(*args))
return -EINVAL;
+ for (i = 0; i < FIFO_ENGINE_NR; i++) {
+ if (args->engine & (1 << i)) {
+ if (nouveau_engine(parent, fifo_engine[i].subdev)) {
+ args->engine = (1 << i);
+ break;
+ }
+ }
+ }
+
+ if (i == FIFO_ENGINE_NR)
+ return -ENODEV;
+
ret = nouveau_fifo_channel_create(parent, engine, oclass, 1,
priv->user.bar.offset, 0x200,
args->pushbuf,
- (1 << NVDEV_ENGINE_SW) |
- (1 << NVDEV_ENGINE_GR), &chan);
+ fifo_engine[i].mask, &chan);
*pobject = nv_object(chan);
if (ret)
return ret;
nv_parent(chan)->context_attach = nve0_fifo_context_attach;
nv_parent(chan)->context_detach = nve0_fifo_context_detach;
+ chan->engine = i;
usermem = chan->base.chid * 0x200;
ioffset = args->ioffset;
@@ -235,6 +267,7 @@ nve0_fifo_chan_init(struct nouveau_object *object)
if (ret)
return ret;
+ nv_mask(priv, 0x800004 + (chid * 8), 0x000f0000, chan->engine << 16);
nv_wr32(priv, 0x800000 + (chid * 8), 0x80000000 | base->addr >> 12);
nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
nve0_fifo_playlist_update(priv, chan->engine);