Commit dbff2dee authored by Ben Skeggs's avatar Ben Skeggs

drm/nve0/fifo: support engine selection when creating fifo channels

Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 43b1e9c9
...@@ -182,7 +182,7 @@ nv50_fifo_chan_ctor(struct nouveau_object *parent, ...@@ -182,7 +182,7 @@ nv50_fifo_chan_ctor(struct nouveau_object *parent,
struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_oclass *oclass, void *data, u32 size,
struct nouveau_object **pobject) struct nouveau_object **pobject)
{ {
struct nv_channel_ind_class *args = data; struct nv50_channel_ind_class *args = data;
struct nouveau_bar *bar = nouveau_bar(parent); struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_base *base = (void *)parent; struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan; struct nv50_fifo_chan *chan;
......
...@@ -150,7 +150,7 @@ nv84_fifo_chan_ctor(struct nouveau_object *parent, ...@@ -150,7 +150,7 @@ nv84_fifo_chan_ctor(struct nouveau_object *parent,
struct nouveau_bar *bar = nouveau_bar(parent); struct nouveau_bar *bar = nouveau_bar(parent);
struct nv50_fifo_base *base = (void *)parent; struct nv50_fifo_base *base = (void *)parent;
struct nv50_fifo_chan *chan; struct nv50_fifo_chan *chan;
struct nv_channel_ind_class *args = data; struct nv50_channel_ind_class *args = data;
u64 ioffset, ilength; u64 ioffset, ilength;
int ret; int ret;
......
...@@ -163,7 +163,7 @@ nvc0_fifo_chan_ctor(struct nouveau_object *parent, ...@@ -163,7 +163,7 @@ nvc0_fifo_chan_ctor(struct nouveau_object *parent,
struct nvc0_fifo_priv *priv = (void *)engine; struct nvc0_fifo_priv *priv = (void *)engine;
struct nvc0_fifo_base *base = (void *)parent; struct nvc0_fifo_base *base = (void *)parent;
struct nvc0_fifo_chan *chan; struct nvc0_fifo_chan *chan;
struct nv_channel_ind_class *args = data; struct nv50_channel_ind_class *args = data;
u64 usermem, ioffset, ilength; u64 usermem, ioffset, ilength;
int ret, i; int ret, i;
......
...@@ -38,6 +38,22 @@ ...@@ -38,6 +38,22 @@
#include <engine/dmaobj.h> #include <engine/dmaobj.h>
#include <engine/fifo.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 nve0_fifo_engn {
struct nouveau_gpuobj *playlist[2]; struct nouveau_gpuobj *playlist[2];
int cur_playlist; int cur_playlist;
...@@ -45,7 +61,7 @@ struct nve0_fifo_engn { ...@@ -45,7 +61,7 @@ struct nve0_fifo_engn {
struct nve0_fifo_priv { struct nve0_fifo_priv {
struct nouveau_fifo base; struct nouveau_fifo base;
struct nve0_fifo_engn engine[16]; struct nve0_fifo_engn engine[FIFO_ENGINE_NR];
struct { struct {
struct nouveau_gpuobj *mem; struct nouveau_gpuobj *mem;
struct nouveau_vma bar; struct nouveau_vma bar;
...@@ -119,7 +135,9 @@ nve0_fifo_context_attach(struct nouveau_object *parent, ...@@ -119,7 +135,9 @@ nve0_fifo_context_attach(struct nouveau_object *parent,
switch (nv_engidx(object->engine)) { switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0; 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: default:
return -EINVAL; return -EINVAL;
} }
...@@ -149,7 +167,9 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend, ...@@ -149,7 +167,9 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
switch (nv_engidx(object->engine)) { switch (nv_engidx(object->engine)) {
case NVDEV_ENGINE_SW : return 0; 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: default:
return -EINVAL; return -EINVAL;
} }
...@@ -178,24 +198,36 @@ nve0_fifo_chan_ctor(struct nouveau_object *parent, ...@@ -178,24 +198,36 @@ nve0_fifo_chan_ctor(struct nouveau_object *parent,
struct nve0_fifo_priv *priv = (void *)engine; struct nve0_fifo_priv *priv = (void *)engine;
struct nve0_fifo_base *base = (void *)parent; struct nve0_fifo_base *base = (void *)parent;
struct nve0_fifo_chan *chan; struct nve0_fifo_chan *chan;
struct nv_channel_ind_class *args = data; struct nve0_channel_ind_class *args = data;
u64 usermem, ioffset, ilength; u64 usermem, ioffset, ilength;
int ret, i; int ret, i;
if (size < sizeof(*args)) if (size < sizeof(*args))
return -EINVAL; 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, ret = nouveau_fifo_channel_create(parent, engine, oclass, 1,
priv->user.bar.offset, 0x200, priv->user.bar.offset, 0x200,
args->pushbuf, args->pushbuf,
(1 << NVDEV_ENGINE_SW) | fifo_engine[i].mask, &chan);
(1 << NVDEV_ENGINE_GR), &chan);
*pobject = nv_object(chan); *pobject = nv_object(chan);
if (ret) if (ret)
return ret; return ret;
nv_parent(chan)->context_attach = nve0_fifo_context_attach; nv_parent(chan)->context_attach = nve0_fifo_context_attach;
nv_parent(chan)->context_detach = nve0_fifo_context_detach; nv_parent(chan)->context_detach = nve0_fifo_context_detach;
chan->engine = i;
usermem = chan->base.chid * 0x200; usermem = chan->base.chid * 0x200;
ioffset = args->ioffset; ioffset = args->ioffset;
...@@ -235,6 +267,7 @@ nve0_fifo_chan_init(struct nouveau_object *object) ...@@ -235,6 +267,7 @@ nve0_fifo_chan_init(struct nouveau_object *object)
if (ret) if (ret)
return ret; return ret;
nv_mask(priv, 0x800004 + (chid * 8), 0x000f0000, chan->engine << 16);
nv_wr32(priv, 0x800000 + (chid * 8), 0x80000000 | base->addr >> 12); nv_wr32(priv, 0x800000 + (chid * 8), 0x80000000 | base->addr >> 12);
nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400); nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
nve0_fifo_playlist_update(priv, chan->engine); nve0_fifo_playlist_update(priv, chan->engine);
......
...@@ -65,13 +65,30 @@ struct nv_channel_dma_class { ...@@ -65,13 +65,30 @@ struct nv_channel_dma_class {
/* 506f: NV50_CHANNEL_IND /* 506f: NV50_CHANNEL_IND
* 826f: NV84_CHANNEL_IND * 826f: NV84_CHANNEL_IND
* 906f: NVC0_CHANNEL_IND * 906f: NVC0_CHANNEL_IND
* a06f: NVE0_CHANNEL_IND
*/ */
struct nv_channel_ind_class { struct nv50_channel_ind_class {
u32 pushbuf; u32 pushbuf;
u32 ilength; u32 ilength;
u64 ioffset; u64 ioffset;
}; };
/* a06f: NVE0_CHANNEL_IND
*/
#define NVE0_CHANNEL_IND_ENGINE_GR 0x00000001
#define NVE0_CHANNEL_IND_ENGINE_VP 0x00000002
#define NVE0_CHANNEL_IND_ENGINE_PPP 0x00000004
#define NVE0_CHANNEL_IND_ENGINE_BSP 0x00000008
#define NVE0_CHANNEL_IND_ENGINE_CE0 0x00000010
#define NVE0_CHANNEL_IND_ENGINE_CE1 0x00000020
#define NVE0_CHANNEL_IND_ENGINE_ENC 0x00000040
struct nve0_channel_ind_class {
u32 pushbuf;
u32 ilength;
u64 ioffset;
u32 engine;
};
#endif #endif
...@@ -36,7 +36,7 @@ enum nv_subdev_type { ...@@ -36,7 +36,7 @@ enum nv_subdev_type {
NVDEV_ENGINE_COPY0, NVDEV_ENGINE_COPY0,
NVDEV_ENGINE_COPY1, NVDEV_ENGINE_COPY1,
NVDEV_ENGINE_UNK1C1, NVDEV_ENGINE_UNK1C1,
NVDEV_ENGINE_FENCE, NVDEV_ENGINE_VENC,
NVDEV_ENGINE_DISP, NVDEV_ENGINE_DISP,
NVDEV_SUBDEV_NR, NVDEV_SUBDEV_NR,
}; };
......
...@@ -188,7 +188,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli, ...@@ -188,7 +188,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli,
{ {
static const u16 oclasses[] = { 0xa06f, 0x906f, 0x826f, 0x506f, 0 }; static const u16 oclasses[] = { 0xa06f, 0x906f, 0x826f, 0x506f, 0 };
const u16 *oclass = oclasses; const u16 *oclass = oclasses;
struct nv_channel_ind_class args; struct nve0_channel_ind_class args;
struct nouveau_channel *chan; struct nouveau_channel *chan;
int ret; int ret;
...@@ -202,6 +202,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli, ...@@ -202,6 +202,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli,
args.pushbuf = chan->push.handle; args.pushbuf = chan->push.handle;
args.ioffset = 0x10000 + chan->push.vma.offset; args.ioffset = 0x10000 + chan->push.vma.offset;
args.ilength = 0x02000; args.ilength = 0x02000;
args.engine = NVE0_CHANNEL_IND_ENGINE_GR;
do { do {
ret = nouveau_object_new(nv_object(cli), parent, handle, ret = nouveau_object_new(nv_object(cli), parent, handle,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment