xref: /linux/drivers/gpu/drm/xe/xe_debugfs.c (revision fb54ea1ee84534cab6a15515c73a0811bdcbc973)
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_sriov.h"
22 #include "xe_step.h"
23 
24 #ifdef CONFIG_DRM_XE_DEBUG
25 #include "xe_bo_evict.h"
26 #include "xe_migrate.h"
27 #include "xe_vm.h"
28 #endif
29 
30 DECLARE_FAULT_ATTR(gt_reset_failure);
31 
32 static struct xe_device *node_to_xe(struct drm_info_node *node)
33 {
34 	return to_xe_device(node->minor->dev);
35 }
36 
37 static int info(struct seq_file *m, void *data)
38 {
39 	struct xe_device *xe = node_to_xe(m->private);
40 	struct drm_printer p = drm_seq_file_printer(m);
41 	struct xe_gt *gt;
42 	u8 id;
43 
44 	xe_pm_runtime_get(xe);
45 
46 	drm_printf(&p, "graphics_verx100 %d\n", xe->info.graphics_verx100);
47 	drm_printf(&p, "media_verx100 %d\n", xe->info.media_verx100);
48 	drm_printf(&p, "stepping G:%s M:%s D:%s B:%s\n",
49 		   xe_step_name(xe->info.step.graphics),
50 		   xe_step_name(xe->info.step.media),
51 		   xe_step_name(xe->info.step.display),
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;
95 
96 	xe_pm_runtime_get(xe);
97 	for_each_gt(gt, xe, id)
98 		XE_WARN_ON(xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL));
99 
100 	return 0;
101 }
102 
103 static int forcewake_release(struct inode *inode, struct file *file)
104 {
105 	struct xe_device *xe = inode->i_private;
106 	struct xe_gt *gt;
107 	u8 id;
108 
109 	for_each_gt(gt, xe, id)
110 		XE_WARN_ON(xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL));
111 	xe_pm_runtime_put(xe);
112 
113 	return 0;
114 }
115 
116 static const struct file_operations forcewake_all_fops = {
117 	.owner = THIS_MODULE,
118 	.open = forcewake_open,
119 	.release = forcewake_release,
120 };
121 
122 static ssize_t wedged_mode_show(struct file *f, char __user *ubuf,
123 				size_t size, loff_t *pos)
124 {
125 	struct xe_device *xe = file_inode(f)->i_private;
126 	char buf[32];
127 	int len = 0;
128 
129 	len = scnprintf(buf, sizeof(buf), "%d\n", xe->wedged.mode);
130 
131 	return simple_read_from_buffer(ubuf, size, pos, buf, len);
132 }
133 
134 static ssize_t wedged_mode_set(struct file *f, const char __user *ubuf,
135 			       size_t size, loff_t *pos)
136 {
137 	struct xe_device *xe = file_inode(f)->i_private;
138 	struct xe_gt *gt;
139 	u32 wedged_mode;
140 	ssize_t ret;
141 	u8 id;
142 
143 	ret = kstrtouint_from_user(ubuf, size, 0, &wedged_mode);
144 	if (ret)
145 		return ret;
146 
147 	if (wedged_mode > 2)
148 		return -EINVAL;
149 
150 	if (xe->wedged.mode == wedged_mode)
151 		return 0;
152 
153 	xe->wedged.mode = wedged_mode;
154 
155 	xe_pm_runtime_get(xe);
156 	for_each_gt(gt, xe, id) {
157 		ret = xe_guc_ads_scheduler_policy_toggle_reset(&gt->uc.guc.ads);
158 		if (ret) {
159 			xe_gt_err(gt, "Failed to update GuC ADS scheduler policy. GuC may still cause engine reset even with wedged_mode=2\n");
160 			return -EIO;
161 		}
162 	}
163 	xe_pm_runtime_put(xe);
164 
165 	return size;
166 }
167 
168 static const struct file_operations wedged_mode_fops = {
169 	.owner = THIS_MODULE,
170 	.read = wedged_mode_show,
171 	.write = wedged_mode_set,
172 };
173 
174 void xe_debugfs_register(struct xe_device *xe)
175 {
176 	struct ttm_device *bdev = &xe->ttm;
177 	struct drm_minor *minor = xe->drm.primary;
178 	struct dentry *root = minor->debugfs_root;
179 	struct ttm_resource_manager *man;
180 	struct xe_gt *gt;
181 	u32 mem_type;
182 	u8 id;
183 
184 	drm_debugfs_create_files(debugfs_list,
185 				 ARRAY_SIZE(debugfs_list),
186 				 root, minor);
187 
188 	debugfs_create_file("forcewake_all", 0400, root, xe,
189 			    &forcewake_all_fops);
190 
191 	debugfs_create_file("wedged_mode", 0400, root, xe,
192 			    &wedged_mode_fops);
193 
194 	for (mem_type = XE_PL_VRAM0; mem_type <= XE_PL_VRAM1; ++mem_type) {
195 		man = ttm_manager_type(bdev, mem_type);
196 
197 		if (man) {
198 			char name[16];
199 
200 			snprintf(name, sizeof(name), "vram%d_mm", mem_type - XE_PL_VRAM0);
201 			ttm_resource_manager_create_debugfs(man, root, name);
202 		}
203 	}
204 
205 	man = ttm_manager_type(bdev, XE_PL_TT);
206 	ttm_resource_manager_create_debugfs(man, root, "gtt_mm");
207 
208 	man = ttm_manager_type(bdev, XE_PL_STOLEN);
209 	if (man)
210 		ttm_resource_manager_create_debugfs(man, root, "stolen_mm");
211 
212 	for_each_gt(gt, xe, id)
213 		xe_gt_debugfs_register(gt);
214 
215 	fault_create_debugfs_attr("fail_gt_reset", root, &gt_reset_failure);
216 }
217