xref: /linux/drivers/gpu/drm/xe/xe_debugfs.c (revision 570f7e331f5febb30f1384817463c7e42b65ca7d)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2022 Intel Corporation
4  */
5 
6 #include "xe_debugfs.h"
7 
8 #include <linux/bits.h>
9 #include <linux/debugfs.h>
10 #include <linux/fault-inject.h>
11 #include <linux/string_helpers.h>
12 
13 #include <drm/drm_debugfs.h>
14 
15 #include "regs/xe_pmt.h"
16 #include "xe_bo.h"
17 #include "xe_device.h"
18 #include "xe_force_wake.h"
19 #include "xe_gt.h"
20 #include "xe_gt_debugfs.h"
21 #include "xe_gt_printk.h"
22 #include "xe_guc_ads.h"
23 #include "xe_hw_engine.h"
24 #include "xe_mmio.h"
25 #include "xe_pcode.h"
26 #include "xe_pm.h"
27 #include "xe_psmi.h"
28 #include "xe_pxp_debugfs.h"
29 #include "xe_sriov.h"
30 #include "xe_sriov_pf_debugfs.h"
31 #include "xe_sriov_vf.h"
32 #include "xe_step.h"
33 #include "xe_tile_debugfs.h"
34 #include "xe_vsec.h"
35 #include "xe_wa.h"
36 
37 #ifdef CONFIG_DRM_XE_DEBUG
38 #include "xe_bo_evict.h"
39 #include "xe_migrate.h"
40 #include "xe_vm.h"
41 #endif
42 
43 DECLARE_FAULT_ATTR(gt_reset_failure);
44 DECLARE_FAULT_ATTR(inject_csc_hw_error);
45 
46 static bool csc_hw_error_available(struct xe_device *xe)
47 {
48 	return !IS_SRIOV_VF(xe) && xe->info.platform == XE_BATTLEMAGE;
49 }
50 
51 /*
52  * Fault injection table.  Each entry registers a debugfs attribute; add a
53  * matching FAULT_ACTION() below for every entry added here.
54  */
55 static struct {
56 	const char *name;
57 	struct fault_attr *attr;
58 	bool (*is_visible)(struct xe_device *xe);
59 } xe_fault_inject_entry[] = {
60 	{ .name = "fail_gt_reset",
61 	  .attr = &gt_reset_failure },
62 	{ .name = "inject_csc_hw_error",
63 	  .attr = &inject_csc_hw_error,
64 	  .is_visible = csc_hw_error_available },
65 };
66 
67 /*
68  * FAULT_ACTION(name, fault_attr) - generate xe_fault_<name>() accessor.
69  * Add one entry per row in xe_fault_inject_entry[].
70  */
71 #define FAULT_ACTION(name, fault_attr)			\
72 bool xe_fault_##name(void)				\
73 {							\
74 	return should_fail(&(fault_attr), 1);		\
75 }
76 
77 FAULT_ACTION(gt_reset, gt_reset_failure)
78 FAULT_ACTION(csc_hw_error, inject_csc_hw_error)
79 
80 static void xe_fault_inject_debugfs_register(struct xe_device *xe,
81 					     struct dentry *root)
82 {
83 	int i;
84 
85 	for (i = 0; i < ARRAY_SIZE(xe_fault_inject_entry); i++) {
86 		if (xe_fault_inject_entry[i].is_visible &&
87 		    !xe_fault_inject_entry[i].is_visible(xe))
88 			continue;
89 
90 		fault_create_debugfs_attr(xe_fault_inject_entry[i].name, root,
91 					  xe_fault_inject_entry[i].attr);
92 	}
93 }
94 
95 static void read_residency_counter(struct xe_device *xe, struct xe_mmio *mmio,
96 				   u32 offset, const char *name, struct drm_printer *p)
97 {
98 	u64 residency = 0;
99 	int ret;
100 
101 	ret = xe_pmt_telem_read(xe->drm.dev,
102 				xe_mmio_read32(mmio, PUNIT_TELEMETRY_GUID),
103 				&residency, offset, sizeof(residency));
104 	if (ret != sizeof(residency)) {
105 		drm_warn(&xe->drm, "%s counter failed to read, ret %d\n", name, ret);
106 		return;
107 	}
108 
109 	drm_printf(p, "%s : %llu\n", name, residency);
110 }
111 
112 static struct xe_device *node_to_xe(struct drm_info_node *node)
113 {
114 	return to_xe_device(node->minor->dev);
115 }
116 
117 static void print_engine_class_mask(struct drm_printer *p, u16 mask)
118 {
119 	if (!mask) {
120 		drm_printf(p, " none\n");
121 		return;
122 	}
123 
124 	for (enum xe_engine_class ec = 0; ec < XE_ENGINE_CLASS_MAX; ec++) {
125 		if (mask & BIT(ec))
126 			drm_printf(p, " %s", xe_hw_engine_class_to_str(ec));
127 	}
128 	drm_printf(p, "\n");
129 }
130 
131 static void print_engine_mask(struct drm_printer *p, struct xe_gt *gt, u64 mask)
132 {
133 	struct xe_hw_engine *hwe;
134 	enum xe_hw_engine_id id;
135 
136 	if (!mask) {
137 		drm_printf(p, " none\n");
138 		return;
139 	}
140 
141 	for_each_hw_engine(hwe, gt, id) {
142 		if (mask & BIT_ULL(id))
143 			drm_printf(p, " %s", hwe->name);
144 	}
145 	drm_printf(p, "\n");
146 }
147 
148 static int info(struct seq_file *m, void *data)
149 {
150 	struct xe_device *xe = node_to_xe(m->private);
151 	struct drm_printer p = drm_seq_file_printer(m);
152 	struct xe_gt *gt;
153 	u8 id;
154 
155 	guard(xe_pm_runtime)(xe);
156 
157 	drm_printf(&p, "graphics_verx100 %d\n", xe->info.graphics_verx100);
158 	drm_printf(&p, "media_verx100 %d\n", xe->info.media_verx100);
159 	drm_printf(&p, "stepping G:%s M:%s B:%s\n",
160 		   xe_step_name(xe->info.step.graphics),
161 		   xe_step_name(xe->info.step.media),
162 		   xe_step_name(xe->info.step.basedie));
163 	drm_printf(&p, "is_dgfx %s\n", str_yes_no(xe->info.is_dgfx));
164 	drm_printf(&p, "platform %d\n", xe->info.platform);
165 	drm_printf(&p, "subplatform %d\n",
166 		   xe->info.subplatform > XE_SUBPLATFORM_NONE ? xe->info.subplatform : 0);
167 	drm_printf(&p, "devid 0x%x\n", xe->info.devid);
168 	drm_printf(&p, "revid %d\n", xe->info.revid);
169 	drm_printf(&p, "tile_count %d\n", xe->info.tile_count);
170 	drm_printf(&p, "vm_max_level %d\n", xe->info.vm_max_level);
171 	drm_printf(&p, "has_flat_ccs %s\n", str_yes_no(xe->info.has_flat_ccs));
172 	drm_printf(&p, "has_usm %s\n", str_yes_no(xe->info.has_usm));
173 	drm_printf(&p, "skip_guc_pc %s\n", str_yes_no(xe->info.skip_guc_pc));
174 	drm_printf(&p, "multi_lrc_engine_classes");
175 	print_engine_class_mask(&p, xe->info.multi_lrc_mask);
176 	for_each_gt(gt, xe, id) {
177 		drm_printf(&p, "gt%d force wake %d\n", id,
178 			   xe_force_wake_ref(gt_to_fw(gt), XE_FW_GT));
179 		drm_printf(&p, "gt%d engines", id);
180 		print_engine_mask(&p, gt, gt->info.engine_mask);
181 		drm_printf(&p, "gt%d multi_queue_engine_classes", id);
182 		print_engine_class_mask(&p, gt->info.multi_queue_engine_class_mask);
183 	}
184 
185 	return 0;
186 }
187 
188 static int sriov_info(struct seq_file *m, void *data)
189 {
190 	struct xe_device *xe = node_to_xe(m->private);
191 	struct drm_printer p = drm_seq_file_printer(m);
192 
193 	xe_sriov_print_info(xe, &p);
194 	return 0;
195 }
196 
197 static int workarounds(struct xe_device *xe, struct drm_printer *p)
198 {
199 	guard(xe_pm_runtime)(xe);
200 	xe_wa_device_dump(xe, p);
201 
202 	return 0;
203 }
204 
205 static int workaround_info(struct seq_file *m, void *data)
206 {
207 	struct xe_device *xe = node_to_xe(m->private);
208 	struct drm_printer p = drm_seq_file_printer(m);
209 
210 	workarounds(xe, &p);
211 	return 0;
212 }
213 
214 static int pcode_info(struct seq_file *m, void *data)
215 {
216 	struct xe_device *xe = node_to_xe(m->private);
217 	struct drm_printer p = drm_seq_file_printer(m);
218 	struct xe_pcode_version version;
219 	int ret = 0;
220 
221 	ret = xe_get_pcode_version(xe, &version);
222 	if (ret)
223 		return ret;
224 
225 	drm_printf(&p, "pcode version: %u.%u.%u\n", version.major,
226 		   version.minor, version.engg);
227 	return 0;
228 }
229 
230 static int dgfx_pkg_residencies_show(struct seq_file *m, void *data)
231 {
232 	struct xe_device *xe;
233 	struct xe_mmio *mmio;
234 	struct drm_printer p;
235 
236 	xe = node_to_xe(m->private);
237 	p = drm_seq_file_printer(m);
238 	guard(xe_pm_runtime)(xe);
239 	mmio = xe_root_tile_mmio(xe);
240 	static const struct {
241 		u32 offset;
242 		const char *name;
243 	} residencies[] = {
244 		{BMG_G2_RESIDENCY_OFFSET, "Package G2"},
245 		{BMG_G6_RESIDENCY_OFFSET, "Package G6"},
246 		{BMG_G7_RESIDENCY_OFFSET, "Package G7"},
247 		{BMG_G8_RESIDENCY_OFFSET, "Package G8"},
248 		{BMG_G10_RESIDENCY_OFFSET, "Package G10"},
249 		{BMG_MODS_RESIDENCY_OFFSET, "Package ModS"}
250 	};
251 
252 	for (int i = 0; i < ARRAY_SIZE(residencies); i++)
253 		read_residency_counter(xe, mmio, residencies[i].offset, residencies[i].name, &p);
254 
255 	return 0;
256 }
257 
258 static int dgfx_pcie_link_residencies_show(struct seq_file *m, void *data)
259 {
260 	struct xe_device *xe;
261 	struct xe_mmio *mmio;
262 	struct drm_printer p;
263 
264 	xe = node_to_xe(m->private);
265 	p = drm_seq_file_printer(m);
266 	guard(xe_pm_runtime)(xe);
267 	mmio = xe_root_tile_mmio(xe);
268 
269 	static const struct {
270 		u32 offset;
271 		const char *name;
272 	} residencies[] = {
273 		{BMG_PCIE_LINK_L0_RESIDENCY_OFFSET, "PCIE LINK L0 RESIDENCY"},
274 		{BMG_PCIE_LINK_L1_RESIDENCY_OFFSET, "PCIE LINK L1 RESIDENCY"},
275 		{BMG_PCIE_LINK_L1_2_RESIDENCY_OFFSET, "PCIE LINK L1.2 RESIDENCY"}
276 	};
277 
278 	for (int i = 0; i < ARRAY_SIZE(residencies); i++)
279 		read_residency_counter(xe, mmio, residencies[i].offset, residencies[i].name, &p);
280 
281 	return 0;
282 }
283 
284 static const struct drm_info_list debugfs_list[] = {
285 	{"info", info, 0},
286 	{ .name = "sriov_info", .show = sriov_info, },
287 	{ .name = "workarounds", .show = workaround_info, },
288 };
289 
290 static const struct drm_info_list pcode_info_debugfs[] = {
291 	{ .name = "pcode_info", .show = pcode_info, },
292 };
293 
294 static const struct drm_info_list debugfs_residencies[] = {
295 	{ .name = "dgfx_pkg_residencies", .show = dgfx_pkg_residencies_show, },
296 	{ .name = "dgfx_pcie_link_residencies", .show = dgfx_pcie_link_residencies_show, },
297 };
298 
299 static int forcewake_open(struct inode *inode, struct file *file)
300 {
301 	struct xe_device *xe = inode->i_private;
302 	struct xe_gt *gt;
303 	u8 id, last_gt;
304 	unsigned int fw_ref;
305 
306 	xe_pm_runtime_get(xe);
307 	for_each_gt(gt, xe, id) {
308 		last_gt = id;
309 
310 		fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
311 		if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL))
312 			goto err_fw_get;
313 	}
314 
315 	return 0;
316 
317 err_fw_get:
318 	for_each_gt(gt, xe, id) {
319 		if (id < last_gt)
320 			xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
321 		else if (id == last_gt)
322 			xe_force_wake_put(gt_to_fw(gt), fw_ref);
323 		else
324 			break;
325 	}
326 
327 	xe_pm_runtime_put(xe);
328 	return -ETIMEDOUT;
329 }
330 
331 static int forcewake_release(struct inode *inode, struct file *file)
332 {
333 	struct xe_device *xe = inode->i_private;
334 	struct xe_gt *gt;
335 	u8 id;
336 
337 	for_each_gt(gt, xe, id)
338 		xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
339 	xe_pm_runtime_put(xe);
340 
341 	return 0;
342 }
343 
344 static const struct file_operations forcewake_all_fops = {
345 	.owner = THIS_MODULE,
346 	.open = forcewake_open,
347 	.release = forcewake_release,
348 };
349 
350 static ssize_t wedged_mode_show(struct file *f, char __user *ubuf,
351 				size_t size, loff_t *pos)
352 {
353 	struct xe_device *xe = file_inode(f)->i_private;
354 	char buf[32];
355 	int len = 0;
356 
357 	len = scnprintf(buf, sizeof(buf), "%d\n", xe->wedged.mode);
358 
359 	return simple_read_from_buffer(ubuf, size, pos, buf, len);
360 }
361 
362 static int __wedged_mode_set_reset_policy(struct xe_gt *gt, enum xe_wedged_mode mode)
363 {
364 	bool enable_engine_reset;
365 	int ret;
366 
367 	enable_engine_reset = (mode != XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET);
368 	ret = xe_guc_ads_scheduler_policy_toggle_reset(&gt->uc.guc.ads,
369 						       enable_engine_reset);
370 	if (ret)
371 		xe_gt_err(gt, "Failed to update GuC ADS scheduler policy (%pe)\n", ERR_PTR(ret));
372 
373 	return ret;
374 }
375 
376 static int wedged_mode_set_reset_policy(struct xe_device *xe, enum xe_wedged_mode mode)
377 {
378 	struct xe_gt *gt;
379 	int ret;
380 	u8 id;
381 
382 	guard(xe_pm_runtime)(xe);
383 	for_each_gt(gt, xe, id) {
384 		ret = __wedged_mode_set_reset_policy(gt, mode);
385 		if (ret) {
386 			if (id > 0) {
387 				xe->wedged.inconsistent_reset = true;
388 				drm_err(&xe->drm, "Inconsistent reset policy state between GTs\n");
389 			}
390 			return ret;
391 		}
392 	}
393 
394 	xe->wedged.inconsistent_reset = false;
395 
396 	return 0;
397 }
398 
399 static bool wedged_mode_needs_policy_update(struct xe_device *xe, enum xe_wedged_mode mode)
400 {
401 	if (xe->wedged.inconsistent_reset)
402 		return true;
403 
404 	if (xe->wedged.mode == mode)
405 		return false;
406 
407 	if (xe->wedged.mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET ||
408 	    mode == XE_WEDGED_MODE_UPON_ANY_HANG_NO_RESET)
409 		return true;
410 
411 	return false;
412 }
413 
414 static ssize_t wedged_mode_set(struct file *f, const char __user *ubuf,
415 			       size_t size, loff_t *pos)
416 {
417 	struct xe_device *xe = file_inode(f)->i_private;
418 	u32 wedged_mode;
419 	ssize_t ret;
420 
421 	ret = kstrtouint_from_user(ubuf, size, 0, &wedged_mode);
422 	if (ret)
423 		return ret;
424 
425 	ret = xe_device_validate_wedged_mode(xe, wedged_mode);
426 	if (ret)
427 		return ret;
428 
429 	if (wedged_mode_needs_policy_update(xe, wedged_mode)) {
430 		ret = wedged_mode_set_reset_policy(xe, wedged_mode);
431 		if (ret)
432 			return ret;
433 	}
434 
435 	xe->wedged.mode = wedged_mode;
436 
437 	return size;
438 }
439 
440 static const struct file_operations wedged_mode_fops = {
441 	.owner = THIS_MODULE,
442 	.read = wedged_mode_show,
443 	.write = wedged_mode_set,
444 };
445 
446 static ssize_t page_reclaim_hw_assist_show(struct file *f, char __user *ubuf,
447 					   size_t size, loff_t *pos)
448 {
449 	struct xe_device *xe = file_inode(f)->i_private;
450 	char buf[8];
451 	int len;
452 
453 	len = scnprintf(buf, sizeof(buf), "%d\n", xe->info.has_page_reclaim_hw_assist);
454 	return simple_read_from_buffer(ubuf, size, pos, buf, len);
455 }
456 
457 static ssize_t page_reclaim_hw_assist_set(struct file *f, const char __user *ubuf,
458 					  size_t size, loff_t *pos)
459 {
460 	struct xe_device *xe = file_inode(f)->i_private;
461 	bool val;
462 	ssize_t ret;
463 
464 	ret = kstrtobool_from_user(ubuf, size, &val);
465 	if (ret)
466 		return ret;
467 
468 	xe->info.has_page_reclaim_hw_assist = val;
469 
470 	return size;
471 }
472 
473 static const struct file_operations page_reclaim_hw_assist_fops = {
474 	.owner = THIS_MODULE,
475 	.read = page_reclaim_hw_assist_show,
476 	.write = page_reclaim_hw_assist_set,
477 };
478 
479 static ssize_t atomic_svm_timeslice_ms_show(struct file *f, char __user *ubuf,
480 					    size_t size, loff_t *pos)
481 {
482 	struct xe_device *xe = file_inode(f)->i_private;
483 	char buf[32];
484 	int len = 0;
485 
486 	len = scnprintf(buf, sizeof(buf), "%d\n", xe->atomic_svm_timeslice_ms);
487 
488 	return simple_read_from_buffer(ubuf, size, pos, buf, len);
489 }
490 
491 static ssize_t atomic_svm_timeslice_ms_set(struct file *f,
492 					   const char __user *ubuf,
493 					   size_t size, loff_t *pos)
494 {
495 	struct xe_device *xe = file_inode(f)->i_private;
496 	u32 atomic_svm_timeslice_ms;
497 	ssize_t ret;
498 
499 	ret = kstrtouint_from_user(ubuf, size, 0, &atomic_svm_timeslice_ms);
500 	if (ret)
501 		return ret;
502 
503 	xe->atomic_svm_timeslice_ms = atomic_svm_timeslice_ms;
504 
505 	return size;
506 }
507 
508 static const struct file_operations atomic_svm_timeslice_ms_fops = {
509 	.owner = THIS_MODULE,
510 	.read = atomic_svm_timeslice_ms_show,
511 	.write = atomic_svm_timeslice_ms_set,
512 };
513 
514 static ssize_t min_run_period_lr_ms_show(struct file *f, char __user *ubuf,
515 					 size_t size, loff_t *pos)
516 {
517 	struct xe_device *xe = file_inode(f)->i_private;
518 	char buf[32];
519 	int len = 0;
520 
521 	len = scnprintf(buf, sizeof(buf), "%d\n", xe->min_run_period_lr_ms);
522 
523 	return simple_read_from_buffer(ubuf, size, pos, buf, len);
524 }
525 
526 static ssize_t min_run_period_lr_ms_set(struct file *f, const char __user *ubuf,
527 					size_t size, loff_t *pos)
528 {
529 	struct xe_device *xe = file_inode(f)->i_private;
530 	u32 min_run_period_lr_ms;
531 	ssize_t ret;
532 
533 	ret = kstrtouint_from_user(ubuf, size, 0, &min_run_period_lr_ms);
534 	if (ret)
535 		return ret;
536 
537 	xe->min_run_period_lr_ms = min_run_period_lr_ms;
538 
539 	return size;
540 }
541 
542 static const struct file_operations min_run_period_lr_ms_fops = {
543 	.owner = THIS_MODULE,
544 	.read = min_run_period_lr_ms_show,
545 	.write = min_run_period_lr_ms_set,
546 };
547 
548 static ssize_t min_run_period_pf_ms_show(struct file *f, char __user *ubuf,
549 					 size_t size, loff_t *pos)
550 {
551 	struct xe_device *xe = file_inode(f)->i_private;
552 	char buf[32];
553 	int len = 0;
554 
555 	len = scnprintf(buf, sizeof(buf), "%d\n", xe->min_run_period_pf_ms);
556 
557 	return simple_read_from_buffer(ubuf, size, pos, buf, len);
558 }
559 
560 static ssize_t min_run_period_pf_ms_set(struct file *f, const char __user *ubuf,
561 					size_t size, loff_t *pos)
562 {
563 	struct xe_device *xe = file_inode(f)->i_private;
564 	u32 min_run_period_pf_ms;
565 	ssize_t ret;
566 
567 	ret = kstrtouint_from_user(ubuf, size, 0, &min_run_period_pf_ms);
568 	if (ret)
569 		return ret;
570 
571 	xe->min_run_period_pf_ms = min_run_period_pf_ms;
572 
573 	return size;
574 }
575 
576 static const struct file_operations min_run_period_pf_ms_fops = {
577 	.owner = THIS_MODULE,
578 	.read = min_run_period_pf_ms_show,
579 	.write = min_run_period_pf_ms_set,
580 };
581 
582 static ssize_t disable_late_binding_show(struct file *f, char __user *ubuf,
583 					 size_t size, loff_t *pos)
584 {
585 	struct xe_device *xe = file_inode(f)->i_private;
586 	struct xe_late_bind *late_bind = &xe->late_bind;
587 	char buf[32];
588 	int len;
589 
590 	len = scnprintf(buf, sizeof(buf), "%d\n", late_bind->disable);
591 
592 	return simple_read_from_buffer(ubuf, size, pos, buf, len);
593 }
594 
595 static ssize_t disable_late_binding_set(struct file *f, const char __user *ubuf,
596 					size_t size, loff_t *pos)
597 {
598 	struct xe_device *xe = file_inode(f)->i_private;
599 	struct xe_late_bind *late_bind = &xe->late_bind;
600 	bool val;
601 	int ret;
602 
603 	ret = kstrtobool_from_user(ubuf, size, &val);
604 	if (ret)
605 		return ret;
606 
607 	late_bind->disable = val;
608 	return size;
609 }
610 
611 static const struct file_operations disable_late_binding_fops = {
612 	.owner = THIS_MODULE,
613 	.read = disable_late_binding_show,
614 	.write = disable_late_binding_set,
615 };
616 
617 #ifdef CONFIG_DRM_XE_DEBUG_PAGE_SIZE
618 static const char * const page_size_alloc_mode_names[] = {
619 	[XE_PAGE_SIZE_ALLOC_CTRL_MODE_NONE]    = "none",
620 	[XE_PAGE_SIZE_ALLOC_CTRL_MODE_ONLY_2M] = "only_2m",
621 	[XE_PAGE_SIZE_ALLOC_CTRL_MODE_ONLY_1G] = "only_1g",
622 	[XE_PAGE_SIZE_ALLOC_CTRL_MODE_MIXED]   = "mixed",
623 };
624 
625 static ssize_t page_size_alloc_mode_show(struct file *f, char __user *ubuf,
626 					 size_t size, loff_t *pos)
627 {
628 	struct xe_device *xe = file_inode(f)->i_private;
629 	char buf[32];
630 	int len;
631 	enum xe_page_size_alloc_ctrl_mode mode;
632 
633 	mode = READ_ONCE(xe->page_size_alloc_ctrl.mode);
634 	if (mode >= ARRAY_SIZE(page_size_alloc_mode_names) ||
635 	    !page_size_alloc_mode_names[mode])
636 		len = scnprintf(buf, sizeof(buf), "unknown\n");
637 	else
638 		len = scnprintf(buf, sizeof(buf), "%s\n",
639 				page_size_alloc_mode_names[mode]);
640 	return simple_read_from_buffer(ubuf, size, pos, buf, len);
641 }
642 
643 static ssize_t page_size_alloc_mode_set(struct file *f, const char __user *ubuf,
644 					size_t size, loff_t *pos)
645 {
646 	struct xe_device *xe = file_inode(f)->i_private;
647 	int ret;
648 	char buf[32];
649 	int mode;
650 
651 	if (*pos)
652 		return -ESPIPE;
653 
654 	if (size > sizeof(buf) - 1)
655 		return -EINVAL;
656 
657 	ret = simple_write_to_buffer(buf, sizeof(buf) - 1, pos, ubuf, size);
658 	if (ret < 0)
659 		return ret;
660 	buf[ret] = '\0';
661 
662 	mode = sysfs_match_string(page_size_alloc_mode_names, buf);
663 	if (mode < 0)
664 		return mode;
665 
666 	mutex_lock(&xe->page_size_alloc_ctrl.lock);
667 	if (mode == XE_PAGE_SIZE_ALLOC_CTRL_MODE_MIXED)
668 		xe->page_size_alloc_ctrl.cur_index = 0;
669 	WRITE_ONCE(xe->page_size_alloc_ctrl.mode,
670 		   (enum xe_page_size_alloc_ctrl_mode)mode);
671 	mutex_unlock(&xe->page_size_alloc_ctrl.lock);
672 
673 	return size;
674 }
675 
676 static const struct file_operations page_size_alloc_mode_fops = {
677 	.owner = THIS_MODULE,
678 	.read = page_size_alloc_mode_show,
679 	.write = page_size_alloc_mode_set,
680 };
681 #endif
682 
683 void xe_debugfs_register(struct xe_device *xe)
684 {
685 	struct ttm_device *bdev = &xe->ttm;
686 	struct drm_minor *minor = xe->drm.primary;
687 	struct dentry *root = minor->debugfs_root;
688 	struct ttm_resource_manager *man;
689 	struct xe_tile *tile;
690 	struct xe_gt *gt;
691 	u8 tile_id;
692 	u8 id;
693 
694 	drm_debugfs_create_files(debugfs_list,
695 				 ARRAY_SIZE(debugfs_list),
696 				 root, minor);
697 
698 	if (xe->info.platform == XE_BATTLEMAGE && !IS_SRIOV_VF(xe)) {
699 		drm_debugfs_create_files(debugfs_residencies,
700 					 ARRAY_SIZE(debugfs_residencies),
701 					 root, minor);
702 	}
703 
704 	/*
705 	 * Pcode version read from PMT is currently only supported on CRI and BMG platforms in PF
706 	 * mode, as both platforms support the necessary telemetry read mechanism and have a fixed
707 	 * PUNIT_VERSION_OFFSET.
708 	 * Attempting this access on other platforms must be verified before enabling support.
709 	 */
710 	if (!IS_SRIOV_VF(xe) &&
711 	    (xe->info.platform == XE_CRESCENTISLAND || xe->info.platform == XE_BATTLEMAGE))
712 		drm_debugfs_create_files(pcode_info_debugfs,
713 					 ARRAY_SIZE(pcode_info_debugfs),
714 					 root, minor);
715 
716 	debugfs_create_file("forcewake_all", 0400, root, xe,
717 			    &forcewake_all_fops);
718 
719 	debugfs_create_file("wedged_mode", 0600, root, xe,
720 			    &wedged_mode_fops);
721 
722 	debugfs_create_file("atomic_svm_timeslice_ms", 0600, root, xe,
723 			    &atomic_svm_timeslice_ms_fops);
724 
725 	debugfs_create_file("min_run_period_lr_ms", 0600, root, xe,
726 			    &min_run_period_lr_ms_fops);
727 
728 	debugfs_create_file("min_run_period_pf_ms", 0600, root, xe,
729 			    &min_run_period_pf_ms_fops);
730 
731 	debugfs_create_file("disable_late_binding", 0600, root, xe,
732 			    &disable_late_binding_fops);
733 
734 #ifdef CONFIG_DRM_XE_DEBUG_PAGE_SIZE
735 	/*
736 	 * Expose a debugfs knob to control user BO page-size allocation:
737 	 * "none"    - default behavior
738 	 * "only_2m" - force 2M page allocations
739 	 * "only_1g" - force 1G page allocations
740 	 * "mixed"   - select 4K, 64K, 2M, and 1G in round-robin order
741 	 */
742 	if (xe_debug_page_size_supported(xe))
743 		debugfs_create_file("page_size_alloc_mode", 0600, root, xe,
744 				    &page_size_alloc_mode_fops);
745 #endif
746 	/*
747 	 * Don't expose page reclaim configuration file if not supported by the
748 	 * hardware initially.
749 	 */
750 	if (xe->info.has_page_reclaim_hw_assist)
751 		debugfs_create_file("page_reclaim_hw_assist", 0600, root, xe,
752 				    &page_reclaim_hw_assist_fops);
753 
754 	man = ttm_manager_type(bdev, XE_PL_TT);
755 	ttm_resource_manager_create_debugfs(man, root, "gtt_mm");
756 
757 	man = ttm_manager_type(bdev, XE_PL_STOLEN);
758 	if (man)
759 		ttm_resource_manager_create_debugfs(man, root, "stolen_mm");
760 
761 	for_each_tile(tile, xe, tile_id)
762 		xe_tile_debugfs_register(tile);
763 
764 	for_each_gt(gt, xe, id)
765 		xe_gt_debugfs_register(gt);
766 
767 	xe_pxp_debugfs_register(xe->pxp);
768 
769 	xe_psmi_debugfs_register(xe);
770 
771 	xe_fault_inject_debugfs_register(xe, root);
772 
773 	if (IS_SRIOV_PF(xe))
774 		xe_sriov_pf_debugfs_register(xe, root);
775 	else if (IS_SRIOV_VF(xe))
776 		xe_sriov_vf_debugfs_register(xe, root);
777 }
778