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