41 #define _(a,b) { (a), ((1 << (a)) | (b)) }
55 #define FIFO_ENGINE_NR ARRAY_SIZE(fifo_engine)
93 u32 match = (engine << 16) | 0x00000001;
99 0x8000, 0x1000, 0, &cur);
101 nv_error(priv,
"playlist alloc failed\n");
110 for (i = 0, p = 0; i < priv->
base.max; i++) {
111 u32 ctrl = nv_rd32(priv, 0x800004 + (i * 8)) & 0x001f0001;
114 nv_wo32(cur, p + 0, i);
115 nv_wo32(cur, p + 4, 0x00000000);
120 nv_wr32(priv, 0x002270, cur->
addr >> 12);
121 nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3));
122 if (!
nv_wait(priv, 0x002284 + (engine * 4), 0x00100000, 0x00000000))
123 nv_error(priv,
"playlist %d update timeout\n", engine);
136 switch (nv_engidx(object->
engine)) {
145 if (!ectx->vma.node) {
151 nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12;
154 nv_wo32(base, addr + 0x00,
lower_32_bits(ectx->vma.offset) | 4);
170 switch (nv_engidx(object->
engine)) {
179 nv_wo32(base, addr + 0x00, 0x00000000);
180 nv_wo32(base, addr + 0x04, 0x00000000);
183 nv_wr32(priv, 0x002634, chan->
base.chid);
184 if (!
nv_wait(priv, 0x002634, 0xffffffff, chan->
base.chid)) {
185 nv_error(priv,
"channel %d kick timeout\n", chan->
base.chid);
207 if (size <
sizeof(*args))
211 if (args->
engine & (1 << i)) {
219 if (i == FIFO_ENGINE_NR)
223 priv->
user.bar.offset, 0x200,
225 fifo_engine[i].mask, &chan);
226 *pobject = nv_object(chan);
230 nv_parent(chan)->context_attach = nve0_fifo_context_attach;
231 nv_parent(chan)->context_detach = nve0_fifo_context_detach;
234 usermem = chan->
base.chid * 0x200;
236 ilength = log2i(args->
ilength / 8);
238 for (i = 0; i < 0x200; i += 4)
239 nv_wo32(priv->
user.mem, usermem + i, 0x00000000);
243 nv_wo32(base, 0x10, 0x0000face);
244 nv_wo32(base, 0x30, 0xfffff902);
246 nv_wo32(base, 0x4c,
upper_32_bits(ioffset) | (ilength << 16));
247 nv_wo32(base, 0x84, 0x20400000);
248 nv_wo32(base, 0x94, 0x30000001);
249 nv_wo32(base, 0x9c, 0x00000100);
250 nv_wo32(base, 0xac, 0x0000001f);
251 nv_wo32(base, 0xe8, chan->
base.chid);
252 nv_wo32(base, 0xb8, 0xf8000000);
253 nv_wo32(base, 0xf8, 0x10003080);
254 nv_wo32(base, 0xfc, 0x10000010);
272 nv_mask(priv, 0x800004 + (chid * 8), 0x000f0000, chan->
engine << 16);
273 nv_wr32(priv, 0x800000 + (chid * 8), 0x80000000 | base->
addr >> 12);
274 nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
275 nve0_fifo_playlist_update(priv, chan->
engine);
276 nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400);
287 nv_mask(priv, 0x800004 + (chid * 8), 0x00000800, 0x00000800);
288 nve0_fifo_playlist_update(priv, chan->
engine);
289 nv_wr32(priv, 0x800000 + (chid * 8), 0x00000000);
296 .ctor = nve0_fifo_chan_ctor,
298 .init = nve0_fifo_chan_init,
299 .fini = nve0_fifo_chan_fini,
305 nve0_fifo_sclass[] = {
325 *pobject = nv_object(base);
335 nv_wo32(base, 0x0208, 0xffffffff);
336 nv_wo32(base, 0x020c, 0x000000ff);
350 nouveau_gpuobj_ref(
NULL, &base->
pgd);
358 .ctor = nve0_fifo_context_ctor,
359 .dtor = nve0_fifo_context_dtor,
371 static const struct nouveau_enum nve0_fifo_fault_unit[] = {
375 static const struct nouveau_enum nve0_fifo_fault_reason[] = {
376 { 0x00,
"PT_NOT_PRESENT" },
377 { 0x01,
"PT_TOO_SHORT" },
378 { 0x02,
"PAGE_NOT_PRESENT" },
379 { 0x03,
"VM_LIMIT_EXCEEDED" },
380 { 0x04,
"NO_CHANNEL" },
381 { 0x05,
"PAGE_SYSTEM_ONLY" },
382 { 0x06,
"PAGE_READ_ONLY" },
383 { 0x0a,
"COMPRESSED_SYSRAM" },
384 { 0x0c,
"INVALID_STORAGE_TYPE" },
388 static const struct nouveau_enum nve0_fifo_fault_hubclient[] = {
392 static const struct nouveau_enum nve0_fifo_fault_gpcclient[] = {
397 { 0x00200000,
"ILLEGAL_MTHD" },
398 { 0x00800000,
"EMPTY_SUBC" },
405 u32 inst = nv_rd32(priv, 0x2800 + (unit * 0x10));
406 u32 valo = nv_rd32(priv, 0x2804 + (unit * 0x10));
407 u32 vahi = nv_rd32(priv, 0x2808 + (unit * 0x10));
408 u32 stat = nv_rd32(priv, 0x280c + (unit * 0x10));
411 nv_error(priv,
"PFIFO: %s fault at 0x%010llx [", (stat & 0x00000080) ?
412 "write" :
"read", (
u64)vahi << 32 | valo);
416 if (stat & 0x00000040) {
420 printk(
"/GPC%d/", (stat & 0x1f000000) >> 24);
423 printk(
" on channel 0x%010llx\n", (
u64)inst << 12);
435 if (
likely(chid >= priv->
base.min && chid <= priv->base.max))
436 chan = (
void *)priv->
base.channel[chid];
442 if (!mthd || !nv_call(bind->
object, mthd, data))
448 spin_unlock_irqrestore(&priv->
base.lock, flags);
455 u32 stat = nv_rd32(priv, 0x040108 + (unit * 0x2000));
456 u32 addr = nv_rd32(priv, 0x0400c0 + (unit * 0x2000));
457 u32 data = nv_rd32(priv, 0x0400c4 + (unit * 0x2000));
458 u32 chid = nv_rd32(priv, 0x040120 + (unit * 0x2000)) & 0xfff;
459 u32 subc = (addr & 0x00070000) >> 16;
460 u32 mthd = (addr & 0x00003ffc);
463 if (stat & 0x00200000) {
464 if (mthd == 0x0054) {
465 if (!nve0_fifo_swmthd(priv, chid, 0x0500, 0x00000000))
470 if (stat & 0x00800000) {
471 if (!nve0_fifo_swmthd(priv, chid, mthd, data))
479 nv_error(priv,
"SUBFIFO%d: ch %d subc %d mthd 0x%04x "
481 unit, chid, subc, mthd, data);
484 nv_wr32(priv, 0x0400c0 + (unit * 0x2000), 0x80600008);
485 nv_wr32(priv, 0x040108 + (unit * 0x2000), stat);
492 u32 mask = nv_rd32(priv, 0x002140);
493 u32 stat = nv_rd32(priv, 0x002100) &
mask;
495 if (stat & 0x00000100) {
496 nv_warn(priv,
"unknown status 0x00000100\n");
497 nv_wr32(priv, 0x002100, 0x00000100);
501 if (stat & 0x10000000) {
502 u32 units = nv_rd32(priv, 0x00259c);
507 nve0_fifo_isr_vm_fault(priv, i);
511 nv_wr32(priv, 0x00259c, units);
515 if (stat & 0x20000000) {
516 u32 units = nv_rd32(priv, 0x0025a0);
521 nve0_fifo_isr_subfifo_intr(priv, i);
525 nv_wr32(priv, 0x0025a0, units);
529 if (stat & 0x40000000) {
530 nv_warn(priv,
"unknown status 0x40000000\n");
531 nv_mask(priv, 0x002a00, 0x00000000, 0x00000000);
536 nv_fatal(priv,
"unhandled status 0x%08x\n", stat);
537 nv_wr32(priv, 0x002100, stat);
538 nv_wr32(priv, 0x002140, 0);
551 *pobject = nv_object(priv);
565 nv_subdev(priv)->unit = 0x00000100;
566 nv_subdev(priv)->intr = nve0_fifo_intr;
567 nv_engine(priv)->cclass = &nve0_fifo_cclass;
568 nv_engine(priv)->sclass = nve0_fifo_sclass;
579 nouveau_gpuobj_ref(
NULL, &priv->
user.mem);
582 nouveau_gpuobj_ref(
NULL, &priv->
engine[i].playlist[1]);
583 nouveau_gpuobj_ref(
NULL, &priv->
engine[i].playlist[0]);
600 nv_wr32(priv, 0x000204, 0xffffffff);
605 for (i = 0; i < priv->
spoon_nr; i++) {
606 nv_mask(priv, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000);
607 nv_wr32(priv, 0x040108 + (i * 0x2000), 0xffffffff);
608 nv_wr32(priv, 0x04010c + (i * 0x2000), 0xfffffeff);
611 nv_wr32(priv, 0x002254, 0x10000000 | priv->
user.bar.offset >> 12);
613 nv_wr32(priv, 0x002a00, 0xffffffff);
614 nv_wr32(priv, 0x002100, 0xffffffff);
615 nv_wr32(priv, 0x002140, 0xbfffffff);
623 .ctor = nve0_fifo_ctor,
624 .dtor = nve0_fifo_dtor,
625 .init = nve0_fifo_init,