gk104.c 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051
  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. #include "changk104.h"
  26. #include <core/client.h>
  27. #include <core/gpuobj.h>
  28. #include <subdev/bar.h>
  29. #include <subdev/timer.h>
  30. #include <subdev/top.h>
  31. #include <engine/sw.h>
  32. #include <nvif/class.h>
  33. struct gk104_fifo_engine_status {
  34. bool busy;
  35. bool faulted;
  36. bool chsw;
  37. bool save;
  38. bool load;
  39. struct {
  40. bool tsg;
  41. u32 id;
  42. } prev, next, *chan;
  43. };
  44. static void
  45. gk104_fifo_engine_status(struct gk104_fifo *fifo, int engn,
  46. struct gk104_fifo_engine_status *status)
  47. {
  48. struct nvkm_engine *engine = fifo->engine[engn].engine;
  49. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  50. struct nvkm_device *device = subdev->device;
  51. u32 stat = nvkm_rd32(device, 0x002640 + (engn * 0x08));
  52. status->busy = !!(stat & 0x80000000);
  53. status->faulted = !!(stat & 0x40000000);
  54. status->next.tsg = !!(stat & 0x10000000);
  55. status->next.id = (stat & 0x0fff0000) >> 16;
  56. status->chsw = !!(stat & 0x00008000);
  57. status->save = !!(stat & 0x00004000);
  58. status->load = !!(stat & 0x00002000);
  59. status->prev.tsg = !!(stat & 0x00001000);
  60. status->prev.id = (stat & 0x00000fff);
  61. status->chan = NULL;
  62. if (status->busy && status->chsw) {
  63. if (status->load && status->save) {
  64. if (engine && nvkm_engine_chsw_load(engine))
  65. status->chan = &status->next;
  66. else
  67. status->chan = &status->prev;
  68. } else
  69. if (status->load) {
  70. status->chan = &status->next;
  71. } else {
  72. status->chan = &status->prev;
  73. }
  74. } else
  75. if (status->load) {
  76. status->chan = &status->prev;
  77. }
  78. nvkm_debug(subdev, "engine %02d: busy %d faulted %d chsw %d "
  79. "save %d load %d %sid %d%s-> %sid %d%s\n",
  80. engn, status->busy, status->faulted,
  81. status->chsw, status->save, status->load,
  82. status->prev.tsg ? "tsg" : "ch", status->prev.id,
  83. status->chan == &status->prev ? "*" : " ",
  84. status->next.tsg ? "tsg" : "ch", status->next.id,
  85. status->chan == &status->next ? "*" : " ");
  86. }
  87. static int
  88. gk104_fifo_class_get(struct nvkm_fifo *base, int index,
  89. const struct nvkm_fifo_chan_oclass **psclass)
  90. {
  91. struct gk104_fifo *fifo = gk104_fifo(base);
  92. int c = 0;
  93. while ((*psclass = fifo->func->chan[c])) {
  94. if (c++ == index)
  95. return 0;
  96. }
  97. return c;
  98. }
  99. static void
  100. gk104_fifo_uevent_fini(struct nvkm_fifo *fifo)
  101. {
  102. struct nvkm_device *device = fifo->engine.subdev.device;
  103. nvkm_mask(device, 0x002140, 0x80000000, 0x00000000);
  104. }
  105. static void
  106. gk104_fifo_uevent_init(struct nvkm_fifo *fifo)
  107. {
  108. struct nvkm_device *device = fifo->engine.subdev.device;
  109. nvkm_mask(device, 0x002140, 0x80000000, 0x80000000);
  110. }
  111. void
  112. gk104_fifo_runlist_commit(struct gk104_fifo *fifo, int runl)
  113. {
  114. struct gk104_fifo_chan *chan;
  115. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  116. struct nvkm_device *device = subdev->device;
  117. struct nvkm_memory *mem;
  118. int nr = 0;
  119. int target;
  120. mutex_lock(&subdev->mutex);
  121. mem = fifo->runlist[runl].mem[fifo->runlist[runl].next];
  122. fifo->runlist[runl].next = !fifo->runlist[runl].next;
  123. nvkm_kmap(mem);
  124. list_for_each_entry(chan, &fifo->runlist[runl].chan, head) {
  125. nvkm_wo32(mem, (nr * 8) + 0, chan->base.chid);
  126. nvkm_wo32(mem, (nr * 8) + 4, 0x00000000);
  127. nr++;
  128. }
  129. nvkm_done(mem);
  130. switch (nvkm_memory_target(mem)) {
  131. case NVKM_MEM_TARGET_VRAM: target = 0; break;
  132. case NVKM_MEM_TARGET_NCOH: target = 3; break;
  133. default:
  134. WARN_ON(1);
  135. goto unlock;
  136. }
  137. nvkm_wr32(device, 0x002270, (nvkm_memory_addr(mem) >> 12) |
  138. (target << 28));
  139. nvkm_wr32(device, 0x002274, (runl << 20) | nr);
  140. if (wait_event_timeout(fifo->runlist[runl].wait,
  141. !(nvkm_rd32(device, 0x002284 + (runl * 0x08))
  142. & 0x00100000),
  143. msecs_to_jiffies(2000)) == 0)
  144. nvkm_error(subdev, "runlist %d update timeout\n", runl);
  145. unlock:
  146. mutex_unlock(&subdev->mutex);
  147. }
  148. void
  149. gk104_fifo_runlist_remove(struct gk104_fifo *fifo, struct gk104_fifo_chan *chan)
  150. {
  151. mutex_lock(&fifo->base.engine.subdev.mutex);
  152. list_del_init(&chan->head);
  153. mutex_unlock(&fifo->base.engine.subdev.mutex);
  154. }
  155. void
  156. gk104_fifo_runlist_insert(struct gk104_fifo *fifo, struct gk104_fifo_chan *chan)
  157. {
  158. mutex_lock(&fifo->base.engine.subdev.mutex);
  159. list_add_tail(&chan->head, &fifo->runlist[chan->runl].chan);
  160. mutex_unlock(&fifo->base.engine.subdev.mutex);
  161. }
  162. static void
  163. gk104_fifo_recover_work(struct work_struct *w)
  164. {
  165. struct gk104_fifo *fifo = container_of(w, typeof(*fifo), recover.work);
  166. struct nvkm_device *device = fifo->base.engine.subdev.device;
  167. struct nvkm_engine *engine;
  168. unsigned long flags;
  169. u32 engm, runm, todo;
  170. int engn, runl;
  171. spin_lock_irqsave(&fifo->base.lock, flags);
  172. runm = fifo->recover.runm;
  173. engm = fifo->recover.engm;
  174. fifo->recover.engm = 0;
  175. fifo->recover.runm = 0;
  176. spin_unlock_irqrestore(&fifo->base.lock, flags);
  177. nvkm_mask(device, 0x002630, runm, runm);
  178. for (todo = engm; engn = __ffs(todo), todo; todo &= ~BIT(engn)) {
  179. if ((engine = fifo->engine[engn].engine)) {
  180. nvkm_subdev_fini(&engine->subdev, false);
  181. WARN_ON(nvkm_subdev_init(&engine->subdev));
  182. }
  183. }
  184. for (todo = runm; runl = __ffs(todo), todo; todo &= ~BIT(runl))
  185. gk104_fifo_runlist_commit(fifo, runl);
  186. nvkm_wr32(device, 0x00262c, runm);
  187. nvkm_mask(device, 0x002630, runm, 0x00000000);
  188. }
  189. static void gk104_fifo_recover_engn(struct gk104_fifo *fifo, int engn);
  190. static void
  191. gk104_fifo_recover_runl(struct gk104_fifo *fifo, int runl)
  192. {
  193. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  194. struct nvkm_device *device = subdev->device;
  195. const u32 runm = BIT(runl);
  196. assert_spin_locked(&fifo->base.lock);
  197. if (fifo->recover.runm & runm)
  198. return;
  199. fifo->recover.runm |= runm;
  200. /* Block runlist to prevent channel assignment(s) from changing. */
  201. nvkm_mask(device, 0x002630, runm, runm);
  202. /* Schedule recovery. */
  203. nvkm_warn(subdev, "runlist %d: scheduled for recovery\n", runl);
  204. schedule_work(&fifo->recover.work);
  205. }
  206. static void
  207. gk104_fifo_recover_chan(struct nvkm_fifo *base, int chid)
  208. {
  209. struct gk104_fifo *fifo = gk104_fifo(base);
  210. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  211. struct nvkm_device *device = subdev->device;
  212. const u32 stat = nvkm_rd32(device, 0x800004 + (chid * 0x08));
  213. const u32 runl = (stat & 0x000f0000) >> 16;
  214. const bool used = (stat & 0x00000001);
  215. unsigned long engn, engm = fifo->runlist[runl].engm;
  216. struct gk104_fifo_chan *chan;
  217. assert_spin_locked(&fifo->base.lock);
  218. if (!used)
  219. return;
  220. /* Lookup SW state for channel, and mark it as dead. */
  221. list_for_each_entry(chan, &fifo->runlist[runl].chan, head) {
  222. if (chan->base.chid == chid) {
  223. list_del_init(&chan->head);
  224. chan->killed = true;
  225. nvkm_fifo_kevent(&fifo->base, chid);
  226. break;
  227. }
  228. }
  229. /* Disable channel. */
  230. nvkm_wr32(device, 0x800004 + (chid * 0x08), stat | 0x00000800);
  231. nvkm_warn(subdev, "channel %d: killed\n", chid);
  232. /* Block channel assignments from changing during recovery. */
  233. gk104_fifo_recover_runl(fifo, runl);
  234. /* Schedule recovery for any engines the channel is on. */
  235. for_each_set_bit(engn, &engm, fifo->engine_nr) {
  236. struct gk104_fifo_engine_status status;
  237. gk104_fifo_engine_status(fifo, engn, &status);
  238. if (!status.chan || status.chan->id != chid)
  239. continue;
  240. gk104_fifo_recover_engn(fifo, engn);
  241. }
  242. }
  243. static void
  244. gk104_fifo_recover_engn(struct gk104_fifo *fifo, int engn)
  245. {
  246. struct nvkm_engine *engine = fifo->engine[engn].engine;
  247. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  248. struct nvkm_device *device = subdev->device;
  249. const u32 runl = fifo->engine[engn].runl;
  250. const u32 engm = BIT(engn);
  251. struct gk104_fifo_engine_status status;
  252. int mmui = -1;
  253. assert_spin_locked(&fifo->base.lock);
  254. if (fifo->recover.engm & engm)
  255. return;
  256. fifo->recover.engm |= engm;
  257. /* Block channel assignments from changing during recovery. */
  258. gk104_fifo_recover_runl(fifo, runl);
  259. /* Determine which channel (if any) is currently on the engine. */
  260. gk104_fifo_engine_status(fifo, engn, &status);
  261. if (status.chan) {
  262. /* The channel is not longer viable, kill it. */
  263. gk104_fifo_recover_chan(&fifo->base, status.chan->id);
  264. }
  265. /* Determine MMU fault ID for the engine, if we're not being
  266. * called from the fault handler already.
  267. */
  268. if (!status.faulted && engine) {
  269. mmui = nvkm_top_fault_id(device, engine->subdev.index);
  270. if (mmui < 0) {
  271. const struct nvkm_enum *en = fifo->func->fault.engine;
  272. for (; en && en->name; en++) {
  273. if (en->data2 == engine->subdev.index) {
  274. mmui = en->value;
  275. break;
  276. }
  277. }
  278. }
  279. WARN_ON(mmui < 0);
  280. }
  281. /* Trigger a MMU fault for the engine.
  282. *
  283. * No good idea why this is needed, but nvgpu does something similar,
  284. * and it makes recovery from CTXSW_TIMEOUT a lot more reliable.
  285. */
  286. if (mmui >= 0) {
  287. nvkm_wr32(device, 0x002a30 + (engn * 0x04), 0x00000100 | mmui);
  288. /* Wait for fault to trigger. */
  289. nvkm_msec(device, 2000,
  290. gk104_fifo_engine_status(fifo, engn, &status);
  291. if (status.faulted)
  292. break;
  293. );
  294. /* Release MMU fault trigger, and ACK the fault. */
  295. nvkm_wr32(device, 0x002a30 + (engn * 0x04), 0x00000000);
  296. nvkm_wr32(device, 0x00259c, BIT(mmui));
  297. nvkm_wr32(device, 0x002100, 0x10000000);
  298. }
  299. /* Schedule recovery. */
  300. nvkm_warn(subdev, "engine %d: scheduled for recovery\n", engn);
  301. schedule_work(&fifo->recover.work);
  302. }
  303. static const struct nvkm_enum
  304. gk104_fifo_bind_reason[] = {
  305. { 0x01, "BIND_NOT_UNBOUND" },
  306. { 0x02, "SNOOP_WITHOUT_BAR1" },
  307. { 0x03, "UNBIND_WHILE_RUNNING" },
  308. { 0x05, "INVALID_RUNLIST" },
  309. { 0x06, "INVALID_CTX_TGT" },
  310. { 0x0b, "UNBIND_WHILE_PARKED" },
  311. {}
  312. };
  313. static void
  314. gk104_fifo_intr_bind(struct gk104_fifo *fifo)
  315. {
  316. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  317. struct nvkm_device *device = subdev->device;
  318. u32 intr = nvkm_rd32(device, 0x00252c);
  319. u32 code = intr & 0x000000ff;
  320. const struct nvkm_enum *en =
  321. nvkm_enum_find(gk104_fifo_bind_reason, code);
  322. nvkm_error(subdev, "BIND_ERROR %02x [%s]\n", code, en ? en->name : "");
  323. }
  324. static const struct nvkm_enum
  325. gk104_fifo_sched_reason[] = {
  326. { 0x0a, "CTXSW_TIMEOUT" },
  327. {}
  328. };
  329. static void
  330. gk104_fifo_intr_sched_ctxsw(struct gk104_fifo *fifo)
  331. {
  332. struct nvkm_device *device = fifo->base.engine.subdev.device;
  333. unsigned long flags, engm = 0;
  334. u32 engn;
  335. /* We need to ACK the SCHED_ERROR here, and prevent it reasserting,
  336. * as MMU_FAULT cannot be triggered while it's pending.
  337. */
  338. spin_lock_irqsave(&fifo->base.lock, flags);
  339. nvkm_mask(device, 0x002140, 0x00000100, 0x00000000);
  340. nvkm_wr32(device, 0x002100, 0x00000100);
  341. for (engn = 0; engn < fifo->engine_nr; engn++) {
  342. struct gk104_fifo_engine_status status;
  343. gk104_fifo_engine_status(fifo, engn, &status);
  344. if (!status.busy || !status.chsw)
  345. continue;
  346. engm |= BIT(engn);
  347. }
  348. for_each_set_bit(engn, &engm, fifo->engine_nr)
  349. gk104_fifo_recover_engn(fifo, engn);
  350. nvkm_mask(device, 0x002140, 0x00000100, 0x00000100);
  351. spin_unlock_irqrestore(&fifo->base.lock, flags);
  352. }
  353. static void
  354. gk104_fifo_intr_sched(struct gk104_fifo *fifo)
  355. {
  356. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  357. struct nvkm_device *device = subdev->device;
  358. u32 intr = nvkm_rd32(device, 0x00254c);
  359. u32 code = intr & 0x000000ff;
  360. const struct nvkm_enum *en =
  361. nvkm_enum_find(gk104_fifo_sched_reason, code);
  362. nvkm_error(subdev, "SCHED_ERROR %02x [%s]\n", code, en ? en->name : "");
  363. switch (code) {
  364. case 0x0a:
  365. gk104_fifo_intr_sched_ctxsw(fifo);
  366. break;
  367. default:
  368. break;
  369. }
  370. }
  371. static void
  372. gk104_fifo_intr_chsw(struct gk104_fifo *fifo)
  373. {
  374. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  375. struct nvkm_device *device = subdev->device;
  376. u32 stat = nvkm_rd32(device, 0x00256c);
  377. nvkm_error(subdev, "CHSW_ERROR %08x\n", stat);
  378. nvkm_wr32(device, 0x00256c, stat);
  379. }
  380. static void
  381. gk104_fifo_intr_dropped_fault(struct gk104_fifo *fifo)
  382. {
  383. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  384. struct nvkm_device *device = subdev->device;
  385. u32 stat = nvkm_rd32(device, 0x00259c);
  386. nvkm_error(subdev, "DROPPED_MMU_FAULT %08x\n", stat);
  387. }
  388. static void
  389. gk104_fifo_intr_fault(struct gk104_fifo *fifo, int unit)
  390. {
  391. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  392. struct nvkm_device *device = subdev->device;
  393. u32 inst = nvkm_rd32(device, 0x002800 + (unit * 0x10));
  394. u32 valo = nvkm_rd32(device, 0x002804 + (unit * 0x10));
  395. u32 vahi = nvkm_rd32(device, 0x002808 + (unit * 0x10));
  396. u32 stat = nvkm_rd32(device, 0x00280c + (unit * 0x10));
  397. u32 gpc = (stat & 0x1f000000) >> 24;
  398. u32 client = (stat & 0x00001f00) >> 8;
  399. u32 write = (stat & 0x00000080);
  400. u32 hub = (stat & 0x00000040);
  401. u32 reason = (stat & 0x0000000f);
  402. const struct nvkm_enum *er, *eu, *ec;
  403. struct nvkm_engine *engine = NULL;
  404. struct nvkm_fifo_chan *chan;
  405. unsigned long flags;
  406. char gpcid[8] = "", en[16] = "";
  407. int engn;
  408. er = nvkm_enum_find(fifo->func->fault.reason, reason);
  409. eu = nvkm_enum_find(fifo->func->fault.engine, unit);
  410. if (hub) {
  411. ec = nvkm_enum_find(fifo->func->fault.hubclient, client);
  412. } else {
  413. ec = nvkm_enum_find(fifo->func->fault.gpcclient, client);
  414. snprintf(gpcid, sizeof(gpcid), "GPC%d/", gpc);
  415. }
  416. if (eu && eu->data2) {
  417. switch (eu->data2) {
  418. case NVKM_SUBDEV_BAR:
  419. nvkm_mask(device, 0x001704, 0x00000000, 0x00000000);
  420. break;
  421. case NVKM_SUBDEV_INSTMEM:
  422. nvkm_mask(device, 0x001714, 0x00000000, 0x00000000);
  423. break;
  424. case NVKM_ENGINE_IFB:
  425. nvkm_mask(device, 0x001718, 0x00000000, 0x00000000);
  426. break;
  427. default:
  428. engine = nvkm_device_engine(device, eu->data2);
  429. break;
  430. }
  431. }
  432. if (eu == NULL) {
  433. enum nvkm_devidx engidx = nvkm_top_fault(device, unit);
  434. if (engidx < NVKM_SUBDEV_NR) {
  435. const char *src = nvkm_subdev_name[engidx];
  436. char *dst = en;
  437. do {
  438. *dst++ = toupper(*src++);
  439. } while(*src);
  440. engine = nvkm_device_engine(device, engidx);
  441. }
  442. } else {
  443. snprintf(en, sizeof(en), "%s", eu->name);
  444. }
  445. spin_lock_irqsave(&fifo->base.lock, flags);
  446. chan = nvkm_fifo_chan_inst_locked(&fifo->base, (u64)inst << 12);
  447. nvkm_error(subdev,
  448. "%s fault at %010llx engine %02x [%s] client %02x [%s%s] "
  449. "reason %02x [%s] on channel %d [%010llx %s]\n",
  450. write ? "write" : "read", (u64)vahi << 32 | valo,
  451. unit, en, client, gpcid, ec ? ec->name : "",
  452. reason, er ? er->name : "", chan ? chan->chid : -1,
  453. (u64)inst << 12,
  454. chan ? chan->object.client->name : "unknown");
  455. /* Kill the channel that caused the fault. */
  456. if (chan)
  457. gk104_fifo_recover_chan(&fifo->base, chan->chid);
  458. /* Channel recovery will probably have already done this for the
  459. * correct engine(s), but just in case we can't find the channel
  460. * information...
  461. */
  462. for (engn = 0; engn < fifo->engine_nr && engine; engn++) {
  463. if (fifo->engine[engn].engine == engine) {
  464. gk104_fifo_recover_engn(fifo, engn);
  465. break;
  466. }
  467. }
  468. spin_unlock_irqrestore(&fifo->base.lock, flags);
  469. }
  470. static const struct nvkm_bitfield gk104_fifo_pbdma_intr_0[] = {
  471. { 0x00000001, "MEMREQ" },
  472. { 0x00000002, "MEMACK_TIMEOUT" },
  473. { 0x00000004, "MEMACK_EXTRA" },
  474. { 0x00000008, "MEMDAT_TIMEOUT" },
  475. { 0x00000010, "MEMDAT_EXTRA" },
  476. { 0x00000020, "MEMFLUSH" },
  477. { 0x00000040, "MEMOP" },
  478. { 0x00000080, "LBCONNECT" },
  479. { 0x00000100, "LBREQ" },
  480. { 0x00000200, "LBACK_TIMEOUT" },
  481. { 0x00000400, "LBACK_EXTRA" },
  482. { 0x00000800, "LBDAT_TIMEOUT" },
  483. { 0x00001000, "LBDAT_EXTRA" },
  484. { 0x00002000, "GPFIFO" },
  485. { 0x00004000, "GPPTR" },
  486. { 0x00008000, "GPENTRY" },
  487. { 0x00010000, "GPCRC" },
  488. { 0x00020000, "PBPTR" },
  489. { 0x00040000, "PBENTRY" },
  490. { 0x00080000, "PBCRC" },
  491. { 0x00100000, "XBARCONNECT" },
  492. { 0x00200000, "METHOD" },
  493. { 0x00400000, "METHODCRC" },
  494. { 0x00800000, "DEVICE" },
  495. { 0x02000000, "SEMAPHORE" },
  496. { 0x04000000, "ACQUIRE" },
  497. { 0x08000000, "PRI" },
  498. { 0x20000000, "NO_CTXSW_SEG" },
  499. { 0x40000000, "PBSEG" },
  500. { 0x80000000, "SIGNATURE" },
  501. {}
  502. };
  503. static void
  504. gk104_fifo_intr_pbdma_0(struct gk104_fifo *fifo, int unit)
  505. {
  506. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  507. struct nvkm_device *device = subdev->device;
  508. u32 mask = nvkm_rd32(device, 0x04010c + (unit * 0x2000));
  509. u32 stat = nvkm_rd32(device, 0x040108 + (unit * 0x2000)) & mask;
  510. u32 addr = nvkm_rd32(device, 0x0400c0 + (unit * 0x2000));
  511. u32 data = nvkm_rd32(device, 0x0400c4 + (unit * 0x2000));
  512. u32 chid = nvkm_rd32(device, 0x040120 + (unit * 0x2000)) & 0xfff;
  513. u32 subc = (addr & 0x00070000) >> 16;
  514. u32 mthd = (addr & 0x00003ffc);
  515. u32 show = stat;
  516. struct nvkm_fifo_chan *chan;
  517. unsigned long flags;
  518. char msg[128];
  519. if (stat & 0x00800000) {
  520. if (device->sw) {
  521. if (nvkm_sw_mthd(device->sw, chid, subc, mthd, data))
  522. show &= ~0x00800000;
  523. }
  524. }
  525. nvkm_wr32(device, 0x0400c0 + (unit * 0x2000), 0x80600008);
  526. if (show) {
  527. nvkm_snprintbf(msg, sizeof(msg), gk104_fifo_pbdma_intr_0, show);
  528. chan = nvkm_fifo_chan_chid(&fifo->base, chid, &flags);
  529. nvkm_error(subdev, "PBDMA%d: %08x [%s] ch %d [%010llx %s] "
  530. "subc %d mthd %04x data %08x\n",
  531. unit, show, msg, chid, chan ? chan->inst->addr : 0,
  532. chan ? chan->object.client->name : "unknown",
  533. subc, mthd, data);
  534. nvkm_fifo_chan_put(&fifo->base, flags, &chan);
  535. }
  536. nvkm_wr32(device, 0x040108 + (unit * 0x2000), stat);
  537. }
  538. static const struct nvkm_bitfield gk104_fifo_pbdma_intr_1[] = {
  539. { 0x00000001, "HCE_RE_ILLEGAL_OP" },
  540. { 0x00000002, "HCE_RE_ALIGNB" },
  541. { 0x00000004, "HCE_PRIV" },
  542. { 0x00000008, "HCE_ILLEGAL_MTHD" },
  543. { 0x00000010, "HCE_ILLEGAL_CLASS" },
  544. {}
  545. };
  546. static void
  547. gk104_fifo_intr_pbdma_1(struct gk104_fifo *fifo, int unit)
  548. {
  549. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  550. struct nvkm_device *device = subdev->device;
  551. u32 mask = nvkm_rd32(device, 0x04014c + (unit * 0x2000));
  552. u32 stat = nvkm_rd32(device, 0x040148 + (unit * 0x2000)) & mask;
  553. u32 chid = nvkm_rd32(device, 0x040120 + (unit * 0x2000)) & 0xfff;
  554. char msg[128];
  555. if (stat) {
  556. nvkm_snprintbf(msg, sizeof(msg), gk104_fifo_pbdma_intr_1, stat);
  557. nvkm_error(subdev, "PBDMA%d: %08x [%s] ch %d %08x %08x\n",
  558. unit, stat, msg, chid,
  559. nvkm_rd32(device, 0x040150 + (unit * 0x2000)),
  560. nvkm_rd32(device, 0x040154 + (unit * 0x2000)));
  561. }
  562. nvkm_wr32(device, 0x040148 + (unit * 0x2000), stat);
  563. }
  564. static void
  565. gk104_fifo_intr_runlist(struct gk104_fifo *fifo)
  566. {
  567. struct nvkm_device *device = fifo->base.engine.subdev.device;
  568. u32 mask = nvkm_rd32(device, 0x002a00);
  569. while (mask) {
  570. int runl = __ffs(mask);
  571. wake_up(&fifo->runlist[runl].wait);
  572. nvkm_wr32(device, 0x002a00, 1 << runl);
  573. mask &= ~(1 << runl);
  574. }
  575. }
  576. static void
  577. gk104_fifo_intr_engine(struct gk104_fifo *fifo)
  578. {
  579. nvkm_fifo_uevent(&fifo->base);
  580. }
  581. static void
  582. gk104_fifo_intr(struct nvkm_fifo *base)
  583. {
  584. struct gk104_fifo *fifo = gk104_fifo(base);
  585. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  586. struct nvkm_device *device = subdev->device;
  587. u32 mask = nvkm_rd32(device, 0x002140);
  588. u32 stat = nvkm_rd32(device, 0x002100) & mask;
  589. if (stat & 0x00000001) {
  590. gk104_fifo_intr_bind(fifo);
  591. nvkm_wr32(device, 0x002100, 0x00000001);
  592. stat &= ~0x00000001;
  593. }
  594. if (stat & 0x00000010) {
  595. nvkm_error(subdev, "PIO_ERROR\n");
  596. nvkm_wr32(device, 0x002100, 0x00000010);
  597. stat &= ~0x00000010;
  598. }
  599. if (stat & 0x00000100) {
  600. gk104_fifo_intr_sched(fifo);
  601. nvkm_wr32(device, 0x002100, 0x00000100);
  602. stat &= ~0x00000100;
  603. }
  604. if (stat & 0x00010000) {
  605. gk104_fifo_intr_chsw(fifo);
  606. nvkm_wr32(device, 0x002100, 0x00010000);
  607. stat &= ~0x00010000;
  608. }
  609. if (stat & 0x00800000) {
  610. nvkm_error(subdev, "FB_FLUSH_TIMEOUT\n");
  611. nvkm_wr32(device, 0x002100, 0x00800000);
  612. stat &= ~0x00800000;
  613. }
  614. if (stat & 0x01000000) {
  615. nvkm_error(subdev, "LB_ERROR\n");
  616. nvkm_wr32(device, 0x002100, 0x01000000);
  617. stat &= ~0x01000000;
  618. }
  619. if (stat & 0x08000000) {
  620. gk104_fifo_intr_dropped_fault(fifo);
  621. nvkm_wr32(device, 0x002100, 0x08000000);
  622. stat &= ~0x08000000;
  623. }
  624. if (stat & 0x10000000) {
  625. u32 mask = nvkm_rd32(device, 0x00259c);
  626. while (mask) {
  627. u32 unit = __ffs(mask);
  628. gk104_fifo_intr_fault(fifo, unit);
  629. nvkm_wr32(device, 0x00259c, (1 << unit));
  630. mask &= ~(1 << unit);
  631. }
  632. stat &= ~0x10000000;
  633. }
  634. if (stat & 0x20000000) {
  635. u32 mask = nvkm_rd32(device, 0x0025a0);
  636. while (mask) {
  637. u32 unit = __ffs(mask);
  638. gk104_fifo_intr_pbdma_0(fifo, unit);
  639. gk104_fifo_intr_pbdma_1(fifo, unit);
  640. nvkm_wr32(device, 0x0025a0, (1 << unit));
  641. mask &= ~(1 << unit);
  642. }
  643. stat &= ~0x20000000;
  644. }
  645. if (stat & 0x40000000) {
  646. gk104_fifo_intr_runlist(fifo);
  647. stat &= ~0x40000000;
  648. }
  649. if (stat & 0x80000000) {
  650. nvkm_wr32(device, 0x002100, 0x80000000);
  651. gk104_fifo_intr_engine(fifo);
  652. stat &= ~0x80000000;
  653. }
  654. if (stat) {
  655. nvkm_error(subdev, "INTR %08x\n", stat);
  656. nvkm_mask(device, 0x002140, stat, 0x00000000);
  657. nvkm_wr32(device, 0x002100, stat);
  658. }
  659. }
  660. static void
  661. gk104_fifo_fini(struct nvkm_fifo *base)
  662. {
  663. struct gk104_fifo *fifo = gk104_fifo(base);
  664. struct nvkm_device *device = fifo->base.engine.subdev.device;
  665. flush_work(&fifo->recover.work);
  666. /* allow mmu fault interrupts, even when we're not using fifo */
  667. nvkm_mask(device, 0x002140, 0x10000000, 0x10000000);
  668. }
  669. static int
  670. gk104_fifo_oneinit(struct nvkm_fifo *base)
  671. {
  672. struct gk104_fifo *fifo = gk104_fifo(base);
  673. struct nvkm_subdev *subdev = &fifo->base.engine.subdev;
  674. struct nvkm_device *device = subdev->device;
  675. int engn, runl, pbid, ret, i, j;
  676. enum nvkm_devidx engidx;
  677. u32 *map;
  678. /* Determine number of PBDMAs by checking valid enable bits. */
  679. nvkm_wr32(device, 0x000204, 0xffffffff);
  680. fifo->pbdma_nr = hweight32(nvkm_rd32(device, 0x000204));
  681. nvkm_debug(subdev, "%d PBDMA(s)\n", fifo->pbdma_nr);
  682. /* Read PBDMA->runlist(s) mapping from HW. */
  683. if (!(map = kzalloc(sizeof(*map) * fifo->pbdma_nr, GFP_KERNEL)))
  684. return -ENOMEM;
  685. for (i = 0; i < fifo->pbdma_nr; i++)
  686. map[i] = nvkm_rd32(device, 0x002390 + (i * 0x04));
  687. /* Determine runlist configuration from topology device info. */
  688. i = 0;
  689. while ((int)(engidx = nvkm_top_engine(device, i++, &runl, &engn)) >= 0) {
  690. /* Determine which PBDMA handles requests for this engine. */
  691. for (j = 0, pbid = -1; j < fifo->pbdma_nr; j++) {
  692. if (map[j] & (1 << runl)) {
  693. pbid = j;
  694. break;
  695. }
  696. }
  697. nvkm_debug(subdev, "engine %2d: runlist %2d pbdma %2d (%s)\n",
  698. engn, runl, pbid, nvkm_subdev_name[engidx]);
  699. fifo->engine[engn].engine = nvkm_device_engine(device, engidx);
  700. fifo->engine[engn].runl = runl;
  701. fifo->engine[engn].pbid = pbid;
  702. fifo->engine_nr = max(fifo->engine_nr, engn + 1);
  703. fifo->runlist[runl].engm |= 1 << engn;
  704. fifo->runlist_nr = max(fifo->runlist_nr, runl + 1);
  705. }
  706. kfree(map);
  707. for (i = 0; i < fifo->runlist_nr; i++) {
  708. ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
  709. 0x8000, 0x1000, false,
  710. &fifo->runlist[i].mem[0]);
  711. if (ret)
  712. return ret;
  713. ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
  714. 0x8000, 0x1000, false,
  715. &fifo->runlist[i].mem[1]);
  716. if (ret)
  717. return ret;
  718. init_waitqueue_head(&fifo->runlist[i].wait);
  719. INIT_LIST_HEAD(&fifo->runlist[i].chan);
  720. }
  721. ret = nvkm_memory_new(device, NVKM_MEM_TARGET_INST,
  722. fifo->base.nr * 0x200, 0x1000, true,
  723. &fifo->user.mem);
  724. if (ret)
  725. return ret;
  726. ret = nvkm_bar_umap(device->bar, fifo->base.nr * 0x200, 12,
  727. &fifo->user.bar);
  728. if (ret)
  729. return ret;
  730. nvkm_memory_map(fifo->user.mem, &fifo->user.bar, 0);
  731. return 0;
  732. }
  733. static void
  734. gk104_fifo_init(struct nvkm_fifo *base)
  735. {
  736. struct gk104_fifo *fifo = gk104_fifo(base);
  737. struct nvkm_device *device = fifo->base.engine.subdev.device;
  738. int i;
  739. /* Enable PBDMAs. */
  740. nvkm_wr32(device, 0x000204, (1 << fifo->pbdma_nr) - 1);
  741. /* PBDMA[n] */
  742. for (i = 0; i < fifo->pbdma_nr; i++) {
  743. nvkm_mask(device, 0x04013c + (i * 0x2000), 0x10000100, 0x00000000);
  744. nvkm_wr32(device, 0x040108 + (i * 0x2000), 0xffffffff); /* INTR */
  745. nvkm_wr32(device, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTREN */
  746. }
  747. /* PBDMA[n].HCE */
  748. for (i = 0; i < fifo->pbdma_nr; i++) {
  749. nvkm_wr32(device, 0x040148 + (i * 0x2000), 0xffffffff); /* INTR */
  750. nvkm_wr32(device, 0x04014c + (i * 0x2000), 0xffffffff); /* INTREN */
  751. }
  752. nvkm_wr32(device, 0x002254, 0x10000000 | fifo->user.bar.offset >> 12);
  753. nvkm_wr32(device, 0x002100, 0xffffffff);
  754. nvkm_wr32(device, 0x002140, 0x7fffffff);
  755. }
  756. static void *
  757. gk104_fifo_dtor(struct nvkm_fifo *base)
  758. {
  759. struct gk104_fifo *fifo = gk104_fifo(base);
  760. int i;
  761. nvkm_vm_put(&fifo->user.bar);
  762. nvkm_memory_del(&fifo->user.mem);
  763. for (i = 0; i < fifo->runlist_nr; i++) {
  764. nvkm_memory_del(&fifo->runlist[i].mem[1]);
  765. nvkm_memory_del(&fifo->runlist[i].mem[0]);
  766. }
  767. return fifo;
  768. }
  769. static const struct nvkm_fifo_func
  770. gk104_fifo_ = {
  771. .dtor = gk104_fifo_dtor,
  772. .oneinit = gk104_fifo_oneinit,
  773. .init = gk104_fifo_init,
  774. .fini = gk104_fifo_fini,
  775. .intr = gk104_fifo_intr,
  776. .uevent_init = gk104_fifo_uevent_init,
  777. .uevent_fini = gk104_fifo_uevent_fini,
  778. .recover_chan = gk104_fifo_recover_chan,
  779. .class_get = gk104_fifo_class_get,
  780. };
  781. int
  782. gk104_fifo_new_(const struct gk104_fifo_func *func, struct nvkm_device *device,
  783. int index, int nr, struct nvkm_fifo **pfifo)
  784. {
  785. struct gk104_fifo *fifo;
  786. if (!(fifo = kzalloc(sizeof(*fifo), GFP_KERNEL)))
  787. return -ENOMEM;
  788. fifo->func = func;
  789. INIT_WORK(&fifo->recover.work, gk104_fifo_recover_work);
  790. *pfifo = &fifo->base;
  791. return nvkm_fifo_ctor(&gk104_fifo_, device, index, nr, &fifo->base);
  792. }
  793. const struct nvkm_enum
  794. gk104_fifo_fault_engine[] = {
  795. { 0x00, "GR", NULL, NVKM_ENGINE_GR },
  796. { 0x01, "DISPLAY" },
  797. { 0x02, "CAPTURE" },
  798. { 0x03, "IFB", NULL, NVKM_ENGINE_IFB },
  799. { 0x04, "BAR1", NULL, NVKM_SUBDEV_BAR },
  800. { 0x05, "BAR2", NULL, NVKM_SUBDEV_INSTMEM },
  801. { 0x06, "SCHED" },
  802. { 0x07, "HOST0", NULL, NVKM_ENGINE_FIFO },
  803. { 0x08, "HOST1", NULL, NVKM_ENGINE_FIFO },
  804. { 0x09, "HOST2", NULL, NVKM_ENGINE_FIFO },
  805. { 0x0a, "HOST3", NULL, NVKM_ENGINE_FIFO },
  806. { 0x0b, "HOST4", NULL, NVKM_ENGINE_FIFO },
  807. { 0x0c, "HOST5", NULL, NVKM_ENGINE_FIFO },
  808. { 0x0d, "HOST6", NULL, NVKM_ENGINE_FIFO },
  809. { 0x0e, "HOST7", NULL, NVKM_ENGINE_FIFO },
  810. { 0x0f, "HOSTSR" },
  811. { 0x10, "MSVLD", NULL, NVKM_ENGINE_MSVLD },
  812. { 0x11, "MSPPP", NULL, NVKM_ENGINE_MSPPP },
  813. { 0x13, "PERF" },
  814. { 0x14, "MSPDEC", NULL, NVKM_ENGINE_MSPDEC },
  815. { 0x15, "CE0", NULL, NVKM_ENGINE_CE0 },
  816. { 0x16, "CE1", NULL, NVKM_ENGINE_CE1 },
  817. { 0x17, "PMU" },
  818. { 0x18, "PTP" },
  819. { 0x19, "MSENC", NULL, NVKM_ENGINE_MSENC },
  820. { 0x1b, "CE2", NULL, NVKM_ENGINE_CE2 },
  821. {}
  822. };
  823. const struct nvkm_enum
  824. gk104_fifo_fault_reason[] = {
  825. { 0x00, "PDE" },
  826. { 0x01, "PDE_SIZE" },
  827. { 0x02, "PTE" },
  828. { 0x03, "VA_LIMIT_VIOLATION" },
  829. { 0x04, "UNBOUND_INST_BLOCK" },
  830. { 0x05, "PRIV_VIOLATION" },
  831. { 0x06, "RO_VIOLATION" },
  832. { 0x07, "WO_VIOLATION" },
  833. { 0x08, "PITCH_MASK_VIOLATION" },
  834. { 0x09, "WORK_CREATION" },
  835. { 0x0a, "UNSUPPORTED_APERTURE" },
  836. { 0x0b, "COMPRESSION_FAILURE" },
  837. { 0x0c, "UNSUPPORTED_KIND" },
  838. { 0x0d, "REGION_VIOLATION" },
  839. { 0x0e, "BOTH_PTES_VALID" },
  840. { 0x0f, "INFO_TYPE_POISONED" },
  841. {}
  842. };
  843. const struct nvkm_enum
  844. gk104_fifo_fault_hubclient[] = {
  845. { 0x00, "VIP" },
  846. { 0x01, "CE0" },
  847. { 0x02, "CE1" },
  848. { 0x03, "DNISO" },
  849. { 0x04, "FE" },
  850. { 0x05, "FECS" },
  851. { 0x06, "HOST" },
  852. { 0x07, "HOST_CPU" },
  853. { 0x08, "HOST_CPU_NB" },
  854. { 0x09, "ISO" },
  855. { 0x0a, "MMU" },
  856. { 0x0b, "MSPDEC" },
  857. { 0x0c, "MSPPP" },
  858. { 0x0d, "MSVLD" },
  859. { 0x0e, "NISO" },
  860. { 0x0f, "P2P" },
  861. { 0x10, "PD" },
  862. { 0x11, "PERF" },
  863. { 0x12, "PMU" },
  864. { 0x13, "RASTERTWOD" },
  865. { 0x14, "SCC" },
  866. { 0x15, "SCC_NB" },
  867. { 0x16, "SEC" },
  868. { 0x17, "SSYNC" },
  869. { 0x18, "GR_CE" },
  870. { 0x19, "CE2" },
  871. { 0x1a, "XV" },
  872. { 0x1b, "MMU_NB" },
  873. { 0x1c, "MSENC" },
  874. { 0x1d, "DFALCON" },
  875. { 0x1e, "SKED" },
  876. { 0x1f, "AFALCON" },
  877. {}
  878. };
  879. const struct nvkm_enum
  880. gk104_fifo_fault_gpcclient[] = {
  881. { 0x00, "L1_0" }, { 0x01, "T1_0" }, { 0x02, "PE_0" },
  882. { 0x03, "L1_1" }, { 0x04, "T1_1" }, { 0x05, "PE_1" },
  883. { 0x06, "L1_2" }, { 0x07, "T1_2" }, { 0x08, "PE_2" },
  884. { 0x09, "L1_3" }, { 0x0a, "T1_3" }, { 0x0b, "PE_3" },
  885. { 0x0c, "RAST" },
  886. { 0x0d, "GCC" },
  887. { 0x0e, "GPCCS" },
  888. { 0x0f, "PROP_0" },
  889. { 0x10, "PROP_1" },
  890. { 0x11, "PROP_2" },
  891. { 0x12, "PROP_3" },
  892. { 0x13, "L1_4" }, { 0x14, "T1_4" }, { 0x15, "PE_4" },
  893. { 0x16, "L1_5" }, { 0x17, "T1_5" }, { 0x18, "PE_5" },
  894. { 0x19, "L1_6" }, { 0x1a, "T1_6" }, { 0x1b, "PE_6" },
  895. { 0x1c, "L1_7" }, { 0x1d, "T1_7" }, { 0x1e, "PE_7" },
  896. { 0x1f, "GPM" },
  897. { 0x20, "LTP_UTLB_0" },
  898. { 0x21, "LTP_UTLB_1" },
  899. { 0x22, "LTP_UTLB_2" },
  900. { 0x23, "LTP_UTLB_3" },
  901. { 0x24, "GPC_RGG_UTLB" },
  902. {}
  903. };
  904. static const struct gk104_fifo_func
  905. gk104_fifo = {
  906. .fault.engine = gk104_fifo_fault_engine,
  907. .fault.reason = gk104_fifo_fault_reason,
  908. .fault.hubclient = gk104_fifo_fault_hubclient,
  909. .fault.gpcclient = gk104_fifo_fault_gpcclient,
  910. .chan = {
  911. &gk104_fifo_gpfifo_oclass,
  912. NULL
  913. },
  914. };
  915. int
  916. gk104_fifo_new(struct nvkm_device *device, int index, struct nvkm_fifo **pfifo)
  917. {
  918. return gk104_fifo_new_(&gk104_fifo, device, index, 4096, pfifo);
  919. }