i915_debugfs.c 20 KB

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