aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2012-08-06 04:16:37 -0400
committerBen Skeggs <bskeggs@redhat.com>2012-10-02 23:13:01 -0400
commitdbff2dee9f8561710fcfe7f6623dd272ddca5a27 (patch)
tree69efde69340d08fdbe02e48e8d753263a14f54b7
parent43b1e9c9899ece92c1f68d45ae0d7b98d009f5d0 (diff)
drm/nve0/fifo: support engine selection when creating fifo channels
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c45
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/class.h21
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/device.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.c3
7 files changed, 64 insertions, 13 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
index 4914c3b94413..5b80f3e10a6f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c
@@ -182,7 +182,7 @@ nv50_fifo_chan_ctor(struct nouveau_object *parent,
182 struct nouveau_oclass *oclass, void *data, u32 size, 182 struct nouveau_oclass *oclass, void *data, u32 size,
183 struct nouveau_object **pobject) 183 struct nouveau_object **pobject)
184{ 184{
185 struct nv_channel_ind_class *args = data; 185 struct nv50_channel_ind_class *args = data;
186 struct nouveau_bar *bar = nouveau_bar(parent); 186 struct nouveau_bar *bar = nouveau_bar(parent);
187 struct nv50_fifo_base *base = (void *)parent; 187 struct nv50_fifo_base *base = (void *)parent;
188 struct nv50_fifo_chan *chan; 188 struct nv50_fifo_chan *chan;
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
index 765affb12666..d3b0356a4283 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c
@@ -150,7 +150,7 @@ nv84_fifo_chan_ctor(struct nouveau_object *parent,
150 struct nouveau_bar *bar = nouveau_bar(parent); 150 struct nouveau_bar *bar = nouveau_bar(parent);
151 struct nv50_fifo_base *base = (void *)parent; 151 struct nv50_fifo_base *base = (void *)parent;
152 struct nv50_fifo_chan *chan; 152 struct nv50_fifo_chan *chan;
153 struct nv_channel_ind_class *args = data; 153 struct nv50_channel_ind_class *args = data;
154 u64 ioffset, ilength; 154 u64 ioffset, ilength;
155 int ret; 155 int ret;
156 156
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
index ef403fe66ce0..a4ae2bfd6035 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c
@@ -163,7 +163,7 @@ nvc0_fifo_chan_ctor(struct nouveau_object *parent,
163 struct nvc0_fifo_priv *priv = (void *)engine; 163 struct nvc0_fifo_priv *priv = (void *)engine;
164 struct nvc0_fifo_base *base = (void *)parent; 164 struct nvc0_fifo_base *base = (void *)parent;
165 struct nvc0_fifo_chan *chan; 165 struct nvc0_fifo_chan *chan;
166 struct nv_channel_ind_class *args = data; 166 struct nv50_channel_ind_class *args = data;
167 u64 usermem, ioffset, ilength; 167 u64 usermem, ioffset, ilength;
168 int ret, i; 168 int ret, i;
169 169
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
index aaff086dfd2a..c3f4955fef56 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 @@
38#include <engine/dmaobj.h> 38#include <engine/dmaobj.h>
39#include <engine/fifo.h> 39#include <engine/fifo.h>
40 40
41#define _(a,b) { (a), ((1 << (a)) | (b)) }
42static const struct {
43 int subdev;
44 u32 mask;
45} fifo_engine[] = {
46 _(NVDEV_ENGINE_GR , (1 << NVDEV_ENGINE_SW)),
47 _(NVDEV_ENGINE_VP , 0),
48 _(NVDEV_ENGINE_PPP , 0),
49 _(NVDEV_ENGINE_BSP , 0),
50 _(NVDEV_ENGINE_COPY0 , 0),
51 _(NVDEV_ENGINE_COPY1 , 0),
52 _(NVDEV_ENGINE_VENC , 0),
53};
54#undef _
55#define FIFO_ENGINE_NR ARRAY_SIZE(fifo_engine)
56
41struct nve0_fifo_engn { 57struct nve0_fifo_engn {
42 struct nouveau_gpuobj *playlist[2]; 58 struct nouveau_gpuobj *playlist[2];
43 int cur_playlist; 59 int cur_playlist;
@@ -45,7 +61,7 @@ struct nve0_fifo_engn {
45 61
46struct nve0_fifo_priv { 62struct nve0_fifo_priv {
47 struct nouveau_fifo base; 63 struct nouveau_fifo base;
48 struct nve0_fifo_engn engine[16]; 64 struct nve0_fifo_engn engine[FIFO_ENGINE_NR];
49 struct { 65 struct {
50 struct nouveau_gpuobj *mem; 66 struct nouveau_gpuobj *mem;
51 struct nouveau_vma bar; 67 struct nouveau_vma bar;
@@ -119,7 +135,9 @@ nve0_fifo_context_attach(struct nouveau_object *parent,
119 135
120 switch (nv_engidx(object->engine)) { 136 switch (nv_engidx(object->engine)) {
121 case NVDEV_ENGINE_SW : return 0; 137 case NVDEV_ENGINE_SW : return 0;
122 case NVDEV_ENGINE_GR : addr = 0x0210; break; 138 case NVDEV_ENGINE_GR :
139 case NVDEV_ENGINE_COPY0:
140 case NVDEV_ENGINE_COPY1: addr = 0x0210; break;
123 default: 141 default:
124 return -EINVAL; 142 return -EINVAL;
125 } 143 }
@@ -149,7 +167,9 @@ nve0_fifo_context_detach(struct nouveau_object *parent, bool suspend,
149 167
150 switch (nv_engidx(object->engine)) { 168 switch (nv_engidx(object->engine)) {
151 case NVDEV_ENGINE_SW : return 0; 169 case NVDEV_ENGINE_SW : return 0;
152 case NVDEV_ENGINE_GR : addr = 0x0210; break; 170 case NVDEV_ENGINE_GR :
171 case NVDEV_ENGINE_COPY0:
172 case NVDEV_ENGINE_COPY1: addr = 0x0210; break;
153 default: 173 default:
154 return -EINVAL; 174 return -EINVAL;
155 } 175 }
@@ -178,24 +198,36 @@ nve0_fifo_chan_ctor(struct nouveau_object *parent,
178 struct nve0_fifo_priv *priv = (void *)engine; 198 struct nve0_fifo_priv *priv = (void *)engine;
179 struct nve0_fifo_base *base = (void *)parent; 199 struct nve0_fifo_base *base = (void *)parent;
180 struct nve0_fifo_chan *chan; 200 struct nve0_fifo_chan *chan;
181 struct nv_channel_ind_class *args = data; 201 struct nve0_channel_ind_class *args = data;
182 u64 usermem, ioffset, ilength; 202 u64 usermem, ioffset, ilength;
183 int ret, i; 203 int ret, i;
184 204
185 if (size < sizeof(*args)) 205 if (size < sizeof(*args))
186 return -EINVAL; 206 return -EINVAL;
187 207
208 for (i = 0; i < FIFO_ENGINE_NR; i++) {
209 if (args->engine & (1 << i)) {
210 if (nouveau_engine(parent, fifo_engine[i].subdev)) {
211 args->engine = (1 << i);
212 break;
213 }
214 }
215 }
216
217 if (i == FIFO_ENGINE_NR)
218 return -ENODEV;
219
188 ret = nouveau_fifo_channel_create(parent, engine, oclass, 1, 220 ret = nouveau_fifo_channel_create(parent, engine, oclass, 1,
189 priv->user.bar.offset, 0x200, 221 priv->user.bar.offset, 0x200,
190 args->pushbuf, 222 args->pushbuf,
191 (1 << NVDEV_ENGINE_SW) | 223 fifo_engine[i].mask, &chan);
192 (1 << NVDEV_ENGINE_GR), &chan);
193 *pobject = nv_object(chan); 224 *pobject = nv_object(chan);
194 if (ret) 225 if (ret)
195 return ret; 226 return ret;
196 227
197 nv_parent(chan)->context_attach = nve0_fifo_context_attach; 228 nv_parent(chan)->context_attach = nve0_fifo_context_attach;
198 nv_parent(chan)->context_detach = nve0_fifo_context_detach; 229 nv_parent(chan)->context_detach = nve0_fifo_context_detach;
230 chan->engine = i;
199 231
200 usermem = chan->base.chid * 0x200; 232 usermem = chan->base.chid * 0x200;
201 ioffset = args->ioffset; 233 ioffset = args->ioffset;
@@ -235,6 +267,7 @@ nve0_fifo_chan_init(struct nouveau_object *object)
235 if (ret) 267 if (ret)
236 return ret; 268 return ret;
237 269
270 nv_mask(priv, 0x800004 + (chid * 8), 0x000f0000, chan->engine << 16);
238 nv_wr32(priv, 0x800000 + (chid * 8), 0x80000000 | base->addr >> 12); 271 nv_wr32(priv, 0x800000 + (chid * 8), 0x80000000 | base->addr >> 12);
239 nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400); 272 nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
240 nve0_fifo_playlist_update(priv, chan->engine); 273 nve0_fifo_playlist_update(priv, chan->engine);
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h
index 17326dd1cfb5..9c6b0eba9699 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/class.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/class.h
@@ -65,13 +65,30 @@ struct nv_channel_dma_class {
65/* 506f: NV50_CHANNEL_IND 65/* 506f: NV50_CHANNEL_IND
66 * 826f: NV84_CHANNEL_IND 66 * 826f: NV84_CHANNEL_IND
67 * 906f: NVC0_CHANNEL_IND 67 * 906f: NVC0_CHANNEL_IND
68 * a06f: NVE0_CHANNEL_IND
69 */ 68 */
70 69
71struct nv_channel_ind_class { 70struct nv50_channel_ind_class {
72 u32 pushbuf; 71 u32 pushbuf;
73 u32 ilength; 72 u32 ilength;
74 u64 ioffset; 73 u64 ioffset;
75}; 74};
76 75
76/* a06f: NVE0_CHANNEL_IND
77 */
78
79#define NVE0_CHANNEL_IND_ENGINE_GR 0x00000001
80#define NVE0_CHANNEL_IND_ENGINE_VP 0x00000002
81#define NVE0_CHANNEL_IND_ENGINE_PPP 0x00000004
82#define NVE0_CHANNEL_IND_ENGINE_BSP 0x00000008
83#define NVE0_CHANNEL_IND_ENGINE_CE0 0x00000010
84#define NVE0_CHANNEL_IND_ENGINE_CE1 0x00000020
85#define NVE0_CHANNEL_IND_ENGINE_ENC 0x00000040
86
87struct nve0_channel_ind_class {
88 u32 pushbuf;
89 u32 ilength;
90 u64 ioffset;
91 u32 engine;
92};
93
77#endif 94#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h
index 4db7b01bf31c..130559327bad 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/device.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/device.h
@@ -36,7 +36,7 @@ enum nv_subdev_type {
36 NVDEV_ENGINE_COPY0, 36 NVDEV_ENGINE_COPY0,
37 NVDEV_ENGINE_COPY1, 37 NVDEV_ENGINE_COPY1,
38 NVDEV_ENGINE_UNK1C1, 38 NVDEV_ENGINE_UNK1C1,
39 NVDEV_ENGINE_FENCE, 39 NVDEV_ENGINE_VENC,
40 NVDEV_ENGINE_DISP, 40 NVDEV_ENGINE_DISP,
41 NVDEV_SUBDEV_NR, 41 NVDEV_SUBDEV_NR,
42}; 42};
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c
index 3dd5f712b98c..b1eea19d99a6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.c
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
@@ -188,7 +188,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli,
188{ 188{
189 static const u16 oclasses[] = { 0xa06f, 0x906f, 0x826f, 0x506f, 0 }; 189 static const u16 oclasses[] = { 0xa06f, 0x906f, 0x826f, 0x506f, 0 };
190 const u16 *oclass = oclasses; 190 const u16 *oclass = oclasses;
191 struct nv_channel_ind_class args; 191 struct nve0_channel_ind_class args;
192 struct nouveau_channel *chan; 192 struct nouveau_channel *chan;
193 int ret; 193 int ret;
194 194
@@ -202,6 +202,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli,
202 args.pushbuf = chan->push.handle; 202 args.pushbuf = chan->push.handle;
203 args.ioffset = 0x10000 + chan->push.vma.offset; 203 args.ioffset = 0x10000 + chan->push.vma.offset;
204 args.ilength = 0x02000; 204 args.ilength = 0x02000;
205 args.engine = NVE0_CHANNEL_IND_ENGINE_GR;
205 206
206 do { 207 do {
207 ret = nouveau_object_new(nv_object(cli), parent, handle, 208 ret = nouveau_object_new(nv_object(cli), parent, handle,