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 "gk104.h" 25 26#include <core/client.h> 27#include <core/engctx.h> 28#include <core/enum.h> 29#include <core/handle.h> 30#include <subdev/bar.h> 31#include <subdev/fb.h> 32#include <subdev/mmu.h> 33#include <subdev/timer.h> 34 35#include <nvif/class.h> 36#include <nvif/unpack.h> 37 38#define _(a,b) { (a), ((1ULL << (a)) | (b)) } 39static const struct { 40 u64 subdev; 41 u64 mask; 42} fifo_engine[] = { 43 _(NVDEV_ENGINE_GR , (1ULL << NVDEV_ENGINE_SW) | 44 (1ULL << NVDEV_ENGINE_CE2)), 45 _(NVDEV_ENGINE_MSPDEC , 0), 46 _(NVDEV_ENGINE_MSPPP , 0), 47 _(NVDEV_ENGINE_MSVLD , 0), 48 _(NVDEV_ENGINE_CE0 , 0), 49 _(NVDEV_ENGINE_CE1 , 0), 50 _(NVDEV_ENGINE_MSENC , 0), 51}; 52#undef _ 53#define FIFO_ENGINE_NR ARRAY_SIZE(fifo_engine) 54 55struct gk104_fifo_engn { 56 struct nvkm_gpuobj *runlist[2]; 57 int cur_runlist; 58 wait_queue_head_t wait; 59}; 60 61struct gk104_fifo_priv { 62 struct nvkm_fifo base; 63 64 struct work_struct fault; 65 u64 mask; 66 67 struct gk104_fifo_engn engine[FIFO_ENGINE_NR]; 68 struct { 69 struct nvkm_gpuobj *mem; 70 struct nvkm_vma bar; 71 } user; 72 int spoon_nr; 73}; 74 75struct gk104_fifo_base { 76 struct nvkm_fifo_base base; 77 struct nvkm_gpuobj *pgd; 78 struct nvkm_vm *vm; 79}; 80 81struct gk104_fifo_chan { 82 struct nvkm_fifo_chan base; 83 u32 engine; 84 enum { 85 STOPPED, 86 RUNNING, 87 KILLED 88 } state; 89}; 90 91/******************************************************************************* 92 * FIFO channel objects 93 ******************************************************************************/ 94 95static void 96gk104_fifo_runlist_update(struct gk104_fifo_priv *priv, u32 engine) 97{ 98 struct nvkm_bar *bar = nvkm_bar(priv); 99 struct gk104_fifo_engn *engn = &priv->engine[engine]; 100 struct nvkm_gpuobj *cur; 101 int i, p; 102 103 mutex_lock(&nv_subdev(priv)->mutex); 104 cur = engn->runlist[engn->cur_runlist]; 105 engn->cur_runlist = !engn->cur_runlist; 106 107 for (i = 0, p = 0; i < priv->base.max; i++) { 108 struct gk104_fifo_chan *chan = (void *)priv->base.channel[i]; 109 if (chan && chan->state == RUNNING && chan->engine == engine) { 110 nv_wo32(cur, p + 0, i); 111 nv_wo32(cur, p + 4, 0x00000000); 112 p += 8; 113 } 114 } 115 bar->flush(bar); 116 117 nv_wr32(priv, 0x002270, cur->addr >> 12); 118 nv_wr32(priv, 0x002274, (engine << 20) | (p >> 3)); 119 120 if (wait_event_timeout(engn->wait, !(nv_rd32(priv, 0x002284 + 121 (engine * 0x08)) & 0x00100000), 122 msecs_to_jiffies(2000)) == 0) 123 nv_error(priv, "runlist %d update timeout\n", engine); 124 mutex_unlock(&nv_subdev(priv)->mutex); 125} 126 127static int 128gk104_fifo_context_attach(struct nvkm_object *parent, 129 struct nvkm_object *object) 130{ 131 struct nvkm_bar *bar = nvkm_bar(parent); 132 struct gk104_fifo_base *base = (void *)parent->parent; 133 struct nvkm_engctx *ectx = (void *)object; 134 u32 addr; 135 int ret; 136 137 switch (nv_engidx(object->engine)) { 138 case NVDEV_ENGINE_SW : 139 return 0; 140 case NVDEV_ENGINE_CE0: 141 case NVDEV_ENGINE_CE1: 142 case NVDEV_ENGINE_CE2: 143 nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12; 144 return 0; 145 case NVDEV_ENGINE_GR : addr = 0x0210; break; 146 case NVDEV_ENGINE_MSVLD : addr = 0x0270; break; 147 case NVDEV_ENGINE_MSPDEC: addr = 0x0250; break; 148 case NVDEV_ENGINE_MSPPP : addr = 0x0260; break; 149 default: 150 return -EINVAL; 151 } 152 153 if (!ectx->vma.node) { 154 ret = nvkm_gpuobj_map_vm(nv_gpuobj(ectx), base->vm, 155 NV_MEM_ACCESS_RW, &ectx->vma); 156 if (ret) 157 return ret; 158 159 nv_engctx(ectx)->addr = nv_gpuobj(base)->addr >> 12; 160 } 161 162 nv_wo32(base, addr + 0x00, lower_32_bits(ectx->vma.offset) | 4); 163 nv_wo32(base, addr + 0x04, upper_32_bits(ectx->vma.offset)); 164 bar->flush(bar); 165 return 0; 166} 167 168static int 169gk104_fifo_context_detach(struct nvkm_object *parent, bool suspend, 170 struct nvkm_object *object) 171{ 172 struct nvkm_bar *bar = nvkm_bar(parent); 173 struct gk104_fifo_priv *priv = (void *)parent->engine; 174 struct gk104_fifo_base *base = (void *)parent->parent; 175 struct gk104_fifo_chan *chan = (void *)parent; 176 u32 addr; 177 178 switch (nv_engidx(object->engine)) { 179 case NVDEV_ENGINE_SW : return 0; 180 case NVDEV_ENGINE_CE0 : 181 case NVDEV_ENGINE_CE1 : 182 case NVDEV_ENGINE_CE2 : addr = 0x0000; break; 183 case NVDEV_ENGINE_GR : addr = 0x0210; break; 184 case NVDEV_ENGINE_MSVLD : addr = 0x0270; break; 185 case NVDEV_ENGINE_MSPDEC: addr = 0x0250; break; 186 case NVDEV_ENGINE_MSPPP : addr = 0x0260; break; 187 default: 188 return -EINVAL; 189 } 190 191 nv_wr32(priv, 0x002634, chan->base.chid); 192 if (!nv_wait(priv, 0x002634, 0xffffffff, chan->base.chid)) { 193 nv_error(priv, "channel %d [%s] kick timeout\n", 194 chan->base.chid, nvkm_client_name(chan)); 195 if (suspend) 196 return -EBUSY; 197 } 198 199 if (addr) { 200 nv_wo32(base, addr + 0x00, 0x00000000); 201 nv_wo32(base, addr + 0x04, 0x00000000); 202 bar->flush(bar); 203 } 204 205 return 0; 206} 207 208static int 209gk104_fifo_chan_ctor(struct nvkm_object *parent, struct nvkm_object *engine, 210 struct nvkm_oclass *oclass, void *data, u32 size, 211 struct nvkm_object **pobject) 212{ 213 union { 214 struct kepler_channel_gpfifo_a_v0 v0; 215 } *args = data; 216 struct nvkm_bar *bar = nvkm_bar(parent); 217 struct gk104_fifo_priv *priv = (void *)engine; 218 struct gk104_fifo_base *base = (void *)parent; 219 struct gk104_fifo_chan *chan; 220 u64 usermem, ioffset, ilength; 221 int ret, i; 222 223 nv_ioctl(parent, "create channel gpfifo size %d\n", size); 224 if (nvif_unpack(args->v0, 0, 0, false)) { 225 nv_ioctl(parent, "create channel gpfifo vers %d pushbuf %08x " 226 "ioffset %016llx ilength %08x engine %08x\n", 227 args->v0.version, args->v0.pushbuf, args->v0.ioffset, 228 args->v0.ilength, args->v0.engine); 229 } else 230 return ret; 231 232 for (i = 0; i < FIFO_ENGINE_NR; i++) { 233 if (args->v0.engine & (1 << i)) { 234 if (nvkm_engine(parent, fifo_engine[i].subdev)) { 235 args->v0.engine = (1 << i); 236 break; 237 } 238 } 239 } 240 241 if (i == FIFO_ENGINE_NR) { 242 nv_error(priv, "unsupported engines 0x%08x\n", args->v0.engine); 243 return -ENODEV; 244 } 245 246 ret = nvkm_fifo_channel_create(parent, engine, oclass, 1, 247 priv->user.bar.offset, 0x200, 248 args->v0.pushbuf, 249 fifo_engine[i].mask, &chan); 250 *pobject = nv_object(chan); 251 if (ret) 252 return ret; 253 254 args->v0.chid = chan->base.chid; 255 256 nv_parent(chan)->context_attach = gk104_fifo_context_attach; 257 nv_parent(chan)->context_detach = gk104_fifo_context_detach; 258 chan->engine = i; 259 260 usermem = chan->base.chid * 0x200; 261 ioffset = args->v0.ioffset; 262 ilength = order_base_2(args->v0.ilength / 8); 263 264 for (i = 0; i < 0x200; i += 4) 265 nv_wo32(priv->user.mem, usermem + i, 0x00000000); 266 267 nv_wo32(base, 0x08, lower_32_bits(priv->user.mem->addr + usermem)); 268 nv_wo32(base, 0x0c, upper_32_bits(priv->user.mem->addr + usermem)); 269 nv_wo32(base, 0x10, 0x0000face); 270 nv_wo32(base, 0x30, 0xfffff902); 271 nv_wo32(base, 0x48, lower_32_bits(ioffset)); 272 nv_wo32(base, 0x4c, upper_32_bits(ioffset) | (ilength << 16)); 273 nv_wo32(base, 0x84, 0x20400000); 274 nv_wo32(base, 0x94, 0x30000001); 275 nv_wo32(base, 0x9c, 0x00000100); 276 nv_wo32(base, 0xac, 0x0000001f); 277 nv_wo32(base, 0xe8, chan->base.chid); 278 nv_wo32(base, 0xb8, 0xf8000000); 279 nv_wo32(base, 0xf8, 0x10003080); /* 0x002310 */ 280 nv_wo32(base, 0xfc, 0x10000010); /* 0x002350 */ 281 bar->flush(bar); 282 return 0; 283} 284 285static int 286gk104_fifo_chan_init(struct nvkm_object *object) 287{ 288 struct nvkm_gpuobj *base = nv_gpuobj(object->parent); 289 struct gk104_fifo_priv *priv = (void *)object->engine; 290 struct gk104_fifo_chan *chan = (void *)object; 291 u32 chid = chan->base.chid; 292 int ret; 293 294 ret = nvkm_fifo_channel_init(&chan->base); 295 if (ret) 296 return ret; 297 298 nv_mask(priv, 0x800004 + (chid * 8), 0x000f0000, chan->engine << 16); 299 nv_wr32(priv, 0x800000 + (chid * 8), 0x80000000 | base->addr >> 12); 300 301 if (chan->state == STOPPED && (chan->state = RUNNING) == RUNNING) { 302 nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400); 303 gk104_fifo_runlist_update(priv, chan->engine); 304 nv_mask(priv, 0x800004 + (chid * 8), 0x00000400, 0x00000400); 305 } 306 307 return 0; 308} 309 310static int 311gk104_fifo_chan_fini(struct nvkm_object *object, bool suspend) 312{ 313 struct gk104_fifo_priv *priv = (void *)object->engine; 314 struct gk104_fifo_chan *chan = (void *)object; 315 u32 chid = chan->base.chid; 316 317 if (chan->state == RUNNING && (chan->state = STOPPED) == STOPPED) { 318 nv_mask(priv, 0x800004 + (chid * 8), 0x00000800, 0x00000800); 319 gk104_fifo_runlist_update(priv, chan->engine); 320 } 321 322 nv_wr32(priv, 0x800000 + (chid * 8), 0x00000000); 323 return nvkm_fifo_channel_fini(&chan->base, suspend); 324} 325 326struct nvkm_ofuncs 327gk104_fifo_chan_ofuncs = { 328 .ctor = gk104_fifo_chan_ctor, 329 .dtor = _nvkm_fifo_channel_dtor, 330 .init = gk104_fifo_chan_init, 331 .fini = gk104_fifo_chan_fini, 332 .map = _nvkm_fifo_channel_map, 333 .rd32 = _nvkm_fifo_channel_rd32, 334 .wr32 = _nvkm_fifo_channel_wr32, 335 .ntfy = _nvkm_fifo_channel_ntfy 336}; 337 338static struct nvkm_oclass 339gk104_fifo_sclass[] = { 340 { KEPLER_CHANNEL_GPFIFO_A, &gk104_fifo_chan_ofuncs }, 341 {} 342}; 343 344/******************************************************************************* 345 * FIFO context - instmem heap and vm setup 346 ******************************************************************************/ 347 348static int 349gk104_fifo_context_ctor(struct nvkm_object *parent, struct nvkm_object *engine, 350 struct nvkm_oclass *oclass, void *data, u32 size, 351 struct nvkm_object **pobject) 352{ 353 struct gk104_fifo_base *base; 354 int ret; 355 356 ret = nvkm_fifo_context_create(parent, engine, oclass, NULL, 0x1000, 357 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &base); 358 *pobject = nv_object(base); 359 if (ret) 360 return ret; 361 362 ret = nvkm_gpuobj_new(nv_object(base), NULL, 0x10000, 0x1000, 0, 363 &base->pgd); 364 if (ret) 365 return ret; 366 367 nv_wo32(base, 0x0200, lower_32_bits(base->pgd->addr)); 368 nv_wo32(base, 0x0204, upper_32_bits(base->pgd->addr)); 369 nv_wo32(base, 0x0208, 0xffffffff); 370 nv_wo32(base, 0x020c, 0x000000ff); 371 372 ret = nvkm_vm_ref(nvkm_client(parent)->vm, &base->vm, base->pgd); 373 if (ret) 374 return ret; 375 376 return 0; 377} 378 379static void 380gk104_fifo_context_dtor(struct nvkm_object *object) 381{ 382 struct gk104_fifo_base *base = (void *)object; 383 nvkm_vm_ref(NULL, &base->vm, base->pgd); 384 nvkm_gpuobj_ref(NULL, &base->pgd); 385 nvkm_fifo_context_destroy(&base->base); 386} 387 388static struct nvkm_oclass 389gk104_fifo_cclass = { 390 .handle = NV_ENGCTX(FIFO, 0xe0), 391 .ofuncs = &(struct nvkm_ofuncs) { 392 .ctor = gk104_fifo_context_ctor, 393 .dtor = gk104_fifo_context_dtor, 394 .init = _nvkm_fifo_context_init, 395 .fini = _nvkm_fifo_context_fini, 396 .rd32 = _nvkm_fifo_context_rd32, 397 .wr32 = _nvkm_fifo_context_wr32, 398 }, 399}; 400 401/******************************************************************************* 402 * PFIFO engine 403 ******************************************************************************/ 404 405static inline int 406gk104_fifo_engidx(struct gk104_fifo_priv *priv, u32 engn) 407{ 408 switch (engn) { 409 case NVDEV_ENGINE_GR : 410 case NVDEV_ENGINE_CE2 : engn = 0; break; 411 case NVDEV_ENGINE_MSVLD : engn = 1; break; 412 case NVDEV_ENGINE_MSPPP : engn = 2; break; 413 case NVDEV_ENGINE_MSPDEC: engn = 3; break; 414 case NVDEV_ENGINE_CE0 : engn = 4; break; 415 case NVDEV_ENGINE_CE1 : engn = 5; break; 416 case NVDEV_ENGINE_MSENC : engn = 6; break; 417 default: 418 return -1; 419 } 420 421 return engn; 422} 423 424static inline struct nvkm_engine * 425gk104_fifo_engine(struct gk104_fifo_priv *priv, u32 engn) 426{ 427 if (engn >= ARRAY_SIZE(fifo_engine)) 428 return NULL; 429 return nvkm_engine(priv, fifo_engine[engn].subdev); 430} 431 432static void 433gk104_fifo_recover_work(struct work_struct *work) 434{ 435 struct gk104_fifo_priv *priv = container_of(work, typeof(*priv), fault); 436 struct nvkm_object *engine; 437 unsigned long flags; 438 u32 engn, engm = 0; 439 u64 mask, todo; 440 441 spin_lock_irqsave(&priv->base.lock, flags); 442 mask = priv->mask; 443 priv->mask = 0ULL; 444 spin_unlock_irqrestore(&priv->base.lock, flags); 445 446 for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) 447 engm |= 1 << gk104_fifo_engidx(priv, engn); 448 nv_mask(priv, 0x002630, engm, engm); 449 450 for (todo = mask; engn = __ffs64(todo), todo; todo &= ~(1 << engn)) { 451 if ((engine = (void *)nvkm_engine(priv, engn))) { 452 nv_ofuncs(engine)->fini(engine, false); 453 WARN_ON(nv_ofuncs(engine)->init(engine)); 454 } 455 gk104_fifo_runlist_update(priv, gk104_fifo_engidx(priv, engn)); 456 } 457 458 nv_wr32(priv, 0x00262c, engm); 459 nv_mask(priv, 0x002630, engm, 0x00000000); 460} 461 462static void 463gk104_fifo_recover(struct gk104_fifo_priv *priv, struct nvkm_engine *engine, 464 struct gk104_fifo_chan *chan) 465{ 466 u32 chid = chan->base.chid; 467 unsigned long flags; 468 469 nv_error(priv, "%s engine fault on channel %d, recovering...\n", 470 nv_subdev(engine)->name, chid); 471 472 nv_mask(priv, 0x800004 + (chid * 0x08), 0x00000800, 0x00000800); 473 chan->state = KILLED; 474 475 spin_lock_irqsave(&priv->base.lock, flags); 476 priv->mask |= 1ULL << nv_engidx(engine); 477 spin_unlock_irqrestore(&priv->base.lock, flags); 478 schedule_work(&priv->fault); 479} 480 481static int 482gk104_fifo_swmthd(struct gk104_fifo_priv *priv, u32 chid, u32 mthd, u32 data) 483{ 484 struct gk104_fifo_chan *chan = NULL; 485 struct nvkm_handle *bind; 486 unsigned long flags; 487 int ret = -EINVAL; 488 489 spin_lock_irqsave(&priv->base.lock, flags); 490 if (likely(chid >= priv->base.min && chid <= priv->base.max)) 491 chan = (void *)priv->base.channel[chid]; 492 if (unlikely(!chan)) 493 goto out; 494 495 bind = nvkm_namedb_get_class(nv_namedb(chan), 0x906e); 496 if (likely(bind)) { 497 if (!mthd || !nv_call(bind->object, mthd, data)) 498 ret = 0; 499 nvkm_namedb_put(bind); 500 } 501 502out: 503 spin_unlock_irqrestore(&priv->base.lock, flags); 504 return ret; 505} 506 507static const struct nvkm_enum 508gk104_fifo_bind_reason[] = { 509 { 0x01, "BIND_NOT_UNBOUND" }, 510 { 0x02, "SNOOP_WITHOUT_BAR1" }, 511 { 0x03, "UNBIND_WHILE_RUNNING" }, 512 { 0x05, "INVALID_RUNLIST" }, 513 { 0x06, "INVALID_CTX_TGT" }, 514 { 0x0b, "UNBIND_WHILE_PARKED" }, 515 {} 516}; 517 518static void 519gk104_fifo_intr_bind(struct gk104_fifo_priv *priv) 520{ 521 u32 intr = nv_rd32(priv, 0x00252c); 522 u32 code = intr & 0x000000ff; 523 const struct nvkm_enum *en; 524 char enunk[6] = ""; 525 526 en = nvkm_enum_find(gk104_fifo_bind_reason, code); 527 if (!en) 528 snprintf(enunk, sizeof(enunk), "UNK%02x", code); 529 530 nv_error(priv, "BIND_ERROR [ %s ]\n", en ? en->name : enunk); 531} 532 533static const struct nvkm_enum 534gk104_fifo_sched_reason[] = { 535 { 0x0a, "CTXSW_TIMEOUT" }, 536 {} 537}; 538 539static void 540gk104_fifo_intr_sched_ctxsw(struct gk104_fifo_priv *priv) 541{ 542 struct nvkm_engine *engine; 543 struct gk104_fifo_chan *chan; 544 u32 engn; 545 546 for (engn = 0; engn < ARRAY_SIZE(fifo_engine); engn++) { 547 u32 stat = nv_rd32(priv, 0x002640 + (engn * 0x04)); 548 u32 busy = (stat & 0x80000000); 549 u32 next = (stat & 0x07ff0000) >> 16; 550 u32 chsw = (stat & 0x00008000); 551 u32 save = (stat & 0x00004000); 552 u32 load = (stat & 0x00002000); 553 u32 prev = (stat & 0x000007ff); 554 u32 chid = load ? next : prev; 555 (void)save; 556 557 if (busy && chsw) { 558 if (!(chan = (void *)priv->base.channel[chid])) 559 continue; 560 if (!(engine = gk104_fifo_engine(priv, engn))) 561 continue; 562 gk104_fifo_recover(priv, engine, chan); 563 } 564 } 565} 566 567static void 568gk104_fifo_intr_sched(struct gk104_fifo_priv *priv) 569{ 570 u32 intr = nv_rd32(priv, 0x00254c); 571 u32 code = intr & 0x000000ff; 572 const struct nvkm_enum *en; 573 char enunk[6] = ""; 574 575 en = nvkm_enum_find(gk104_fifo_sched_reason, code); 576 if (!en) 577 snprintf(enunk, sizeof(enunk), "UNK%02x", code); 578 579 nv_error(priv, "SCHED_ERROR [ %s ]\n", en ? en->name : enunk); 580 581 switch (code) { 582 case 0x0a: 583 gk104_fifo_intr_sched_ctxsw(priv); 584 break; 585 default: 586 break; 587 } 588} 589 590static void 591gk104_fifo_intr_chsw(struct gk104_fifo_priv *priv) 592{ 593 u32 stat = nv_rd32(priv, 0x00256c); 594 nv_error(priv, "CHSW_ERROR 0x%08x\n", stat); 595 nv_wr32(priv, 0x00256c, stat); 596} 597 598static void 599gk104_fifo_intr_dropped_fault(struct gk104_fifo_priv *priv) 600{ 601 u32 stat = nv_rd32(priv, 0x00259c); 602 nv_error(priv, "DROPPED_MMU_FAULT 0x%08x\n", stat); 603} 604 605static const struct nvkm_enum 606gk104_fifo_fault_engine[] = { 607 { 0x00, "GR", NULL, NVDEV_ENGINE_GR }, 608 { 0x03, "IFB", NULL, NVDEV_ENGINE_IFB }, 609 { 0x04, "BAR1", NULL, NVDEV_SUBDEV_BAR }, 610 { 0x05, "BAR3", NULL, NVDEV_SUBDEV_INSTMEM }, 611 { 0x07, "PBDMA0", NULL, NVDEV_ENGINE_FIFO }, 612 { 0x08, "PBDMA1", NULL, NVDEV_ENGINE_FIFO }, 613 { 0x09, "PBDMA2", NULL, NVDEV_ENGINE_FIFO }, 614 { 0x10, "MSVLD", NULL, NVDEV_ENGINE_MSVLD }, 615 { 0x11, "MSPPP", NULL, NVDEV_ENGINE_MSPPP }, 616 { 0x13, "PERF" }, 617 { 0x14, "MSPDEC", NULL, NVDEV_ENGINE_MSPDEC }, 618 { 0x15, "CE0", NULL, NVDEV_ENGINE_CE0 }, 619 { 0x16, "CE1", NULL, NVDEV_ENGINE_CE1 }, 620 { 0x17, "PMU" }, 621 { 0x19, "MSENC", NULL, NVDEV_ENGINE_MSENC }, 622 { 0x1b, "CE2", NULL, NVDEV_ENGINE_CE2 }, 623 {} 624}; 625 626static const struct nvkm_enum 627gk104_fifo_fault_reason[] = { 628 { 0x00, "PDE" }, 629 { 0x01, "PDE_SIZE" }, 630 { 0x02, "PTE" }, 631 { 0x03, "VA_LIMIT_VIOLATION" }, 632 { 0x04, "UNBOUND_INST_BLOCK" }, 633 { 0x05, "PRIV_VIOLATION" }, 634 { 0x06, "RO_VIOLATION" }, 635 { 0x07, "WO_VIOLATION" }, 636 { 0x08, "PITCH_MASK_VIOLATION" }, 637 { 0x09, "WORK_CREATION" }, 638 { 0x0a, "UNSUPPORTED_APERTURE" }, 639 { 0x0b, "COMPRESSION_FAILURE" }, 640 { 0x0c, "UNSUPPORTED_KIND" }, 641 { 0x0d, "REGION_VIOLATION" }, 642 { 0x0e, "BOTH_PTES_VALID" }, 643 { 0x0f, "INFO_TYPE_POISONED" }, 644 {} 645}; 646 647static const struct nvkm_enum 648gk104_fifo_fault_hubclient[] = { 649 { 0x00, "VIP" }, 650 { 0x01, "CE0" }, 651 { 0x02, "CE1" }, 652 { 0x03, "DNISO" }, 653 { 0x04, "FE" }, 654 { 0x05, "FECS" }, 655 { 0x06, "HOST" }, 656 { 0x07, "HOST_CPU" }, 657 { 0x08, "HOST_CPU_NB" }, 658 { 0x09, "ISO" }, 659 { 0x0a, "MMU" }, 660 { 0x0b, "MSPDEC" }, 661 { 0x0c, "MSPPP" }, 662 { 0x0d, "MSVLD" }, 663 { 0x0e, "NISO" }, 664 { 0x0f, "P2P" }, 665 { 0x10, "PD" }, 666 { 0x11, "PERF" }, 667 { 0x12, "PMU" }, 668 { 0x13, "RASTERTWOD" }, 669 { 0x14, "SCC" }, 670 { 0x15, "SCC_NB" }, 671 { 0x16, "SEC" }, 672 { 0x17, "SSYNC" }, 673 { 0x18, "GR_CE" }, 674 { 0x19, "CE2" }, 675 { 0x1a, "XV" }, 676 { 0x1b, "MMU_NB" }, 677 { 0x1c, "MSENC" }, 678 { 0x1d, "DFALCON" }, 679 { 0x1e, "SKED" }, 680 { 0x1f, "AFALCON" }, 681 {} 682}; 683 684static const struct nvkm_enum 685gk104_fifo_fault_gpcclient[] = { 686 { 0x00, "L1_0" }, { 0x01, "T1_0" }, { 0x02, "PE_0" }, 687 { 0x03, "L1_1" }, { 0x04, "T1_1" }, { 0x05, "PE_1" }, 688 { 0x06, "L1_2" }, { 0x07, "T1_2" }, { 0x08, "PE_2" }, 689 { 0x09, "L1_3" }, { 0x0a, "T1_3" }, { 0x0b, "PE_3" }, 690 { 0x0c, "RAST" }, 691 { 0x0d, "GCC" }, 692 { 0x0e, "GPCCS" }, 693 { 0x0f, "PROP_0" }, 694 { 0x10, "PROP_1" }, 695 { 0x11, "PROP_2" }, 696 { 0x12, "PROP_3" }, 697 { 0x13, "L1_4" }, { 0x14, "T1_4" }, { 0x15, "PE_4" }, 698 { 0x16, "L1_5" }, { 0x17, "T1_5" }, { 0x18, "PE_5" }, 699 { 0x19, "L1_6" }, { 0x1a, "T1_6" }, { 0x1b, "PE_6" }, 700 { 0x1c, "L1_7" }, { 0x1d, "T1_7" }, { 0x1e, "PE_7" }, 701 { 0x1f, "GPM" }, 702 { 0x20, "LTP_UTLB_0" }, 703 { 0x21, "LTP_UTLB_1" }, 704 { 0x22, "LTP_UTLB_2" }, 705 { 0x23, "LTP_UTLB_3" }, 706 { 0x24, "GPC_RGG_UTLB" }, 707 {} 708}; 709 710static void 711gk104_fifo_intr_fault(struct gk104_fifo_priv *priv, int unit) 712{ 713 u32 inst = nv_rd32(priv, 0x002800 + (unit * 0x10)); 714 u32 valo = nv_rd32(priv, 0x002804 + (unit * 0x10)); 715 u32 vahi = nv_rd32(priv, 0x002808 + (unit * 0x10)); 716 u32 stat = nv_rd32(priv, 0x00280c + (unit * 0x10)); 717 u32 gpc = (stat & 0x1f000000) >> 24; 718 u32 client = (stat & 0x00001f00) >> 8; 719 u32 write = (stat & 0x00000080); 720 u32 hub = (stat & 0x00000040); 721 u32 reason = (stat & 0x0000000f); 722 struct nvkm_object *engctx = NULL, *object; 723 struct nvkm_engine *engine = NULL; 724 const struct nvkm_enum *er, *eu, *ec; 725 char erunk[6] = ""; 726 char euunk[6] = ""; 727 char ecunk[6] = ""; 728 char gpcid[3] = ""; 729 730 er = nvkm_enum_find(gk104_fifo_fault_reason, reason); 731 if (!er) 732 snprintf(erunk, sizeof(erunk), "UNK%02X", reason); 733 734 eu = nvkm_enum_find(gk104_fifo_fault_engine, unit); 735 if (eu) { 736 switch (eu->data2) { 737 case NVDEV_SUBDEV_BAR: 738 nv_mask(priv, 0x001704, 0x00000000, 0x00000000); 739 break; 740 case NVDEV_SUBDEV_INSTMEM: 741 nv_mask(priv, 0x001714, 0x00000000, 0x00000000); 742 break; 743 case NVDEV_ENGINE_IFB: 744 nv_mask(priv, 0x001718, 0x00000000, 0x00000000); 745 break; 746 default: 747 engine = nvkm_engine(priv, eu->data2); 748 if (engine) 749 engctx = nvkm_engctx_get(engine, inst); 750 break; 751 } 752 } else { 753 snprintf(euunk, sizeof(euunk), "UNK%02x", unit); 754 } 755 756 if (hub) { 757 ec = nvkm_enum_find(gk104_fifo_fault_hubclient, client); 758 } else { 759 ec = nvkm_enum_find(gk104_fifo_fault_gpcclient, client); 760 snprintf(gpcid, sizeof(gpcid), "%d", gpc); 761 } 762 763 if (!ec) 764 snprintf(ecunk, sizeof(ecunk), "UNK%02x", client); 765 766 nv_error(priv, "%s fault at 0x%010llx [%s] from %s/%s%s%s%s on " 767 "channel 0x%010llx [%s]\n", write ? "write" : "read", 768 (u64)vahi << 32 | valo, er ? er->name : erunk, 769 eu ? eu->name : euunk, hub ? "" : "GPC", gpcid, hub ? "" : "/", 770 ec ? ec->name : ecunk, (u64)inst << 12, 771 nvkm_client_name(engctx)); 772 773 object = engctx; 774 while (object) { 775 switch (nv_mclass(object)) { 776 case KEPLER_CHANNEL_GPFIFO_A: 777 case MAXWELL_CHANNEL_GPFIFO_A: 778 gk104_fifo_recover(priv, engine, (void *)object); 779 break; 780 } 781 object = object->parent; 782 } 783 784 nvkm_engctx_put(engctx); 785} 786 787static const struct nvkm_bitfield gk104_fifo_pbdma_intr_0[] = { 788 { 0x00000001, "MEMREQ" }, 789 { 0x00000002, "MEMACK_TIMEOUT" }, 790 { 0x00000004, "MEMACK_EXTRA" }, 791 { 0x00000008, "MEMDAT_TIMEOUT" }, 792 { 0x00000010, "MEMDAT_EXTRA" }, 793 { 0x00000020, "MEMFLUSH" }, 794 { 0x00000040, "MEMOP" }, 795 { 0x00000080, "LBCONNECT" }, 796 { 0x00000100, "LBREQ" }, 797 { 0x00000200, "LBACK_TIMEOUT" }, 798 { 0x00000400, "LBACK_EXTRA" }, 799 { 0x00000800, "LBDAT_TIMEOUT" }, 800 { 0x00001000, "LBDAT_EXTRA" }, 801 { 0x00002000, "GPFIFO" }, 802 { 0x00004000, "GPPTR" }, 803 { 0x00008000, "GPENTRY" }, 804 { 0x00010000, "GPCRC" }, 805 { 0x00020000, "PBPTR" }, 806 { 0x00040000, "PBENTRY" }, 807 { 0x00080000, "PBCRC" }, 808 { 0x00100000, "XBARCONNECT" }, 809 { 0x00200000, "METHOD" }, 810 { 0x00400000, "METHODCRC" }, 811 { 0x00800000, "DEVICE" }, 812 { 0x02000000, "SEMAPHORE" }, 813 { 0x04000000, "ACQUIRE" }, 814 { 0x08000000, "PRI" }, 815 { 0x20000000, "NO_CTXSW_SEG" }, 816 { 0x40000000, "PBSEG" }, 817 { 0x80000000, "SIGNATURE" }, 818 {} 819}; 820 821static void 822gk104_fifo_intr_pbdma_0(struct gk104_fifo_priv *priv, int unit) 823{ 824 u32 mask = nv_rd32(priv, 0x04010c + (unit * 0x2000)); 825 u32 stat = nv_rd32(priv, 0x040108 + (unit * 0x2000)) & mask; 826 u32 addr = nv_rd32(priv, 0x0400c0 + (unit * 0x2000)); 827 u32 data = nv_rd32(priv, 0x0400c4 + (unit * 0x2000)); 828 u32 chid = nv_rd32(priv, 0x040120 + (unit * 0x2000)) & 0xfff; 829 u32 subc = (addr & 0x00070000) >> 16; 830 u32 mthd = (addr & 0x00003ffc); 831 u32 show = stat; 832 833 if (stat & 0x00800000) { 834 if (!gk104_fifo_swmthd(priv, chid, mthd, data)) 835 show &= ~0x00800000; 836 nv_wr32(priv, 0x0400c0 + (unit * 0x2000), 0x80600008); 837 } 838 839 if (show) { 840 nv_error(priv, "PBDMA%d:", unit); 841 nvkm_bitfield_print(gk104_fifo_pbdma_intr_0, show); 842 pr_cont("\n"); 843 nv_error(priv, 844 "PBDMA%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n", 845 unit, chid, 846 nvkm_client_name_for_fifo_chid(&priv->base, chid), 847 subc, mthd, data); 848 } 849 850 nv_wr32(priv, 0x040108 + (unit * 0x2000), stat); 851} 852 853static const struct nvkm_bitfield gk104_fifo_pbdma_intr_1[] = { 854 { 0x00000001, "HCE_RE_ILLEGAL_OP" }, 855 { 0x00000002, "HCE_RE_ALIGNB" }, 856 { 0x00000004, "HCE_PRIV" }, 857 { 0x00000008, "HCE_ILLEGAL_MTHD" }, 858 { 0x00000010, "HCE_ILLEGAL_CLASS" }, 859 {} 860}; 861 862static void 863gk104_fifo_intr_pbdma_1(struct gk104_fifo_priv *priv, int unit) 864{ 865 u32 mask = nv_rd32(priv, 0x04014c + (unit * 0x2000)); 866 u32 stat = nv_rd32(priv, 0x040148 + (unit * 0x2000)) & mask; 867 u32 chid = nv_rd32(priv, 0x040120 + (unit * 0x2000)) & 0xfff; 868 869 if (stat) { 870 nv_error(priv, "PBDMA%d:", unit); 871 nvkm_bitfield_print(gk104_fifo_pbdma_intr_1, stat); 872 pr_cont("\n"); 873 nv_error(priv, "PBDMA%d: ch %d %08x %08x\n", unit, chid, 874 nv_rd32(priv, 0x040150 + (unit * 0x2000)), 875 nv_rd32(priv, 0x040154 + (unit * 0x2000))); 876 } 877 878 nv_wr32(priv, 0x040148 + (unit * 0x2000), stat); 879} 880 881static void 882gk104_fifo_intr_runlist(struct gk104_fifo_priv *priv) 883{ 884 u32 mask = nv_rd32(priv, 0x002a00); 885 while (mask) { 886 u32 engn = __ffs(mask); 887 wake_up(&priv->engine[engn].wait); 888 nv_wr32(priv, 0x002a00, 1 << engn); 889 mask &= ~(1 << engn); 890 } 891} 892 893static void 894gk104_fifo_intr_engine(struct gk104_fifo_priv *priv) 895{ 896 nvkm_fifo_uevent(&priv->base); 897} 898 899static void 900gk104_fifo_intr(struct nvkm_subdev *subdev) 901{ 902 struct gk104_fifo_priv *priv = (void *)subdev; 903 u32 mask = nv_rd32(priv, 0x002140); 904 u32 stat = nv_rd32(priv, 0x002100) & mask; 905 906 if (stat & 0x00000001) { 907 gk104_fifo_intr_bind(priv); 908 nv_wr32(priv, 0x002100, 0x00000001); 909 stat &= ~0x00000001; 910 } 911 912 if (stat & 0x00000010) { 913 nv_error(priv, "PIO_ERROR\n"); 914 nv_wr32(priv, 0x002100, 0x00000010); 915 stat &= ~0x00000010; 916 } 917 918 if (stat & 0x00000100) { 919 gk104_fifo_intr_sched(priv); 920 nv_wr32(priv, 0x002100, 0x00000100); 921 stat &= ~0x00000100; 922 } 923 924 if (stat & 0x00010000) { 925 gk104_fifo_intr_chsw(priv); 926 nv_wr32(priv, 0x002100, 0x00010000); 927 stat &= ~0x00010000; 928 } 929 930 if (stat & 0x00800000) { 931 nv_error(priv, "FB_FLUSH_TIMEOUT\n"); 932 nv_wr32(priv, 0x002100, 0x00800000); 933 stat &= ~0x00800000; 934 } 935 936 if (stat & 0x01000000) { 937 nv_error(priv, "LB_ERROR\n"); 938 nv_wr32(priv, 0x002100, 0x01000000); 939 stat &= ~0x01000000; 940 } 941 942 if (stat & 0x08000000) { 943 gk104_fifo_intr_dropped_fault(priv); 944 nv_wr32(priv, 0x002100, 0x08000000); 945 stat &= ~0x08000000; 946 } 947 948 if (stat & 0x10000000) { 949 u32 mask = nv_rd32(priv, 0x00259c); 950 while (mask) { 951 u32 unit = __ffs(mask); 952 gk104_fifo_intr_fault(priv, unit); 953 nv_wr32(priv, 0x00259c, (1 << unit)); 954 mask &= ~(1 << unit); 955 } 956 stat &= ~0x10000000; 957 } 958 959 if (stat & 0x20000000) { 960 u32 mask = nv_rd32(priv, 0x0025a0); 961 while (mask) { 962 u32 unit = __ffs(mask); 963 gk104_fifo_intr_pbdma_0(priv, unit); 964 gk104_fifo_intr_pbdma_1(priv, unit); 965 nv_wr32(priv, 0x0025a0, (1 << unit)); 966 mask &= ~(1 << unit); 967 } 968 stat &= ~0x20000000; 969 } 970 971 if (stat & 0x40000000) { 972 gk104_fifo_intr_runlist(priv); 973 stat &= ~0x40000000; 974 } 975 976 if (stat & 0x80000000) { 977 nv_wr32(priv, 0x002100, 0x80000000); 978 gk104_fifo_intr_engine(priv); 979 stat &= ~0x80000000; 980 } 981 982 if (stat) { 983 nv_error(priv, "INTR 0x%08x\n", stat); 984 nv_mask(priv, 0x002140, stat, 0x00000000); 985 nv_wr32(priv, 0x002100, stat); 986 } 987} 988 989static void 990gk104_fifo_uevent_init(struct nvkm_event *event, int type, int index) 991{ 992 struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent); 993 nv_mask(fifo, 0x002140, 0x80000000, 0x80000000); 994} 995 996static void 997gk104_fifo_uevent_fini(struct nvkm_event *event, int type, int index) 998{ 999 struct nvkm_fifo *fifo = container_of(event, typeof(*fifo), uevent); 1000 nv_mask(fifo, 0x002140, 0x80000000, 0x00000000); 1001} 1002 1003static const struct nvkm_event_func 1004gk104_fifo_uevent_func = { 1005 .ctor = nvkm_fifo_uevent_ctor, 1006 .init = gk104_fifo_uevent_init, 1007 .fini = gk104_fifo_uevent_fini, 1008}; 1009 1010int 1011gk104_fifo_fini(struct nvkm_object *object, bool suspend) 1012{ 1013 struct gk104_fifo_priv *priv = (void *)object; 1014 int ret; 1015 1016 ret = nvkm_fifo_fini(&priv->base, suspend); 1017 if (ret) 1018 return ret; 1019 1020 /* allow mmu fault interrupts, even when we're not using fifo */ 1021 nv_mask(priv, 0x002140, 0x10000000, 0x10000000); 1022 return 0; 1023} 1024 1025int 1026gk104_fifo_init(struct nvkm_object *object) 1027{ 1028 struct gk104_fifo_priv *priv = (void *)object; 1029 int ret, i; 1030 1031 ret = nvkm_fifo_init(&priv->base); 1032 if (ret) 1033 return ret; 1034 1035 /* enable all available PBDMA units */ 1036 nv_wr32(priv, 0x000204, 0xffffffff); 1037 priv->spoon_nr = hweight32(nv_rd32(priv, 0x000204)); 1038 nv_debug(priv, "%d PBDMA unit(s)\n", priv->spoon_nr); 1039 1040 /* PBDMA[n] */ 1041 for (i = 0; i < priv->spoon_nr; i++) { 1042 nv_mask(priv, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000); 1043 nv_wr32(priv, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */ 1044 nv_wr32(priv, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTREN */ 1045 } 1046 1047 /* PBDMA[n].HCE */ 1048 for (i = 0; i < priv->spoon_nr; i++) { 1049 nv_wr32(priv, 0x040148 + (i * 0x2000), 0xffffffff); /* INTR */ 1050 nv_wr32(priv, 0x04014c + (i * 0x2000), 0xffffffff); /* INTREN */ 1051 } 1052 1053 nv_wr32(priv, 0x002254, 0x10000000 | priv->user.bar.offset >> 12); 1054 1055 nv_wr32(priv, 0x002100, 0xffffffff); 1056 nv_wr32(priv, 0x002140, 0x7fffffff); 1057 return 0; 1058} 1059 1060void 1061gk104_fifo_dtor(struct nvkm_object *object) 1062{ 1063 struct gk104_fifo_priv *priv = (void *)object; 1064 int i; 1065 1066 nvkm_gpuobj_unmap(&priv->user.bar); 1067 nvkm_gpuobj_ref(NULL, &priv->user.mem); 1068 1069 for (i = 0; i < FIFO_ENGINE_NR; i++) { 1070 nvkm_gpuobj_ref(NULL, &priv->engine[i].runlist[1]); 1071 nvkm_gpuobj_ref(NULL, &priv->engine[i].runlist[0]); 1072 } 1073 1074 nvkm_fifo_destroy(&priv->base); 1075} 1076 1077int 1078gk104_fifo_ctor(struct nvkm_object *parent, struct nvkm_object *engine, 1079 struct nvkm_oclass *oclass, void *data, u32 size, 1080 struct nvkm_object **pobject) 1081{ 1082 struct gk104_fifo_impl *impl = (void *)oclass; 1083 struct gk104_fifo_priv *priv; 1084 int ret, i; 1085 1086 ret = nvkm_fifo_create(parent, engine, oclass, 0, 1087 impl->channels - 1, &priv); 1088 *pobject = nv_object(priv); 1089 if (ret) 1090 return ret; 1091 1092 INIT_WORK(&priv->fault, gk104_fifo_recover_work); 1093 1094 for (i = 0; i < FIFO_ENGINE_NR; i++) { 1095 ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000, 1096 0, &priv->engine[i].runlist[0]); 1097 if (ret) 1098 return ret; 1099 1100 ret = nvkm_gpuobj_new(nv_object(priv), NULL, 0x8000, 0x1000, 1101 0, &priv->engine[i].runlist[1]); 1102 if (ret) 1103 return ret; 1104 1105 init_waitqueue_head(&priv->engine[i].wait); 1106 } 1107 1108 ret = nvkm_gpuobj_new(nv_object(priv), NULL, impl->channels * 0x200, 1109 0x1000, NVOBJ_FLAG_ZERO_ALLOC, &priv->user.mem); 1110 if (ret) 1111 return ret; 1112 1113 ret = nvkm_gpuobj_map(priv->user.mem, NV_MEM_ACCESS_RW, 1114 &priv->user.bar); 1115 if (ret) 1116 return ret; 1117 1118 ret = nvkm_event_init(&gk104_fifo_uevent_func, 1, 1, &priv->base.uevent); 1119 if (ret) 1120 return ret; 1121 1122 nv_subdev(priv)->unit = 0x00000100; 1123 nv_subdev(priv)->intr = gk104_fifo_intr; 1124 nv_engine(priv)->cclass = &gk104_fifo_cclass; 1125 nv_engine(priv)->sclass = gk104_fifo_sclass; 1126 return 0; 1127} 1128 1129struct nvkm_oclass * 1130gk104_fifo_oclass = &(struct gk104_fifo_impl) { 1131 .base.handle = NV_ENGINE(FIFO, 0xe0), 1132 .base.ofuncs = &(struct nvkm_ofuncs) { 1133 .ctor = gk104_fifo_ctor, 1134 .dtor = gk104_fifo_dtor, 1135 .init = gk104_fifo_init, 1136 .fini = gk104_fifo_fini, 1137 }, 1138 .channels = 4096, 1139}.base; 1140