Merge remote-tracking branch 'regmap/fix/cache' into regmap-linus
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / nouveau / core / engine / fifo / nv50.c
1 /*
2  * Copyright 2012 Red Hat Inc.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20  * OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * Authors: Ben Skeggs
23  */
24
25 #include <core/client.h>
26 #include <core/engctx.h>
27 #include <core/ramht.h>
28 #include <core/class.h>
29 #include <core/math.h>
30
31 #include <subdev/timer.h>
32 #include <subdev/bar.h>
33
34 #include <engine/dmaobj.h>
35 #include <engine/fifo.h>
36
37 #include "nv50.h"
38
39 /*******************************************************************************
40  * FIFO channel objects
41  ******************************************************************************/
42
43 void
44 nv50_fifo_playlist_update(struct nv50_fifo_priv *priv)
45 {
46         struct nouveau_bar *bar = nouveau_bar(priv);
47         struct nouveau_gpuobj *cur;
48         int i, p;
49
50         mutex_lock(&nv_subdev(priv)->mutex);
51         cur = priv->playlist[priv->cur_playlist];
52         priv->cur_playlist = !priv->cur_playlist;
53
54         for (i = priv->base.min, p = 0; i < priv->base.max; i++) {
55                 if (nv_rd32(priv, 0x002600 + (i * 4)) & 0x80000000)
56                         nv_wo32(cur, p++ * 4, i);
57         }
58
59         bar->flush(bar);
60
61         nv_wr32(priv, 0x0032f4, cur->addr >> 12);
62         nv_wr32(priv, 0x0032ec, p);
63         nv_wr32(priv, 0x002500, 0x00000101);
64         mutex_unlock(&nv_subdev(priv)->mutex);
65 }
66
67 static int
68 nv50_fifo_context_attach(struct nouveau_object *parent,
69                          struct nouveau_object *object)
70 {
71         struct nouveau_bar *bar = nouveau_bar(parent);
72         struct nv50_fifo_base *base = (void *)parent->parent;
73         struct nouveau_gpuobj *ectx = (void *)object;
74         u64 limit = ectx->addr + ectx->size - 1;
75         u64 start = ectx->addr;
76         u32 addr;
77
78         switch (nv_engidx(object->engine)) {
79         case NVDEV_ENGINE_SW   : return 0;
80         case NVDEV_ENGINE_GR   : addr = 0x0000; break;
81         case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
82         default:
83                 return -EINVAL;
84         }
85
86         nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
87         nv_wo32(base->eng, addr + 0x00, 0x00190000);
88         nv_wo32(base->eng, addr + 0x04, lower_32_bits(limit));
89         nv_wo32(base->eng, addr + 0x08, lower_32_bits(start));
90         nv_wo32(base->eng, addr + 0x0c, upper_32_bits(limit) << 24 |
91                                         upper_32_bits(start));
92         nv_wo32(base->eng, addr + 0x10, 0x00000000);
93         nv_wo32(base->eng, addr + 0x14, 0x00000000);
94         bar->flush(bar);
95         return 0;
96 }
97
98 static int
99 nv50_fifo_context_detach(struct nouveau_object *parent, bool suspend,
100                          struct nouveau_object *object)
101 {
102         struct nouveau_bar *bar = nouveau_bar(parent);
103         struct nv50_fifo_priv *priv = (void *)parent->engine;
104         struct nv50_fifo_base *base = (void *)parent->parent;
105         struct nv50_fifo_chan *chan = (void *)parent;
106         u32 addr, me;
107         int ret = 0;
108
109         switch (nv_engidx(object->engine)) {
110         case NVDEV_ENGINE_SW   : return 0;
111         case NVDEV_ENGINE_GR   : addr = 0x0000; break;
112         case NVDEV_ENGINE_MPEG : addr = 0x0060; break;
113         default:
114                 return -EINVAL;
115         }
116
117         /* HW bug workaround:
118          *
119          * PFIFO will hang forever if the connected engines don't report
120          * that they've processed the context switch request.
121          *
122          * In order for the kickoff to work, we need to ensure all the
123          * connected engines are in a state where they can answer.
124          *
125          * Newer chipsets don't seem to suffer from this issue, and well,
126          * there's also a "ignore these engines" bitmask reg we can use
127          * if we hit the issue there..
128          */
129         me = nv_mask(priv, 0x00b860, 0x00000001, 0x00000001);
130
131         /* do the kickoff... */
132         nv_wr32(priv, 0x0032fc, nv_gpuobj(base)->addr >> 12);
133         if (!nv_wait_ne(priv, 0x0032fc, 0xffffffff, 0xffffffff)) {
134                 nv_error(priv, "channel %d [%s] unload timeout\n",
135                          chan->base.chid, nouveau_client_name(chan));
136                 if (suspend)
137                         ret = -EBUSY;
138         }
139         nv_wr32(priv, 0x00b860, me);
140
141         if (ret == 0) {
142                 nv_wo32(base->eng, addr + 0x00, 0x00000000);
143                 nv_wo32(base->eng, addr + 0x04, 0x00000000);
144                 nv_wo32(base->eng, addr + 0x08, 0x00000000);
145                 nv_wo32(base->eng, addr + 0x0c, 0x00000000);
146                 nv_wo32(base->eng, addr + 0x10, 0x00000000);
147                 nv_wo32(base->eng, addr + 0x14, 0x00000000);
148                 bar->flush(bar);
149         }
150
151         return ret;
152 }
153
154 static int
155 nv50_fifo_object_attach(struct nouveau_object *parent,
156                         struct nouveau_object *object, u32 handle)
157 {
158         struct nv50_fifo_chan *chan = (void *)parent;
159         u32 context;
160
161         if (nv_iclass(object, NV_GPUOBJ_CLASS))
162                 context = nv_gpuobj(object)->node->offset >> 4;
163         else
164                 context = 0x00000004; /* just non-zero */
165
166         switch (nv_engidx(object->engine)) {
167         case NVDEV_ENGINE_DMAOBJ:
168         case NVDEV_ENGINE_SW    : context |= 0x00000000; break;
169         case NVDEV_ENGINE_GR    : context |= 0x00100000; break;
170         case NVDEV_ENGINE_MPEG  : context |= 0x00200000; break;
171         default:
172                 return -EINVAL;
173         }
174
175         return nouveau_ramht_insert(chan->ramht, 0, handle, context);
176 }
177
178 void
179 nv50_fifo_object_detach(struct nouveau_object *parent, int cookie)
180 {
181         struct nv50_fifo_chan *chan = (void *)parent;
182         nouveau_ramht_remove(chan->ramht, cookie);
183 }
184
185 static int
186 nv50_fifo_chan_ctor_dma(struct nouveau_object *parent,
187                         struct nouveau_object *engine,
188                         struct nouveau_oclass *oclass, void *data, u32 size,
189                         struct nouveau_object **pobject)
190 {
191         struct nouveau_bar *bar = nouveau_bar(parent);
192         struct nv50_fifo_base *base = (void *)parent;
193         struct nv50_fifo_chan *chan;
194         struct nv03_channel_dma_class *args = data;
195         int ret;
196
197         if (size < sizeof(*args))
198                 return -EINVAL;
199
200         ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
201                                           0x2000, args->pushbuf,
202                                           (1ULL << NVDEV_ENGINE_DMAOBJ) |
203                                           (1ULL << NVDEV_ENGINE_SW) |
204                                           (1ULL << NVDEV_ENGINE_GR) |
205                                           (1ULL << NVDEV_ENGINE_MPEG), &chan);
206         *pobject = nv_object(chan);
207         if (ret)
208                 return ret;
209
210         nv_parent(chan)->context_attach = nv50_fifo_context_attach;
211         nv_parent(chan)->context_detach = nv50_fifo_context_detach;
212         nv_parent(chan)->object_attach = nv50_fifo_object_attach;
213         nv_parent(chan)->object_detach = nv50_fifo_object_detach;
214
215         ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
216                                 &chan->ramht);
217         if (ret)
218                 return ret;
219
220         nv_wo32(base->ramfc, 0x08, lower_32_bits(args->offset));
221         nv_wo32(base->ramfc, 0x0c, upper_32_bits(args->offset));
222         nv_wo32(base->ramfc, 0x10, lower_32_bits(args->offset));
223         nv_wo32(base->ramfc, 0x14, upper_32_bits(args->offset));
224         nv_wo32(base->ramfc, 0x3c, 0x003f6078);
225         nv_wo32(base->ramfc, 0x44, 0x01003fff);
226         nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4);
227         nv_wo32(base->ramfc, 0x4c, 0xffffffff);
228         nv_wo32(base->ramfc, 0x60, 0x7fffffff);
229         nv_wo32(base->ramfc, 0x78, 0x00000000);
230         nv_wo32(base->ramfc, 0x7c, 0x30000001);
231         nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
232                                    (4 << 24) /* SEARCH_FULL */ |
233                                    (chan->ramht->base.node->offset >> 4));
234         bar->flush(bar);
235         return 0;
236 }
237
238 static int
239 nv50_fifo_chan_ctor_ind(struct nouveau_object *parent,
240                         struct nouveau_object *engine,
241                         struct nouveau_oclass *oclass, void *data, u32 size,
242                         struct nouveau_object **pobject)
243 {
244         struct nv50_channel_ind_class *args = data;
245         struct nouveau_bar *bar = nouveau_bar(parent);
246         struct nv50_fifo_base *base = (void *)parent;
247         struct nv50_fifo_chan *chan;
248         u64 ioffset, ilength;
249         int ret;
250
251         if (size < sizeof(*args))
252                 return -EINVAL;
253
254         ret = nouveau_fifo_channel_create(parent, engine, oclass, 0, 0xc00000,
255                                           0x2000, args->pushbuf,
256                                           (1ULL << NVDEV_ENGINE_DMAOBJ) |
257                                           (1ULL << NVDEV_ENGINE_SW) |
258                                           (1ULL << NVDEV_ENGINE_GR) |
259                                           (1ULL << NVDEV_ENGINE_MPEG), &chan);
260         *pobject = nv_object(chan);
261         if (ret)
262                 return ret;
263
264         nv_parent(chan)->context_attach = nv50_fifo_context_attach;
265         nv_parent(chan)->context_detach = nv50_fifo_context_detach;
266         nv_parent(chan)->object_attach = nv50_fifo_object_attach;
267         nv_parent(chan)->object_detach = nv50_fifo_object_detach;
268
269         ret = nouveau_ramht_new(nv_object(chan), nv_object(chan), 0x8000, 16,
270                                &chan->ramht);
271         if (ret)
272                 return ret;
273
274         ioffset = args->ioffset;
275         ilength = log2i(args->ilength / 8);
276
277         nv_wo32(base->ramfc, 0x3c, 0x403f6078);
278         nv_wo32(base->ramfc, 0x44, 0x01003fff);
279         nv_wo32(base->ramfc, 0x48, chan->base.pushgpu->node->offset >> 4);
280         nv_wo32(base->ramfc, 0x50, lower_32_bits(ioffset));
281         nv_wo32(base->ramfc, 0x54, upper_32_bits(ioffset) | (ilength << 16));
282         nv_wo32(base->ramfc, 0x60, 0x7fffffff);
283         nv_wo32(base->ramfc, 0x78, 0x00000000);
284         nv_wo32(base->ramfc, 0x7c, 0x30000001);
285         nv_wo32(base->ramfc, 0x80, ((chan->ramht->bits - 9) << 27) |
286                                    (4 << 24) /* SEARCH_FULL */ |
287                                    (chan->ramht->base.node->offset >> 4));
288         bar->flush(bar);
289         return 0;
290 }
291
292 void
293 nv50_fifo_chan_dtor(struct nouveau_object *object)
294 {
295         struct nv50_fifo_chan *chan = (void *)object;
296         nouveau_ramht_ref(NULL, &chan->ramht);
297         nouveau_fifo_channel_destroy(&chan->base);
298 }
299
300 static int
301 nv50_fifo_chan_init(struct nouveau_object *object)
302 {
303         struct nv50_fifo_priv *priv = (void *)object->engine;
304         struct nv50_fifo_base *base = (void *)object->parent;
305         struct nv50_fifo_chan *chan = (void *)object;
306         struct nouveau_gpuobj *ramfc = base->ramfc;
307         u32 chid = chan->base.chid;
308         int ret;
309
310         ret = nouveau_fifo_channel_init(&chan->base);
311         if (ret)
312                 return ret;
313
314         nv_wr32(priv, 0x002600 + (chid * 4), 0x80000000 | ramfc->addr >> 12);
315         nv50_fifo_playlist_update(priv);
316         return 0;
317 }
318
319 int
320 nv50_fifo_chan_fini(struct nouveau_object *object, bool suspend)
321 {
322         struct nv50_fifo_priv *priv = (void *)object->engine;
323         struct nv50_fifo_chan *chan = (void *)object;
324         u32 chid = chan->base.chid;
325
326         /* remove channel from playlist, fifo will unload context */
327         nv_mask(priv, 0x002600 + (chid * 4), 0x80000000, 0x00000000);
328         nv50_fifo_playlist_update(priv);
329         nv_wr32(priv, 0x002600 + (chid * 4), 0x00000000);
330
331         return nouveau_fifo_channel_fini(&chan->base, suspend);
332 }
333
334 static struct nouveau_ofuncs
335 nv50_fifo_ofuncs_dma = {
336         .ctor = nv50_fifo_chan_ctor_dma,
337         .dtor = nv50_fifo_chan_dtor,
338         .init = nv50_fifo_chan_init,
339         .fini = nv50_fifo_chan_fini,
340         .rd32 = _nouveau_fifo_channel_rd32,
341         .wr32 = _nouveau_fifo_channel_wr32,
342 };
343
344 static struct nouveau_ofuncs
345 nv50_fifo_ofuncs_ind = {
346         .ctor = nv50_fifo_chan_ctor_ind,
347         .dtor = nv50_fifo_chan_dtor,
348         .init = nv50_fifo_chan_init,
349         .fini = nv50_fifo_chan_fini,
350         .rd32 = _nouveau_fifo_channel_rd32,
351         .wr32 = _nouveau_fifo_channel_wr32,
352 };
353
354 static struct nouveau_oclass
355 nv50_fifo_sclass[] = {
356         { NV50_CHANNEL_DMA_CLASS, &nv50_fifo_ofuncs_dma },
357         { NV50_CHANNEL_IND_CLASS, &nv50_fifo_ofuncs_ind },
358         {}
359 };
360
361 /*******************************************************************************
362  * FIFO context - basically just the instmem reserved for the channel
363  ******************************************************************************/
364
365 static int
366 nv50_fifo_context_ctor(struct nouveau_object *parent,
367                        struct nouveau_object *engine,
368                        struct nouveau_oclass *oclass, void *data, u32 size,
369                        struct nouveau_object **pobject)
370 {
371         struct nv50_fifo_base *base;
372         int ret;
373
374         ret = nouveau_fifo_context_create(parent, engine, oclass, NULL, 0x10000,
375                                           0x1000, NVOBJ_FLAG_HEAP, &base);
376         *pobject = nv_object(base);
377         if (ret)
378                 return ret;
379
380         ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x0200,
381                                  0x1000, NVOBJ_FLAG_ZERO_ALLOC, &base->ramfc);
382         if (ret)
383                 return ret;
384
385         ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x1200, 0,
386                                  NVOBJ_FLAG_ZERO_ALLOC, &base->eng);
387         if (ret)
388                 return ret;
389
390         ret = nouveau_gpuobj_new(nv_object(base), nv_object(base), 0x4000, 0, 0,
391                                 &base->pgd);
392         if (ret)
393                 return ret;
394
395         ret = nouveau_vm_ref(nouveau_client(parent)->vm, &base->vm, base->pgd);
396         if (ret)
397                 return ret;
398
399         return 0;
400 }
401
402 void
403 nv50_fifo_context_dtor(struct nouveau_object *object)
404 {
405         struct nv50_fifo_base *base = (void *)object;
406         nouveau_vm_ref(NULL, &base->vm, base->pgd);
407         nouveau_gpuobj_ref(NULL, &base->pgd);
408         nouveau_gpuobj_ref(NULL, &base->eng);
409         nouveau_gpuobj_ref(NULL, &base->ramfc);
410         nouveau_gpuobj_ref(NULL, &base->cache);
411         nouveau_fifo_context_destroy(&base->base);
412 }
413
414 static struct nouveau_oclass
415 nv50_fifo_cclass = {
416         .handle = NV_ENGCTX(FIFO, 0x50),
417         .ofuncs = &(struct nouveau_ofuncs) {
418                 .ctor = nv50_fifo_context_ctor,
419                 .dtor = nv50_fifo_context_dtor,
420                 .init = _nouveau_fifo_context_init,
421                 .fini = _nouveau_fifo_context_fini,
422                 .rd32 = _nouveau_fifo_context_rd32,
423                 .wr32 = _nouveau_fifo_context_wr32,
424         },
425 };
426
427 /*******************************************************************************
428  * PFIFO engine
429  ******************************************************************************/
430
431 static int
432 nv50_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
433                struct nouveau_oclass *oclass, void *data, u32 size,
434                struct nouveau_object **pobject)
435 {
436         struct nv50_fifo_priv *priv;
437         int ret;
438
439         ret = nouveau_fifo_create(parent, engine, oclass, 1, 127, &priv);
440         *pobject = nv_object(priv);
441         if (ret)
442                 return ret;
443
444         ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
445                                 &priv->playlist[0]);
446         if (ret)
447                 return ret;
448
449         ret = nouveau_gpuobj_new(nv_object(priv), NULL, 128 * 4, 0x1000, 0,
450                                 &priv->playlist[1]);
451         if (ret)
452                 return ret;
453
454         nv_subdev(priv)->unit = 0x00000100;
455         nv_subdev(priv)->intr = nv04_fifo_intr;
456         nv_engine(priv)->cclass = &nv50_fifo_cclass;
457         nv_engine(priv)->sclass = nv50_fifo_sclass;
458         return 0;
459 }
460
461 void
462 nv50_fifo_dtor(struct nouveau_object *object)
463 {
464         struct nv50_fifo_priv *priv = (void *)object;
465
466         nouveau_gpuobj_ref(NULL, &priv->playlist[1]);
467         nouveau_gpuobj_ref(NULL, &priv->playlist[0]);
468
469         nouveau_fifo_destroy(&priv->base);
470 }
471
472 int
473 nv50_fifo_init(struct nouveau_object *object)
474 {
475         struct nv50_fifo_priv *priv = (void *)object;
476         int ret, i;
477
478         ret = nouveau_fifo_init(&priv->base);
479         if (ret)
480                 return ret;
481
482         nv_mask(priv, 0x000200, 0x00000100, 0x00000000);
483         nv_mask(priv, 0x000200, 0x00000100, 0x00000100);
484         nv_wr32(priv, 0x00250c, 0x6f3cfc34);
485         nv_wr32(priv, 0x002044, 0x01003fff);
486
487         nv_wr32(priv, 0x002100, 0xffffffff);
488         nv_wr32(priv, 0x002140, 0xbfffffff);
489
490         for (i = 0; i < 128; i++)
491                 nv_wr32(priv, 0x002600 + (i * 4), 0x00000000);
492         nv50_fifo_playlist_update(priv);
493
494         nv_wr32(priv, 0x003200, 0x00000001);
495         nv_wr32(priv, 0x003250, 0x00000001);
496         nv_wr32(priv, 0x002500, 0x00000001);
497         return 0;
498 }
499
500 struct nouveau_oclass
501 nv50_fifo_oclass = {
502         .handle = NV_ENGINE(FIFO, 0x50),
503         .ofuncs = &(struct nouveau_ofuncs) {
504                 .ctor = nv50_fifo_ctor,
505                 .dtor = nv50_fifo_dtor,
506                 .init = nv50_fifo_init,
507                 .fini = _nouveau_fifo_fini,
508         },
509 };