diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-08-06 04:16:37 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-10-02 23:13:01 -0400 |
commit | dbff2dee9f8561710fcfe7f6623dd272ddca5a27 (patch) | |
tree | 69efde69340d08fdbe02e48e8d753263a14f54b7 /drivers/gpu/drm | |
parent | 43b1e9c9899ece92c1f68d45ae0d7b98d009f5d0 (diff) |
drm/nve0/fifo: support engine selection when creating fifo channels
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/class.h | 21 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/device.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_chan.c | 3 |
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)) } | ||
42 | static 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 | |||
41 | struct nve0_fifo_engn { | 57 | struct 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 | ||
46 | struct nve0_fifo_priv { | 62 | struct 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 | ||
71 | struct nv_channel_ind_class { | 70 | struct 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 | |||
87 | struct 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, |