i915_debugfs.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745
  1. /*
  2. * Copyright © 2008 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. * Authors:
  24. * Eric Anholt <eric@anholt.net>
  25. * Keith Packard <keithp@keithp.com>
  26. *
  27. */
  28. #include <linux/debugfs.h>
  29. #include <linux/sched/mm.h>
  30. #include <linux/sort.h>
  31. #include <linux/string_helpers.h>
  32. #include <drm/drm_debugfs.h>
  33. #include <drm/drm_print.h>
  34. #include "gem/i915_gem_context.h"
  35. #include "gt/intel_gt.h"
  36. #include "gt/intel_gt_buffer_pool.h"
  37. #include "gt/intel_gt_clock_utils.h"
  38. #include "gt/intel_gt_debugfs.h"
  39. #include "gt/intel_gt_pm.h"
  40. #include "gt/intel_gt_pm_debugfs.h"
  41. #include "gt/intel_gt_regs.h"
  42. #include "gt/intel_gt_requests.h"
  43. #include "gt/intel_rc6.h"
  44. #include "gt/intel_reset.h"
  45. #include "gt/intel_rps.h"
  46. #include "gt/intel_sseu_debugfs.h"
  47. #include "i915_debugfs.h"
  48. #include "i915_debugfs_params.h"
  49. #include "i915_driver.h"
  50. #include "i915_gpu_error.h"
  51. #include "i915_irq.h"
  52. #include "i915_reg.h"
  53. #include "i915_scheduler.h"
  54. #include "i915_wait_util.h"
  55. #include "intel_mchbar_regs.h"
  56. static inline struct drm_i915_private *node_to_i915(struct drm_info_node *node)
  57. {
  58. return to_i915(node->minor->dev);
  59. }
  60. static int i915_capabilities(struct seq_file *m, void *data)
  61. {
  62. struct drm_i915_private *i915 = node_to_i915(m->private);
  63. struct drm_printer p = drm_seq_file_printer(m);
  64. intel_device_info_print(INTEL_INFO(i915), RUNTIME_INFO(i915), &p);
  65. i915_print_iommu_status(i915, &p);
  66. intel_gt_info_print(&to_gt(i915)->info, &p);
  67. intel_driver_caps_print(&i915->caps, &p);
  68. i915_params_dump(&i915->params, &p);
  69. return 0;
  70. }
  71. static char get_tiling_flag(struct drm_i915_gem_object *obj)
  72. {
  73. switch (i915_gem_object_get_tiling(obj)) {
  74. default:
  75. case I915_TILING_NONE: return ' ';
  76. case I915_TILING_X: return 'X';
  77. case I915_TILING_Y: return 'Y';
  78. }
  79. }
  80. static char get_global_flag(struct drm_i915_gem_object *obj)
  81. {
  82. return READ_ONCE(obj->userfault_count) ? 'g' : ' ';
  83. }
  84. static char get_pin_mapped_flag(struct drm_i915_gem_object *obj)
  85. {
  86. return obj->mm.mapping ? 'M' : ' ';
  87. }
  88. static const char *
  89. stringify_page_sizes(unsigned int page_sizes, char *buf, size_t len)
  90. {
  91. size_t x = 0;
  92. switch (page_sizes) {
  93. case 0:
  94. return "";
  95. case I915_GTT_PAGE_SIZE_4K:
  96. return "4K";
  97. case I915_GTT_PAGE_SIZE_64K:
  98. return "64K";
  99. case I915_GTT_PAGE_SIZE_2M:
  100. return "2M";
  101. default:
  102. if (!buf)
  103. return "M";
  104. if (page_sizes & I915_GTT_PAGE_SIZE_2M)
  105. x += snprintf(buf + x, len - x, "2M, ");
  106. if (page_sizes & I915_GTT_PAGE_SIZE_64K)
  107. x += snprintf(buf + x, len - x, "64K, ");
  108. if (page_sizes & I915_GTT_PAGE_SIZE_4K)
  109. x += snprintf(buf + x, len - x, "4K, ");
  110. buf[x-2] = '\0';
  111. return buf;
  112. }
  113. }
  114. static const char *stringify_vma_type(const struct i915_vma *vma)
  115. {
  116. if (i915_vma_is_ggtt(vma))
  117. return "ggtt";
  118. if (i915_vma_is_dpt(vma))
  119. return "dpt";
  120. return "ppgtt";
  121. }
  122. static const char *i915_cache_level_str(struct drm_i915_gem_object *obj)
  123. {
  124. struct drm_i915_private *i915 = obj_to_i915(obj);
  125. if (IS_GFX_GT_IP_RANGE(to_gt(i915), IP_VER(12, 70), IP_VER(12, 74))) {
  126. switch (obj->pat_index) {
  127. case 0: return " WB";
  128. case 1: return " WT";
  129. case 2: return " UC";
  130. case 3: return " WB (1-Way Coh)";
  131. case 4: return " WB (2-Way Coh)";
  132. default: return " not defined";
  133. }
  134. } else if (GRAPHICS_VER(i915) >= 12) {
  135. switch (obj->pat_index) {
  136. case 0: return " WB";
  137. case 1: return " WC";
  138. case 2: return " WT";
  139. case 3: return " UC";
  140. default: return " not defined";
  141. }
  142. } else {
  143. switch (obj->pat_index) {
  144. case 0: return " UC";
  145. case 1: return HAS_LLC(i915) ?
  146. " LLC" : " snooped";
  147. case 2: return " L3+LLC";
  148. case 3: return " WT";
  149. default: return " not defined";
  150. }
  151. }
  152. }
  153. void
  154. i915_debugfs_describe_obj(struct seq_file *m, struct drm_i915_gem_object *obj)
  155. {
  156. struct i915_vma *vma;
  157. int pin_count = 0;
  158. seq_printf(m, "%pK: %c%c%c %8zdKiB %02x %02x %s%s%s",
  159. &obj->base,
  160. get_tiling_flag(obj),
  161. get_global_flag(obj),
  162. get_pin_mapped_flag(obj),
  163. obj->base.size / 1024,
  164. obj->read_domains,
  165. obj->write_domain,
  166. i915_cache_level_str(obj),
  167. obj->mm.dirty ? " dirty" : "",
  168. obj->mm.madv == I915_MADV_DONTNEED ? " purgeable" : "");
  169. if (obj->base.name)
  170. seq_printf(m, " (name: %d)", obj->base.name);
  171. spin_lock(&obj->vma.lock);
  172. list_for_each_entry(vma, &obj->vma.list, obj_link) {
  173. if (!drm_mm_node_allocated(&vma->node))
  174. continue;
  175. spin_unlock(&obj->vma.lock);
  176. if (i915_vma_is_pinned(vma))
  177. pin_count++;
  178. seq_printf(m, " (%s offset: %08llx, size: %08llx, pages: %s",
  179. stringify_vma_type(vma),
  180. i915_vma_offset(vma), i915_vma_size(vma),
  181. stringify_page_sizes(vma->resource->page_sizes_gtt,
  182. NULL, 0));
  183. if (i915_vma_is_ggtt(vma) || i915_vma_is_dpt(vma)) {
  184. switch (vma->gtt_view.type) {
  185. case I915_GTT_VIEW_NORMAL:
  186. seq_puts(m, ", normal");
  187. break;
  188. case I915_GTT_VIEW_PARTIAL:
  189. seq_printf(m, ", partial [%08llx+%x]",
  190. vma->gtt_view.partial.offset << PAGE_SHIFT,
  191. vma->gtt_view.partial.size << PAGE_SHIFT);
  192. break;
  193. case I915_GTT_VIEW_ROTATED:
  194. seq_printf(m, ", rotated [(%ux%u, src_stride=%u, dst_stride=%u, offset=%u), (%ux%u, src_stride=%u, dst_stride=%u, offset=%u)]",
  195. vma->gtt_view.rotated.plane[0].width,
  196. vma->gtt_view.rotated.plane[0].height,
  197. vma->gtt_view.rotated.plane[0].src_stride,
  198. vma->gtt_view.rotated.plane[0].dst_stride,
  199. vma->gtt_view.rotated.plane[0].offset,
  200. vma->gtt_view.rotated.plane[1].width,
  201. vma->gtt_view.rotated.plane[1].height,
  202. vma->gtt_view.rotated.plane[1].src_stride,
  203. vma->gtt_view.rotated.plane[1].dst_stride,
  204. vma->gtt_view.rotated.plane[1].offset);
  205. break;
  206. case I915_GTT_VIEW_REMAPPED:
  207. seq_printf(m, ", remapped [(%ux%u, src_stride=%u, dst_stride=%u, offset=%u), (%ux%u, src_stride=%u, dst_stride=%u, offset=%u)]",
  208. vma->gtt_view.remapped.plane[0].width,
  209. vma->gtt_view.remapped.plane[0].height,
  210. vma->gtt_view.remapped.plane[0].src_stride,
  211. vma->gtt_view.remapped.plane[0].dst_stride,
  212. vma->gtt_view.remapped.plane[0].offset,
  213. vma->gtt_view.remapped.plane[1].width,
  214. vma->gtt_view.remapped.plane[1].height,
  215. vma->gtt_view.remapped.plane[1].src_stride,
  216. vma->gtt_view.remapped.plane[1].dst_stride,
  217. vma->gtt_view.remapped.plane[1].offset);
  218. break;
  219. default:
  220. MISSING_CASE(vma->gtt_view.type);
  221. break;
  222. }
  223. }
  224. if (vma->fence)
  225. seq_printf(m, " , fence: %d", vma->fence->id);
  226. seq_puts(m, ")");
  227. spin_lock(&obj->vma.lock);
  228. }
  229. spin_unlock(&obj->vma.lock);
  230. seq_printf(m, " (pinned x %d)", pin_count);
  231. if (i915_gem_object_is_stolen(obj))
  232. seq_printf(m, " (stolen: %08llx)", obj->stolen->start);
  233. if (i915_gem_object_is_framebuffer(obj))
  234. seq_printf(m, " (fb)");
  235. }
  236. static int i915_gem_object_info(struct seq_file *m, void *data)
  237. {
  238. struct drm_i915_private *i915 = node_to_i915(m->private);
  239. struct drm_printer p = drm_seq_file_printer(m);
  240. struct intel_memory_region *mr;
  241. enum intel_region_id id;
  242. seq_printf(m, "%u shrinkable [%u free] objects, %llu bytes\n",
  243. i915->mm.shrink_count,
  244. atomic_read(&i915->mm.free_count),
  245. i915->mm.shrink_memory);
  246. for_each_memory_region(mr, i915, id)
  247. intel_memory_region_debug(mr, &p);
  248. return 0;
  249. }
  250. static int i915_frequency_info(struct seq_file *m, void *unused)
  251. {
  252. struct drm_i915_private *i915 = node_to_i915(m->private);
  253. struct intel_gt *gt = to_gt(i915);
  254. struct drm_printer p = drm_seq_file_printer(m);
  255. intel_gt_pm_frequency_dump(gt, &p);
  256. return 0;
  257. }
  258. static const char *swizzle_string(unsigned swizzle)
  259. {
  260. switch (swizzle) {
  261. case I915_BIT_6_SWIZZLE_NONE:
  262. return "none";
  263. case I915_BIT_6_SWIZZLE_9:
  264. return "bit9";
  265. case I915_BIT_6_SWIZZLE_9_10:
  266. return "bit9/bit10";
  267. case I915_BIT_6_SWIZZLE_9_11:
  268. return "bit9/bit11";
  269. case I915_BIT_6_SWIZZLE_9_10_11:
  270. return "bit9/bit10/bit11";
  271. case I915_BIT_6_SWIZZLE_9_17:
  272. return "bit9/bit17";
  273. case I915_BIT_6_SWIZZLE_9_10_17:
  274. return "bit9/bit10/bit17";
  275. case I915_BIT_6_SWIZZLE_UNKNOWN:
  276. return "unknown";
  277. }
  278. return "bug";
  279. }
  280. static int i915_swizzle_info(struct seq_file *m, void *data)
  281. {
  282. struct drm_i915_private *dev_priv = node_to_i915(m->private);
  283. struct intel_uncore *uncore = &dev_priv->uncore;
  284. intel_wakeref_t wakeref;
  285. seq_printf(m, "bit6 swizzle for X-tiling = %s\n",
  286. swizzle_string(to_gt(dev_priv)->ggtt->bit_6_swizzle_x));
  287. seq_printf(m, "bit6 swizzle for Y-tiling = %s\n",
  288. swizzle_string(to_gt(dev_priv)->ggtt->bit_6_swizzle_y));
  289. if (dev_priv->gem_quirks & GEM_QUIRK_PIN_SWIZZLED_PAGES)
  290. seq_puts(m, "L-shaped memory detected\n");
  291. /* On BDW+, swizzling is not used. See detect_bit_6_swizzle() */
  292. if (GRAPHICS_VER(dev_priv) >= 8 || IS_VALLEYVIEW(dev_priv))
  293. return 0;
  294. wakeref = intel_runtime_pm_get(&dev_priv->runtime_pm);
  295. if (IS_GRAPHICS_VER(dev_priv, 3, 4)) {
  296. seq_printf(m, "DDC = 0x%08x\n",
  297. intel_uncore_read(uncore, DCC));
  298. seq_printf(m, "DDC2 = 0x%08x\n",
  299. intel_uncore_read(uncore, DCC2));
  300. seq_printf(m, "C0DRB3 = 0x%04x\n",
  301. intel_uncore_read16(uncore, C0DRB3_BW));
  302. seq_printf(m, "C1DRB3 = 0x%04x\n",
  303. intel_uncore_read16(uncore, C1DRB3_BW));
  304. } else if (GRAPHICS_VER(dev_priv) >= 6) {
  305. seq_printf(m, "MAD_DIMM_C0 = 0x%08x\n",
  306. intel_uncore_read(uncore, MAD_DIMM_C0));
  307. seq_printf(m, "MAD_DIMM_C1 = 0x%08x\n",
  308. intel_uncore_read(uncore, MAD_DIMM_C1));
  309. seq_printf(m, "MAD_DIMM_C2 = 0x%08x\n",
  310. intel_uncore_read(uncore, MAD_DIMM_C2));
  311. seq_printf(m, "TILECTL = 0x%08x\n",
  312. intel_uncore_read(uncore, TILECTL));
  313. if (GRAPHICS_VER(dev_priv) >= 8)
  314. seq_printf(m, "GAMTARBMODE = 0x%08x\n",
  315. intel_uncore_read(uncore, GAMTARBMODE));
  316. else
  317. seq_printf(m, "ARB_MODE = 0x%08x\n",
  318. intel_uncore_read(uncore, ARB_MODE));
  319. seq_printf(m, "DISP_ARB_CTL = 0x%08x\n",
  320. intel_uncore_read(uncore, DISP_ARB_CTL));
  321. }
  322. intel_runtime_pm_put(&dev_priv->runtime_pm, wakeref);
  323. return 0;
  324. }
  325. static int i915_rps_boost_info(struct seq_file *m, void *data)
  326. {
  327. struct drm_i915_private *dev_priv = node_to_i915(m->private);
  328. struct intel_rps *rps = &to_gt(dev_priv)->rps;
  329. seq_printf(m, "RPS enabled? %s\n",
  330. str_yes_no(intel_rps_is_enabled(rps)));
  331. seq_printf(m, "RPS active? %s\n",
  332. str_yes_no(intel_rps_is_active(rps)));
  333. seq_printf(m, "GPU busy? %s\n", str_yes_no(to_gt(dev_priv)->awake));
  334. seq_printf(m, "Boosts outstanding? %d\n",
  335. atomic_read(&rps->num_waiters));
  336. seq_printf(m, "Interactive? %d\n", READ_ONCE(rps->power.interactive));
  337. seq_printf(m, "Frequency requested %d, actual %d\n",
  338. intel_gpu_freq(rps, rps->cur_freq),
  339. intel_rps_read_actual_frequency(rps));
  340. seq_printf(m, " min hard:%d, soft:%d; max soft:%d, hard:%d\n",
  341. intel_gpu_freq(rps, rps->min_freq),
  342. intel_gpu_freq(rps, rps->min_freq_softlimit),
  343. intel_gpu_freq(rps, rps->max_freq_softlimit),
  344. intel_gpu_freq(rps, rps->max_freq));
  345. seq_printf(m, " idle:%d, efficient:%d, boost:%d\n",
  346. intel_gpu_freq(rps, rps->idle_freq),
  347. intel_gpu_freq(rps, rps->efficient_freq),
  348. intel_gpu_freq(rps, rps->boost_freq));
  349. seq_printf(m, "Wait boosts: %d\n", READ_ONCE(rps->boosts));
  350. return 0;
  351. }
  352. static int i915_runtime_pm_status(struct seq_file *m, void *unused)
  353. {
  354. struct drm_i915_private *dev_priv = node_to_i915(m->private);
  355. struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev);
  356. if (!HAS_RUNTIME_PM(dev_priv))
  357. seq_puts(m, "Runtime power management not supported\n");
  358. seq_printf(m, "GPU idle: %s\n", str_yes_no(!to_gt(dev_priv)->awake));
  359. seq_printf(m, "IRQs disabled: %s\n",
  360. str_yes_no(!intel_irqs_enabled(dev_priv)));
  361. #ifdef CONFIG_PM
  362. seq_printf(m, "Usage count: %d\n",
  363. atomic_read(&dev_priv->drm.dev->power.usage_count));
  364. #else
  365. seq_printf(m, "Device Power Management (CONFIG_PM) disabled\n");
  366. #endif
  367. seq_printf(m, "PCI device power state: %s [%d]\n",
  368. pci_power_name(pdev->current_state),
  369. pdev->current_state);
  370. if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_RUNTIME_PM)) {
  371. struct drm_printer p = drm_seq_file_printer(m);
  372. print_intel_runtime_pm_wakeref(&dev_priv->runtime_pm, &p);
  373. }
  374. return 0;
  375. }
  376. static int i915_engine_info(struct seq_file *m, void *unused)
  377. {
  378. struct drm_i915_private *i915 = node_to_i915(m->private);
  379. struct intel_engine_cs *engine;
  380. intel_wakeref_t wakeref;
  381. struct drm_printer p;
  382. wakeref = intel_runtime_pm_get(&i915->runtime_pm);
  383. seq_printf(m, "GT awake? %s [%d], %llums\n",
  384. str_yes_no(to_gt(i915)->awake),
  385. atomic_read(&to_gt(i915)->wakeref.count),
  386. ktime_to_ms(intel_gt_get_awake_time(to_gt(i915))));
  387. seq_printf(m, "CS timestamp frequency: %u Hz, %d ns\n",
  388. to_gt(i915)->clock_frequency,
  389. to_gt(i915)->clock_period_ns);
  390. p = drm_seq_file_printer(m);
  391. for_each_uabi_engine(engine, i915)
  392. intel_engine_dump(engine, &p, "%s\n", engine->name);
  393. intel_gt_show_timelines(to_gt(i915), &p, i915_request_show_with_schedule);
  394. intel_runtime_pm_put(&i915->runtime_pm, wakeref);
  395. return 0;
  396. }
  397. static int i915_wa_registers(struct seq_file *m, void *unused)
  398. {
  399. struct drm_i915_private *i915 = node_to_i915(m->private);
  400. struct intel_engine_cs *engine;
  401. for_each_uabi_engine(engine, i915) {
  402. const struct i915_wa_list *wal = &engine->ctx_wa_list;
  403. const struct i915_wa *wa;
  404. unsigned int count;
  405. count = wal->count;
  406. if (!count)
  407. continue;
  408. seq_printf(m, "%s: Workarounds applied: %u\n",
  409. engine->name, count);
  410. for (wa = wal->list; count--; wa++)
  411. seq_printf(m, "0x%X: 0x%08X, mask: 0x%08X\n",
  412. i915_mmio_reg_offset(wa->reg),
  413. wa->set, wa->clr);
  414. seq_printf(m, "\n");
  415. }
  416. return 0;
  417. }
  418. static int i915_wedged_get(void *data, u64 *val)
  419. {
  420. struct drm_i915_private *i915 = data;
  421. struct intel_gt *gt;
  422. unsigned int i;
  423. *val = 0;
  424. for_each_gt(gt, i915, i) {
  425. int ret;
  426. ret = intel_gt_debugfs_reset_show(gt, val);
  427. if (ret)
  428. return ret;
  429. /* at least one tile should be wedged */
  430. if (*val)
  431. break;
  432. }
  433. return 0;
  434. }
  435. static int i915_wedged_set(void *data, u64 val)
  436. {
  437. struct drm_i915_private *i915 = data;
  438. struct intel_gt *gt;
  439. unsigned int i;
  440. for_each_gt(gt, i915, i)
  441. intel_gt_debugfs_reset_store(gt, val);
  442. return 0;
  443. }
  444. DEFINE_SIMPLE_ATTRIBUTE(i915_wedged_fops,
  445. i915_wedged_get, i915_wedged_set,
  446. "%llu\n");
  447. static int
  448. i915_perf_noa_delay_set(void *data, u64 val)
  449. {
  450. struct drm_i915_private *i915 = data;
  451. /*
  452. * This would lead to infinite waits as we're doing timestamp
  453. * difference on the CS with only 32bits.
  454. */
  455. if (intel_gt_ns_to_clock_interval(to_gt(i915), val) > U32_MAX)
  456. return -EINVAL;
  457. atomic64_set(&i915->perf.noa_programming_delay, val);
  458. return 0;
  459. }
  460. static int
  461. i915_perf_noa_delay_get(void *data, u64 *val)
  462. {
  463. struct drm_i915_private *i915 = data;
  464. *val = atomic64_read(&i915->perf.noa_programming_delay);
  465. return 0;
  466. }
  467. DEFINE_SIMPLE_ATTRIBUTE(i915_perf_noa_delay_fops,
  468. i915_perf_noa_delay_get,
  469. i915_perf_noa_delay_set,
  470. "%llu\n");
  471. #define DROP_UNBOUND BIT(0)
  472. #define DROP_BOUND BIT(1)
  473. #define DROP_RETIRE BIT(2)
  474. #define DROP_ACTIVE BIT(3)
  475. #define DROP_FREED BIT(4)
  476. #define DROP_SHRINK_ALL BIT(5)
  477. #define DROP_IDLE BIT(6)
  478. #define DROP_RESET_ACTIVE BIT(7)
  479. #define DROP_RESET_SEQNO BIT(8)
  480. #define DROP_RCU BIT(9)
  481. #define DROP_ALL (DROP_UNBOUND | \
  482. DROP_BOUND | \
  483. DROP_RETIRE | \
  484. DROP_ACTIVE | \
  485. DROP_FREED | \
  486. DROP_SHRINK_ALL |\
  487. DROP_IDLE | \
  488. DROP_RESET_ACTIVE | \
  489. DROP_RESET_SEQNO | \
  490. DROP_RCU)
  491. static int
  492. i915_drop_caches_get(void *data, u64 *val)
  493. {
  494. *val = DROP_ALL;
  495. return 0;
  496. }
  497. static int
  498. gt_drop_caches(struct intel_gt *gt, u64 val)
  499. {
  500. int ret;
  501. if (val & DROP_RESET_ACTIVE &&
  502. wait_for(intel_engines_are_idle(gt), 200))
  503. intel_gt_set_wedged(gt);
  504. if (val & DROP_RETIRE)
  505. intel_gt_retire_requests(gt);
  506. if (val & (DROP_IDLE | DROP_ACTIVE)) {
  507. ret = intel_gt_wait_for_idle(gt, MAX_SCHEDULE_TIMEOUT);
  508. if (ret)
  509. return ret;
  510. }
  511. if (val & DROP_IDLE) {
  512. ret = intel_gt_pm_wait_for_idle(gt);
  513. if (ret)
  514. return ret;
  515. }
  516. if (val & DROP_RESET_ACTIVE && intel_gt_terminally_wedged(gt))
  517. intel_gt_handle_error(gt, ALL_ENGINES, 0, NULL);
  518. if (val & DROP_FREED)
  519. intel_gt_flush_buffer_pool(gt);
  520. return 0;
  521. }
  522. static int
  523. i915_drop_caches_set(void *data, u64 val)
  524. {
  525. struct drm_i915_private *i915 = data;
  526. struct intel_gt *gt;
  527. unsigned int flags;
  528. unsigned int i;
  529. int ret;
  530. drm_dbg(&i915->drm, "Dropping caches: 0x%08llx [0x%08llx]\n",
  531. val, val & DROP_ALL);
  532. for_each_gt(gt, i915, i) {
  533. ret = gt_drop_caches(gt, val);
  534. if (ret)
  535. return ret;
  536. }
  537. fs_reclaim_acquire(GFP_KERNEL);
  538. flags = memalloc_noreclaim_save();
  539. if (val & DROP_BOUND)
  540. i915_gem_shrink(NULL, i915, LONG_MAX, NULL, I915_SHRINK_BOUND);
  541. if (val & DROP_UNBOUND)
  542. i915_gem_shrink(NULL, i915, LONG_MAX, NULL, I915_SHRINK_UNBOUND);
  543. if (val & DROP_SHRINK_ALL)
  544. i915_gem_shrink_all(i915);
  545. memalloc_noreclaim_restore(flags);
  546. fs_reclaim_release(GFP_KERNEL);
  547. if (val & DROP_RCU)
  548. rcu_barrier();
  549. if (val & DROP_FREED)
  550. i915_gem_drain_freed_objects(i915);
  551. return 0;
  552. }
  553. DEFINE_SIMPLE_ATTRIBUTE(i915_drop_caches_fops,
  554. i915_drop_caches_get, i915_drop_caches_set,
  555. "0x%08llx\n");
  556. static int i915_sseu_status(struct seq_file *m, void *unused)
  557. {
  558. struct drm_i915_private *i915 = node_to_i915(m->private);
  559. struct intel_gt *gt = to_gt(i915);
  560. return intel_sseu_status(m, gt);
  561. }
  562. static int i915_forcewake_open(struct inode *inode, struct file *file)
  563. {
  564. struct drm_i915_private *i915 = inode->i_private;
  565. struct intel_gt *gt;
  566. unsigned int i;
  567. for_each_gt(gt, i915, i)
  568. intel_gt_pm_debugfs_forcewake_user_open(gt);
  569. return 0;
  570. }
  571. static int i915_forcewake_release(struct inode *inode, struct file *file)
  572. {
  573. struct drm_i915_private *i915 = inode->i_private;
  574. struct intel_gt *gt;
  575. unsigned int i;
  576. for_each_gt(gt, i915, i)
  577. intel_gt_pm_debugfs_forcewake_user_release(gt);
  578. return 0;
  579. }
  580. static const struct file_operations i915_forcewake_fops = {
  581. .owner = THIS_MODULE,
  582. .open = i915_forcewake_open,
  583. .release = i915_forcewake_release,
  584. };
  585. static const struct drm_info_list i915_debugfs_list[] = {
  586. {"i915_capabilities", i915_capabilities, 0},
  587. {"i915_gem_objects", i915_gem_object_info, 0},
  588. {"i915_frequency_info", i915_frequency_info, 0},
  589. {"i915_swizzle_info", i915_swizzle_info, 0},
  590. {"i915_runtime_pm_status", i915_runtime_pm_status, 0},
  591. {"i915_engine_info", i915_engine_info, 0},
  592. {"i915_wa_registers", i915_wa_registers, 0},
  593. {"i915_sseu_status", i915_sseu_status, 0},
  594. {"i915_rps_boost_info", i915_rps_boost_info, 0},
  595. };
  596. static const struct i915_debugfs_files {
  597. const char *name;
  598. const struct file_operations *fops;
  599. } i915_debugfs_files[] = {
  600. {"i915_perf_noa_delay", &i915_perf_noa_delay_fops},
  601. {"i915_wedged", &i915_wedged_fops},
  602. {"i915_gem_drop_caches", &i915_drop_caches_fops},
  603. };
  604. void i915_debugfs_register(struct drm_i915_private *i915)
  605. {
  606. struct dentry *debugfs_root = i915->drm.debugfs_root;
  607. int i;
  608. i915_debugfs_params(i915);
  609. debugfs_create_file("i915_forcewake_user", S_IRUSR, debugfs_root,
  610. i915, &i915_forcewake_fops);
  611. for (i = 0; i < ARRAY_SIZE(i915_debugfs_files); i++) {
  612. debugfs_create_file(i915_debugfs_files[i].name, S_IRUGO | S_IWUSR,
  613. debugfs_root, i915,
  614. i915_debugfs_files[i].fops);
  615. }
  616. drm_debugfs_create_files(i915_debugfs_list,
  617. ARRAY_SIZE(i915_debugfs_list),
  618. debugfs_root, i915->drm.primary);
  619. i915_gpu_error_debugfs_register(i915);
  620. }