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 #include "gf100.h" 25 #include "changf100.h" 26 27 #include <core/client.h> 28 #include <core/enum.h> 29 #include <core/gpuobj.h> 30 #include <core/handle.h> 31 #include <subdev/bar.h> 32 #include <engine/sw.h> 33 34 #include <nvif/class.h> 35 36 static void 37 gf100_fifo_uevent_init(struct nvkm_fifo *fifo) 38 { 39 struct nvkm_device *device = fifo->engine.subdev.device; 40 nvkm_mask(device, 0x002140, 0x80000000, 0x80000000); 41 } 42 43 static void 44 gf100_fifo_uevent_fini(struct nvkm_fifo *fifo) 45 { 46 struct nvkm_device *device = fifo->engine.subdev.device; 47 nvkm_mask(device, 0x002140, 0x80000000, 0x00000000); 48 } 49 50 void 51 gf100_fifo_runlist_update(struct gf100_fifo *fifo) 52 { 53 struct gf100_fifo_chan *chan; 54 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 55 struct nvkm_device *device = subdev->device; 56 struct nvkm_memory *cur; 57 int nr = 0; 58 59 mutex_lock(&subdev->mutex); 60 cur = fifo->runlist.mem[fifo->runlist.active]; 61 fifo->runlist.active = !fifo->runlist.active; 62 63 nvkm_kmap(cur); 64 list_for_each_entry(chan, &fifo->chan, head) { 65 nvkm_wo32(cur, (nr * 8) + 0, chan->base.chid); 66 nvkm_wo32(cur, (nr * 8) + 4, 0x00000004); 67 nr++; 68 } 69 nvkm_done(cur); 70 71 nvkm_wr32(device, 0x002270, nvkm_memory_addr(cur) >> 12); 72 nvkm_wr32(device, 0x002274, 0x01f00000 | nr); 73 74 if (wait_event_timeout(fifo->runlist.wait, 75 !(nvkm_rd32(device, 0x00227c) & 0x00100000), 76 msecs_to_jiffies(2000)) == 0) 77 nvkm_error(subdev, "runlist update timeout\n"); 78 mutex_unlock(&subdev->mutex); 79 } 80 81 static inline int 82 gf100_fifo_engidx(struct gf100_fifo *fifo, u32 engn) 83 { 84 switch (engn) { 85 case NVKM_ENGINE_GR : engn = 0; break; 86 case NVKM_ENGINE_MSVLD : engn = 1; break; 87 case NVKM_ENGINE_MSPPP : engn = 2; break; 88 case NVKM_ENGINE_MSPDEC: engn = 3; break; 89 case NVKM_ENGINE_CE0 : engn = 4; break; 90 case NVKM_ENGINE_CE1 : engn = 5; break; 91 default: 92 return -1; 93 } 94 95 return engn; 96 } 97 98 static inline struct nvkm_engine * 99 gf100_fifo_engine(struct gf100_fifo *fifo, u32 engn) 100 { 101 struct nvkm_device *device = fifo->base.engine.subdev.device; 102 103 switch (engn) { 104 case 0: engn = NVKM_ENGINE_GR; break; 105 case 1: engn = NVKM_ENGINE_MSVLD; break; 106 case 2: engn = NVKM_ENGINE_MSPPP; break; 107 case 3: engn = NVKM_ENGINE_MSPDEC; break; 108 case 4: engn = NVKM_ENGINE_CE0; break; 109 case 5: engn = NVKM_ENGINE_CE1; break; 110 default: 111 return NULL; 112 } 113 114 return nvkm_device_engine(device, engn); 115 } 116 117 static void 118 gf100_fifo_recover_work(struct work_struct *work) 119 { 120 struct gf100_fifo *fifo = container_of(work, typeof(*fifo), fault); 121 struct nvkm_device *device = fifo->base.engine.subdev.device; 122 struct nvkm_engine *engine; 123 unsigned long flags; 124 u32 engn, engm = 0; 125 u64 mask, todo; 126 127 spin_lock_irqsave(&fifo->base.lock, flags); 128 mask = fifo->mask; 129 fifo->mask = 0ULL; 130 spin_unlock_irqrestore(&fifo->base.lock, flags); 131 132 for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) 133 engm |= 1 << gf100_fifo_engidx(fifo, engn); 134 nvkm_mask(device, 0x002630, engm, engm); 135 136 for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) { 137 if ((engine = nvkm_device_engine(device, engn))) { 138 nvkm_subdev_fini(&engine->subdev, false); 139 WARN_ON(nvkm_subdev_init(&engine->subdev)); 140 } 141 } 142 143 gf100_fifo_runlist_update(fifo); 144 nvkm_wr32(device, 0x00262c, engm); 145 nvkm_mask(device, 0x002630, engm, 0x00000000); 146 } 147 148 static void 149 gf100_fifo_recover(struct gf100_fifo *fifo, struct nvkm_engine *engine, 150 struct gf100_fifo_chan *chan) 151 { 152 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 153 struct nvkm_device *device = subdev->device; 154 u32 chid = chan->base.chid; 155 156 nvkm_error(subdev, "%s engine fault on channel %d, recovering...\n", 157 nvkm_subdev_name[engine->subdev.index], chid); 158 assert_spin_locked(&fifo->base.lock); 159 160 nvkm_mask(device, 0x003004 + (chid * 0x08), 0x00000001, 0x00000000); 161 list_del_init(&chan->head); 162 chan->killed = true; 163 164 fifo->mask |= 1ULL << engine->subdev.index; 165 schedule_work(&fifo->fault); 166 } 167 168 static const struct nvkm_enum 169 gf100_fifo_sched_reason[] = { 170 { 0x0a, "CTXSW_TIMEOUT" }, 171 {} 172 }; 173 174 static void 175 gf100_fifo_intr_sched_ctxsw(struct gf100_fifo *fifo) 176 { 177 struct nvkm_device *device = fifo->base.engine.subdev.device; 178 struct nvkm_engine *engine; 179 struct gf100_fifo_chan *chan; 180 unsigned long flags; 181 u32 engn; 182 183 spin_lock_irqsave(&fifo->base.lock, flags); 184 for (engn = 0; engn < 6; engn++) { 185 u32 stat = nvkm_rd32(device, 0x002640 + (engn * 0x04)); 186 u32 busy = (stat & 0x80000000); 187 u32 save = (stat & 0x00100000); /* maybe? */ 188 u32 unk0 = (stat & 0x00040000); 189 u32 unk1 = (stat & 0x00001000); 190 u32 chid = (stat & 0x0000007f); 191 (void)save; 192 193 if (busy && unk0 && unk1) { 194 list_for_each_entry(chan, &fifo->chan, head) { 195 if (chan->base.chid == chid) { 196 engine = gf100_fifo_engine(fifo, engn); 197 if (!engine) 198 break; 199 gf100_fifo_recover(fifo, engine, chan); 200 break; 201 } 202 } 203 } 204 } 205 spin_unlock_irqrestore(&fifo->base.lock, flags); 206 } 207 208 static void 209 gf100_fifo_intr_sched(struct gf100_fifo *fifo) 210 { 211 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 212 struct nvkm_device *device = subdev->device; 213 u32 intr = nvkm_rd32(device, 0x00254c); 214 u32 code = intr & 0x000000ff; 215 const struct nvkm_enum *en; 216 217 en = nvkm_enum_find(gf100_fifo_sched_reason, code); 218 219 nvkm_error(subdev, "SCHED_ERROR %02x [%s]\n", code, en ? en->name : ""); 220 221 switch (code) { 222 case 0x0a: 223 gf100_fifo_intr_sched_ctxsw(fifo); 224 break; 225 default: 226 break; 227 } 228 } 229 230 static const struct nvkm_enum 231 gf100_fifo_fault_engine[] = { 232 { 0x00, "PGRAPH", NULL, NVKM_ENGINE_GR }, 233 { 0x03, "PEEPHOLE", NULL, NVKM_ENGINE_IFB }, 234 { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR }, 235 { 0x05, "BAR3", NULL, NVKM_SUBDEV_INSTMEM }, 236 { 0x07, "PFIFO", NULL, NVKM_ENGINE_FIFO }, 237 { 0x10, "PMSVLD", NULL, NVKM_ENGINE_MSVLD }, 238 { 0x11, "PMSPPP", NULL, NVKM_ENGINE_MSPPP }, 239 { 0x13, "PCOUNTER" }, 240 { 0x14, "PMSPDEC", NULL, NVKM_ENGINE_MSPDEC }, 241 { 0x15, "PCE0", NULL, NVKM_ENGINE_CE0 }, 242 { 0x16, "PCE1", NULL, NVKM_ENGINE_CE1 }, 243 { 0x17, "PDAEMON" }, 244 {} 245 }; 246 247 static const struct nvkm_enum 248 gf100_fifo_fault_reason[] = { 249 { 0x00, "PT_NOT_PRESENT" }, 250 { 0x01, "PT_TOO_SHORT" }, 251 { 0x02, "PAGE_NOT_PRESENT" }, 252 { 0x03, "VM_LIMIT_EXCEEDED" }, 253 { 0x04, "NO_CHANNEL" }, 254 { 0x05, "PAGE_SYSTEM_ONLY" }, 255 { 0x06, "PAGE_READ_ONLY" }, 256 { 0x0a, "COMPRESSED_SYSRAM" }, 257 { 0x0c, "INVALID_STORAGE_TYPE" }, 258 {} 259 }; 260 261 static const struct nvkm_enum 262 gf100_fifo_fault_hubclient[] = { 263 { 0x01, "PCOPY0" }, 264 { 0x02, "PCOPY1" }, 265 { 0x04, "DISPATCH" }, 266 { 0x05, "CTXCTL" }, 267 { 0x06, "PFIFO" }, 268 { 0x07, "BAR_READ" }, 269 { 0x08, "BAR_WRITE" }, 270 { 0x0b, "PVP" }, 271 { 0x0c, "PMSPPP" }, 272 { 0x0d, "PMSVLD" }, 273 { 0x11, "PCOUNTER" }, 274 { 0x12, "PDAEMON" }, 275 { 0x14, "CCACHE" }, 276 { 0x15, "CCACHE_POST" }, 277 {} 278 }; 279 280 static const struct nvkm_enum 281 gf100_fifo_fault_gpcclient[] = { 282 { 0x01, "TEX" }, 283 { 0x0c, "ESETUP" }, 284 { 0x0e, "CTXCTL" }, 285 { 0x0f, "PROP" }, 286 {} 287 }; 288 289 static void 290 gf100_fifo_intr_fault(struct gf100_fifo *fifo, int unit) 291 { 292 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 293 struct nvkm_device *device = subdev->device; 294 u32 inst = nvkm_rd32(device, 0x002800 + (unit * 0x10)); 295 u32 valo = nvkm_rd32(device, 0x002804 + (unit * 0x10)); 296 u32 vahi = nvkm_rd32(device, 0x002808 + (unit * 0x10)); 297 u32 stat = nvkm_rd32(device, 0x00280c + (unit * 0x10)); 298 u32 gpc = (stat & 0x1f000000) >> 24; 299 u32 client = (stat & 0x00001f00) >> 8; 300 u32 write = (stat & 0x00000080); 301 u32 hub = (stat & 0x00000040); 302 u32 reason = (stat & 0x0000000f); 303 const struct nvkm_enum *er, *eu, *ec; 304 struct nvkm_engine *engine = NULL; 305 struct nvkm_fifo_chan *chan; 306 unsigned long flags; 307 char gpcid[8] = ""; 308 309 er = nvkm_enum_find(gf100_fifo_fault_reason, reason); 310 eu = nvkm_enum_find(gf100_fifo_fault_engine, unit); 311 if (hub) { 312 ec = nvkm_enum_find(gf100_fifo_fault_hubclient, client); 313 } else { 314 ec = nvkm_enum_find(gf100_fifo_fault_gpcclient, client); 315 snprintf(gpcid, sizeof(gpcid), "GPC%d/", gpc); 316 } 317 318 if (eu) { 319 switch (eu->data2) { 320 case NVKM_SUBDEV_BAR: 321 nvkm_mask(device, 0x001704, 0x00000000, 0x00000000); 322 break; 323 case NVKM_SUBDEV_INSTMEM: 324 nvkm_mask(device, 0x001714, 0x00000000, 0x00000000); 325 break; 326 case NVKM_ENGINE_IFB: 327 nvkm_mask(device, 0x001718, 0x00000000, 0x00000000); 328 break; 329 default: 330 engine = nvkm_device_engine(device, eu->data2); 331 break; 332 } 333 } 334 335 chan = nvkm_fifo_chan_inst(&fifo->base, (u64)inst << 12, &flags); 336 337 nvkm_error(subdev, 338 "%s fault at %010llx engine %02x [%s] client %02x [%s%s] " 339 "reason %02x [%s] on channel %d [%010llx %s]\n", 340 write ? "write" : "read", (u64)vahi << 32 | valo, 341 unit, eu ? eu->name : "", client, gpcid, ec ? ec->name : "", 342 reason, er ? er->name : "", chan ? chan->chid : -1, 343 (u64)inst << 12, 344 chan ? chan->object.client->name : "unknown"); 345 346 if (engine && chan) 347 gf100_fifo_recover(fifo, engine, (void *)chan); 348 nvkm_fifo_chan_put(&fifo->base, flags, &chan); 349 } 350 351 static const struct nvkm_bitfield 352 gf100_fifo_pbdma_intr[] = { 353 /* { 0x00008000, "" } seen with null ib push */ 354 { 0x00200000, "ILLEGAL_MTHD" }, 355 { 0x00800000, "EMPTY_SUBC" }, 356 {} 357 }; 358 359 static void 360 gf100_fifo_intr_pbdma(struct gf100_fifo *fifo, int unit) 361 { 362 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 363 struct nvkm_device *device = subdev->device; 364 u32 stat = nvkm_rd32(device, 0x040108 + (unit * 0x2000)); 365 u32 addr = nvkm_rd32(device, 0x0400c0 + (unit * 0x2000)); 366 u32 data = nvkm_rd32(device, 0x0400c4 + (unit * 0x2000)); 367 u32 chid = nvkm_rd32(device, 0x040120 + (unit * 0x2000)) & 0x7f; 368 u32 subc = (addr & 0x00070000) >> 16; 369 u32 mthd = (addr & 0x00003ffc); 370 struct nvkm_fifo_chan *chan; 371 unsigned long flags; 372 u32 show= stat; 373 char msg[128]; 374 375 if (stat & 0x00800000) { 376 if (device->sw) { 377 if (nvkm_sw_mthd(device->sw, chid, subc, mthd, data)) 378 show &= ~0x00800000; 379 } 380 } 381 382 if (show) { 383 nvkm_snprintbf(msg, sizeof(msg), gf100_fifo_pbdma_intr, show); 384 chan = nvkm_fifo_chan_chid(&fifo->base, chid, &flags); 385 nvkm_error(subdev, "PBDMA%d: %08x [%s] ch %d [%010llx %s] " 386 "subc %d mthd %04x data %08x\n", 387 unit, show, msg, chid, chan ? chan->inst->addr : 0, 388 chan ? chan->object.client->name : "unknown", 389 subc, mthd, data); 390 nvkm_fifo_chan_put(&fifo->base, flags, &chan); 391 } 392 393 nvkm_wr32(device, 0x0400c0 + (unit * 0x2000), 0x80600008); 394 nvkm_wr32(device, 0x040108 + (unit * 0x2000), stat); 395 } 396 397 static void 398 gf100_fifo_intr_runlist(struct gf100_fifo *fifo) 399 { 400 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 401 struct nvkm_device *device = subdev->device; 402 u32 intr = nvkm_rd32(device, 0x002a00); 403 404 if (intr & 0x10000000) { 405 wake_up(&fifo->runlist.wait); 406 nvkm_wr32(device, 0x002a00, 0x10000000); 407 intr &= ~0x10000000; 408 } 409 410 if (intr) { 411 nvkm_error(subdev, "RUNLIST %08x\n", intr); 412 nvkm_wr32(device, 0x002a00, intr); 413 } 414 } 415 416 static void 417 gf100_fifo_intr_engine_unit(struct gf100_fifo *fifo, int engn) 418 { 419 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 420 struct nvkm_device *device = subdev->device; 421 u32 intr = nvkm_rd32(device, 0x0025a8 + (engn * 0x04)); 422 u32 inte = nvkm_rd32(device, 0x002628); 423 u32 unkn; 424 425 nvkm_wr32(device, 0x0025a8 + (engn * 0x04), intr); 426 427 for (unkn = 0; unkn < 8; unkn++) { 428 u32 ints = (intr >> (unkn * 0x04)) & inte; 429 if (ints & 0x1) { 430 nvkm_fifo_uevent(&fifo->base); 431 ints &= ~1; 432 } 433 if (ints) { 434 nvkm_error(subdev, "ENGINE %d %d %01x", 435 engn, unkn, ints); 436 nvkm_mask(device, 0x002628, ints, 0); 437 } 438 } 439 } 440 441 void 442 gf100_fifo_intr_engine(struct gf100_fifo *fifo) 443 { 444 struct nvkm_device *device = fifo->base.engine.subdev.device; 445 u32 mask = nvkm_rd32(device, 0x0025a4); 446 while (mask) { 447 u32 unit = __ffs(mask); 448 gf100_fifo_intr_engine_unit(fifo, unit); 449 mask &= ~(1 << unit); 450 } 451 } 452 453 static void 454 gf100_fifo_intr(struct nvkm_fifo *base) 455 { 456 struct gf100_fifo *fifo = gf100_fifo(base); 457 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 458 struct nvkm_device *device = subdev->device; 459 u32 mask = nvkm_rd32(device, 0x002140); 460 u32 stat = nvkm_rd32(device, 0x002100) & mask; 461 462 if (stat & 0x00000001) { 463 u32 intr = nvkm_rd32(device, 0x00252c); 464 nvkm_warn(subdev, "INTR 00000001: %08x\n", intr); 465 nvkm_wr32(device, 0x002100, 0x00000001); 466 stat &= ~0x00000001; 467 } 468 469 if (stat & 0x00000100) { 470 gf100_fifo_intr_sched(fifo); 471 nvkm_wr32(device, 0x002100, 0x00000100); 472 stat &= ~0x00000100; 473 } 474 475 if (stat & 0x00010000) { 476 u32 intr = nvkm_rd32(device, 0x00256c); 477 nvkm_warn(subdev, "INTR 00010000: %08x\n", intr); 478 nvkm_wr32(device, 0x002100, 0x00010000); 479 stat &= ~0x00010000; 480 } 481 482 if (stat & 0x01000000) { 483 u32 intr = nvkm_rd32(device, 0x00258c); 484 nvkm_warn(subdev, "INTR 01000000: %08x\n", intr); 485 nvkm_wr32(device, 0x002100, 0x01000000); 486 stat &= ~0x01000000; 487 } 488 489 if (stat & 0x10000000) { 490 u32 mask = nvkm_rd32(device, 0x00259c); 491 while (mask) { 492 u32 unit = __ffs(mask); 493 gf100_fifo_intr_fault(fifo, unit); 494 nvkm_wr32(device, 0x00259c, (1 << unit)); 495 mask &= ~(1 << unit); 496 } 497 stat &= ~0x10000000; 498 } 499 500 if (stat & 0x20000000) { 501 u32 mask = nvkm_rd32(device, 0x0025a0); 502 while (mask) { 503 u32 unit = __ffs(mask); 504 gf100_fifo_intr_pbdma(fifo, unit); 505 nvkm_wr32(device, 0x0025a0, (1 << unit)); 506 mask &= ~(1 << unit); 507 } 508 stat &= ~0x20000000; 509 } 510 511 if (stat & 0x40000000) { 512 gf100_fifo_intr_runlist(fifo); 513 stat &= ~0x40000000; 514 } 515 516 if (stat & 0x80000000) { 517 gf100_fifo_intr_engine(fifo); 518 stat &= ~0x80000000; 519 } 520 521 if (stat) { 522 nvkm_error(subdev, "INTR %08x\n", stat); 523 nvkm_mask(device, 0x002140, stat, 0x00000000); 524 nvkm_wr32(device, 0x002100, stat); 525 } 526 } 527 528 static int 529 gf100_fifo_oneinit(struct nvkm_fifo *base) 530 { 531 struct gf100_fifo *fifo = gf100_fifo(base); 532 struct nvkm_device *device = fifo->base.engine.subdev.device; 533 int ret; 534 535 ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, 536 false, &fifo->runlist.mem[0]); 537 if (ret) 538 return ret; 539 540 ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 0x1000, 0x1000, 541 false, &fifo->runlist.mem[1]); 542 if (ret) 543 return ret; 544 545 init_waitqueue_head(&fifo->runlist.wait); 546 547 ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST, 128 * 0x1000, 548 0x1000, false, &fifo->user.mem); 549 if (ret) 550 return ret; 551 552 ret = nvkm_bar_umap(device->bar, 128 * 0x1000, 12, &fifo->user.bar); 553 if (ret) 554 return ret; 555 556 nvkm_memory_map(fifo->user.mem, &fifo->user.bar, 0); 557 return 0; 558 } 559 560 static void 561 gf100_fifo_fini(struct nvkm_fifo *base) 562 { 563 struct gf100_fifo *fifo = gf100_fifo(base); 564 flush_work(&fifo->fault); 565 } 566 567 static void 568 gf100_fifo_init(struct nvkm_fifo *base) 569 { 570 struct gf100_fifo *fifo = gf100_fifo(base); 571 struct nvkm_subdev *subdev = &fifo->base.engine.subdev; 572 struct nvkm_device *device = subdev->device; 573 int i; 574 575 nvkm_wr32(device, 0x000204, 0xffffffff); 576 nvkm_wr32(device, 0x002204, 0xffffffff); 577 578 fifo->spoon_nr = hweight32(nvkm_rd32(device, 0x002204)); 579 nvkm_debug(subdev, "%d PBDMA unit(s)\n", fifo->spoon_nr); 580 581 /* assign engines to PBDMAs */ 582 if (fifo->spoon_nr >= 3) { 583 nvkm_wr32(device, 0x002208, ~(1 << 0)); /* PGRAPH */ 584 nvkm_wr32(device, 0x00220c, ~(1 << 1)); /* PVP */ 585 nvkm_wr32(device, 0x002210, ~(1 << 1)); /* PMSPP */ 586 nvkm_wr32(device, 0x002214, ~(1 << 1)); /* PMSVLD */ 587 nvkm_wr32(device, 0x002218, ~(1 << 2)); /* PCE0 */ 588 nvkm_wr32(device, 0x00221c, ~(1 << 1)); /* PCE1 */ 589 } 590 591 /* PBDMA[n] */ 592 for (i = 0; i < fifo->spoon_nr; i++) { 593 nvkm_mask(device, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000); 594 nvkm_wr32(device, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */ 595 nvkm_wr32(device, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTREN */ 596 } 597 598 nvkm_mask(device, 0x002200, 0x00000001, 0x00000001); 599 nvkm_wr32(device, 0x002254, 0x10000000 | fifo->user.bar.offset >> 12); 600 601 nvkm_wr32(device, 0x002100, 0xffffffff); 602 nvkm_wr32(device, 0x002140, 0x7fffffff); 603 nvkm_wr32(device, 0x002628, 0x00000001); /* ENGINE_INTR_EN */ 604 } 605 606 static void * 607 gf100_fifo_dtor(struct nvkm_fifo *base) 608 { 609 struct gf100_fifo *fifo = gf100_fifo(base); 610 nvkm_vm_put(&fifo->user.bar); 611 nvkm_memory_del(&fifo->user.mem); 612 nvkm_memory_del(&fifo->runlist.mem[0]); 613 nvkm_memory_del(&fifo->runlist.mem[1]); 614 return fifo; 615 } 616 617 static const struct nvkm_fifo_func 618 gf100_fifo = { 619 .dtor = gf100_fifo_dtor, 620 .oneinit = gf100_fifo_oneinit, 621 .init = gf100_fifo_init, 622 .fini = gf100_fifo_fini, 623 .intr = gf100_fifo_intr, 624 .uevent_init = gf100_fifo_uevent_init, 625 .uevent_fini = gf100_fifo_uevent_fini, 626 .chan = { 627 &gf100_fifo_gpfifo_oclass, 628 NULL 629 }, 630 }; 631 632 int 633 gf100_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo) 634 { 635 struct gf100_fifo *fifo; 636 637 if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL))) 638 return -ENOMEM; 639 INIT_LIST_HEAD(&fifo->chan); 640 INIT_WORK(&fifo->fault, gf100_fifo_recover_work); 641 *pfifo = &fifo->base; 642 643 return nvkm_fifo_ctor(&gf100_fifo, device, index, 128, &fifo->base); 644 } 645