xref: /linux/drivers/gpu/drm/xe/xe_psmi.c (revision 9fd2da71c301184d98fe37674ca8d017d1ce6600)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2025 Intel Corporation
4  */
5 
6 #include <linux/debugfs.h>
7 
8 #include "xe_bo.h"
9 #include "xe_device.h"
10 #include "xe_configfs.h"
11 #include "xe_psmi.h"
12 
13 /*
14  * PSMI capture support
15  *
16  * Requirement for PSMI capture is to have a physically contiguous buffer.  The
17  * PSMI tool owns doing all necessary configuration (MMIO register writes are
18  * done from user-space). However, KMD needs to provide the PSMI tool with the
19  * required physical address of the base of PSMI buffer in case of VRAM.
20  *
21  * VRAM backed PSMI buffer:
22  * Buffer is allocated as GEM object and with XE_BO_CREATE_PINNED_BIT flag which
23  * creates a contiguous allocation. The physical address is returned from
24  * psmi_debugfs_capture_addr_show(). PSMI tool can mmap the buffer via the
25  * PCIBAR through sysfs.
26  *
27  * SYSTEM memory backed PSMI buffer:
28  * Interface here does not support allocating from SYSTEM memory region.  The
29  * PSMI tool needs to allocate memory themselves using hugetlbfs. In order to
30  * get the physical address, user-space can query /proc/[pid]/pagemap. As an
31  * alternative, CMA debugfs could also be used to allocate reserved CMA memory.
32  */
33 
34 static bool psmi_enabled(struct xe_device *xe)
35 {
36 	return xe_configfs_get_psmi_enabled(to_pci_dev(xe->drm.dev));
37 }
38 
39 static void psmi_free_object(struct xe_bo *bo)
40 {
41 	xe_bo_lock(bo, NULL);
42 	xe_bo_unpin(bo);
43 	xe_bo_unlock(bo);
44 	xe_bo_put(bo);
45 }
46 
47 /*
48  * Free PSMI capture buffer objects.
49  */
50 static void psmi_cleanup(struct xe_device *xe)
51 {
52 	unsigned long id, region_mask = xe->psmi.region_mask;
53 	struct xe_bo *bo;
54 
55 	for_each_set_bit(id, &region_mask,
56 			 ARRAY_SIZE(xe->psmi.capture_obj)) {
57 		/* smem should never be set */
58 		xe_assert(xe, id);
59 
60 		bo = xe->psmi.capture_obj[id];
61 		if (bo) {
62 			psmi_free_object(bo);
63 			xe->psmi.capture_obj[id] = NULL;
64 		}
65 	}
66 }
67 
68 static struct xe_bo *psmi_alloc_object(struct xe_device *xe,
69 				       unsigned int id, size_t bo_size)
70 {
71 	struct xe_bo *bo = NULL;
72 	struct xe_tile *tile;
73 	int err;
74 
75 	if (!id || !bo_size)
76 		return NULL;
77 
78 	tile = &xe->tiles[id - 1];
79 
80 	/* VRAM: Allocate GEM object for the capture buffer */
81 	bo = xe_bo_create_locked(xe, tile, NULL, bo_size,
82 				 ttm_bo_type_kernel,
83 				 XE_BO_FLAG_VRAM_IF_DGFX(tile) |
84 				 XE_BO_FLAG_PINNED |
85 				 XE_BO_FLAG_PINNED_LATE_RESTORE |
86 				 XE_BO_FLAG_NEEDS_CPU_ACCESS);
87 
88 	if (!IS_ERR(bo)) {
89 		/* Buffer written by HW, ensure stays resident */
90 		err = xe_bo_pin(bo);
91 		if (err)
92 			bo = ERR_PTR(err);
93 		xe_bo_unlock(bo);
94 	}
95 
96 	return bo;
97 }
98 
99 /*
100  * Allocate PSMI capture buffer objects (via debugfs set function), based on
101  * which regions the user has selected in region_mask.  @size: size in bytes
102  * (should be power of 2)
103  *
104  * Always release/free the current buffer objects before attempting to allocate
105  * new ones.  Size == 0 will free all current buffers.
106  *
107  * Note, we don't write any registers as the capture tool is already configuring
108  * all PSMI registers itself via mmio space.
109  */
110 static int psmi_resize_object(struct xe_device *xe, size_t size)
111 {
112 	unsigned long id, region_mask = xe->psmi.region_mask;
113 	struct xe_bo *bo = NULL;
114 	int err = 0;
115 
116 	/* if resizing, free currently allocated buffers first */
117 	psmi_cleanup(xe);
118 
119 	/* can set size to 0, in which case, now done */
120 	if (!size)
121 		return 0;
122 
123 	for_each_set_bit(id, &region_mask,
124 			 ARRAY_SIZE(xe->psmi.capture_obj)) {
125 		/* smem should never be set */
126 		xe_assert(xe, id);
127 
128 		bo = psmi_alloc_object(xe, id, size);
129 		if (IS_ERR(bo)) {
130 			err = PTR_ERR(bo);
131 			break;
132 		}
133 		xe->psmi.capture_obj[id] = bo;
134 
135 		drm_info(&xe->drm,
136 			 "PSMI capture size requested: %zu bytes, allocated: %lu:%zu\n",
137 			 size, id, bo ? xe_bo_size(bo) : 0);
138 	}
139 
140 	/* on error, reverse what was allocated */
141 	if (err)
142 		psmi_cleanup(xe);
143 
144 	return err;
145 }
146 
147 /*
148  * Returns an address for the capture tool to use to find start of capture
149  * buffer. Capture tool requires the capability to have a buffer allocated per
150  * each tile (VRAM region), thus we return an address for each region.
151  */
152 static int psmi_debugfs_capture_addr_show(struct seq_file *m, void *data)
153 {
154 	struct xe_device *xe = m->private;
155 	unsigned long id, region_mask;
156 	struct xe_bo *bo;
157 	u64 val;
158 
159 	region_mask = xe->psmi.region_mask;
160 	for_each_set_bit(id, &region_mask,
161 			 ARRAY_SIZE(xe->psmi.capture_obj)) {
162 		/* smem should never be set */
163 		xe_assert(xe, id);
164 
165 		/* VRAM region */
166 		bo = xe->psmi.capture_obj[id];
167 		if (!bo)
168 			continue;
169 
170 		/* pinned, so don't need bo_lock */
171 		val = __xe_bo_addr(bo, 0, PAGE_SIZE);
172 		seq_printf(m, "%ld: 0x%llx\n", id, val);
173 	}
174 
175 	return 0;
176 }
177 
178 /*
179  * Return capture buffer size, using the size from first allocated object that
180  * is found. This works because all objects must be of the same size.
181  */
182 static int psmi_debugfs_capture_size_get(void *data, u64 *val)
183 {
184 	unsigned long id, region_mask;
185 	struct xe_device *xe = data;
186 	struct xe_bo *bo;
187 
188 	region_mask = xe->psmi.region_mask;
189 	for_each_set_bit(id, &region_mask,
190 			 ARRAY_SIZE(xe->psmi.capture_obj)) {
191 		/* smem should never be set */
192 		xe_assert(xe, id);
193 
194 		bo = xe->psmi.capture_obj[id];
195 		if (bo) {
196 			*val = xe_bo_size(bo);
197 			return 0;
198 		}
199 	}
200 
201 	/* no capture objects are allocated */
202 	*val = 0;
203 
204 	return 0;
205 }
206 
207 /*
208  * Set size of PSMI capture buffer. This triggers the allocation of capture
209  * buffer in each memory region as specified with prior write to
210  * psmi_capture_region_mask.
211  */
212 static int psmi_debugfs_capture_size_set(void *data, u64 val)
213 {
214 	struct xe_device *xe = data;
215 
216 	/* user must have specified at least one region */
217 	if (!xe->psmi.region_mask)
218 		return -EINVAL;
219 
220 	return psmi_resize_object(xe, val);
221 }
222 
223 static int psmi_debugfs_capture_region_mask_get(void *data, u64 *val)
224 {
225 	struct xe_device *xe = data;
226 
227 	*val = xe->psmi.region_mask;
228 
229 	return 0;
230 }
231 
232 /*
233  * Select VRAM regions for multi-tile devices, only allowed when buffer is not
234  * currently allocated.
235  */
236 static int psmi_debugfs_capture_region_mask_set(void *data, u64 region_mask)
237 {
238 	struct xe_device *xe = data;
239 	u64 size = 0;
240 
241 	/* SMEM is not supported (see comments at top of file) */
242 	if (region_mask & 0x1)
243 		return -EOPNOTSUPP;
244 
245 	/* input bitmask should contain only valid TTM regions */
246 	if (!region_mask || region_mask & ~xe->info.mem_region_mask)
247 		return -EINVAL;
248 
249 	/* only allow setting mask if buffer is not yet allocated */
250 	psmi_debugfs_capture_size_get(xe, &size);
251 	if (size)
252 		return -EBUSY;
253 
254 	xe->psmi.region_mask = region_mask;
255 
256 	return 0;
257 }
258 
259 DEFINE_SHOW_ATTRIBUTE(psmi_debugfs_capture_addr);
260 
261 DEFINE_DEBUGFS_ATTRIBUTE(psmi_debugfs_capture_region_mask_fops,
262 			 psmi_debugfs_capture_region_mask_get,
263 			 psmi_debugfs_capture_region_mask_set,
264 			 "0x%llx\n");
265 
266 DEFINE_DEBUGFS_ATTRIBUTE(psmi_debugfs_capture_size_fops,
267 			 psmi_debugfs_capture_size_get,
268 			 psmi_debugfs_capture_size_set,
269 			 "%lld\n");
270 
271 void xe_psmi_debugfs_register(struct xe_device *xe)
272 {
273 	struct drm_minor *minor;
274 
275 	if (!psmi_enabled(xe))
276 		return;
277 
278 	minor = xe->drm.primary;
279 	if (!minor->debugfs_root)
280 		return;
281 
282 	debugfs_create_file("psmi_capture_addr",
283 			    0400, minor->debugfs_root, xe,
284 			    &psmi_debugfs_capture_addr_fops);
285 
286 	debugfs_create_file("psmi_capture_region_mask",
287 			    0600, minor->debugfs_root, xe,
288 			    &psmi_debugfs_capture_region_mask_fops);
289 
290 	debugfs_create_file("psmi_capture_size",
291 			    0600, minor->debugfs_root, xe,
292 			    &psmi_debugfs_capture_size_fops);
293 }
294 
295 static void psmi_fini(void *arg)
296 {
297 	psmi_cleanup(arg);
298 }
299 
300 int xe_psmi_init(struct xe_device *xe)
301 {
302 	if (!psmi_enabled(xe))
303 		return 0;
304 
305 	return devm_add_action(xe->drm.dev, psmi_fini, xe);
306 }
307