xref: /linux/drivers/gpu/drm/xe/xe_gt_debugfs.c (revision dd08ebf6c3525a7ea2186e636df064ea47281987)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2022 Intel Corporation
4  */
5 
6 #include <drm/drm_debugfs.h>
7 #include <drm/drm_managed.h>
8 
9 #include "xe_device.h"
10 #include "xe_force_wake.h"
11 #include "xe_gt.h"
12 #include "xe_gt_debugfs.h"
13 #include "xe_gt_mcr.h"
14 #include "xe_gt_pagefault.h"
15 #include "xe_gt_topology.h"
16 #include "xe_hw_engine.h"
17 #include "xe_macros.h"
18 #include "xe_uc_debugfs.h"
19 
20 static struct xe_gt *node_to_gt(struct drm_info_node *node)
21 {
22 	return node->info_ent->data;
23 }
24 
25 static int hw_engines(struct seq_file *m, void *data)
26 {
27 	struct xe_gt *gt = node_to_gt(m->private);
28 	struct xe_device *xe = gt_to_xe(gt);
29 	struct drm_printer p = drm_seq_file_printer(m);
30 	struct xe_hw_engine *hwe;
31 	enum xe_hw_engine_id id;
32 	int err;
33 
34 	xe_device_mem_access_get(xe);
35 	err = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
36 	if (err) {
37 		xe_device_mem_access_put(xe);
38 		return err;
39 	}
40 
41 	for_each_hw_engine(hwe, gt, id)
42 		xe_hw_engine_print_state(hwe, &p);
43 
44 	xe_device_mem_access_put(xe);
45 	err = xe_force_wake_put(gt_to_fw(gt), XE_FORCEWAKE_ALL);
46 	if (err)
47 		return err;
48 
49 	return 0;
50 }
51 
52 static int force_reset(struct seq_file *m, void *data)
53 {
54 	struct xe_gt *gt = node_to_gt(m->private);
55 
56 	xe_gt_reset_async(gt);
57 
58 	return 0;
59 }
60 
61 static int sa_info(struct seq_file *m, void *data)
62 {
63 	struct xe_gt *gt = node_to_gt(m->private);
64 	struct drm_printer p = drm_seq_file_printer(m);
65 
66 	drm_suballoc_dump_debug_info(&gt->kernel_bb_pool.base, &p,
67 				     gt->kernel_bb_pool.gpu_addr);
68 
69 	return 0;
70 }
71 
72 static int topology(struct seq_file *m, void *data)
73 {
74 	struct xe_gt *gt = node_to_gt(m->private);
75 	struct drm_printer p = drm_seq_file_printer(m);
76 
77 	xe_gt_topology_dump(gt, &p);
78 
79 	return 0;
80 }
81 
82 static int steering(struct seq_file *m, void *data)
83 {
84 	struct xe_gt *gt = node_to_gt(m->private);
85 	struct drm_printer p = drm_seq_file_printer(m);
86 
87 	xe_gt_mcr_steering_dump(gt, &p);
88 
89 	return 0;
90 }
91 
92 #ifdef CONFIG_DRM_XE_DEBUG
93 static int invalidate_tlb(struct seq_file *m, void *data)
94 {
95 	struct xe_gt *gt = node_to_gt(m->private);
96 	int seqno;
97 	int ret = 0;
98 
99 	seqno = xe_gt_tlb_invalidation(gt);
100 	XE_WARN_ON(seqno < 0);
101 	if (seqno > 0)
102 		ret = xe_gt_tlb_invalidation_wait(gt, seqno);
103 	XE_WARN_ON(ret < 0);
104 
105 	return 0;
106 }
107 #endif
108 
109 static const struct drm_info_list debugfs_list[] = {
110 	{"hw_engines", hw_engines, 0},
111 	{"force_reset", force_reset, 0},
112 	{"sa_info", sa_info, 0},
113 	{"topology", topology, 0},
114 	{"steering", steering, 0},
115 #ifdef CONFIG_DRM_XE_DEBUG
116 	{"invalidate_tlb", invalidate_tlb, 0},
117 #endif
118 };
119 
120 void xe_gt_debugfs_register(struct xe_gt *gt)
121 {
122 	struct drm_minor *minor = gt_to_xe(gt)->drm.primary;
123 	struct dentry *root;
124 	struct drm_info_list *local;
125 	char name[8];
126 	int i;
127 
128 	XE_BUG_ON(!minor->debugfs_root);
129 
130 	sprintf(name, "gt%d", gt->info.id);
131 	root = debugfs_create_dir(name, minor->debugfs_root);
132 	if (IS_ERR(root)) {
133 		XE_WARN_ON("Create GT directory failed");
134 		return;
135 	}
136 
137 	/*
138 	 * Allocate local copy as we need to pass in the GT to the debugfs
139 	 * entry and drm_debugfs_create_files just references the drm_info_list
140 	 * passed in (e.g. can't define this on the stack).
141 	 */
142 #define DEBUGFS_SIZE	ARRAY_SIZE(debugfs_list) * sizeof(struct drm_info_list)
143 	local = drmm_kmalloc(&gt_to_xe(gt)->drm, DEBUGFS_SIZE, GFP_KERNEL);
144 	if (!local) {
145 		XE_WARN_ON("Couldn't allocate memory");
146 		return;
147 	}
148 
149 	memcpy(local, debugfs_list, DEBUGFS_SIZE);
150 #undef DEBUGFS_SIZE
151 
152 	for (i = 0; i < ARRAY_SIZE(debugfs_list); ++i)
153 		local[i].data = gt;
154 
155 	drm_debugfs_create_files(local,
156 				 ARRAY_SIZE(debugfs_list),
157 				 root, minor);
158 
159 	xe_uc_debugfs_register(&gt->uc, root);
160 }
161