intel_engine_cs.c 31 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133
  1. /*
  2. * Copyright © 2016 Intel Corporation
  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 (including the next
  12. * paragraph) shall be included in all copies or substantial portions of the
  13. * Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  18. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21. * IN THE SOFTWARE.
  22. *
  23. */
  24. #include "i915_drv.h"
  25. #include "intel_ringbuffer.h"
  26. #include "intel_lrc.h"
  27. static const struct engine_info {
  28. const char *name;
  29. unsigned int exec_id;
  30. unsigned int hw_id;
  31. u32 mmio_base;
  32. unsigned irq_shift;
  33. int (*init_legacy)(struct intel_engine_cs *engine);
  34. int (*init_execlists)(struct intel_engine_cs *engine);
  35. } intel_engines[] = {
  36. [RCS] = {
  37. .name = "render ring",
  38. .exec_id = I915_EXEC_RENDER,
  39. .hw_id = RCS_HW,
  40. .mmio_base = RENDER_RING_BASE,
  41. .irq_shift = GEN8_RCS_IRQ_SHIFT,
  42. .init_execlists = logical_render_ring_init,
  43. .init_legacy = intel_init_render_ring_buffer,
  44. },
  45. [BCS] = {
  46. .name = "blitter ring",
  47. .exec_id = I915_EXEC_BLT,
  48. .hw_id = BCS_HW,
  49. .mmio_base = BLT_RING_BASE,
  50. .irq_shift = GEN8_BCS_IRQ_SHIFT,
  51. .init_execlists = logical_xcs_ring_init,
  52. .init_legacy = intel_init_blt_ring_buffer,
  53. },
  54. [VCS] = {
  55. .name = "bsd ring",
  56. .exec_id = I915_EXEC_BSD,
  57. .hw_id = VCS_HW,
  58. .mmio_base = GEN6_BSD_RING_BASE,
  59. .irq_shift = GEN8_VCS1_IRQ_SHIFT,
  60. .init_execlists = logical_xcs_ring_init,
  61. .init_legacy = intel_init_bsd_ring_buffer,
  62. },
  63. [VCS2] = {
  64. .name = "bsd2 ring",
  65. .exec_id = I915_EXEC_BSD,
  66. .hw_id = VCS2_HW,
  67. .mmio_base = GEN8_BSD2_RING_BASE,
  68. .irq_shift = GEN8_VCS2_IRQ_SHIFT,
  69. .init_execlists = logical_xcs_ring_init,
  70. .init_legacy = intel_init_bsd2_ring_buffer,
  71. },
  72. [VECS] = {
  73. .name = "video enhancement ring",
  74. .exec_id = I915_EXEC_VEBOX,
  75. .hw_id = VECS_HW,
  76. .mmio_base = VEBOX_RING_BASE,
  77. .irq_shift = GEN8_VECS_IRQ_SHIFT,
  78. .init_execlists = logical_xcs_ring_init,
  79. .init_legacy = intel_init_vebox_ring_buffer,
  80. },
  81. };
  82. static int
  83. intel_engine_setup(struct drm_i915_private *dev_priv,
  84. enum intel_engine_id id)
  85. {
  86. const struct engine_info *info = &intel_engines[id];
  87. struct intel_engine_cs *engine;
  88. GEM_BUG_ON(dev_priv->engine[id]);
  89. engine = kzalloc(sizeof(*engine), GFP_KERNEL);
  90. if (!engine)
  91. return -ENOMEM;
  92. engine->id = id;
  93. engine->i915 = dev_priv;
  94. engine->name = info->name;
  95. engine->exec_id = info->exec_id;
  96. engine->hw_id = engine->guc_id = info->hw_id;
  97. engine->mmio_base = info->mmio_base;
  98. engine->irq_shift = info->irq_shift;
  99. /* Nothing to do here, execute in order of dependencies */
  100. engine->schedule = NULL;
  101. ATOMIC_INIT_NOTIFIER_HEAD(&engine->context_status_notifier);
  102. dev_priv->engine[id] = engine;
  103. return 0;
  104. }
  105. /**
  106. * intel_engines_init_early() - allocate the Engine Command Streamers
  107. * @dev_priv: i915 device private
  108. *
  109. * Return: non-zero if the initialization failed.
  110. */
  111. int intel_engines_init_early(struct drm_i915_private *dev_priv)
  112. {
  113. struct intel_device_info *device_info = mkwrite_device_info(dev_priv);
  114. unsigned int ring_mask = INTEL_INFO(dev_priv)->ring_mask;
  115. unsigned int mask = 0;
  116. struct intel_engine_cs *engine;
  117. enum intel_engine_id id;
  118. unsigned int i;
  119. int err;
  120. WARN_ON(ring_mask == 0);
  121. WARN_ON(ring_mask &
  122. GENMASK(sizeof(mask) * BITS_PER_BYTE - 1, I915_NUM_ENGINES));
  123. for (i = 0; i < ARRAY_SIZE(intel_engines); i++) {
  124. if (!HAS_ENGINE(dev_priv, i))
  125. continue;
  126. err = intel_engine_setup(dev_priv, i);
  127. if (err)
  128. goto cleanup;
  129. mask |= ENGINE_MASK(i);
  130. }
  131. /*
  132. * Catch failures to update intel_engines table when the new engines
  133. * are added to the driver by a warning and disabling the forgotten
  134. * engines.
  135. */
  136. if (WARN_ON(mask != ring_mask))
  137. device_info->ring_mask = mask;
  138. device_info->num_rings = hweight32(mask);
  139. return 0;
  140. cleanup:
  141. for_each_engine(engine, dev_priv, id)
  142. kfree(engine);
  143. return err;
  144. }
  145. /**
  146. * intel_engines_init() - allocate, populate and init the Engine Command Streamers
  147. * @dev_priv: i915 device private
  148. *
  149. * Return: non-zero if the initialization failed.
  150. */
  151. int intel_engines_init(struct drm_i915_private *dev_priv)
  152. {
  153. struct intel_device_info *device_info = mkwrite_device_info(dev_priv);
  154. struct intel_engine_cs *engine;
  155. enum intel_engine_id id, err_id;
  156. unsigned int mask = 0;
  157. int err = 0;
  158. for_each_engine(engine, dev_priv, id) {
  159. int (*init)(struct intel_engine_cs *engine);
  160. if (i915.enable_execlists)
  161. init = intel_engines[id].init_execlists;
  162. else
  163. init = intel_engines[id].init_legacy;
  164. if (!init) {
  165. kfree(engine);
  166. dev_priv->engine[id] = NULL;
  167. continue;
  168. }
  169. err = init(engine);
  170. if (err) {
  171. err_id = id;
  172. goto cleanup;
  173. }
  174. GEM_BUG_ON(!engine->submit_request);
  175. mask |= ENGINE_MASK(id);
  176. }
  177. /*
  178. * Catch failures to update intel_engines table when the new engines
  179. * are added to the driver by a warning and disabling the forgotten
  180. * engines.
  181. */
  182. if (WARN_ON(mask != INTEL_INFO(dev_priv)->ring_mask))
  183. device_info->ring_mask = mask;
  184. device_info->num_rings = hweight32(mask);
  185. return 0;
  186. cleanup:
  187. for_each_engine(engine, dev_priv, id) {
  188. if (id >= err_id)
  189. kfree(engine);
  190. else
  191. dev_priv->gt.cleanup_engine(engine);
  192. }
  193. return err;
  194. }
  195. void intel_engine_init_global_seqno(struct intel_engine_cs *engine, u32 seqno)
  196. {
  197. struct drm_i915_private *dev_priv = engine->i915;
  198. /* Our semaphore implementation is strictly monotonic (i.e. we proceed
  199. * so long as the semaphore value in the register/page is greater
  200. * than the sync value), so whenever we reset the seqno,
  201. * so long as we reset the tracking semaphore value to 0, it will
  202. * always be before the next request's seqno. If we don't reset
  203. * the semaphore value, then when the seqno moves backwards all
  204. * future waits will complete instantly (causing rendering corruption).
  205. */
  206. if (IS_GEN6(dev_priv) || IS_GEN7(dev_priv)) {
  207. I915_WRITE(RING_SYNC_0(engine->mmio_base), 0);
  208. I915_WRITE(RING_SYNC_1(engine->mmio_base), 0);
  209. if (HAS_VEBOX(dev_priv))
  210. I915_WRITE(RING_SYNC_2(engine->mmio_base), 0);
  211. }
  212. if (dev_priv->semaphore) {
  213. struct page *page = i915_vma_first_page(dev_priv->semaphore);
  214. void *semaphores;
  215. /* Semaphores are in noncoherent memory, flush to be safe */
  216. semaphores = kmap_atomic(page);
  217. memset(semaphores + GEN8_SEMAPHORE_OFFSET(engine->id, 0),
  218. 0, I915_NUM_ENGINES * gen8_semaphore_seqno_size);
  219. drm_clflush_virt_range(semaphores + GEN8_SEMAPHORE_OFFSET(engine->id, 0),
  220. I915_NUM_ENGINES * gen8_semaphore_seqno_size);
  221. kunmap_atomic(semaphores);
  222. }
  223. intel_write_status_page(engine, I915_GEM_HWS_INDEX, seqno);
  224. clear_bit(ENGINE_IRQ_BREADCRUMB, &engine->irq_posted);
  225. GEM_BUG_ON(i915_gem_active_isset(&engine->timeline->last_request));
  226. engine->hangcheck.seqno = seqno;
  227. /* After manually advancing the seqno, fake the interrupt in case
  228. * there are any waiters for that seqno.
  229. */
  230. intel_engine_wakeup(engine);
  231. }
  232. static void intel_engine_init_timeline(struct intel_engine_cs *engine)
  233. {
  234. engine->timeline = &engine->i915->gt.global_timeline.engine[engine->id];
  235. }
  236. /**
  237. * intel_engines_setup_common - setup engine state not requiring hw access
  238. * @engine: Engine to setup.
  239. *
  240. * Initializes @engine@ structure members shared between legacy and execlists
  241. * submission modes which do not require hardware access.
  242. *
  243. * Typically done early in the submission mode specific engine setup stage.
  244. */
  245. void intel_engine_setup_common(struct intel_engine_cs *engine)
  246. {
  247. engine->execlist_queue = RB_ROOT;
  248. engine->execlist_first = NULL;
  249. intel_engine_init_timeline(engine);
  250. intel_engine_init_hangcheck(engine);
  251. i915_gem_batch_pool_init(engine, &engine->batch_pool);
  252. intel_engine_init_cmd_parser(engine);
  253. }
  254. int intel_engine_create_scratch(struct intel_engine_cs *engine, int size)
  255. {
  256. struct drm_i915_gem_object *obj;
  257. struct i915_vma *vma;
  258. int ret;
  259. WARN_ON(engine->scratch);
  260. obj = i915_gem_object_create_stolen(engine->i915, size);
  261. if (!obj)
  262. obj = i915_gem_object_create_internal(engine->i915, size);
  263. if (IS_ERR(obj)) {
  264. DRM_ERROR("Failed to allocate scratch page\n");
  265. return PTR_ERR(obj);
  266. }
  267. vma = i915_vma_instance(obj, &engine->i915->ggtt.base, NULL);
  268. if (IS_ERR(vma)) {
  269. ret = PTR_ERR(vma);
  270. goto err_unref;
  271. }
  272. ret = i915_vma_pin(vma, 0, 4096, PIN_GLOBAL | PIN_HIGH);
  273. if (ret)
  274. goto err_unref;
  275. engine->scratch = vma;
  276. DRM_DEBUG_DRIVER("%s pipe control offset: 0x%08x\n",
  277. engine->name, i915_ggtt_offset(vma));
  278. return 0;
  279. err_unref:
  280. i915_gem_object_put(obj);
  281. return ret;
  282. }
  283. static void intel_engine_cleanup_scratch(struct intel_engine_cs *engine)
  284. {
  285. i915_vma_unpin_and_release(&engine->scratch);
  286. }
  287. /**
  288. * intel_engines_init_common - initialize cengine state which might require hw access
  289. * @engine: Engine to initialize.
  290. *
  291. * Initializes @engine@ structure members shared between legacy and execlists
  292. * submission modes which do require hardware access.
  293. *
  294. * Typcally done at later stages of submission mode specific engine setup.
  295. *
  296. * Returns zero on success or an error code on failure.
  297. */
  298. int intel_engine_init_common(struct intel_engine_cs *engine)
  299. {
  300. int ret;
  301. engine->set_default_submission(engine);
  302. /* We may need to do things with the shrinker which
  303. * require us to immediately switch back to the default
  304. * context. This can cause a problem as pinning the
  305. * default context also requires GTT space which may not
  306. * be available. To avoid this we always pin the default
  307. * context.
  308. */
  309. ret = engine->context_pin(engine, engine->i915->kernel_context);
  310. if (ret)
  311. return ret;
  312. ret = intel_engine_init_breadcrumbs(engine);
  313. if (ret)
  314. goto err_unpin;
  315. ret = i915_gem_render_state_init(engine);
  316. if (ret)
  317. goto err_unpin;
  318. return 0;
  319. err_unpin:
  320. engine->context_unpin(engine, engine->i915->kernel_context);
  321. return ret;
  322. }
  323. /**
  324. * intel_engines_cleanup_common - cleans up the engine state created by
  325. * the common initiailizers.
  326. * @engine: Engine to cleanup.
  327. *
  328. * This cleans up everything created by the common helpers.
  329. */
  330. void intel_engine_cleanup_common(struct intel_engine_cs *engine)
  331. {
  332. intel_engine_cleanup_scratch(engine);
  333. i915_gem_render_state_fini(engine);
  334. intel_engine_fini_breadcrumbs(engine);
  335. intel_engine_cleanup_cmd_parser(engine);
  336. i915_gem_batch_pool_fini(&engine->batch_pool);
  337. engine->context_unpin(engine, engine->i915->kernel_context);
  338. }
  339. u64 intel_engine_get_active_head(struct intel_engine_cs *engine)
  340. {
  341. struct drm_i915_private *dev_priv = engine->i915;
  342. u64 acthd;
  343. if (INTEL_GEN(dev_priv) >= 8)
  344. acthd = I915_READ64_2x32(RING_ACTHD(engine->mmio_base),
  345. RING_ACTHD_UDW(engine->mmio_base));
  346. else if (INTEL_GEN(dev_priv) >= 4)
  347. acthd = I915_READ(RING_ACTHD(engine->mmio_base));
  348. else
  349. acthd = I915_READ(ACTHD);
  350. return acthd;
  351. }
  352. u64 intel_engine_get_last_batch_head(struct intel_engine_cs *engine)
  353. {
  354. struct drm_i915_private *dev_priv = engine->i915;
  355. u64 bbaddr;
  356. if (INTEL_GEN(dev_priv) >= 8)
  357. bbaddr = I915_READ64_2x32(RING_BBADDR(engine->mmio_base),
  358. RING_BBADDR_UDW(engine->mmio_base));
  359. else
  360. bbaddr = I915_READ(RING_BBADDR(engine->mmio_base));
  361. return bbaddr;
  362. }
  363. const char *i915_cache_level_str(struct drm_i915_private *i915, int type)
  364. {
  365. switch (type) {
  366. case I915_CACHE_NONE: return " uncached";
  367. case I915_CACHE_LLC: return HAS_LLC(i915) ? " LLC" : " snooped";
  368. case I915_CACHE_L3_LLC: return " L3+LLC";
  369. case I915_CACHE_WT: return " WT";
  370. default: return "";
  371. }
  372. }
  373. static inline uint32_t
  374. read_subslice_reg(struct drm_i915_private *dev_priv, int slice,
  375. int subslice, i915_reg_t reg)
  376. {
  377. uint32_t mcr;
  378. uint32_t ret;
  379. enum forcewake_domains fw_domains;
  380. fw_domains = intel_uncore_forcewake_for_reg(dev_priv, reg,
  381. FW_REG_READ);
  382. fw_domains |= intel_uncore_forcewake_for_reg(dev_priv,
  383. GEN8_MCR_SELECTOR,
  384. FW_REG_READ | FW_REG_WRITE);
  385. spin_lock_irq(&dev_priv->uncore.lock);
  386. intel_uncore_forcewake_get__locked(dev_priv, fw_domains);
  387. mcr = I915_READ_FW(GEN8_MCR_SELECTOR);
  388. /*
  389. * The HW expects the slice and sublice selectors to be reset to 0
  390. * after reading out the registers.
  391. */
  392. WARN_ON_ONCE(mcr & (GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK));
  393. mcr &= ~(GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK);
  394. mcr |= GEN8_MCR_SLICE(slice) | GEN8_MCR_SUBSLICE(subslice);
  395. I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr);
  396. ret = I915_READ_FW(reg);
  397. mcr &= ~(GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK);
  398. I915_WRITE_FW(GEN8_MCR_SELECTOR, mcr);
  399. intel_uncore_forcewake_put__locked(dev_priv, fw_domains);
  400. spin_unlock_irq(&dev_priv->uncore.lock);
  401. return ret;
  402. }
  403. /* NB: please notice the memset */
  404. void intel_engine_get_instdone(struct intel_engine_cs *engine,
  405. struct intel_instdone *instdone)
  406. {
  407. struct drm_i915_private *dev_priv = engine->i915;
  408. u32 mmio_base = engine->mmio_base;
  409. int slice;
  410. int subslice;
  411. memset(instdone, 0, sizeof(*instdone));
  412. switch (INTEL_GEN(dev_priv)) {
  413. default:
  414. instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
  415. if (engine->id != RCS)
  416. break;
  417. instdone->slice_common = I915_READ(GEN7_SC_INSTDONE);
  418. for_each_instdone_slice_subslice(dev_priv, slice, subslice) {
  419. instdone->sampler[slice][subslice] =
  420. read_subslice_reg(dev_priv, slice, subslice,
  421. GEN7_SAMPLER_INSTDONE);
  422. instdone->row[slice][subslice] =
  423. read_subslice_reg(dev_priv, slice, subslice,
  424. GEN7_ROW_INSTDONE);
  425. }
  426. break;
  427. case 7:
  428. instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
  429. if (engine->id != RCS)
  430. break;
  431. instdone->slice_common = I915_READ(GEN7_SC_INSTDONE);
  432. instdone->sampler[0][0] = I915_READ(GEN7_SAMPLER_INSTDONE);
  433. instdone->row[0][0] = I915_READ(GEN7_ROW_INSTDONE);
  434. break;
  435. case 6:
  436. case 5:
  437. case 4:
  438. instdone->instdone = I915_READ(RING_INSTDONE(mmio_base));
  439. if (engine->id == RCS)
  440. /* HACK: Using the wrong struct member */
  441. instdone->slice_common = I915_READ(GEN4_INSTDONE1);
  442. break;
  443. case 3:
  444. case 2:
  445. instdone->instdone = I915_READ(GEN2_INSTDONE);
  446. break;
  447. }
  448. }
  449. static int wa_add(struct drm_i915_private *dev_priv,
  450. i915_reg_t addr,
  451. const u32 mask, const u32 val)
  452. {
  453. const u32 idx = dev_priv->workarounds.count;
  454. if (WARN_ON(idx >= I915_MAX_WA_REGS))
  455. return -ENOSPC;
  456. dev_priv->workarounds.reg[idx].addr = addr;
  457. dev_priv->workarounds.reg[idx].value = val;
  458. dev_priv->workarounds.reg[idx].mask = mask;
  459. dev_priv->workarounds.count++;
  460. return 0;
  461. }
  462. #define WA_REG(addr, mask, val) do { \
  463. const int r = wa_add(dev_priv, (addr), (mask), (val)); \
  464. if (r) \
  465. return r; \
  466. } while (0)
  467. #define WA_SET_BIT_MASKED(addr, mask) \
  468. WA_REG(addr, (mask), _MASKED_BIT_ENABLE(mask))
  469. #define WA_CLR_BIT_MASKED(addr, mask) \
  470. WA_REG(addr, (mask), _MASKED_BIT_DISABLE(mask))
  471. #define WA_SET_FIELD_MASKED(addr, mask, value) \
  472. WA_REG(addr, mask, _MASKED_FIELD(mask, value))
  473. #define WA_SET_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) | (mask))
  474. #define WA_CLR_BIT(addr, mask) WA_REG(addr, mask, I915_READ(addr) & ~(mask))
  475. #define WA_WRITE(addr, val) WA_REG(addr, 0xffffffff, val)
  476. static int wa_ring_whitelist_reg(struct intel_engine_cs *engine,
  477. i915_reg_t reg)
  478. {
  479. struct drm_i915_private *dev_priv = engine->i915;
  480. struct i915_workarounds *wa = &dev_priv->workarounds;
  481. const uint32_t index = wa->hw_whitelist_count[engine->id];
  482. if (WARN_ON(index >= RING_MAX_NONPRIV_SLOTS))
  483. return -EINVAL;
  484. WA_WRITE(RING_FORCE_TO_NONPRIV(engine->mmio_base, index),
  485. i915_mmio_reg_offset(reg));
  486. wa->hw_whitelist_count[engine->id]++;
  487. return 0;
  488. }
  489. static int gen8_init_workarounds(struct intel_engine_cs *engine)
  490. {
  491. struct drm_i915_private *dev_priv = engine->i915;
  492. WA_SET_BIT_MASKED(INSTPM, INSTPM_FORCE_ORDERING);
  493. /* WaDisableAsyncFlipPerfMode:bdw,chv */
  494. WA_SET_BIT_MASKED(MI_MODE, ASYNC_FLIP_PERF_DISABLE);
  495. /* WaDisablePartialInstShootdown:bdw,chv */
  496. WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
  497. PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
  498. /* Use Force Non-Coherent whenever executing a 3D context. This is a
  499. * workaround for for a possible hang in the unlikely event a TLB
  500. * invalidation occurs during a PSD flush.
  501. */
  502. /* WaForceEnableNonCoherent:bdw,chv */
  503. /* WaHdcDisableFetchWhenMasked:bdw,chv */
  504. WA_SET_BIT_MASKED(HDC_CHICKEN0,
  505. HDC_DONOT_FETCH_MEM_WHEN_MASKED |
  506. HDC_FORCE_NON_COHERENT);
  507. /* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0:
  508. * "The Hierarchical Z RAW Stall Optimization allows non-overlapping
  509. * polygons in the same 8x4 pixel/sample area to be processed without
  510. * stalling waiting for the earlier ones to write to Hierarchical Z
  511. * buffer."
  512. *
  513. * This optimization is off by default for BDW and CHV; turn it on.
  514. */
  515. WA_CLR_BIT_MASKED(CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
  516. /* Wa4x4STCOptimizationDisable:bdw,chv */
  517. WA_SET_BIT_MASKED(CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE);
  518. /*
  519. * BSpec recommends 8x4 when MSAA is used,
  520. * however in practice 16x4 seems fastest.
  521. *
  522. * Note that PS/WM thread counts depend on the WIZ hashing
  523. * disable bit, which we don't touch here, but it's good
  524. * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).
  525. */
  526. WA_SET_FIELD_MASKED(GEN7_GT_MODE,
  527. GEN6_WIZ_HASHING_MASK,
  528. GEN6_WIZ_HASHING_16x4);
  529. return 0;
  530. }
  531. static int bdw_init_workarounds(struct intel_engine_cs *engine)
  532. {
  533. struct drm_i915_private *dev_priv = engine->i915;
  534. int ret;
  535. ret = gen8_init_workarounds(engine);
  536. if (ret)
  537. return ret;
  538. /* WaDisableThreadStallDopClockGating:bdw (pre-production) */
  539. WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
  540. /* WaDisableDopClockGating:bdw
  541. *
  542. * Also see the related UCGTCL1 write in broadwell_init_clock_gating()
  543. * to disable EUTC clock gating.
  544. */
  545. WA_SET_BIT_MASKED(GEN7_ROW_CHICKEN2,
  546. DOP_CLOCK_GATING_DISABLE);
  547. WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
  548. GEN8_SAMPLER_POWER_BYPASS_DIS);
  549. WA_SET_BIT_MASKED(HDC_CHICKEN0,
  550. /* WaForceContextSaveRestoreNonCoherent:bdw */
  551. HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
  552. /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */
  553. (IS_BDW_GT3(dev_priv) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
  554. return 0;
  555. }
  556. static int chv_init_workarounds(struct intel_engine_cs *engine)
  557. {
  558. struct drm_i915_private *dev_priv = engine->i915;
  559. int ret;
  560. ret = gen8_init_workarounds(engine);
  561. if (ret)
  562. return ret;
  563. /* WaDisableThreadStallDopClockGating:chv */
  564. WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
  565. /* Improve HiZ throughput on CHV. */
  566. WA_SET_BIT_MASKED(HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);
  567. return 0;
  568. }
  569. static int gen9_init_workarounds(struct intel_engine_cs *engine)
  570. {
  571. struct drm_i915_private *dev_priv = engine->i915;
  572. int ret;
  573. /* WaConextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk */
  574. I915_WRITE(GEN9_CSFE_CHICKEN1_RCS, _MASKED_BIT_ENABLE(GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE));
  575. /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk */
  576. I915_WRITE(BDW_SCRATCH1, I915_READ(BDW_SCRATCH1) |
  577. GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
  578. /* WaDisableKillLogic:bxt,skl,kbl */
  579. I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
  580. ECOCHK_DIS_TLB);
  581. /* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk */
  582. /* WaDisablePartialInstShootdown:skl,bxt,kbl,glk */
  583. WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
  584. FLOW_CONTROL_ENABLE |
  585. PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
  586. /* Syncing dependencies between camera and graphics:skl,bxt,kbl */
  587. WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
  588. GEN9_DISABLE_OCL_OOB_SUPPRESS_LOGIC);
  589. /* WaDisableDgMirrorFixInHalfSliceChicken5:bxt */
  590. if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
  591. WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
  592. GEN9_DG_MIRROR_FIX_ENABLE);
  593. /* WaSetDisablePixMaskCammingAndRhwoInCommonSliceChicken:bxt */
  594. if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
  595. WA_SET_BIT_MASKED(GEN7_COMMON_SLICE_CHICKEN1,
  596. GEN9_RHWO_OPTIMIZATION_DISABLE);
  597. /*
  598. * WA also requires GEN9_SLICE_COMMON_ECO_CHICKEN0[14:14] to be set
  599. * but we do that in per ctx batchbuffer as there is an issue
  600. * with this register not getting restored on ctx restore
  601. */
  602. }
  603. /* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl */
  604. WA_SET_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN7,
  605. GEN9_ENABLE_GPGPU_PREEMPTION);
  606. /* Wa4x4STCOptimizationDisable:skl,bxt,kbl,glk */
  607. /* WaDisablePartialResolveInVc:skl,bxt,kbl */
  608. WA_SET_BIT_MASKED(CACHE_MODE_1, (GEN8_4x4_STC_OPTIMIZATION_DISABLE |
  609. GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE));
  610. /* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk */
  611. WA_CLR_BIT_MASKED(GEN9_HALF_SLICE_CHICKEN5,
  612. GEN9_CCS_TLB_PREFETCH_ENABLE);
  613. /* WaDisableMaskBasedCammingInRCC:bxt */
  614. if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
  615. WA_SET_BIT_MASKED(SLICE_ECO_CHICKEN0,
  616. PIXEL_MASK_CAMMING_DISABLE);
  617. /* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl */
  618. WA_SET_BIT_MASKED(HDC_CHICKEN0,
  619. HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
  620. HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE);
  621. /* WaForceEnableNonCoherent and WaDisableHDCInvalidation are
  622. * both tied to WaForceContextSaveRestoreNonCoherent
  623. * in some hsds for skl. We keep the tie for all gen9. The
  624. * documentation is a bit hazy and so we want to get common behaviour,
  625. * even though there is no clear evidence we would need both on kbl/bxt.
  626. * This area has been source of system hangs so we play it safe
  627. * and mimic the skl regardless of what bspec says.
  628. *
  629. * Use Force Non-Coherent whenever executing a 3D context. This
  630. * is a workaround for a possible hang in the unlikely event
  631. * a TLB invalidation occurs during a PSD flush.
  632. */
  633. /* WaForceEnableNonCoherent:skl,bxt,kbl */
  634. WA_SET_BIT_MASKED(HDC_CHICKEN0,
  635. HDC_FORCE_NON_COHERENT);
  636. /* WaDisableHDCInvalidation:skl,bxt,kbl */
  637. I915_WRITE(GAM_ECOCHK, I915_READ(GAM_ECOCHK) |
  638. BDW_DISABLE_HDC_INVALIDATION);
  639. /* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl */
  640. if (IS_SKYLAKE(dev_priv) ||
  641. IS_KABYLAKE(dev_priv) ||
  642. IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0))
  643. WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN3,
  644. GEN8_SAMPLER_POWER_BYPASS_DIS);
  645. /* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk */
  646. WA_SET_BIT_MASKED(HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE);
  647. /* WaOCLCoherentLineFlush:skl,bxt,kbl */
  648. I915_WRITE(GEN8_L3SQCREG4, (I915_READ(GEN8_L3SQCREG4) |
  649. GEN8_LQSC_FLUSH_COHERENT_LINES));
  650. /* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk */
  651. ret = wa_ring_whitelist_reg(engine, GEN9_CTX_PREEMPT_REG);
  652. if (ret)
  653. return ret;
  654. /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl */
  655. ret= wa_ring_whitelist_reg(engine, GEN8_CS_CHICKEN1);
  656. if (ret)
  657. return ret;
  658. /* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk */
  659. ret = wa_ring_whitelist_reg(engine, GEN8_HDC_CHICKEN1);
  660. if (ret)
  661. return ret;
  662. return 0;
  663. }
  664. static int skl_tune_iz_hashing(struct intel_engine_cs *engine)
  665. {
  666. struct drm_i915_private *dev_priv = engine->i915;
  667. u8 vals[3] = { 0, 0, 0 };
  668. unsigned int i;
  669. for (i = 0; i < 3; i++) {
  670. u8 ss;
  671. /*
  672. * Only consider slices where one, and only one, subslice has 7
  673. * EUs
  674. */
  675. if (!is_power_of_2(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]))
  676. continue;
  677. /*
  678. * subslice_7eu[i] != 0 (because of the check above) and
  679. * ss_max == 4 (maximum number of subslices possible per slice)
  680. *
  681. * -> 0 <= ss <= 3;
  682. */
  683. ss = ffs(INTEL_INFO(dev_priv)->sseu.subslice_7eu[i]) - 1;
  684. vals[i] = 3 - ss;
  685. }
  686. if (vals[0] == 0 && vals[1] == 0 && vals[2] == 0)
  687. return 0;
  688. /* Tune IZ hashing. See intel_device_info_runtime_init() */
  689. WA_SET_FIELD_MASKED(GEN7_GT_MODE,
  690. GEN9_IZ_HASHING_MASK(2) |
  691. GEN9_IZ_HASHING_MASK(1) |
  692. GEN9_IZ_HASHING_MASK(0),
  693. GEN9_IZ_HASHING(2, vals[2]) |
  694. GEN9_IZ_HASHING(1, vals[1]) |
  695. GEN9_IZ_HASHING(0, vals[0]));
  696. return 0;
  697. }
  698. static int skl_init_workarounds(struct intel_engine_cs *engine)
  699. {
  700. struct drm_i915_private *dev_priv = engine->i915;
  701. int ret;
  702. ret = gen9_init_workarounds(engine);
  703. if (ret)
  704. return ret;
  705. /*
  706. * Actual WA is to disable percontext preemption granularity control
  707. * until D0 which is the default case so this is equivalent to
  708. * !WaDisablePerCtxtPreemptionGranularityControl:skl
  709. */
  710. I915_WRITE(GEN7_FF_SLICE_CS_CHICKEN1,
  711. _MASKED_BIT_ENABLE(GEN9_FFSC_PERCTX_PREEMPT_CTRL));
  712. /* WaEnableGapsTsvCreditFix:skl */
  713. I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
  714. GEN9_GAPS_TSV_CREDIT_DISABLE));
  715. /* WaDisableGafsUnitClkGating:skl */
  716. WA_SET_BIT(GEN7_UCGCTL4, GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
  717. /* WaInPlaceDecompressionHang:skl */
  718. if (IS_SKL_REVID(dev_priv, SKL_REVID_H0, REVID_FOREVER))
  719. WA_SET_BIT(GEN9_GAMT_ECO_REG_RW_IA,
  720. GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
  721. /* WaDisableLSQCROPERFforOCL:skl */
  722. ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
  723. if (ret)
  724. return ret;
  725. return skl_tune_iz_hashing(engine);
  726. }
  727. static int bxt_init_workarounds(struct intel_engine_cs *engine)
  728. {
  729. struct drm_i915_private *dev_priv = engine->i915;
  730. int ret;
  731. ret = gen9_init_workarounds(engine);
  732. if (ret)
  733. return ret;
  734. /* WaStoreMultiplePTEenable:bxt */
  735. /* This is a requirement according to Hardware specification */
  736. if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1))
  737. I915_WRITE(TILECTL, I915_READ(TILECTL) | TILECTL_TLBPF);
  738. /* WaSetClckGatingDisableMedia:bxt */
  739. if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
  740. I915_WRITE(GEN7_MISCCPCTL, (I915_READ(GEN7_MISCCPCTL) &
  741. ~GEN8_DOP_CLOCK_GATE_MEDIA_ENABLE));
  742. }
  743. /* WaDisableThreadStallDopClockGating:bxt */
  744. WA_SET_BIT_MASKED(GEN8_ROW_CHICKEN,
  745. STALL_DOP_GATING_DISABLE);
  746. /* WaDisablePooledEuLoadBalancingFix:bxt */
  747. if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER)) {
  748. WA_SET_BIT_MASKED(FF_SLICE_CS_CHICKEN2,
  749. GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE);
  750. }
  751. /* WaDisableSbeCacheDispatchPortSharing:bxt */
  752. if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_B0)) {
  753. WA_SET_BIT_MASKED(
  754. GEN7_HALF_SLICE_CHICKEN1,
  755. GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
  756. }
  757. /* WaDisableObjectLevelPreemptionForTrifanOrPolygon:bxt */
  758. /* WaDisableObjectLevelPreemptionForInstancedDraw:bxt */
  759. /* WaDisableObjectLevelPreemtionForInstanceId:bxt */
  760. /* WaDisableLSQCROPERFforOCL:bxt */
  761. if (IS_BXT_REVID(dev_priv, 0, BXT_REVID_A1)) {
  762. ret = wa_ring_whitelist_reg(engine, GEN9_CS_DEBUG_MODE1);
  763. if (ret)
  764. return ret;
  765. ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
  766. if (ret)
  767. return ret;
  768. }
  769. /* WaProgramL3SqcReg1DefaultForPerf:bxt */
  770. if (IS_BXT_REVID(dev_priv, BXT_REVID_B0, REVID_FOREVER))
  771. I915_WRITE(GEN8_L3SQCREG1, L3_GENERAL_PRIO_CREDITS(62) |
  772. L3_HIGH_PRIO_CREDITS(2));
  773. /* WaToEnableHwFixForPushConstHWBug:bxt */
  774. if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
  775. WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
  776. GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
  777. /* WaInPlaceDecompressionHang:bxt */
  778. if (IS_BXT_REVID(dev_priv, BXT_REVID_C0, REVID_FOREVER))
  779. WA_SET_BIT(GEN9_GAMT_ECO_REG_RW_IA,
  780. GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
  781. return 0;
  782. }
  783. static int kbl_init_workarounds(struct intel_engine_cs *engine)
  784. {
  785. struct drm_i915_private *dev_priv = engine->i915;
  786. int ret;
  787. ret = gen9_init_workarounds(engine);
  788. if (ret)
  789. return ret;
  790. /* WaEnableGapsTsvCreditFix:kbl */
  791. I915_WRITE(GEN8_GARBCNTL, (I915_READ(GEN8_GARBCNTL) |
  792. GEN9_GAPS_TSV_CREDIT_DISABLE));
  793. /* WaDisableDynamicCreditSharing:kbl */
  794. if (IS_KBL_REVID(dev_priv, 0, KBL_REVID_B0))
  795. WA_SET_BIT(GAMT_CHKN_BIT_REG,
  796. GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING);
  797. /* WaDisableFenceDestinationToSLM:kbl (pre-prod) */
  798. if (IS_KBL_REVID(dev_priv, KBL_REVID_A0, KBL_REVID_A0))
  799. WA_SET_BIT_MASKED(HDC_CHICKEN0,
  800. HDC_FENCE_DEST_SLM_DISABLE);
  801. /* WaToEnableHwFixForPushConstHWBug:kbl */
  802. if (IS_KBL_REVID(dev_priv, KBL_REVID_C0, REVID_FOREVER))
  803. WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
  804. GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
  805. /* WaDisableGafsUnitClkGating:kbl */
  806. WA_SET_BIT(GEN7_UCGCTL4, GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
  807. /* WaDisableSbeCacheDispatchPortSharing:kbl */
  808. WA_SET_BIT_MASKED(
  809. GEN7_HALF_SLICE_CHICKEN1,
  810. GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
  811. /* WaInPlaceDecompressionHang:kbl */
  812. WA_SET_BIT(GEN9_GAMT_ECO_REG_RW_IA,
  813. GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
  814. /* WaDisableLSQCROPERFforOCL:kbl */
  815. ret = wa_ring_whitelist_reg(engine, GEN8_L3SQCREG4);
  816. if (ret)
  817. return ret;
  818. return 0;
  819. }
  820. static int glk_init_workarounds(struct intel_engine_cs *engine)
  821. {
  822. struct drm_i915_private *dev_priv = engine->i915;
  823. int ret;
  824. ret = gen9_init_workarounds(engine);
  825. if (ret)
  826. return ret;
  827. /* WaToEnableHwFixForPushConstHWBug:glk */
  828. WA_SET_BIT_MASKED(COMMON_SLICE_CHICKEN2,
  829. GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
  830. return 0;
  831. }
  832. int init_workarounds_ring(struct intel_engine_cs *engine)
  833. {
  834. struct drm_i915_private *dev_priv = engine->i915;
  835. int err;
  836. WARN_ON(engine->id != RCS);
  837. dev_priv->workarounds.count = 0;
  838. dev_priv->workarounds.hw_whitelist_count[engine->id] = 0;
  839. if (IS_BROADWELL(dev_priv))
  840. err = bdw_init_workarounds(engine);
  841. else if (IS_CHERRYVIEW(dev_priv))
  842. err = chv_init_workarounds(engine);
  843. else if (IS_SKYLAKE(dev_priv))
  844. err = skl_init_workarounds(engine);
  845. else if (IS_BROXTON(dev_priv))
  846. err = bxt_init_workarounds(engine);
  847. else if (IS_KABYLAKE(dev_priv))
  848. err = kbl_init_workarounds(engine);
  849. else if (IS_GEMINILAKE(dev_priv))
  850. err = glk_init_workarounds(engine);
  851. else
  852. err = 0;
  853. if (err)
  854. return err;
  855. DRM_DEBUG_DRIVER("%s: Number of context specific w/a: %d\n",
  856. engine->name, dev_priv->workarounds.count);
  857. return 0;
  858. }
  859. int intel_ring_workarounds_emit(struct drm_i915_gem_request *req)
  860. {
  861. struct i915_workarounds *w = &req->i915->workarounds;
  862. u32 *cs;
  863. int ret, i;
  864. if (w->count == 0)
  865. return 0;
  866. ret = req->engine->emit_flush(req, EMIT_BARRIER);
  867. if (ret)
  868. return ret;
  869. cs = intel_ring_begin(req, (w->count * 2 + 2));
  870. if (IS_ERR(cs))
  871. return PTR_ERR(cs);
  872. *cs++ = MI_LOAD_REGISTER_IMM(w->count);
  873. for (i = 0; i < w->count; i++) {
  874. *cs++ = i915_mmio_reg_offset(w->reg[i].addr);
  875. *cs++ = w->reg[i].value;
  876. }
  877. *cs++ = MI_NOOP;
  878. intel_ring_advance(req, cs);
  879. ret = req->engine->emit_flush(req, EMIT_BARRIER);
  880. if (ret)
  881. return ret;
  882. return 0;
  883. }
  884. /**
  885. * intel_engine_is_idle() - Report if the engine has finished process all work
  886. * @engine: the intel_engine_cs
  887. *
  888. * Return true if there are no requests pending, nothing left to be submitted
  889. * to hardware, and that the engine is idle.
  890. */
  891. bool intel_engine_is_idle(struct intel_engine_cs *engine)
  892. {
  893. struct drm_i915_private *dev_priv = engine->i915;
  894. /* Any inflight/incomplete requests? */
  895. if (!i915_seqno_passed(intel_engine_get_seqno(engine),
  896. intel_engine_last_submit(engine)))
  897. return false;
  898. /* Interrupt/tasklet pending? */
  899. if (test_bit(ENGINE_IRQ_EXECLIST, &engine->irq_posted))
  900. return false;
  901. /* Both ports drained, no more ELSP submission? */
  902. if (engine->execlist_port[0].request)
  903. return false;
  904. /* Ring stopped? */
  905. if (INTEL_GEN(dev_priv) > 2 && !(I915_READ_MODE(engine) & MODE_IDLE))
  906. return false;
  907. return true;
  908. }
  909. bool intel_engines_are_idle(struct drm_i915_private *dev_priv)
  910. {
  911. struct intel_engine_cs *engine;
  912. enum intel_engine_id id;
  913. for_each_engine(engine, dev_priv, id) {
  914. if (!intel_engine_is_idle(engine))
  915. return false;
  916. }
  917. return true;
  918. }
  919. void intel_engines_reset_default_submission(struct drm_i915_private *i915)
  920. {
  921. struct intel_engine_cs *engine;
  922. enum intel_engine_id id;
  923. for_each_engine(engine, i915, id)
  924. engine->set_default_submission(engine);
  925. }
  926. #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
  927. #include "selftests/mock_engine.c"
  928. #endif