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