1 | // SPDX-License-Identifier: MIT |
2 | /* |
3 | * Copyright © 2019 Intel Corporation |
4 | */ |
5 | |
6 | #include <linux/debugfs.h> |
7 | |
8 | #include "i915_drv.h" |
9 | #include "intel_gt.h" |
10 | #include "intel_gt_debugfs.h" |
11 | #include "intel_gt_engines_debugfs.h" |
12 | #include "intel_gt_mcr.h" |
13 | #include "intel_gt_pm_debugfs.h" |
14 | #include "intel_sseu_debugfs.h" |
15 | #include "uc/intel_uc_debugfs.h" |
16 | |
17 | int intel_gt_debugfs_reset_show(struct intel_gt *gt, u64 *val) |
18 | { |
19 | int ret = intel_gt_terminally_wedged(gt); |
20 | |
21 | switch (ret) { |
22 | case -EIO: |
23 | *val = 1; |
24 | return 0; |
25 | case 0: |
26 | *val = 0; |
27 | return 0; |
28 | default: |
29 | return ret; |
30 | } |
31 | } |
32 | |
33 | void intel_gt_debugfs_reset_store(struct intel_gt *gt, u64 val) |
34 | { |
35 | /* Flush any previous reset before applying for a new one */ |
36 | wait_event(gt->reset.queue, |
37 | !test_bit(I915_RESET_BACKOFF, >->reset.flags)); |
38 | |
39 | intel_gt_handle_error(gt, engine_mask: val, I915_ERROR_CAPTURE, |
40 | fmt: "Manually reset engine mask to %llx" , val); |
41 | } |
42 | |
43 | /* |
44 | * keep the interface clean where the first parameter |
45 | * is a 'struct intel_gt *' instead of 'void *' |
46 | */ |
47 | static int __intel_gt_debugfs_reset_show(void *data, u64 *val) |
48 | { |
49 | return intel_gt_debugfs_reset_show(gt: data, val); |
50 | } |
51 | |
52 | static int __intel_gt_debugfs_reset_store(void *data, u64 val) |
53 | { |
54 | intel_gt_debugfs_reset_store(gt: data, val); |
55 | |
56 | return 0; |
57 | } |
58 | |
59 | DEFINE_SIMPLE_ATTRIBUTE(reset_fops, __intel_gt_debugfs_reset_show, |
60 | __intel_gt_debugfs_reset_store, "%llu\n" ); |
61 | |
62 | static int steering_show(struct seq_file *m, void *data) |
63 | { |
64 | struct drm_printer p = drm_seq_file_printer(f: m); |
65 | struct intel_gt *gt = m->private; |
66 | |
67 | intel_gt_mcr_report_steering(p: &p, gt, dump_table: true); |
68 | |
69 | return 0; |
70 | } |
71 | DEFINE_INTEL_GT_DEBUGFS_ATTRIBUTE(steering); |
72 | |
73 | static void gt_debugfs_register(struct intel_gt *gt, struct dentry *root) |
74 | { |
75 | static const struct intel_gt_debugfs_file files[] = { |
76 | { "reset" , &reset_fops, NULL }, |
77 | { "steering" , &steering_fops }, |
78 | }; |
79 | |
80 | intel_gt_debugfs_register_files(root, files, ARRAY_SIZE(files), data: gt); |
81 | } |
82 | |
83 | void intel_gt_debugfs_register(struct intel_gt *gt) |
84 | { |
85 | struct dentry *root; |
86 | char gtname[4]; |
87 | |
88 | if (!gt->i915->drm.primary->debugfs_root) |
89 | return; |
90 | |
91 | snprintf(buf: gtname, size: sizeof(gtname), fmt: "gt%u" , gt->info.id); |
92 | root = debugfs_create_dir(name: gtname, parent: gt->i915->drm.primary->debugfs_root); |
93 | if (IS_ERR(ptr: root)) |
94 | return; |
95 | |
96 | gt_debugfs_register(gt, root); |
97 | |
98 | intel_gt_engines_debugfs_register(gt, root); |
99 | intel_gt_pm_debugfs_register(gt, root); |
100 | intel_sseu_debugfs_register(gt, root); |
101 | |
102 | intel_uc_debugfs_register(uc: >->uc, gt_root: root); |
103 | } |
104 | |
105 | void intel_gt_debugfs_register_files(struct dentry *root, |
106 | const struct intel_gt_debugfs_file *files, |
107 | unsigned long count, void *data) |
108 | { |
109 | while (count--) { |
110 | umode_t mode = files->fops->write ? 0644 : 0444; |
111 | |
112 | if (!files->eval || files->eval(data)) |
113 | debugfs_create_file(name: files->name, |
114 | mode, parent: root, data, |
115 | fops: files->fops); |
116 | |
117 | files++; |
118 | } |
119 | } |
120 | |