1 /* $NetBSD: nouveau_nvkm_engine_fifo_gk104.c,v 1.6 2021/12/19 10:51:57 riastradh Exp $ */ 2 3 /* 4 * Copyright 2012 Red Hat Inc. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice shall be included in 14 * all copies or substantial portions of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 * OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: Ben Skeggs 25 */ 26 #include <sys/cdefs.h> 27 __KERNEL_RCSID(0, "$NetBSD: nouveau_nvkm_engine_fifo_gk104.c,v 1.6 2021/12/19 10:51:57 riastradh Exp $"); 28 29 #include "gk104.h" 30 #include "cgrp.h" 31 #include "changk104.h" 32 33 #include <core/client.h> 34 #include <core/gpuobj.h> 35 #include <subdev/bar.h> 36 #include <subdev/fault.h> 37 #include <subdev/timer.h> 38 #include <subdev/top.h> 39 #include <engine/sw.h> 40 41 #include <nvif/class.h> 42 #include <nvif/cl0080.h> 43 44 struct gk104_fifo_engine_status { 45 bool busy; 46 bool faulted; 47 bool chsw; 48 bool save; 49 bool load; 50 struct { 51 bool tsg; 52 u32 id; 53 } prev, next, *chan; 54 }; 55 56 static void 57 gk104_fifo_engine_status(struct gk104_fifo *fifo, int engn, 58 struct gk104_fifo_engine_status *status) 59 { 60 struct nvkm_engine *engine = fifo->engine[engn].engine; 61 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 62 struct nvkm_device *device = subdev->device; 63 u32 stat = nvkm_rd32(device, 0x002640 + (engn * 0x08)); 64 65 status->busy = !!(stat & 0x80000000); 66 status->faulted = !!(stat & 0x40000000); 67 status->next.tsg = !!(stat & 0x10000000); 68 status->next.id = (stat & 0x0fff0000) >> 16; 69 status->chsw = !!(stat & 0x00008000); 70 status->save = !!(stat & 0x00004000); 71 status->load = !!(stat & 0x00002000); 72 status->prev.tsg = !!(stat & 0x00001000); 73 status->prev.id = (stat & 0x00000fff); 74 status->chan = NULL; 75 76 if (status->busy && status->chsw) { 77 if (status->load && status->save) { 78 if (engine && nvkm_engine_chsw_load(engine)) 79 status->chan = &status->next; 80 else 81 status->chan = &status->prev; 82 } else 83 if (status->load) { 84 status->chan = &status->next; 85 } else { 86 status->chan = &status->prev; 87 } 88 } else 89 if (status->load) { 90 status->chan = &status->prev; 91 } 92 93 nvkm_debug(subdev, "engine %02d: busy %d faulted %d chsw %d " 94 "save %d load %d %sid %d%s-> %sid %d%s\n", 95 engn, status->busy, status->faulted, 96 status->chsw, status->save, status->load, 97 status->prev.tsg ? "tsg" : "ch", status->prev.id, 98 status->chan == &status->prev ? "*" : " ", 99 status->next.tsg ? "tsg" : "ch", status->next.id, 100 status->chan == &status->next ? "*" : " "); 101 } 102 103 static int 104 gk104_fifo_class_new(struct nvkm_fifo *base, const struct nvkm_oclass *oclass, 105 void *argv, u32 argc, struct nvkm_object **pobject) 106 { 107 struct gk104_fifo *fifo = gk104_fifo(base); 108 if (oclass->engn == &fifo->func->chan) { 109 const struct gk104_fifo_chan_user *user = oclass->engn; 110 return user->ctor(fifo, oclass, argv, argc, pobject); 111 } else 112 if (oclass->engn == &fifo->func->user) { 113 const struct gk104_fifo_user_user *user = oclass->engn; 114 return user->ctor(oclass, argv, argc, pobject); 115 } 116 WARN_ON(1); 117 return -EINVAL; 118 } 119 120 static int 121 gk104_fifo_class_get(struct nvkm_fifo *base, int index, 122 struct nvkm_oclass *oclass) 123 { 124 struct gk104_fifo *fifo = gk104_fifo(base); 125 int c = 0; 126 127 if (fifo->func->user.ctor && c++ == index) { 128 oclass->base = fifo->func->user.user; 129 oclass->engn = &fifo->func->user; 130 return 0; 131 } 132 133 if (fifo->func->chan.ctor && c++ == index) { 134 oclass->base = fifo->func->chan.user; 135 oclass->engn = &fifo->func->chan; 136 return 0; 137 } 138 139 return c; 140 } 141 142 static void 143 gk104_fifo_uevent_fini(struct nvkm_fifo *fifo) 144 { 145 struct nvkm_device *device = fifo->engine.subdev.device; 146 nvkm_mask(device, 0x002140, 0x80000000, 0x00000000); 147 } 148 149 static void 150 gk104_fifo_uevent_init(struct nvkm_fifo *fifo) 151 { 152 struct nvkm_device *device = fifo->engine.subdev.device; 153 nvkm_mask(device, 0x002140, 0x80000000, 0x80000000); 154 } 155 156 void 157 gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl, 158 struct nvkm_memory *mem, int nr) 159 { 160 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 161 struct nvkm_device *device = subdev->device; 162 int target; 163 164 switch (nvkm_memory_target(mem)) { 165 case NVKM_MEM_TARGET_VRAM: target = 0; break; 166 case NVKM_MEM_TARGET_NCOH: target = 3; break; 167 default: 168 WARN_ON(1); 169 return; 170 } 171 172 nvkm_wr32(device, 0x002270, (nvkm_memory_addr(mem) >> 12) | 173 (target << 28)); 174 nvkm_wr32(device, 0x002274, (runl << 20) | nr); 175 176 if (nvkm_msec(device, 2000, 177 if (!(nvkm_rd32(device, 0x002284 + (runl * 0x08)) & 0x00100000)) 178 break; 179 ) < 0) 180 nvkm_error(subdev, "runlist %d update timeout\n", runl); 181 } 182 183 void 184 gk104_fifo_runlist_update(struct gk104_fifo *fifo, int runl) 185 { 186 const struct gk104_fifo_runlist_func *func = fifo->func->runlist; 187 struct gk104_fifo_chan *chan; 188 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 189 struct nvkm_memory *mem; 190 struct nvkm_fifo_cgrp *cgrp; 191 int nr = 0; 192 193 mutex_lock(&subdev->mutex); 194 mem = fifo->runlist[runl].mem[fifo->runlist[runl].next]; 195 fifo->runlist[runl].next = !fifo->runlist[runl].next; 196 197 nvkm_kmap(mem); 198 list_for_each_entry(chan, &fifo->runlist[runl].chan, head) { 199 func->chan(chan, mem, nr++ * func->size); 200 } 201 202 list_for_each_entry(cgrp, &fifo->runlist[runl].cgrp, head) { 203 func->cgrp(cgrp, mem, nr++ * func->size); 204 list_for_each_entry(chan, &cgrp->chan, head) { 205 func->chan(chan, mem, nr++ * func->size); 206 } 207 } 208 nvkm_done(mem); 209 210 func->commit(fifo, runl, mem, nr); 211 mutex_unlock(&subdev->mutex); 212 } 213 214 void 215 gk104_fifo_runlist_remove(struct gk104_fifo *fifo, struct gk104_fifo_chan *chan) 216 { 217 struct nvkm_fifo_cgrp *cgrp = chan->cgrp; 218 mutex_lock(&fifo->base.engine.subdev.mutex); 219 if (!list_empty(&chan->head)) { 220 list_del_init(&chan->head); 221 if (cgrp && !--cgrp->chan_nr) 222 list_del_init(&cgrp->head); 223 } 224 mutex_unlock(&fifo->base.engine.subdev.mutex); 225 } 226 227 void 228 gk104_fifo_runlist_insert(struct gk104_fifo *fifo, struct gk104_fifo_chan *chan) 229 { 230 struct nvkm_fifo_cgrp *cgrp = chan->cgrp; 231 mutex_lock(&fifo->base.engine.subdev.mutex); 232 if (cgrp) { 233 if (!cgrp->chan_nr++) 234 list_add_tail(&cgrp->head, &fifo->runlist[chan->runl].cgrp); 235 list_add_tail(&chan->head, &cgrp->chan); 236 } else { 237 list_add_tail(&chan->head, &fifo->runlist[chan->runl].chan); 238 } 239 mutex_unlock(&fifo->base.engine.subdev.mutex); 240 } 241 242 void 243 gk104_fifo_runlist_chan(struct gk104_fifo_chan *chan, 244 struct nvkm_memory *memory, u32 offset) 245 { 246 nvkm_wo32(memory, offset + 0, chan->base.chid); 247 nvkm_wo32(memory, offset + 4, 0x00000000); 248 } 249 250 const struct gk104_fifo_runlist_func 251 gk104_fifo_runlist = { 252 .size = 8, 253 .chan = gk104_fifo_runlist_chan, 254 .commit = gk104_fifo_runlist_commit, 255 }; 256 257 void 258 gk104_fifo_pbdma_init(struct gk104_fifo *fifo) 259 { 260 struct nvkm_device *device = fifo->base.engine.subdev.device; 261 nvkm_wr32(device, 0x000204, (1 << fifo->pbdma_nr) - 1); 262 } 263 264 int 265 gk104_fifo_pbdma_nr(struct gk104_fifo *fifo) 266 { 267 struct nvkm_device *device = fifo->base.engine.subdev.device; 268 /* Determine number of PBDMAs by checking valid enable bits. */ 269 nvkm_wr32(device, 0x000204, 0xffffffff); 270 return hweight32(nvkm_rd32(device, 0x000204)); 271 } 272 273 const struct gk104_fifo_pbdma_func 274 gk104_fifo_pbdma = { 275 .nr = gk104_fifo_pbdma_nr, 276 .init = gk104_fifo_pbdma_init, 277 }; 278 279 static void 280 gk104_fifo_recover_work(struct work_struct *w) 281 { 282 struct gk104_fifo *fifo = container_of(w, typeof(*fifo), recover.work); 283 struct nvkm_device *device = fifo->base.engine.subdev.device; 284 struct nvkm_engine *engine; 285 unsigned long flags; 286 u32 engm, runm, todo; 287 int engn, runl; 288 289 spin_lock_irqsave(&fifo->base.lock, flags); 290 runm = fifo->recover.runm; 291 engm = fifo->recover.engm; 292 fifo->recover.engm = 0; 293 fifo->recover.runm = 0; 294 spin_unlock_irqrestore(&fifo->base.lock, flags); 295 296 nvkm_mask(device, 0x002630, runm, runm); 297 298 for (todo = engm; todo && (engn = __ffs64(todo), 1); todo &= ~BIT(engn)) { 299 if ((engine = fifo->engine[engn].engine)) { 300 nvkm_subdev_fini(&engine->subdev, false); 301 WARN_ON(nvkm_subdev_init(&engine->subdev)); 302 } 303 } 304 305 for (todo = runm; todo && (runl = __ffs(todo), 1); todo &= ~BIT(runl)) 306 gk104_fifo_runlist_update(fifo, runl); 307 308 nvkm_wr32(device, 0x00262c, runm); 309 nvkm_mask(device, 0x002630, runm, 0x00000000); 310 } 311 312 static void gk104_fifo_recover_engn(struct gk104_fifo *fifo, int engn); 313 314 static void 315 gk104_fifo_recover_runl(struct gk104_fifo *fifo, int runl) 316 { 317 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 318 struct nvkm_device *device = subdev->device; 319 const u32 runm = BIT(runl); 320 321 assert_spin_locked(&fifo->base.lock); 322 if (fifo->recover.runm & runm) 323 return; 324 fifo->recover.runm |= runm; 325 326 /* Block runlist to prevent channel assignment(s) from changing. */ 327 nvkm_mask(device, 0x002630, runm, runm); 328 329 /* Schedule recovery. */ 330 nvkm_warn(subdev, "runlist %d: scheduled for recovery\n", runl); 331 schedule_work(&fifo->recover.work); 332 } 333 334 static struct gk104_fifo_chan * 335 gk104_fifo_recover_chid(struct gk104_fifo *fifo, int runl, int chid) 336 { 337 struct gk104_fifo_chan *chan; 338 struct nvkm_fifo_cgrp *cgrp; 339 340 list_for_each_entry(chan, &fifo->runlist[runl].chan, head) { 341 if (chan->base.chid == chid) { 342 list_del_init(&chan->head); 343 return chan; 344 } 345 } 346 347 list_for_each_entry(cgrp, &fifo->runlist[runl].cgrp, head) { 348 if (cgrp->id == chid) { 349 chan = list_first_entry(&cgrp->chan, typeof(*chan), head); 350 list_del_init(&chan->head); 351 if (!--cgrp->chan_nr) 352 list_del_init(&cgrp->head); 353 return chan; 354 } 355 } 356 357 return NULL; 358 } 359 360 static void 361 gk104_fifo_recover_chan(struct nvkm_fifo *base, int chid) 362 { 363 struct gk104_fifo *fifo = gk104_fifo(base); 364 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 365 struct nvkm_device *device = subdev->device; 366 const u32 stat = nvkm_rd32(device, 0x800004 + (chid * 0x08)); 367 const u32 runl = (stat & 0x000f0000) >> 16; 368 const bool used = (stat & 0x00000001); 369 unsigned long engn, engm = fifo->runlist[runl].engm; 370 struct gk104_fifo_chan *chan; 371 372 assert_spin_locked(&fifo->base.lock); 373 if (!used) 374 return; 375 376 /* Lookup SW state for channel, and mark it as dead. */ 377 chan = gk104_fifo_recover_chid(fifo, runl, chid); 378 if (chan) { 379 chan->killed = true; 380 nvkm_fifo_kevent(&fifo->base, chid); 381 } 382 383 /* Disable channel. */ 384 nvkm_wr32(device, 0x800004 + (chid * 0x08), stat | 0x00000800); 385 nvkm_warn(subdev, "channel %d: killed\n", chid); 386 387 /* Block channel assignments from changing during recovery. */ 388 gk104_fifo_recover_runl(fifo, runl); 389 390 /* Schedule recovery for any engines the channel is on. */ 391 for_each_set_bit(engn, &engm, fifo->engine_nr) { 392 struct gk104_fifo_engine_status status; 393 gk104_fifo_engine_status(fifo, engn, &status); 394 if (!status.chan || status.chan->id != chid) 395 continue; 396 gk104_fifo_recover_engn(fifo, engn); 397 } 398 } 399 400 static void 401 gk104_fifo_recover_engn(struct gk104_fifo *fifo, int engn) 402 { 403 struct nvkm_engine *engine = fifo->engine[engn].engine; 404 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 405 struct nvkm_device *device = subdev->device; 406 const u32 runl = fifo->engine[engn].runl; 407 const u32 engm = BIT(engn); 408 struct gk104_fifo_engine_status status; 409 int mmui = -1; 410 411 assert_spin_locked(&fifo->base.lock); 412 if (fifo->recover.engm & engm) 413 return; 414 fifo->recover.engm |= engm; 415 416 /* Block channel assignments from changing during recovery. */ 417 gk104_fifo_recover_runl(fifo, runl); 418 419 /* Determine which channel (if any) is currently on the engine. */ 420 gk104_fifo_engine_status(fifo, engn, &status); 421 if (status.chan) { 422 /* The channel is not longer viable, kill it. */ 423 gk104_fifo_recover_chan(&fifo->base, status.chan->id); 424 } 425 426 /* Determine MMU fault ID for the engine, if we're not being 427 * called from the fault handler already. 428 */ 429 if (!status.faulted && engine) { 430 mmui = nvkm_top_fault_id(device, engine->subdev.index); 431 if (mmui < 0) { 432 const struct nvkm_enum *en = fifo->func->fault.engine; 433 for (; en && en->name; en++) { 434 if (en->data2 == engine->subdev.index) { 435 mmui = en->value; 436 break; 437 } 438 } 439 } 440 WARN_ON(mmui < 0); 441 } 442 443 /* Trigger a MMU fault for the engine. 444 * 445 * No good idea why this is needed, but nvgpu does something similar, 446 * and it makes recovery from CTXSW_TIMEOUT a lot more reliable. 447 */ 448 if (mmui >= 0) { 449 nvkm_wr32(device, 0x002a30 + (engn * 0x04), 0x00000100 | mmui); 450 451 /* Wait for fault to trigger. */ 452 nvkm_msec(device, 2000, 453 gk104_fifo_engine_status(fifo, engn, &status); 454 if (status.faulted) 455 break; 456 ); 457 458 /* Release MMU fault trigger, and ACK the fault. */ 459 nvkm_wr32(device, 0x002a30 + (engn * 0x04), 0x00000000); 460 nvkm_wr32(device, 0x00259c, BIT(mmui)); 461 nvkm_wr32(device, 0x002100, 0x10000000); 462 } 463 464 /* Schedule recovery. */ 465 nvkm_warn(subdev, "engine %d: scheduled for recovery\n", engn); 466 schedule_work(&fifo->recover.work); 467 } 468 469 static void 470 gk104_fifo_fault(struct nvkm_fifo *base, struct nvkm_fault_data *info) 471 { 472 struct gk104_fifo *fifo = gk104_fifo(base); 473 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 474 struct nvkm_device *device = subdev->device; 475 const struct nvkm_enum *er, *ee, *ec, *ea; 476 struct nvkm_engine *engine = NULL; 477 struct nvkm_fifo_chan *chan; 478 unsigned long flags; 479 char ct[8] = "HUB/", en[16] = ""; 480 int engn; 481 482 er = nvkm_enum_find(fifo->func->fault.reason, info->reason); 483 ee = nvkm_enum_find(fifo->func->fault.engine, info->engine); 484 if (info->hub) { 485 ec = nvkm_enum_find(fifo->func->fault.hubclient, info->client); 486 } else { 487 ec = nvkm_enum_find(fifo->func->fault.gpcclient, info->client); 488 snprintf(ct, sizeof(ct), "GPC%d/", info->gpc); 489 } 490 ea = nvkm_enum_find(fifo->func->fault.access, info->access); 491 492 if (ee && ee->data2) { 493 switch (ee->data2) { 494 case NVKM_SUBDEV_BAR: 495 nvkm_bar_bar1_reset(device); 496 break; 497 case NVKM_SUBDEV_INSTMEM: 498 nvkm_bar_bar2_reset(device); 499 break; 500 case NVKM_ENGINE_IFB: 501 nvkm_mask(device, 0x001718, 0x00000000, 0x00000000); 502 break; 503 default: 504 engine = nvkm_device_engine(device, ee->data2); 505 break; 506 } 507 } 508 509 if (ee == NULL) { 510 enum nvkm_devidx engidx = nvkm_top_fault(device, info->engine); 511 if (engidx < NVKM_SUBDEV_NR) { 512 const char *src = nvkm_subdev_name[engidx]; 513 char *dst = en; 514 do { 515 *dst++ = toupper(*src++); 516 } while(*src); 517 engine = nvkm_device_engine(device, engidx); 518 } 519 } else { 520 snprintf(en, sizeof(en), "%s", ee->name); 521 } 522 523 spin_lock_irqsave(&fifo->base.lock, flags); 524 chan = nvkm_fifo_chan_inst_locked(&fifo->base, info->inst); 525 526 nvkm_error(subdev, 527 "fault %02x [%s] at %016"PRIx64" engine %02x [%s] client %02x " 528 "[%s%s] reason %02x [%s] on channel %d [%010"PRIx64" %s]\n", 529 info->access, ea ? ea->name : "", info->addr, 530 info->engine, ee ? ee->name : en, 531 info->client, ct, ec ? ec->name : "", 532 info->reason, er ? er->name : "", chan ? chan->chid : -1, 533 info->inst, chan ? chan->object.client->name : "unknown"); 534 535 /* Kill the channel that caused the fault. */ 536 if (chan) 537 gk104_fifo_recover_chan(&fifo->base, chan->chid); 538 539 /* Channel recovery will probably have already done this for the 540 * correct engine(s), but just in case we can't find the channel 541 * information... 542 */ 543 for (engn = 0; engn < fifo->engine_nr && engine; engn++) { 544 if (fifo->engine[engn].engine == engine) { 545 gk104_fifo_recover_engn(fifo, engn); 546 break; 547 } 548 } 549 550 spin_unlock_irqrestore(&fifo->base.lock, flags); 551 } 552 553 static const struct nvkm_enum 554 gk104_fifo_bind_reason[] = { 555 { 0x01, "BIND_NOT_UNBOUND" }, 556 { 0x02, "SNOOP_WITHOUT_BAR1" }, 557 { 0x03, "UNBIND_WHILE_RUNNING" }, 558 { 0x05, "INVALID_RUNLIST" }, 559 { 0x06, "INVALID_CTX_TGT" }, 560 { 0x0b, "UNBIND_WHILE_PARKED" }, 561 {} 562 }; 563 564 static void 565 gk104_fifo_intr_bind(struct gk104_fifo *fifo) 566 { 567 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 568 struct nvkm_device *device = subdev->device; 569 u32 intr = nvkm_rd32(device, 0x00252c); 570 u32 code = intr & 0x000000ff; 571 const struct nvkm_enum *en = 572 nvkm_enum_find(gk104_fifo_bind_reason, code); 573 574 nvkm_error(subdev, "BIND_ERROR %02x [%s]\n", code, en ? en->name : ""); 575 } 576 577 static const struct nvkm_enum 578 gk104_fifo_sched_reason[] = { 579 { 0x0a, "CTXSW_TIMEOUT" }, 580 {} 581 }; 582 583 static void 584 gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo) 585 { 586 struct nvkm_device *device = fifo->base.engine.subdev.device; 587 unsigned long flags, engm = 0; 588 u32 engn; 589 590 /* We need to ACK the SCHED_ERROR here, and prevent it reasserting, 591 * as MMU_FAULT cannot be triggered while it's pending. 592 */ 593 spin_lock_irqsave(&fifo->base.lock, flags); 594 nvkm_mask(device, 0x002140, 0x00000100, 0x00000000); 595 nvkm_wr32(device, 0x002100, 0x00000100); 596 597 for (engn = 0; engn < fifo->engine_nr; engn++) { 598 struct gk104_fifo_engine_status status; 599 600 gk104_fifo_engine_status(fifo, engn, &status); 601 if (!status.busy || !status.chsw) 602 continue; 603 604 engm |= BIT(engn); 605 } 606 607 for_each_set_bit(engn, &engm, fifo->engine_nr) 608 gk104_fifo_recover_engn(fifo, engn); 609 610 nvkm_mask(device, 0x002140, 0x00000100, 0x00000100); 611 spin_unlock_irqrestore(&fifo->base.lock, flags); 612 } 613 614 static void 615 gk104_fifo_intr_sched(struct gk104_fifo *fifo) 616 { 617 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 618 struct nvkm_device *device = subdev->device; 619 u32 intr = nvkm_rd32(device, 0x00254c); 620 u32 code = intr & 0x000000ff; 621 const struct nvkm_enum *en = 622 nvkm_enum_find(gk104_fifo_sched_reason, code); 623 624 nvkm_error(subdev, "SCHED_ERROR %02x [%s]\n", code, en ? en->name : ""); 625 626 switch (code) { 627 case 0x0a: 628 gk104_fifo_intr_sched_ctxsw(fifo); 629 break; 630 default: 631 break; 632 } 633 } 634 635 static void 636 gk104_fifo_intr_chsw(struct gk104_fifo *fifo) 637 { 638 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 639 struct nvkm_device *device = subdev->device; 640 u32 stat = nvkm_rd32(device, 0x00256c); 641 nvkm_error(subdev, "CHSW_ERROR %08x\n", stat); 642 nvkm_wr32(device, 0x00256c, stat); 643 } 644 645 static void 646 gk104_fifo_intr_dropped_fault(struct gk104_fifo *fifo) 647 { 648 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 649 struct nvkm_device *device = subdev->device; 650 u32 stat = nvkm_rd32(device, 0x00259c); 651 nvkm_error(subdev, "DROPPED_MMU_FAULT %08x\n", stat); 652 } 653 654 static const struct nvkm_bitfield gk104_fifo_pbdma_intr_0[] = { 655 { 0x00000001, "MEMREQ" }, 656 { 0x00000002, "MEMACK_TIMEOUT" }, 657 { 0x00000004, "MEMACK_EXTRA" }, 658 { 0x00000008, "MEMDAT_TIMEOUT" }, 659 { 0x00000010, "MEMDAT_EXTRA" }, 660 { 0x00000020, "MEMFLUSH" }, 661 { 0x00000040, "MEMOP" }, 662 { 0x00000080, "LBCONNECT" }, 663 { 0x00000100, "LBREQ" }, 664 { 0x00000200, "LBACK_TIMEOUT" }, 665 { 0x00000400, "LBACK_EXTRA" }, 666 { 0x00000800, "LBDAT_TIMEOUT" }, 667 { 0x00001000, "LBDAT_EXTRA" }, 668 { 0x00002000, "GPFIFO" }, 669 { 0x00004000, "GPPTR" }, 670 { 0x00008000, "GPENTRY" }, 671 { 0x00010000, "GPCRC" }, 672 { 0x00020000, "PBPTR" }, 673 { 0x00040000, "PBENTRY" }, 674 { 0x00080000, "PBCRC" }, 675 { 0x00100000, "XBARCONNECT" }, 676 { 0x00200000, "METHOD" }, 677 { 0x00400000, "METHODCRC" }, 678 { 0x00800000, "DEVICE" }, 679 { 0x02000000, "SEMAPHORE" }, 680 { 0x04000000, "ACQUIRE" }, 681 { 0x08000000, "PRI" }, 682 { 0x20000000, "NO_CTXSW_SEG" }, 683 { 0x40000000, "PBSEG" }, 684 { 0x80000000, "SIGNATURE" }, 685 {} 686 }; 687 688 static void 689 gk104_fifo_intr_pbdma_0(struct gk104_fifo *fifo, int unit) 690 { 691 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 692 struct nvkm_device *device = subdev->device; 693 u32 mask = nvkm_rd32(device, 0x04010c + (unit * 0x2000)); 694 u32 stat = nvkm_rd32(device, 0x040108 + (unit * 0x2000)) & mask; 695 u32 addr = nvkm_rd32(device, 0x0400c0 + (unit * 0x2000)); 696 u32 data = nvkm_rd32(device, 0x0400c4 + (unit * 0x2000)); 697 u32 chid = nvkm_rd32(device, 0x040120 + (unit * 0x2000)) & 0xfff; 698 u32 subc = (addr & 0x00070000) >> 16; 699 u32 mthd = (addr & 0x00003ffc); 700 u32 show = stat; 701 struct nvkm_fifo_chan *chan; 702 unsigned long flags; 703 char msg[128]; 704 705 if (stat & 0x00800000) { 706 if (device->sw) { 707 if (nvkm_sw_mthd(device->sw, chid, subc, mthd, data)) 708 show &= ~0x00800000; 709 } 710 } 711 712 nvkm_wr32(device, 0x0400c0 + (unit * 0x2000), 0x80600008); 713 714 if (show) { 715 nvkm_snprintbf(msg, sizeof(msg), gk104_fifo_pbdma_intr_0, show); 716 chan = nvkm_fifo_chan_chid(&fifo->base, chid, &flags); 717 nvkm_error(subdev, "PBDMA%d: %08x [%s] ch %d [%010"PRIx64" %s] " 718 "subc %d mthd %04x data %08x\n", 719 unit, show, msg, chid, chan ? chan->inst->addr : 0, 720 chan ? chan->object.client->name : "unknown", 721 subc, mthd, data); 722 nvkm_fifo_chan_put(&fifo->base, flags, &chan); 723 } 724 725 nvkm_wr32(device, 0x040108 + (unit * 0x2000), stat); 726 } 727 728 static const struct nvkm_bitfield gk104_fifo_pbdma_intr_1[] = { 729 { 0x00000001, "HCE_RE_ILLEGAL_OP" }, 730 { 0x00000002, "HCE_RE_ALIGNB" }, 731 { 0x00000004, "HCE_PRIV" }, 732 { 0x00000008, "HCE_ILLEGAL_MTHD" }, 733 { 0x00000010, "HCE_ILLEGAL_CLASS" }, 734 {} 735 }; 736 737 static void 738 gk104_fifo_intr_pbdma_1(struct gk104_fifo *fifo, int unit) 739 { 740 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 741 struct nvkm_device *device = subdev->device; 742 u32 mask = nvkm_rd32(device, 0x04014c + (unit * 0x2000)); 743 u32 stat = nvkm_rd32(device, 0x040148 + (unit * 0x2000)) & mask; 744 u32 chid = nvkm_rd32(device, 0x040120 + (unit * 0x2000)) & 0xfff; 745 char msg[128]; 746 747 if (stat) { 748 nvkm_snprintbf(msg, sizeof(msg), gk104_fifo_pbdma_intr_1, stat); 749 nvkm_error(subdev, "PBDMA%d: %08x [%s] ch %d %08x %08x\n", 750 unit, stat, msg, chid, 751 nvkm_rd32(device, 0x040150 + (unit * 0x2000)), 752 nvkm_rd32(device, 0x040154 + (unit * 0x2000))); 753 } 754 755 nvkm_wr32(device, 0x040148 + (unit * 0x2000), stat); 756 } 757 758 static void 759 gk104_fifo_intr_runlist(struct gk104_fifo *fifo) 760 { 761 struct nvkm_device *device = fifo->base.engine.subdev.device; 762 u32 mask = nvkm_rd32(device, 0x002a00); 763 while (mask) { 764 int runl = __ffs(mask); 765 #ifdef __NetBSD__ 766 spin_lock(&fifo->runlist[runl].lock); 767 DRM_SPIN_WAKEUP_ONE(&fifo->runlist[runl].wait, 768 &fifo->runlist[runl].lock); 769 spin_unlock(&fifo->runlist[runl].lock); 770 #else 771 wake_up(&fifo->runlist[runl].wait); 772 #endif 773 nvkm_wr32(device, 0x002a00, 1 << runl); 774 mask &= ~(1 << runl); 775 } 776 } 777 778 static void 779 gk104_fifo_intr_engine(struct gk104_fifo *fifo) 780 { 781 nvkm_fifo_uevent(&fifo->base); 782 } 783 784 static void 785 gk104_fifo_intr(struct nvkm_fifo *base) 786 { 787 struct gk104_fifo *fifo = gk104_fifo(base); 788 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 789 struct nvkm_device *device = subdev->device; 790 u32 mask = nvkm_rd32(device, 0x002140); 791 u32 stat = nvkm_rd32(device, 0x002100) & mask; 792 793 if (stat & 0x00000001) { 794 gk104_fifo_intr_bind(fifo); 795 nvkm_wr32(device, 0x002100, 0x00000001); 796 stat &= ~0x00000001; 797 } 798 799 if (stat & 0x00000010) { 800 nvkm_error(subdev, "PIO_ERROR\n"); 801 nvkm_wr32(device, 0x002100, 0x00000010); 802 stat &= ~0x00000010; 803 } 804 805 if (stat & 0x00000100) { 806 gk104_fifo_intr_sched(fifo); 807 nvkm_wr32(device, 0x002100, 0x00000100); 808 stat &= ~0x00000100; 809 } 810 811 if (stat & 0x00010000) { 812 gk104_fifo_intr_chsw(fifo); 813 nvkm_wr32(device, 0x002100, 0x00010000); 814 stat &= ~0x00010000; 815 } 816 817 if (stat & 0x00800000) { 818 nvkm_error(subdev, "FB_FLUSH_TIMEOUT\n"); 819 nvkm_wr32(device, 0x002100, 0x00800000); 820 stat &= ~0x00800000; 821 } 822 823 if (stat & 0x01000000) { 824 nvkm_error(subdev, "LB_ERROR\n"); 825 nvkm_wr32(device, 0x002100, 0x01000000); 826 stat &= ~0x01000000; 827 } 828 829 if (stat & 0x08000000) { 830 gk104_fifo_intr_dropped_fault(fifo); 831 nvkm_wr32(device, 0x002100, 0x08000000); 832 stat &= ~0x08000000; 833 } 834 835 if (stat & 0x10000000) { 836 u32 mask = nvkm_rd32(device, 0x00259c); 837 while (mask) { 838 u32 unit = __ffs(mask); 839 fifo->func->intr.fault(&fifo->base, unit); 840 nvkm_wr32(device, 0x00259c, (1 << unit)); 841 mask &= ~(1 << unit); 842 } 843 stat &= ~0x10000000; 844 } 845 846 if (stat & 0x20000000) { 847 u32 mask = nvkm_rd32(device, 0x0025a0); 848 while (mask) { 849 u32 unit = __ffs(mask); 850 gk104_fifo_intr_pbdma_0(fifo, unit); 851 gk104_fifo_intr_pbdma_1(fifo, unit); 852 nvkm_wr32(device, 0x0025a0, (1 << unit)); 853 mask &= ~(1 << unit); 854 } 855 stat &= ~0x20000000; 856 } 857 858 if (stat & 0x40000000) { 859 gk104_fifo_intr_runlist(fifo); 860 stat &= ~0x40000000; 861 } 862 863 if (stat & 0x80000000) { 864 nvkm_wr32(device, 0x002100, 0x80000000); 865 gk104_fifo_intr_engine(fifo); 866 stat &= ~0x80000000; 867 } 868 869 if (stat) { 870 nvkm_error(subdev, "INTR %08x\n", stat); 871 nvkm_mask(device, 0x002140, stat, 0x00000000); 872 nvkm_wr32(device, 0x002100, stat); 873 } 874 } 875 876 static void 877 gk104_fifo_fini(struct nvkm_fifo *base) 878 { 879 struct gk104_fifo *fifo = gk104_fifo(base); 880 struct nvkm_device *device = fifo->base.engine.subdev.device; 881 flush_work(&fifo->recover.work); 882 /* allow mmu fault interrupts, even when we're not using fifo */ 883 nvkm_mask(device, 0x002140, 0x10000000, 0x10000000); 884 } 885 886 static int 887 gk104_fifo_info(struct nvkm_fifo *base, u64 mthd, u64 *data) 888 { 889 struct gk104_fifo *fifo = gk104_fifo(base); 890 switch (mthd) { 891 case NV_DEVICE_FIFO_RUNLISTS: 892 *data = (1ULL << fifo->runlist_nr) - 1; 893 return 0; 894 case NV_DEVICE_FIFO_RUNLIST_ENGINES(0)... 895 NV_DEVICE_FIFO_RUNLIST_ENGINES(63): { 896 int runl = mthd - NV_DEVICE_FIFO_RUNLIST_ENGINES(0), engn; 897 if (runl < fifo->runlist_nr) { 898 unsigned long engm = fifo->runlist[runl].engm; 899 struct nvkm_engine *engine; 900 *data = 0; 901 for_each_set_bit(engn, &engm, fifo->engine_nr) { 902 if ((engine = fifo->engine[engn].engine)) 903 *data |= BIT_ULL(engine->subdev.index); 904 } 905 return 0; 906 } 907 } 908 return -EINVAL; 909 default: 910 return -EINVAL; 911 } 912 } 913 914 static int 915 gk104_fifo_oneinit(struct nvkm_fifo *base) 916 { 917 struct gk104_fifo *fifo = gk104_fifo(base); 918 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 919 struct nvkm_device *device = subdev->device; 920 struct nvkm_vmm *bar = nvkm_bar_bar1_vmm(device); 921 int engn, runl, pbid, ret, i, j; 922 enum nvkm_devidx engidx; 923 u32 *map; 924 925 fifo->pbdma_nr = fifo->func->pbdma->nr(fifo); 926 nvkm_debug(subdev, "%d PBDMA(s)\n", fifo->pbdma_nr); 927 928 /* Read PBDMA->runlist(s) mapping from HW. */ 929 if (!(map = kcalloc(fifo->pbdma_nr, sizeof(*map), GFP_KERNEL))) 930 return -ENOMEM; 931 932 for (i = 0; i < fifo->pbdma_nr; i++) 933 map[i] = nvkm_rd32(device, 0x002390 + (i * 0x04)); 934 935 /* Determine runlist configuration from topology device info. */ 936 i = 0; 937 while ((int)(engidx = nvkm_top_engine(device, i++, &runl, &engn)) >= 0) { 938 /* Determine which PBDMA handles requests for this engine. */ 939 for (j = 0, pbid = -1; j < fifo->pbdma_nr; j++) { 940 if (map[j] & (1 << runl)) { 941 pbid = j; 942 break; 943 } 944 } 945 946 nvkm_debug(subdev, "engine %2d: runlist %2d pbdma %2d (%s)\n", 947 engn, runl, pbid, nvkm_subdev_name[engidx]); 948 949 fifo->engine[engn].engine = nvkm_device_engine(device, engidx); 950 fifo->engine[engn].runl = runl; 951 fifo->engine[engn].pbid = pbid; 952 fifo->engine_nr = max(fifo->engine_nr, engn + 1); 953 fifo->runlist[runl].engm |= 1 << engn; 954 fifo->runlist_nr = max(fifo->runlist_nr, runl + 1); 955 } 956 957 kfree(map); 958 959 for (i = 0; i < fifo->runlist_nr; i++) { 960 for (j = 0; j < ARRAY_SIZE(fifo->runlist[i].mem); j++) { 961 ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 962 fifo->base.nr * 2/* TSG+chan */ * 963 fifo->func->runlist->size, 964 0x1000, false, 965 &fifo->runlist[i].mem[j]); 966 if (ret) 967 return ret; 968 } 969 970 #ifdef __NetBSD__ 971 spin_lock_init(&fifo->runlist[i].lock); 972 DRM_INIT_WAITQUEUE(&fifo->runlist[i].wait, "gk104fifo"); 973 #else 974 init_waitqueue_head(&fifo->runlist[i].wait); 975 #endif 976 INIT_LIST_HEAD(&fifo->runlist[i].cgrp); 977 INIT_LIST_HEAD(&fifo->runlist[i].chan); 978 } 979 980 ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 981 fifo->base.nr * 0x200, 0x1000, true, 982 &fifo->user.mem); 983 if (ret) 984 return ret; 985 986 ret = nvkm_vmm_get(bar, 12, nvkm_memory_size(fifo->user.mem), 987 &fifo->user.bar); 988 if (ret) 989 return ret; 990 991 return nvkm_memory_map(fifo->user.mem, 0, bar, fifo->user.bar, NULL, 0); 992 } 993 994 static void 995 gk104_fifo_init(struct nvkm_fifo *base) 996 { 997 struct gk104_fifo *fifo = gk104_fifo(base); 998 struct nvkm_device *device = fifo->base.engine.subdev.device; 999 int i; 1000 1001 /* Enable PBDMAs. */ 1002 fifo->func->pbdma->init(fifo); 1003 1004 /* PBDMA[n] */ 1005 for (i = 0; i < fifo->pbdma_nr; i++) { 1006 nvkm_mask(device, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000); 1007 nvkm_wr32(device, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */ 1008 nvkm_wr32(device, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTREN */ 1009 } 1010 1011 /* PBDMA[n].HCE */ 1012 for (i = 0; i < fifo->pbdma_nr; i++) { 1013 nvkm_wr32(device, 0x040148 + (i * 0x2000), 0xffffffff); /* INTR */ 1014 nvkm_wr32(device, 0x04014c + (i * 0x2000), 0xffffffff); /* INTREN */ 1015 } 1016 1017 nvkm_wr32(device, 0x002254, 0x10000000 | fifo->user.bar->addr >> 12); 1018 1019 if (fifo->func->pbdma->init_timeout) 1020 fifo->func->pbdma->init_timeout(fifo); 1021 1022 nvkm_wr32(device, 0x002100, 0xffffffff); 1023 nvkm_wr32(device, 0x002140, 0x7fffffff); 1024 } 1025 1026 static void * 1027 gk104_fifo_dtor(struct nvkm_fifo *base) 1028 { 1029 struct gk104_fifo *fifo = gk104_fifo(base); 1030 struct nvkm_device *device = fifo->base.engine.subdev.device; 1031 int i; 1032 1033 nvkm_vmm_put(nvkm_bar_bar1_vmm(device), &fifo->user.bar); 1034 nvkm_memory_unref(&fifo->user.mem); 1035 1036 for (i = 0; i < fifo->runlist_nr; i++) { 1037 #ifdef __NetBSD__ 1038 DRM_DESTROY_WAITQUEUE(&fifo->runlist[i].wait); 1039 spin_lock_destroy(&fifo->runlist[i].lock); 1040 #endif 1041 nvkm_memory_unref(&fifo->runlist[i].mem[1]); 1042 nvkm_memory_unref(&fifo->runlist[i].mem[0]); 1043 } 1044 1045 return fifo; 1046 } 1047 1048 static const struct nvkm_fifo_func 1049 gk104_fifo_ = { 1050 .dtor = gk104_fifo_dtor, 1051 .oneinit = gk104_fifo_oneinit, 1052 .info = gk104_fifo_info, 1053 .init = gk104_fifo_init, 1054 .fini = gk104_fifo_fini, 1055 .intr = gk104_fifo_intr, 1056 .fault = gk104_fifo_fault, 1057 .uevent_init = gk104_fifo_uevent_init, 1058 .uevent_fini = gk104_fifo_uevent_fini, 1059 .recover_chan = gk104_fifo_recover_chan, 1060 .class_get = gk104_fifo_class_get, 1061 .class_new = gk104_fifo_class_new, 1062 }; 1063 1064 int 1065 gk104_fifo_new_(const struct gk104_fifo_func *func, struct nvkm_device *device, 1066 int index, int nr, struct nvkm_fifo **pfifo) 1067 { 1068 struct gk104_fifo *fifo; 1069 1070 if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL))) 1071 return -ENOMEM; 1072 fifo->func = func; 1073 INIT_WORK(&fifo->recover.work, gk104_fifo_recover_work); 1074 *pfifo = &fifo->base; 1075 1076 return nvkm_fifo_ctor(&gk104_fifo_, device, index, nr, &fifo->base); 1077 } 1078 1079 const struct nvkm_enum 1080 gk104_fifo_fault_access[] = { 1081 { 0x0, "READ" }, 1082 { 0x1, "WRITE" }, 1083 {} 1084 }; 1085 1086 const struct nvkm_enum 1087 gk104_fifo_fault_engine[] = { 1088 { 0x00, "GR", NULL, NVKM_ENGINE_GR }, 1089 { 0x01, "DISPLAY" }, 1090 { 0x02, "CAPTURE" }, 1091 { 0x03, "IFB", NULL, NVKM_ENGINE_IFB }, 1092 { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR }, 1093 { 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM }, 1094 { 0x06, "SCHED" }, 1095 { 0x07, "HOST0", NULL, NVKM_ENGINE_FIFO }, 1096 { 0x08, "HOST1", NULL, NVKM_ENGINE_FIFO }, 1097 { 0x09, "HOST2", NULL, NVKM_ENGINE_FIFO }, 1098 { 0x0a, "HOST3", NULL, NVKM_ENGINE_FIFO }, 1099 { 0x0b, "HOST4", NULL, NVKM_ENGINE_FIFO }, 1100 { 0x0c, "HOST5", NULL, NVKM_ENGINE_FIFO }, 1101 { 0x0d, "HOST6", NULL, NVKM_ENGINE_FIFO }, 1102 { 0x0e, "HOST7", NULL, NVKM_ENGINE_FIFO }, 1103 { 0x0f, "HOSTSR" }, 1104 { 0x10, "MSVLD", NULL, NVKM_ENGINE_MSVLD }, 1105 { 0x11, "MSPPP", NULL, NVKM_ENGINE_MSPPP }, 1106 { 0x13, "PERF" }, 1107 { 0x14, "MSPDEC", NULL, NVKM_ENGINE_MSPDEC }, 1108 { 0x15, "CE0", NULL, NVKM_ENGINE_CE0 }, 1109 { 0x16, "CE1", NULL, NVKM_ENGINE_CE1 }, 1110 { 0x17, "PMU" }, 1111 { 0x18, "PTP" }, 1112 { 0x19, "MSENC", NULL, NVKM_ENGINE_MSENC }, 1113 { 0x1b, "CE2", NULL, NVKM_ENGINE_CE2 }, 1114 {} 1115 }; 1116 1117 const struct nvkm_enum 1118 gk104_fifo_fault_reason[] = { 1119 { 0x00, "PDE" }, 1120 { 0x01, "PDE_SIZE" }, 1121 { 0x02, "PTE" }, 1122 { 0x03, "VA_LIMIT_VIOLATION" }, 1123 { 0x04, "UNBOUND_INST_BLOCK" }, 1124 { 0x05, "PRIV_VIOLATION" }, 1125 { 0x06, "RO_VIOLATION" }, 1126 { 0x07, "WO_VIOLATION" }, 1127 { 0x08, "PITCH_MASK_VIOLATION" }, 1128 { 0x09, "WORK_CREATION" }, 1129 { 0x0a, "UNSUPPORTED_APERTURE" }, 1130 { 0x0b, "COMPRESSION_FAILURE" }, 1131 { 0x0c, "UNSUPPORTED_KIND" }, 1132 { 0x0d, "REGION_VIOLATION" }, 1133 { 0x0e, "BOTH_PTES_VALID" }, 1134 { 0x0f, "INFO_TYPE_POISONED" }, 1135 {} 1136 }; 1137 1138 const struct nvkm_enum 1139 gk104_fifo_fault_hubclient[] = { 1140 { 0x00, "VIP" }, 1141 { 0x01, "CE0" }, 1142 { 0x02, "CE1" }, 1143 { 0x03, "DNISO" }, 1144 { 0x04, "FE" }, 1145 { 0x05, "FECS" }, 1146 { 0x06, "HOST" }, 1147 { 0x07, "HOST_CPU" }, 1148 { 0x08, "HOST_CPU_NB" }, 1149 { 0x09, "ISO" }, 1150 { 0x0a, "MMU" }, 1151 { 0x0b, "MSPDEC" }, 1152 { 0x0c, "MSPPP" }, 1153 { 0x0d, "MSVLD" }, 1154 { 0x0e, "NISO" }, 1155 { 0x0f, "P2P" }, 1156 { 0x10, "PD" }, 1157 { 0x11, "PERF" }, 1158 { 0x12, "PMU" }, 1159 { 0x13, "RASTERTWOD" }, 1160 { 0x14, "SCC" }, 1161 { 0x15, "SCC_NB" }, 1162 { 0x16, "SEC" }, 1163 { 0x17, "SSYNC" }, 1164 { 0x18, "GR_CE" }, 1165 { 0x19, "CE2" }, 1166 { 0x1a, "XV" }, 1167 { 0x1b, "MMU_NB" }, 1168 { 0x1c, "MSENC" }, 1169 { 0x1d, "DFALCON" }, 1170 { 0x1e, "SKED" }, 1171 { 0x1f, "AFALCON" }, 1172 {} 1173 }; 1174 1175 const struct nvkm_enum 1176 gk104_fifo_fault_gpcclient[] = { 1177 { 0x00, "L1_0" }, { 0x01, "T1_0" }, { 0x02, "PE_0" }, 1178 { 0x03, "L1_1" }, { 0x04, "T1_1" }, { 0x05, "PE_1" }, 1179 { 0x06, "L1_2" }, { 0x07, "T1_2" }, { 0x08, "PE_2" }, 1180 { 0x09, "L1_3" }, { 0x0a, "T1_3" }, { 0x0b, "PE_3" }, 1181 { 0x0c, "RAST" }, 1182 { 0x0d, "GCC" }, 1183 { 0x0e, "GPCCS" }, 1184 { 0x0f, "PROP_0" }, 1185 { 0x10, "PROP_1" }, 1186 { 0x11, "PROP_2" }, 1187 { 0x12, "PROP_3" }, 1188 { 0x13, "L1_4" }, { 0x14, "T1_4" }, { 0x15, "PE_4" }, 1189 { 0x16, "L1_5" }, { 0x17, "T1_5" }, { 0x18, "PE_5" }, 1190 { 0x19, "L1_6" }, { 0x1a, "T1_6" }, { 0x1b, "PE_6" }, 1191 { 0x1c, "L1_7" }, { 0x1d, "T1_7" }, { 0x1e, "PE_7" }, 1192 { 0x1f, "GPM" }, 1193 { 0x20, "LTP_UTLB_0" }, 1194 { 0x21, "LTP_UTLB_1" }, 1195 { 0x22, "LTP_UTLB_2" }, 1196 { 0x23, "LTP_UTLB_3" }, 1197 { 0x24, "GPC_RGG_UTLB" }, 1198 {} 1199 }; 1200 1201 static const struct gk104_fifo_func 1202 gk104_fifo = { 1203 .intr.fault = gf100_fifo_intr_fault, 1204 .pbdma = &gk104_fifo_pbdma, 1205 .fault.access = gk104_fifo_fault_access, 1206 .fault.engine = gk104_fifo_fault_engine, 1207 .fault.reason = gk104_fifo_fault_reason, 1208 .fault.hubclient = gk104_fifo_fault_hubclient, 1209 .fault.gpcclient = gk104_fifo_fault_gpcclient, 1210 .runlist = &gk104_fifo_runlist, 1211 .chan = {{0,0,KEPLER_CHANNEL_GPFIFO_A}, gk104_fifo_gpfifo_new }, 1212 }; 1213 1214 int 1215 gk104_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo) 1216 { 1217 return gk104_fifo_new_(&gk104_fifo, device, index, 4096, pfifo); 1218 } 1219