Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1// SPDX-License-Identifier: MIT
2/*
3 * Copyright © 2022 Intel Corporation
4 */
5
6#include "xe_gt_debugfs.h"
7
8#include <linux/debugfs.h>
9
10#include <drm/drm_debugfs.h>
11#include <drm/drm_managed.h>
12
13#include "xe_device.h"
14#include "xe_force_wake.h"
15#include "xe_ggtt.h"
16#include "xe_gt.h"
17#include "xe_gt_mcr.h"
18#include "xe_gt_idle.h"
19#include "xe_gt_sriov_pf_debugfs.h"
20#include "xe_gt_sriov_vf_debugfs.h"
21#include "xe_gt_stats.h"
22#include "xe_gt_topology.h"
23#include "xe_guc_hwconfig.h"
24#include "xe_hw_engine.h"
25#include "xe_lrc.h"
26#include "xe_macros.h"
27#include "xe_mocs.h"
28#include "xe_pat.h"
29#include "xe_pm.h"
30#include "xe_reg_sr.h"
31#include "xe_reg_whitelist.h"
32#include "xe_sriov.h"
33#include "xe_tuning.h"
34#include "xe_uc_debugfs.h"
35#include "xe_wa.h"
36
37/**
38 * xe_gt_debugfs_simple_show - A show callback for struct drm_info_list
39 * @m: the &seq_file
40 * @data: data used by the drm debugfs helpers
41 *
42 * This callback can be used in struct drm_info_list to describe debugfs
43 * files that are &xe_gt specific.
44 *
45 * It is assumed that those debugfs files will be created on directory entry
46 * which struct dentry d_inode->i_private points to &xe_gt.
47 *
48 * This function assumes that &m->private will be set to the &struct
49 * drm_info_node corresponding to the instance of the info on a given &struct
50 * drm_minor (see struct drm_info_list.show for details).
51 *
52 * This function also assumes that struct drm_info_list.data will point to the
53 * function code that will actually print a file content::
54 *
55 * int (*print)(struct xe_gt *, struct drm_printer *)
56 *
57 * Example::
58 *
59 * int foo(struct xe_gt *gt, struct drm_printer *p)
60 * {
61 * drm_printf(p, "GT%u\n", gt->info.id);
62 * return 0;
63 * }
64 *
65 * static const struct drm_info_list bar[] = {
66 * { name = "foo", .show = xe_gt_debugfs_simple_show, .data = foo },
67 * };
68 *
69 * dir = debugfs_create_dir("gt", parent);
70 * dir->d_inode->i_private = gt;
71 * drm_debugfs_create_files(bar, ARRAY_SIZE(bar), dir, minor);
72 *
73 * Return: 0 on success or a negative error code on failure.
74 */
75int xe_gt_debugfs_simple_show(struct seq_file *m, void *data)
76{
77 struct drm_printer p = drm_seq_file_printer(m);
78 struct drm_info_node *node = m->private;
79 struct dentry *parent = node->dent->d_parent;
80 struct xe_gt *gt = parent->d_inode->i_private;
81 int (*print)(struct xe_gt *, struct drm_printer *) = node->info_ent->data;
82
83 if (WARN_ON(!print))
84 return -EINVAL;
85
86 return print(gt, &p);
87}
88
89static int hw_engines(struct xe_gt *gt, struct drm_printer *p)
90{
91 struct xe_device *xe = gt_to_xe(gt);
92 struct xe_hw_engine *hwe;
93 enum xe_hw_engine_id id;
94 unsigned int fw_ref;
95
96 xe_pm_runtime_get(xe);
97 fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
98 if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL)) {
99 xe_pm_runtime_put(xe);
100 xe_force_wake_put(gt_to_fw(gt), fw_ref);
101 return -ETIMEDOUT;
102 }
103
104 for_each_hw_engine(hwe, gt, id)
105 xe_hw_engine_print(hwe, p);
106
107 xe_force_wake_put(gt_to_fw(gt), fw_ref);
108 xe_pm_runtime_put(xe);
109
110 return 0;
111}
112
113static int powergate_info(struct xe_gt *gt, struct drm_printer *p)
114{
115 int ret;
116
117 xe_pm_runtime_get(gt_to_xe(gt));
118 ret = xe_gt_idle_pg_print(gt, p);
119 xe_pm_runtime_put(gt_to_xe(gt));
120
121 return ret;
122}
123
124static int force_reset(struct xe_gt *gt, struct drm_printer *p)
125{
126 xe_pm_runtime_get(gt_to_xe(gt));
127 xe_gt_reset_async(gt);
128 xe_pm_runtime_put(gt_to_xe(gt));
129
130 return 0;
131}
132
133static int force_reset_sync(struct xe_gt *gt, struct drm_printer *p)
134{
135 xe_pm_runtime_get(gt_to_xe(gt));
136 xe_gt_reset(gt);
137 xe_pm_runtime_put(gt_to_xe(gt));
138
139 return 0;
140}
141
142static int sa_info(struct xe_gt *gt, struct drm_printer *p)
143{
144 struct xe_tile *tile = gt_to_tile(gt);
145
146 xe_pm_runtime_get(gt_to_xe(gt));
147 drm_suballoc_dump_debug_info(&tile->mem.kernel_bb_pool->base, p,
148 tile->mem.kernel_bb_pool->gpu_addr);
149 xe_pm_runtime_put(gt_to_xe(gt));
150
151 return 0;
152}
153
154static int topology(struct xe_gt *gt, struct drm_printer *p)
155{
156 xe_pm_runtime_get(gt_to_xe(gt));
157 xe_gt_topology_dump(gt, p);
158 xe_pm_runtime_put(gt_to_xe(gt));
159
160 return 0;
161}
162
163static int steering(struct xe_gt *gt, struct drm_printer *p)
164{
165 xe_pm_runtime_get(gt_to_xe(gt));
166 xe_gt_mcr_steering_dump(gt, p);
167 xe_pm_runtime_put(gt_to_xe(gt));
168
169 return 0;
170}
171
172static int ggtt(struct xe_gt *gt, struct drm_printer *p)
173{
174 int ret;
175
176 xe_pm_runtime_get(gt_to_xe(gt));
177 ret = xe_ggtt_dump(gt_to_tile(gt)->mem.ggtt, p);
178 xe_pm_runtime_put(gt_to_xe(gt));
179
180 return ret;
181}
182
183static int register_save_restore(struct xe_gt *gt, struct drm_printer *p)
184{
185 struct xe_hw_engine *hwe;
186 enum xe_hw_engine_id id;
187
188 xe_pm_runtime_get(gt_to_xe(gt));
189
190 xe_reg_sr_dump(>->reg_sr, p);
191 drm_printf(p, "\n");
192
193 drm_printf(p, "Engine\n");
194 for_each_hw_engine(hwe, gt, id)
195 xe_reg_sr_dump(&hwe->reg_sr, p);
196 drm_printf(p, "\n");
197
198 drm_printf(p, "LRC\n");
199 for_each_hw_engine(hwe, gt, id)
200 xe_reg_sr_dump(&hwe->reg_lrc, p);
201 drm_printf(p, "\n");
202
203 drm_printf(p, "Whitelist\n");
204 for_each_hw_engine(hwe, gt, id)
205 xe_reg_whitelist_dump(&hwe->reg_whitelist, p);
206
207 xe_pm_runtime_put(gt_to_xe(gt));
208
209 return 0;
210}
211
212static int workarounds(struct xe_gt *gt, struct drm_printer *p)
213{
214 xe_pm_runtime_get(gt_to_xe(gt));
215 xe_wa_dump(gt, p);
216 xe_pm_runtime_put(gt_to_xe(gt));
217
218 return 0;
219}
220
221static int tunings(struct xe_gt *gt, struct drm_printer *p)
222{
223 xe_pm_runtime_get(gt_to_xe(gt));
224 xe_tuning_dump(gt, p);
225 xe_pm_runtime_put(gt_to_xe(gt));
226
227 return 0;
228}
229
230static int pat(struct xe_gt *gt, struct drm_printer *p)
231{
232 xe_pm_runtime_get(gt_to_xe(gt));
233 xe_pat_dump(gt, p);
234 xe_pm_runtime_put(gt_to_xe(gt));
235
236 return 0;
237}
238
239static int mocs(struct xe_gt *gt, struct drm_printer *p)
240{
241 xe_pm_runtime_get(gt_to_xe(gt));
242 xe_mocs_dump(gt, p);
243 xe_pm_runtime_put(gt_to_xe(gt));
244
245 return 0;
246}
247
248static int rcs_default_lrc(struct xe_gt *gt, struct drm_printer *p)
249{
250 xe_pm_runtime_get(gt_to_xe(gt));
251 xe_lrc_dump_default(p, gt, XE_ENGINE_CLASS_RENDER);
252 xe_pm_runtime_put(gt_to_xe(gt));
253
254 return 0;
255}
256
257static int ccs_default_lrc(struct xe_gt *gt, struct drm_printer *p)
258{
259 xe_pm_runtime_get(gt_to_xe(gt));
260 xe_lrc_dump_default(p, gt, XE_ENGINE_CLASS_COMPUTE);
261 xe_pm_runtime_put(gt_to_xe(gt));
262
263 return 0;
264}
265
266static int bcs_default_lrc(struct xe_gt *gt, struct drm_printer *p)
267{
268 xe_pm_runtime_get(gt_to_xe(gt));
269 xe_lrc_dump_default(p, gt, XE_ENGINE_CLASS_COPY);
270 xe_pm_runtime_put(gt_to_xe(gt));
271
272 return 0;
273}
274
275static int vcs_default_lrc(struct xe_gt *gt, struct drm_printer *p)
276{
277 xe_pm_runtime_get(gt_to_xe(gt));
278 xe_lrc_dump_default(p, gt, XE_ENGINE_CLASS_VIDEO_DECODE);
279 xe_pm_runtime_put(gt_to_xe(gt));
280
281 return 0;
282}
283
284static int vecs_default_lrc(struct xe_gt *gt, struct drm_printer *p)
285{
286 xe_pm_runtime_get(gt_to_xe(gt));
287 xe_lrc_dump_default(p, gt, XE_ENGINE_CLASS_VIDEO_ENHANCE);
288 xe_pm_runtime_put(gt_to_xe(gt));
289
290 return 0;
291}
292
293static int hwconfig(struct xe_gt *gt, struct drm_printer *p)
294{
295 xe_pm_runtime_get(gt_to_xe(gt));
296 xe_guc_hwconfig_dump(>->uc.guc, p);
297 xe_pm_runtime_put(gt_to_xe(gt));
298
299 return 0;
300}
301
302static const struct drm_info_list debugfs_list[] = {
303 {"hw_engines", .show = xe_gt_debugfs_simple_show, .data = hw_engines},
304 {"force_reset", .show = xe_gt_debugfs_simple_show, .data = force_reset},
305 {"force_reset_sync", .show = xe_gt_debugfs_simple_show, .data = force_reset_sync},
306 {"sa_info", .show = xe_gt_debugfs_simple_show, .data = sa_info},
307 {"topology", .show = xe_gt_debugfs_simple_show, .data = topology},
308 {"steering", .show = xe_gt_debugfs_simple_show, .data = steering},
309 {"ggtt", .show = xe_gt_debugfs_simple_show, .data = ggtt},
310 {"powergate_info", .show = xe_gt_debugfs_simple_show, .data = powergate_info},
311 {"register-save-restore", .show = xe_gt_debugfs_simple_show, .data = register_save_restore},
312 {"workarounds", .show = xe_gt_debugfs_simple_show, .data = workarounds},
313 {"tunings", .show = xe_gt_debugfs_simple_show, .data = tunings},
314 {"pat", .show = xe_gt_debugfs_simple_show, .data = pat},
315 {"mocs", .show = xe_gt_debugfs_simple_show, .data = mocs},
316 {"default_lrc_rcs", .show = xe_gt_debugfs_simple_show, .data = rcs_default_lrc},
317 {"default_lrc_ccs", .show = xe_gt_debugfs_simple_show, .data = ccs_default_lrc},
318 {"default_lrc_bcs", .show = xe_gt_debugfs_simple_show, .data = bcs_default_lrc},
319 {"default_lrc_vcs", .show = xe_gt_debugfs_simple_show, .data = vcs_default_lrc},
320 {"default_lrc_vecs", .show = xe_gt_debugfs_simple_show, .data = vecs_default_lrc},
321 {"stats", .show = xe_gt_debugfs_simple_show, .data = xe_gt_stats_print_info},
322 {"hwconfig", .show = xe_gt_debugfs_simple_show, .data = hwconfig},
323};
324
325void xe_gt_debugfs_register(struct xe_gt *gt)
326{
327 struct xe_device *xe = gt_to_xe(gt);
328 struct drm_minor *minor = gt_to_xe(gt)->drm.primary;
329 struct dentry *root;
330 char name[8];
331
332 xe_gt_assert(gt, minor->debugfs_root);
333
334 snprintf(name, sizeof(name), "gt%d", gt->info.id);
335 root = debugfs_create_dir(name, minor->debugfs_root);
336 if (IS_ERR(root)) {
337 drm_warn(&xe->drm, "Create GT directory failed");
338 return;
339 }
340
341 /*
342 * Store the xe_gt pointer as private data of the gt/ directory node
343 * so other GT specific attributes under that directory may refer to
344 * it by looking at its parent node private data.
345 */
346 root->d_inode->i_private = gt;
347
348 drm_debugfs_create_files(debugfs_list,
349 ARRAY_SIZE(debugfs_list),
350 root, minor);
351
352 xe_uc_debugfs_register(>->uc, root);
353
354 if (IS_SRIOV_PF(xe))
355 xe_gt_sriov_pf_debugfs_register(gt, root);
356 else if (IS_SRIOV_VF(xe))
357 xe_gt_sriov_vf_debugfs_register(gt, root);
358}