panfrost_job.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989
  1. // SPDX-License-Identifier: GPL-2.0
  2. /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
  3. /* Copyright 2019 Collabora ltd. */
  4. #include <linux/delay.h>
  5. #include <linux/interrupt.h>
  6. #include <linux/io.h>
  7. #include <linux/iopoll.h>
  8. #include <linux/platform_device.h>
  9. #include <linux/pm_runtime.h>
  10. #include <linux/dma-resv.h>
  11. #include <drm/gpu_scheduler.h>
  12. #include <drm/panfrost_drm.h>
  13. #include "panfrost_device.h"
  14. #include "panfrost_devfreq.h"
  15. #include "panfrost_job.h"
  16. #include "panfrost_features.h"
  17. #include "panfrost_issues.h"
  18. #include "panfrost_gem.h"
  19. #include "panfrost_regs.h"
  20. #include "panfrost_gpu.h"
  21. #include "panfrost_mmu.h"
  22. #include "panfrost_dump.h"
  23. #define JOB_TIMEOUT_MS 500
  24. #define job_write(dev, reg, data) writel(data, dev->iomem + (reg))
  25. #define job_read(dev, reg) readl(dev->iomem + (reg))
  26. struct panfrost_queue_state {
  27. struct drm_gpu_scheduler sched;
  28. u64 fence_context;
  29. u64 emit_seqno;
  30. };
  31. struct panfrost_job_slot {
  32. struct panfrost_queue_state queue[NUM_JOB_SLOTS];
  33. spinlock_t job_lock;
  34. int irq;
  35. };
  36. static struct panfrost_job *
  37. to_panfrost_job(struct drm_sched_job *sched_job)
  38. {
  39. return container_of(sched_job, struct panfrost_job, base);
  40. }
  41. struct panfrost_fence {
  42. struct dma_fence base;
  43. struct drm_device *dev;
  44. /* panfrost seqno for signaled() test */
  45. u64 seqno;
  46. int queue;
  47. };
  48. static inline struct panfrost_fence *
  49. to_panfrost_fence(struct dma_fence *fence)
  50. {
  51. return (struct panfrost_fence *)fence;
  52. }
  53. static const char *panfrost_fence_get_driver_name(struct dma_fence *fence)
  54. {
  55. return "panfrost";
  56. }
  57. static const char *panfrost_fence_get_timeline_name(struct dma_fence *fence)
  58. {
  59. struct panfrost_fence *f = to_panfrost_fence(fence);
  60. switch (f->queue) {
  61. case 0:
  62. return "panfrost-js-0";
  63. case 1:
  64. return "panfrost-js-1";
  65. case 2:
  66. return "panfrost-js-2";
  67. default:
  68. return NULL;
  69. }
  70. }
  71. static const struct dma_fence_ops panfrost_fence_ops = {
  72. .get_driver_name = panfrost_fence_get_driver_name,
  73. .get_timeline_name = panfrost_fence_get_timeline_name,
  74. };
  75. static struct dma_fence *panfrost_fence_create(struct panfrost_device *pfdev, int js_num)
  76. {
  77. struct panfrost_fence *fence;
  78. struct panfrost_job_slot *js = pfdev->js;
  79. fence = kzalloc(sizeof(*fence), GFP_KERNEL);
  80. if (!fence)
  81. return ERR_PTR(-ENOMEM);
  82. fence->dev = pfdev->ddev;
  83. fence->queue = js_num;
  84. fence->seqno = ++js->queue[js_num].emit_seqno;
  85. dma_fence_init(&fence->base, &panfrost_fence_ops, &js->job_lock,
  86. js->queue[js_num].fence_context, fence->seqno);
  87. return &fence->base;
  88. }
  89. int panfrost_job_get_slot(struct panfrost_job *job)
  90. {
  91. /* JS0: fragment jobs.
  92. * JS1: vertex/tiler jobs
  93. * JS2: compute jobs
  94. */
  95. if (job->requirements & PANFROST_JD_REQ_FS)
  96. return 0;
  97. /* Not exposed to userspace yet */
  98. #if 0
  99. if (job->requirements & PANFROST_JD_REQ_ONLY_COMPUTE) {
  100. if ((job->requirements & PANFROST_JD_REQ_CORE_GRP_MASK) &&
  101. (job->pfdev->features.nr_core_groups == 2))
  102. return 2;
  103. if (panfrost_has_hw_issue(job->pfdev, HW_ISSUE_8987))
  104. return 2;
  105. }
  106. #endif
  107. return 1;
  108. }
  109. static void panfrost_job_write_affinity(struct panfrost_device *pfdev,
  110. u32 requirements,
  111. int js)
  112. {
  113. u64 affinity;
  114. /*
  115. * Use all cores for now.
  116. * Eventually we may need to support tiler only jobs and h/w with
  117. * multiple (2) coherent core groups
  118. */
  119. affinity = pfdev->features.shader_present;
  120. job_write(pfdev, JS_AFFINITY_NEXT_LO(js), lower_32_bits(affinity));
  121. job_write(pfdev, JS_AFFINITY_NEXT_HI(js), upper_32_bits(affinity));
  122. }
  123. static u32
  124. panfrost_get_job_chain_flag(const struct panfrost_job *job)
  125. {
  126. struct panfrost_fence *f = to_panfrost_fence(job->done_fence);
  127. if (!panfrost_has_hw_feature(job->pfdev, HW_FEATURE_JOBCHAIN_DISAMBIGUATION))
  128. return 0;
  129. return (f->seqno & 1) ? JS_CONFIG_JOB_CHAIN_FLAG : 0;
  130. }
  131. static struct panfrost_job *
  132. panfrost_dequeue_job(struct panfrost_device *pfdev, int slot)
  133. {
  134. struct panfrost_job *job = pfdev->jobs[slot][0];
  135. WARN_ON(!job);
  136. if (job->is_profiled) {
  137. if (job->engine_usage) {
  138. job->engine_usage->elapsed_ns[slot] +=
  139. ktime_to_ns(ktime_sub(ktime_get(), job->start_time));
  140. job->engine_usage->cycles[slot] +=
  141. panfrost_cycle_counter_read(pfdev) - job->start_cycles;
  142. }
  143. panfrost_cycle_counter_put(job->pfdev);
  144. }
  145. pfdev->jobs[slot][0] = pfdev->jobs[slot][1];
  146. pfdev->jobs[slot][1] = NULL;
  147. return job;
  148. }
  149. static unsigned int
  150. panfrost_enqueue_job(struct panfrost_device *pfdev, int slot,
  151. struct panfrost_job *job)
  152. {
  153. if (WARN_ON(!job))
  154. return 0;
  155. if (!pfdev->jobs[slot][0]) {
  156. pfdev->jobs[slot][0] = job;
  157. return 0;
  158. }
  159. WARN_ON(pfdev->jobs[slot][1]);
  160. pfdev->jobs[slot][1] = job;
  161. WARN_ON(panfrost_get_job_chain_flag(job) ==
  162. panfrost_get_job_chain_flag(pfdev->jobs[slot][0]));
  163. return 1;
  164. }
  165. static void panfrost_job_hw_submit(struct panfrost_job *job, int js)
  166. {
  167. struct panfrost_device *pfdev = job->pfdev;
  168. unsigned int subslot;
  169. u32 cfg;
  170. u64 jc_head = job->jc;
  171. int ret;
  172. panfrost_devfreq_record_busy(&pfdev->pfdevfreq);
  173. ret = pm_runtime_get_sync(pfdev->dev);
  174. if (ret < 0)
  175. return;
  176. if (WARN_ON(job_read(pfdev, JS_COMMAND_NEXT(js)))) {
  177. return;
  178. }
  179. cfg = panfrost_mmu_as_get(pfdev, job->mmu);
  180. job_write(pfdev, JS_HEAD_NEXT_LO(js), lower_32_bits(jc_head));
  181. job_write(pfdev, JS_HEAD_NEXT_HI(js), upper_32_bits(jc_head));
  182. panfrost_job_write_affinity(pfdev, job->requirements, js);
  183. /* start MMU, medium priority, cache clean/flush on end, clean/flush on
  184. * start */
  185. cfg |= JS_CONFIG_THREAD_PRI(8) |
  186. JS_CONFIG_START_FLUSH_CLEAN_INVALIDATE |
  187. JS_CONFIG_END_FLUSH_CLEAN_INVALIDATE |
  188. panfrost_get_job_chain_flag(job);
  189. if (panfrost_has_hw_feature(pfdev, HW_FEATURE_FLUSH_REDUCTION))
  190. cfg |= JS_CONFIG_ENABLE_FLUSH_REDUCTION;
  191. if (panfrost_has_hw_issue(pfdev, HW_ISSUE_10649))
  192. cfg |= JS_CONFIG_START_MMU;
  193. job_write(pfdev, JS_CONFIG_NEXT(js), cfg);
  194. if (panfrost_has_hw_feature(pfdev, HW_FEATURE_FLUSH_REDUCTION))
  195. job_write(pfdev, JS_FLUSH_ID_NEXT(js), job->flush_id);
  196. /* GO ! */
  197. spin_lock(&pfdev->js->job_lock);
  198. subslot = panfrost_enqueue_job(pfdev, js, job);
  199. /* Don't queue the job if a reset is in progress */
  200. if (!atomic_read(&pfdev->reset.pending)) {
  201. if (pfdev->profile_mode) {
  202. panfrost_cycle_counter_get(pfdev);
  203. job->is_profiled = true;
  204. job->start_time = ktime_get();
  205. job->start_cycles = panfrost_cycle_counter_read(pfdev);
  206. }
  207. job_write(pfdev, JS_COMMAND_NEXT(js), JS_COMMAND_START);
  208. dev_dbg(pfdev->dev,
  209. "JS: Submitting atom %p to js[%d][%d] with head=0x%llx AS %d",
  210. job, js, subslot, jc_head, cfg & 0xf);
  211. }
  212. spin_unlock(&pfdev->js->job_lock);
  213. }
  214. static int panfrost_acquire_object_fences(struct drm_gem_object **bos,
  215. int bo_count,
  216. struct drm_sched_job *job)
  217. {
  218. int i, ret;
  219. for (i = 0; i < bo_count; i++) {
  220. ret = dma_resv_reserve_fences(bos[i]->resv, 1);
  221. if (ret)
  222. return ret;
  223. /* panfrost always uses write mode in its current uapi */
  224. ret = drm_sched_job_add_implicit_dependencies(job, bos[i],
  225. true);
  226. if (ret)
  227. return ret;
  228. }
  229. return 0;
  230. }
  231. static void panfrost_attach_object_fences(struct drm_gem_object **bos,
  232. int bo_count,
  233. struct dma_fence *fence)
  234. {
  235. int i;
  236. for (i = 0; i < bo_count; i++)
  237. dma_resv_add_fence(bos[i]->resv, fence, DMA_RESV_USAGE_WRITE);
  238. }
  239. int panfrost_job_push(struct panfrost_job *job)
  240. {
  241. struct panfrost_device *pfdev = job->pfdev;
  242. struct ww_acquire_ctx acquire_ctx;
  243. int ret = 0;
  244. ret = drm_gem_lock_reservations(job->bos, job->bo_count,
  245. &acquire_ctx);
  246. if (ret)
  247. return ret;
  248. mutex_lock(&pfdev->sched_lock);
  249. drm_sched_job_arm(&job->base);
  250. job->render_done_fence = dma_fence_get(&job->base.s_fence->finished);
  251. ret = panfrost_acquire_object_fences(job->bos, job->bo_count,
  252. &job->base);
  253. if (ret) {
  254. mutex_unlock(&pfdev->sched_lock);
  255. goto unlock;
  256. }
  257. kref_get(&job->refcount); /* put by scheduler job completion */
  258. drm_sched_entity_push_job(&job->base);
  259. mutex_unlock(&pfdev->sched_lock);
  260. panfrost_attach_object_fences(job->bos, job->bo_count,
  261. job->render_done_fence);
  262. unlock:
  263. drm_gem_unlock_reservations(job->bos, job->bo_count, &acquire_ctx);
  264. return ret;
  265. }
  266. static void panfrost_job_cleanup(struct kref *ref)
  267. {
  268. struct panfrost_job *job = container_of(ref, struct panfrost_job,
  269. refcount);
  270. unsigned int i;
  271. dma_fence_put(job->done_fence);
  272. dma_fence_put(job->render_done_fence);
  273. if (job->mappings) {
  274. for (i = 0; i < job->bo_count; i++) {
  275. if (!job->mappings[i])
  276. break;
  277. atomic_dec(&job->mappings[i]->obj->gpu_usecount);
  278. panfrost_gem_mapping_put(job->mappings[i]);
  279. }
  280. kvfree(job->mappings);
  281. }
  282. if (job->bos) {
  283. for (i = 0; i < job->bo_count; i++)
  284. drm_gem_object_put(job->bos[i]);
  285. kvfree(job->bos);
  286. }
  287. kfree(job);
  288. }
  289. void panfrost_job_put(struct panfrost_job *job)
  290. {
  291. kref_put(&job->refcount, panfrost_job_cleanup);
  292. }
  293. static void panfrost_job_free(struct drm_sched_job *sched_job)
  294. {
  295. struct panfrost_job *job = to_panfrost_job(sched_job);
  296. drm_sched_job_cleanup(sched_job);
  297. panfrost_job_put(job);
  298. }
  299. static struct dma_fence *panfrost_job_run(struct drm_sched_job *sched_job)
  300. {
  301. struct panfrost_job *job = to_panfrost_job(sched_job);
  302. struct panfrost_device *pfdev = job->pfdev;
  303. int slot = panfrost_job_get_slot(job);
  304. struct dma_fence *fence = NULL;
  305. if (unlikely(job->base.s_fence->finished.error))
  306. return NULL;
  307. /* Nothing to execute: can happen if the job has finished while
  308. * we were resetting the GPU.
  309. */
  310. if (!job->jc)
  311. return NULL;
  312. fence = panfrost_fence_create(pfdev, slot);
  313. if (IS_ERR(fence))
  314. return fence;
  315. if (job->done_fence)
  316. dma_fence_put(job->done_fence);
  317. job->done_fence = dma_fence_get(fence);
  318. panfrost_job_hw_submit(job, slot);
  319. return fence;
  320. }
  321. void panfrost_job_enable_interrupts(struct panfrost_device *pfdev)
  322. {
  323. int j;
  324. u32 irq_mask = 0;
  325. clear_bit(PANFROST_COMP_BIT_JOB, pfdev->is_suspended);
  326. for (j = 0; j < NUM_JOB_SLOTS; j++) {
  327. irq_mask |= MK_JS_MASK(j);
  328. }
  329. job_write(pfdev, JOB_INT_CLEAR, irq_mask);
  330. job_write(pfdev, JOB_INT_MASK, irq_mask);
  331. }
  332. void panfrost_job_suspend_irq(struct panfrost_device *pfdev)
  333. {
  334. set_bit(PANFROST_COMP_BIT_JOB, pfdev->is_suspended);
  335. job_write(pfdev, JOB_INT_MASK, 0);
  336. synchronize_irq(pfdev->js->irq);
  337. }
  338. static void panfrost_job_handle_err(struct panfrost_device *pfdev,
  339. struct panfrost_job *job,
  340. unsigned int js)
  341. {
  342. u32 js_status = job_read(pfdev, JS_STATUS(js));
  343. const char *exception_name = panfrost_exception_name(js_status);
  344. bool signal_fence = true;
  345. if (!panfrost_exception_is_fault(js_status)) {
  346. dev_dbg(pfdev->dev, "js event, js=%d, status=%s, head=0x%x, tail=0x%x",
  347. js, exception_name,
  348. job_read(pfdev, JS_HEAD_LO(js)),
  349. job_read(pfdev, JS_TAIL_LO(js)));
  350. } else {
  351. dev_err(pfdev->dev, "js fault, js=%d, status=%s, head=0x%x, tail=0x%x",
  352. js, exception_name,
  353. job_read(pfdev, JS_HEAD_LO(js)),
  354. job_read(pfdev, JS_TAIL_LO(js)));
  355. }
  356. if (js_status == DRM_PANFROST_EXCEPTION_STOPPED) {
  357. /* Update the job head so we can resume */
  358. job->jc = job_read(pfdev, JS_TAIL_LO(js)) |
  359. ((u64)job_read(pfdev, JS_TAIL_HI(js)) << 32);
  360. /* The job will be resumed, don't signal the fence */
  361. signal_fence = false;
  362. } else if (js_status == DRM_PANFROST_EXCEPTION_TERMINATED) {
  363. /* Job has been hard-stopped, flag it as canceled */
  364. dma_fence_set_error(job->done_fence, -ECANCELED);
  365. job->jc = 0;
  366. } else if (panfrost_exception_is_fault(js_status)) {
  367. /* We might want to provide finer-grained error code based on
  368. * the exception type, but unconditionally setting to EINVAL
  369. * is good enough for now.
  370. */
  371. dma_fence_set_error(job->done_fence, -EINVAL);
  372. job->jc = 0;
  373. }
  374. panfrost_mmu_as_put(pfdev, job->mmu);
  375. panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
  376. if (signal_fence)
  377. dma_fence_signal_locked(job->done_fence);
  378. pm_runtime_put_autosuspend(pfdev->dev);
  379. if (panfrost_exception_needs_reset(pfdev, js_status)) {
  380. atomic_set(&pfdev->reset.pending, 1);
  381. drm_sched_fault(&pfdev->js->queue[js].sched);
  382. }
  383. }
  384. static void panfrost_job_handle_done(struct panfrost_device *pfdev,
  385. struct panfrost_job *job)
  386. {
  387. /* Set ->jc to 0 to avoid re-submitting an already finished job (can
  388. * happen when we receive the DONE interrupt while doing a GPU reset).
  389. */
  390. job->jc = 0;
  391. panfrost_mmu_as_put(pfdev, job->mmu);
  392. panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
  393. dma_fence_signal_locked(job->done_fence);
  394. pm_runtime_put_autosuspend(pfdev->dev);
  395. }
  396. static void panfrost_job_handle_irq(struct panfrost_device *pfdev, u32 status)
  397. {
  398. struct panfrost_job *done[NUM_JOB_SLOTS][2] = {};
  399. struct panfrost_job *failed[NUM_JOB_SLOTS] = {};
  400. u32 js_state = 0, js_events = 0;
  401. unsigned int i, j;
  402. /* First we collect all failed/done jobs. */
  403. while (status) {
  404. u32 js_state_mask = 0;
  405. for (j = 0; j < NUM_JOB_SLOTS; j++) {
  406. if (status & MK_JS_MASK(j))
  407. js_state_mask |= MK_JS_MASK(j);
  408. if (status & JOB_INT_MASK_DONE(j)) {
  409. if (done[j][0])
  410. done[j][1] = panfrost_dequeue_job(pfdev, j);
  411. else
  412. done[j][0] = panfrost_dequeue_job(pfdev, j);
  413. }
  414. if (status & JOB_INT_MASK_ERR(j)) {
  415. /* Cancel the next submission. Will be submitted
  416. * after we're done handling this failure if
  417. * there's no reset pending.
  418. */
  419. job_write(pfdev, JS_COMMAND_NEXT(j), JS_COMMAND_NOP);
  420. failed[j] = panfrost_dequeue_job(pfdev, j);
  421. }
  422. }
  423. /* JS_STATE is sampled when JOB_INT_CLEAR is written.
  424. * For each BIT(slot) or BIT(slot + 16) bit written to
  425. * JOB_INT_CLEAR, the corresponding bits in JS_STATE
  426. * (BIT(slot) and BIT(slot + 16)) are updated, but this
  427. * is racy. If we only have one job done at the time we
  428. * read JOB_INT_RAWSTAT but the second job fails before we
  429. * clear the status, we end up with a status containing
  430. * only the DONE bit and consider both jobs as DONE since
  431. * JS_STATE reports both NEXT and CURRENT as inactive.
  432. * To prevent that, let's repeat this clear+read steps
  433. * until status is 0.
  434. */
  435. job_write(pfdev, JOB_INT_CLEAR, status);
  436. js_state &= ~js_state_mask;
  437. js_state |= job_read(pfdev, JOB_INT_JS_STATE) & js_state_mask;
  438. js_events |= status;
  439. status = job_read(pfdev, JOB_INT_RAWSTAT);
  440. }
  441. /* Then we handle the dequeued jobs. */
  442. for (j = 0; j < NUM_JOB_SLOTS; j++) {
  443. if (!(js_events & MK_JS_MASK(j)))
  444. continue;
  445. if (failed[j]) {
  446. panfrost_job_handle_err(pfdev, failed[j], j);
  447. } else if (pfdev->jobs[j][0] && !(js_state & MK_JS_MASK(j))) {
  448. /* When the current job doesn't fail, the JM dequeues
  449. * the next job without waiting for an ACK, this means
  450. * we can have 2 jobs dequeued and only catch the
  451. * interrupt when the second one is done. If both slots
  452. * are inactive, but one job remains in pfdev->jobs[j],
  453. * consider it done. Of course that doesn't apply if a
  454. * failure happened since we cancelled execution of the
  455. * job in _NEXT (see above).
  456. */
  457. if (WARN_ON(!done[j][0]))
  458. done[j][0] = panfrost_dequeue_job(pfdev, j);
  459. else
  460. done[j][1] = panfrost_dequeue_job(pfdev, j);
  461. }
  462. for (i = 0; i < ARRAY_SIZE(done[0]) && done[j][i]; i++)
  463. panfrost_job_handle_done(pfdev, done[j][i]);
  464. }
  465. /* And finally we requeue jobs that were waiting in the second slot
  466. * and have been stopped if we detected a failure on the first slot.
  467. */
  468. for (j = 0; j < NUM_JOB_SLOTS; j++) {
  469. if (!(js_events & MK_JS_MASK(j)))
  470. continue;
  471. if (!failed[j] || !pfdev->jobs[j][0])
  472. continue;
  473. if (pfdev->jobs[j][0]->jc == 0) {
  474. /* The job was cancelled, signal the fence now */
  475. struct panfrost_job *canceled = panfrost_dequeue_job(pfdev, j);
  476. dma_fence_set_error(canceled->done_fence, -ECANCELED);
  477. panfrost_job_handle_done(pfdev, canceled);
  478. } else if (!atomic_read(&pfdev->reset.pending)) {
  479. /* Requeue the job we removed if no reset is pending */
  480. job_write(pfdev, JS_COMMAND_NEXT(j), JS_COMMAND_START);
  481. }
  482. }
  483. }
  484. static void panfrost_job_handle_irqs(struct panfrost_device *pfdev)
  485. {
  486. u32 status = job_read(pfdev, JOB_INT_RAWSTAT);
  487. while (status) {
  488. pm_runtime_mark_last_busy(pfdev->dev);
  489. spin_lock(&pfdev->js->job_lock);
  490. panfrost_job_handle_irq(pfdev, status);
  491. spin_unlock(&pfdev->js->job_lock);
  492. status = job_read(pfdev, JOB_INT_RAWSTAT);
  493. }
  494. }
  495. static u32 panfrost_active_slots(struct panfrost_device *pfdev,
  496. u32 *js_state_mask, u32 js_state)
  497. {
  498. u32 rawstat;
  499. if (!(js_state & *js_state_mask))
  500. return 0;
  501. rawstat = job_read(pfdev, JOB_INT_RAWSTAT);
  502. if (rawstat) {
  503. unsigned int i;
  504. for (i = 0; i < NUM_JOB_SLOTS; i++) {
  505. if (rawstat & MK_JS_MASK(i))
  506. *js_state_mask &= ~MK_JS_MASK(i);
  507. }
  508. }
  509. return js_state & *js_state_mask;
  510. }
  511. static void
  512. panfrost_reset(struct panfrost_device *pfdev,
  513. struct drm_sched_job *bad)
  514. {
  515. u32 js_state, js_state_mask = 0xffffffff;
  516. unsigned int i, j;
  517. bool cookie;
  518. int ret;
  519. if (!atomic_read(&pfdev->reset.pending))
  520. return;
  521. /* Stop the schedulers.
  522. *
  523. * FIXME: We temporarily get out of the dma_fence_signalling section
  524. * because the cleanup path generate lockdep splats when taking locks
  525. * to release job resources. We should rework the code to follow this
  526. * pattern:
  527. *
  528. * try_lock
  529. * if (locked)
  530. * release
  531. * else
  532. * schedule_work_to_release_later
  533. */
  534. for (i = 0; i < NUM_JOB_SLOTS; i++)
  535. drm_sched_stop(&pfdev->js->queue[i].sched, bad);
  536. cookie = dma_fence_begin_signalling();
  537. if (bad)
  538. drm_sched_increase_karma(bad);
  539. /* Mask job interrupts and synchronize to make sure we won't be
  540. * interrupted during our reset.
  541. */
  542. job_write(pfdev, JOB_INT_MASK, 0);
  543. synchronize_irq(pfdev->js->irq);
  544. for (i = 0; i < NUM_JOB_SLOTS; i++) {
  545. /* Cancel the next job and soft-stop the running job. */
  546. job_write(pfdev, JS_COMMAND_NEXT(i), JS_COMMAND_NOP);
  547. job_write(pfdev, JS_COMMAND(i), JS_COMMAND_SOFT_STOP);
  548. }
  549. /* Wait at most 10ms for soft-stops to complete */
  550. ret = readl_poll_timeout(pfdev->iomem + JOB_INT_JS_STATE, js_state,
  551. !panfrost_active_slots(pfdev, &js_state_mask, js_state),
  552. 10, 10000);
  553. if (ret)
  554. dev_err(pfdev->dev, "Soft-stop failed\n");
  555. /* Handle the remaining interrupts before we reset. */
  556. panfrost_job_handle_irqs(pfdev);
  557. /* Remaining interrupts have been handled, but we might still have
  558. * stuck jobs. Let's make sure the PM counters stay balanced by
  559. * manually calling pm_runtime_put_noidle() and
  560. * panfrost_devfreq_record_idle() for each stuck job.
  561. * Let's also make sure the cycle counting register's refcnt is
  562. * kept balanced to prevent it from running forever
  563. */
  564. spin_lock(&pfdev->js->job_lock);
  565. for (i = 0; i < NUM_JOB_SLOTS; i++) {
  566. for (j = 0; j < ARRAY_SIZE(pfdev->jobs[0]) && pfdev->jobs[i][j]; j++) {
  567. if (pfdev->jobs[i][j]->is_profiled)
  568. panfrost_cycle_counter_put(pfdev->jobs[i][j]->pfdev);
  569. pm_runtime_put_noidle(pfdev->dev);
  570. panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
  571. }
  572. }
  573. memset(pfdev->jobs, 0, sizeof(pfdev->jobs));
  574. spin_unlock(&pfdev->js->job_lock);
  575. /* Proceed with reset now. */
  576. panfrost_device_reset(pfdev);
  577. /* panfrost_device_reset() unmasks job interrupts, but we want to
  578. * keep them masked a bit longer.
  579. */
  580. job_write(pfdev, JOB_INT_MASK, 0);
  581. /* GPU has been reset, we can clear the reset pending bit. */
  582. atomic_set(&pfdev->reset.pending, 0);
  583. /* Now resubmit jobs that were previously queued but didn't have a
  584. * chance to finish.
  585. * FIXME: We temporarily get out of the DMA fence signalling section
  586. * while resubmitting jobs because the job submission logic will
  587. * allocate memory with the GFP_KERNEL flag which can trigger memory
  588. * reclaim and exposes a lock ordering issue.
  589. */
  590. dma_fence_end_signalling(cookie);
  591. for (i = 0; i < NUM_JOB_SLOTS; i++)
  592. drm_sched_resubmit_jobs(&pfdev->js->queue[i].sched);
  593. cookie = dma_fence_begin_signalling();
  594. /* Restart the schedulers */
  595. for (i = 0; i < NUM_JOB_SLOTS; i++)
  596. drm_sched_start(&pfdev->js->queue[i].sched);
  597. /* Re-enable job interrupts now that everything has been restarted. */
  598. job_write(pfdev, JOB_INT_MASK,
  599. GENMASK(16 + NUM_JOB_SLOTS - 1, 16) |
  600. GENMASK(NUM_JOB_SLOTS - 1, 0));
  601. dma_fence_end_signalling(cookie);
  602. }
  603. static enum drm_gpu_sched_stat panfrost_job_timedout(struct drm_sched_job
  604. *sched_job)
  605. {
  606. struct panfrost_job *job = to_panfrost_job(sched_job);
  607. struct panfrost_device *pfdev = job->pfdev;
  608. int js = panfrost_job_get_slot(job);
  609. /*
  610. * If the GPU managed to complete this jobs fence, the timeout is
  611. * spurious. Bail out.
  612. */
  613. if (dma_fence_is_signaled(job->done_fence))
  614. return DRM_GPU_SCHED_STAT_NOMINAL;
  615. /*
  616. * Panfrost IRQ handler may take a long time to process an interrupt
  617. * if there is another IRQ handler hogging the processing.
  618. * For example, the HDMI encoder driver might be stuck in the IRQ
  619. * handler for a significant time in a case of bad cable connection.
  620. * In order to catch such cases and not report spurious Panfrost
  621. * job timeouts, synchronize the IRQ handler and re-check the fence
  622. * status.
  623. */
  624. synchronize_irq(pfdev->js->irq);
  625. if (dma_fence_is_signaled(job->done_fence)) {
  626. dev_warn(pfdev->dev, "unexpectedly high interrupt latency\n");
  627. return DRM_GPU_SCHED_STAT_NOMINAL;
  628. }
  629. dev_err(pfdev->dev, "gpu sched timeout, js=%d, config=0x%x, status=0x%x, head=0x%x, tail=0x%x, sched_job=%p",
  630. js,
  631. job_read(pfdev, JS_CONFIG(js)),
  632. job_read(pfdev, JS_STATUS(js)),
  633. job_read(pfdev, JS_HEAD_LO(js)),
  634. job_read(pfdev, JS_TAIL_LO(js)),
  635. sched_job);
  636. panfrost_core_dump(job);
  637. atomic_set(&pfdev->reset.pending, 1);
  638. panfrost_reset(pfdev, sched_job);
  639. return DRM_GPU_SCHED_STAT_NOMINAL;
  640. }
  641. static void panfrost_reset_work(struct work_struct *work)
  642. {
  643. struct panfrost_device *pfdev;
  644. pfdev = container_of(work, struct panfrost_device, reset.work);
  645. panfrost_reset(pfdev, NULL);
  646. }
  647. static const struct drm_sched_backend_ops panfrost_sched_ops = {
  648. .run_job = panfrost_job_run,
  649. .timedout_job = panfrost_job_timedout,
  650. .free_job = panfrost_job_free
  651. };
  652. static irqreturn_t panfrost_job_irq_handler_thread(int irq, void *data)
  653. {
  654. struct panfrost_device *pfdev = data;
  655. panfrost_job_handle_irqs(pfdev);
  656. /* Enable interrupts only if we're not about to get suspended */
  657. if (!test_bit(PANFROST_COMP_BIT_JOB, pfdev->is_suspended))
  658. job_write(pfdev, JOB_INT_MASK,
  659. GENMASK(16 + NUM_JOB_SLOTS - 1, 16) |
  660. GENMASK(NUM_JOB_SLOTS - 1, 0));
  661. return IRQ_HANDLED;
  662. }
  663. static irqreturn_t panfrost_job_irq_handler(int irq, void *data)
  664. {
  665. struct panfrost_device *pfdev = data;
  666. u32 status;
  667. if (test_bit(PANFROST_COMP_BIT_JOB, pfdev->is_suspended))
  668. return IRQ_NONE;
  669. status = job_read(pfdev, JOB_INT_STAT);
  670. if (!status)
  671. return IRQ_NONE;
  672. job_write(pfdev, JOB_INT_MASK, 0);
  673. return IRQ_WAKE_THREAD;
  674. }
  675. int panfrost_job_init(struct panfrost_device *pfdev)
  676. {
  677. struct panfrost_job_slot *js;
  678. unsigned int nentries = 2;
  679. int ret, j;
  680. /* All GPUs have two entries per queue, but without jobchain
  681. * disambiguation stopping the right job in the close path is tricky,
  682. * so let's just advertise one entry in that case.
  683. */
  684. if (!panfrost_has_hw_feature(pfdev, HW_FEATURE_JOBCHAIN_DISAMBIGUATION))
  685. nentries = 1;
  686. pfdev->js = js = devm_kzalloc(pfdev->dev, sizeof(*js), GFP_KERNEL);
  687. if (!js)
  688. return -ENOMEM;
  689. INIT_WORK(&pfdev->reset.work, panfrost_reset_work);
  690. spin_lock_init(&js->job_lock);
  691. js->irq = platform_get_irq_byname(to_platform_device(pfdev->dev), "job");
  692. if (js->irq < 0)
  693. return js->irq;
  694. ret = devm_request_threaded_irq(pfdev->dev, js->irq,
  695. panfrost_job_irq_handler,
  696. panfrost_job_irq_handler_thread,
  697. IRQF_SHARED, KBUILD_MODNAME "-job",
  698. pfdev);
  699. if (ret) {
  700. dev_err(pfdev->dev, "failed to request job irq");
  701. return ret;
  702. }
  703. pfdev->reset.wq = alloc_ordered_workqueue("panfrost-reset", 0);
  704. if (!pfdev->reset.wq)
  705. return -ENOMEM;
  706. for (j = 0; j < NUM_JOB_SLOTS; j++) {
  707. js->queue[j].fence_context = dma_fence_context_alloc(1);
  708. ret = drm_sched_init(&js->queue[j].sched,
  709. &panfrost_sched_ops, NULL,
  710. DRM_SCHED_PRIORITY_COUNT,
  711. nentries, 0,
  712. msecs_to_jiffies(JOB_TIMEOUT_MS),
  713. pfdev->reset.wq,
  714. NULL, "pan_js", pfdev->dev);
  715. if (ret) {
  716. dev_err(pfdev->dev, "Failed to create scheduler: %d.", ret);
  717. goto err_sched;
  718. }
  719. }
  720. panfrost_job_enable_interrupts(pfdev);
  721. return 0;
  722. err_sched:
  723. for (j--; j >= 0; j--)
  724. drm_sched_fini(&js->queue[j].sched);
  725. destroy_workqueue(pfdev->reset.wq);
  726. return ret;
  727. }
  728. void panfrost_job_fini(struct panfrost_device *pfdev)
  729. {
  730. struct panfrost_job_slot *js = pfdev->js;
  731. int j;
  732. job_write(pfdev, JOB_INT_MASK, 0);
  733. for (j = 0; j < NUM_JOB_SLOTS; j++) {
  734. drm_sched_fini(&js->queue[j].sched);
  735. }
  736. cancel_work_sync(&pfdev->reset.work);
  737. destroy_workqueue(pfdev->reset.wq);
  738. }
  739. int panfrost_job_open(struct panfrost_file_priv *panfrost_priv)
  740. {
  741. struct panfrost_device *pfdev = panfrost_priv->pfdev;
  742. struct panfrost_job_slot *js = pfdev->js;
  743. struct drm_gpu_scheduler *sched;
  744. int ret, i;
  745. for (i = 0; i < NUM_JOB_SLOTS; i++) {
  746. sched = &js->queue[i].sched;
  747. ret = drm_sched_entity_init(&panfrost_priv->sched_entity[i],
  748. DRM_SCHED_PRIORITY_NORMAL, &sched,
  749. 1, NULL);
  750. if (WARN_ON(ret))
  751. return ret;
  752. }
  753. return 0;
  754. }
  755. void panfrost_job_close(struct panfrost_file_priv *panfrost_priv)
  756. {
  757. struct panfrost_device *pfdev = panfrost_priv->pfdev;
  758. int i;
  759. for (i = 0; i < NUM_JOB_SLOTS; i++)
  760. drm_sched_entity_destroy(&panfrost_priv->sched_entity[i]);
  761. /* Kill in-flight jobs */
  762. spin_lock(&pfdev->js->job_lock);
  763. for (i = 0; i < NUM_JOB_SLOTS; i++) {
  764. struct drm_sched_entity *entity = &panfrost_priv->sched_entity[i];
  765. int j;
  766. for (j = ARRAY_SIZE(pfdev->jobs[0]) - 1; j >= 0; j--) {
  767. struct panfrost_job *job = pfdev->jobs[i][j];
  768. u32 cmd;
  769. if (!job || job->base.entity != entity)
  770. continue;
  771. if (j == 1) {
  772. /* Try to cancel the job before it starts */
  773. job_write(pfdev, JS_COMMAND_NEXT(i), JS_COMMAND_NOP);
  774. /* Reset the job head so it doesn't get restarted if
  775. * the job in the first slot failed.
  776. */
  777. job->jc = 0;
  778. }
  779. if (panfrost_has_hw_feature(pfdev, HW_FEATURE_JOBCHAIN_DISAMBIGUATION)) {
  780. cmd = panfrost_get_job_chain_flag(job) ?
  781. JS_COMMAND_HARD_STOP_1 :
  782. JS_COMMAND_HARD_STOP_0;
  783. } else {
  784. cmd = JS_COMMAND_HARD_STOP;
  785. }
  786. job_write(pfdev, JS_COMMAND(i), cmd);
  787. /* Jobs can outlive their file context */
  788. job->engine_usage = NULL;
  789. }
  790. }
  791. spin_unlock(&pfdev->js->job_lock);
  792. }
  793. int panfrost_job_is_idle(struct panfrost_device *pfdev)
  794. {
  795. struct panfrost_job_slot *js = pfdev->js;
  796. int i;
  797. for (i = 0; i < NUM_JOB_SLOTS; i++) {
  798. /* If there are any jobs in the HW queue, we're not idle */
  799. if (atomic_read(&js->queue[i].sched.credit_count))
  800. return false;
  801. }
  802. return true;
  803. }