xref: /linux/drivers/gpu/drm/xe/xe_debugfs.c (revision cf4cebcec619d963fa7496018f03cb0ff00dc257)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2022 Intel Corporation
4  */
5 
6 #include "xe_debugfs.h"
7 
8 #include <linux/debugfs.h>
9 #include <linux/string_helpers.h>
10 
11 #include <drm/drm_debugfs.h>
12 
13 #include "xe_bo.h"
14 #include "xe_device.h"
15 #include "xe_force_wake.h"
16 #include "xe_gt_debugfs.h"
17 #include "xe_gt_printk.h"
18 #include "xe_guc_ads.h"
19 #include "xe_pm.h"
20 #include "xe_sriov.h"
21 #include "xe_step.h"
22 
23 #ifdef CONFIG_DRM_XE_DEBUG
24 #include "xe_bo_evict.h"
25 #include "xe_migrate.h"
26 #include "xe_vm.h"
27 #endif
28 
29 #ifdef CONFIG_FAULT_INJECTION
30 #include <linux/fault-inject.h> /* XXX: fault-inject.h is broken */
31 DECLARE_FAULT_ATTR(gt_reset_failure);
32 #endif
33 
34 static struct xe_device *node_to_xe(struct drm_info_node *node)
35 {
36 	return to_xe_device(node->minor->dev);
37 }
38 
39 static int info(struct seq_file *m, void *data)
40 {
41 	struct xe_device *xe = node_to_xe(m->private);
42 	struct drm_printer p = drm_seq_file_printer(m);
43 	struct xe_gt *gt;
44 	u8 id;
45 
46 	xe_pm_runtime_get(xe);
47 
48 	drm_printf(&p, "graphics_verx100 %d\n", xe->info.graphics_verx100);
49 	drm_printf(&p, "media_verx100 %d\n", xe->info.media_verx100);
50 	drm_printf(&p, "stepping G:%s M:%s B:%s\n",
51 		   xe_step_name(xe->info.step.graphics),
52 		   xe_step_name(xe->info.step.media),
53 		   xe_step_name(xe->info.step.basedie));
54 	drm_printf(&p, "is_dgfx %s\n", str_yes_no(xe->info.is_dgfx));
55 	drm_printf(&p, "platform %d\n", xe->info.platform);
56 	drm_printf(&p, "subplatform %d\n",
57 		   xe->info.subplatform > XE_SUBPLATFORM_NONE ? xe->info.subplatform : 0);
58 	drm_printf(&p, "devid 0x%x\n", xe->info.devid);
59 	drm_printf(&p, "revid %d\n", xe->info.revid);
60 	drm_printf(&p, "tile_count %d\n", xe->info.tile_count);
61 	drm_printf(&p, "vm_max_level %d\n", xe->info.vm_max_level);
62 	drm_printf(&p, "force_execlist %s\n", str_yes_no(xe->info.force_execlist));
63 	drm_printf(&p, "has_flat_ccs %s\n", str_yes_no(xe->info.has_flat_ccs));
64 	drm_printf(&p, "has_usm %s\n", str_yes_no(xe->info.has_usm));
65 	drm_printf(&p, "skip_guc_pc %s\n", str_yes_no(xe->info.skip_guc_pc));
66 	for_each_gt(gt, xe, id) {
67 		drm_printf(&p, "gt%d force wake %d\n", id,
68 			   xe_force_wake_ref(gt_to_fw(gt), XE_FW_GT));
69 		drm_printf(&p, "gt%d engine_mask 0x%llx\n", id,
70 			   gt->info.engine_mask);
71 	}
72 
73 	xe_pm_runtime_put(xe);
74 	return 0;
75 }
76 
77 static int sriov_info(struct seq_file *m, void *data)
78 {
79 	struct xe_device *xe = node_to_xe(m->private);
80 	struct drm_printer p = drm_seq_file_printer(m);
81 
82 	xe_sriov_print_info(xe, &p);
83 	return 0;
84 }
85 
86 static const struct drm_info_list debugfs_list[] = {
87 	{"info", info, 0},
88 	{ .name = "sriov_info", .show = sriov_info, },
89 };
90 
91 static int forcewake_open(struct inode *inode, struct file *file)
92 {
93 	struct xe_device *xe = inode->i_private;
94 	struct xe_gt *gt;
95 	u8 id;
96 
97 	xe_pm_runtime_get(xe);
98 	for_each_gt(gt, xe, id)
99 		XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL));
100 
101 	return 0;
102 }
103 
104 static int forcewake_release(struct inode *inode, struct file *file)
105 {
106 	struct xe_device *xe = inode->i_private;
107 	struct xe_gt *gt;
108 	u8 id;
109 
110 	for_each_gt(gt, xe, id)
111 		XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
112 	xe_pm_runtime_put(xe);
113 
114 	return 0;
115 }
116 
117 static const struct file_operations forcewake_all_fops = {
118 	.owner = THIS_MODULE,
119 	.open = forcewake_open,
120 	.release = forcewake_release,
121 };
122 
123 static ssize_t wedged_mode_show(struct file *f, char __user *ubuf,
124 				size_t size, loff_t *pos)
125 {
126 	struct xe_device *xe = file_inode(f)->i_private;
127 	char buf[32];
128 	int len = 0;
129 
130 	len = scnprintf(buf, sizeof(buf), "%d\n", xe->wedged.mode);
131 
132 	return simple_read_from_buffer(ubuf, size, pos, buf, len);
133 }
134 
135 static ssize_t wedged_mode_set(struct file *f, const char __user *ubuf,
136 			       size_t size, loff_t *pos)
137 {
138 	struct xe_device *xe = file_inode(f)->i_private;
139 	struct xe_gt *gt;
140 	u32 wedged_mode;
141 	ssize_t ret;
142 	u8 id;
143 
144 	ret = kstrtouint_from_user(ubuf, size, 0, &wedged_mode);
145 	if (ret)
146 		return ret;
147 
148 	if (wedged_mode > 2)
149 		return -EINVAL;
150 
151 	if (xe->wedged.mode == wedged_mode)
152 		return 0;
153 
154 	xe->wedged.mode = wedged_mode;
155 
156 	xe_pm_runtime_get(xe);
157 	for_each_gt(gt, xe, id) {
158 		ret = xe_guc_ads_scheduler_policy_toggle_reset(&gt->uc.guc.ads);
159 		if (ret) {
160 			xe_gt_err(gt, "Failed to update GuC ADS scheduler policy. GuC may still cause engine reset even with wedged_mode=2\n");
161 			return -EIO;
162 		}
163 	}
164 	xe_pm_runtime_put(xe);
165 
166 	return size;
167 }
168 
169 static const struct file_operations wedged_mode_fops = {
170 	.owner = THIS_MODULE,
171 	.read = wedged_mode_show,
172 	.write = wedged_mode_set,
173 };
174 
175 void xe_debugfs_register(struct xe_device *xe)
176 {
177 	struct ttm_device *bdev = &xe->ttm;
178 	struct drm_minor *minor = xe->drm.primary;
179 	struct dentry *root = minor->debugfs_root;
180 	struct ttm_resource_manager *man;
181 	struct xe_gt *gt;
182 	u32 mem_type;
183 	u8 id;
184 
185 	drm_debugfs_create_files(debugfs_list,
186 				 ARRAY_SIZE(debugfs_list),
187 				 root, minor);
188 
189 	debugfs_create_file("forcewake_all", 0400, root, xe,
190 			    &forcewake_all_fops);
191 
192 	debugfs_create_file("wedged_mode", 0400, root, xe,
193 			    &wedged_mode_fops);
194 
195 	for (mem_type = XE_PL_VRAM0; mem_type <= XE_PL_VRAM1; ++mem_type) {
196 		man = ttm_manager_type(bdev, mem_type);
197 
198 		if (man) {
199 			char name[16];
200 
201 			snprintf(name, sizeof(name), "vram%d_mm", mem_type - XE_PL_VRAM0);
202 			ttm_resource_manager_create_debugfs(man, root, name);
203 		}
204 	}
205 
206 	man = ttm_manager_type(bdev, XE_PL_TT);
207 	ttm_resource_manager_create_debugfs(man, root, "gtt_mm");
208 
209 	man = ttm_manager_type(bdev, XE_PL_STOLEN);
210 	if (man)
211 		ttm_resource_manager_create_debugfs(man, root, "stolen_mm");
212 
213 	for_each_gt(gt, xe, id)
214 		xe_gt_debugfs_register(gt);
215 
216 #ifdef CONFIG_FAULT_INJECTION
217 	fault_create_debugfs_attr("fail_gt_reset", root, &gt_reset_failure);
218 #endif
219 
220 }
221