xref: /linux/drivers/gpu/drm/xe/xe_tile_debugfs.c (revision f6e8dc9edf963dbc99085e54f6ced6da9daa6100)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2025 Intel Corporation
4  */
5 
6 #include <linux/debugfs.h>
7 #include <drm/drm_debugfs.h>
8 
9 #include "xe_ggtt.h"
10 #include "xe_pm.h"
11 #include "xe_sa.h"
12 #include "xe_tile_debugfs.h"
13 
14 static struct xe_tile *node_to_tile(struct drm_info_node *node)
15 {
16 	return node->dent->d_parent->d_inode->i_private;
17 }
18 
19 /**
20  * xe_tile_debugfs_simple_show() - A show callback for struct drm_info_list
21  * @m: the &seq_file
22  * @data: data used by the drm debugfs helpers
23  *
24  * This callback can be used in struct drm_info_list to describe debugfs
25  * files that are &xe_tile specific.
26  *
27  * It is assumed that those debugfs files will be created on directory entry
28  * which struct dentry d_inode->i_private points to &xe_tile.
29  *
30  *      /sys/kernel/debug/dri/0/
31  *      ├── tile0/		# tile = dentry->d_inode->i_private
32  *      │   │   ├── id		# tile = dentry->d_parent->d_inode->i_private
33  *
34  * This function assumes that &m->private will be set to the &struct
35  * drm_info_node corresponding to the instance of the info on a given &struct
36  * drm_minor (see struct drm_info_list.show for details).
37  *
38  * This function also assumes that struct drm_info_list.data will point to the
39  * function code that will actually print a file content::
40  *
41  *   int (*print)(struct xe_tile *, struct drm_printer *)
42  *
43  * Example::
44  *
45  *    int tile_id(struct xe_tile *tile, struct drm_printer *p)
46  *    {
47  *        drm_printf(p, "%u\n", tile->id);
48  *        return 0;
49  *    }
50  *
51  *    static const struct drm_info_list info[] = {
52  *        { name = "id", .show = tile_debugfs_simple_show, .data = tile_id },
53  *    };
54  *
55  *    dir = debugfs_create_dir("tile0", parent);
56  *    dir->d_inode->i_private = tile;
57  *    drm_debugfs_create_files(info, ARRAY_SIZE(info), dir, minor);
58  *
59  * Return: 0 on success or a negative error code on failure.
60  */
61 int xe_tile_debugfs_simple_show(struct seq_file *m, void *data)
62 {
63 	struct drm_printer p = drm_seq_file_printer(m);
64 	struct drm_info_node *node = m->private;
65 	struct xe_tile *tile = node_to_tile(node);
66 	int (*print)(struct xe_tile *, struct drm_printer *) = node->info_ent->data;
67 
68 	return print(tile, &p);
69 }
70 
71 /**
72  * xe_tile_debugfs_show_with_rpm() - A show callback for struct drm_info_list
73  * @m: the &seq_file
74  * @data: data used by the drm debugfs helpers
75  *
76  * Similar to tile_debugfs_simple_show() but implicitly takes a RPM ref.
77  *
78  * Return: 0 on success or a negative error code on failure.
79  */
80 int xe_tile_debugfs_show_with_rpm(struct seq_file *m, void *data)
81 {
82 	struct drm_info_node *node = m->private;
83 	struct xe_tile *tile = node_to_tile(node);
84 	struct xe_device *xe = tile_to_xe(tile);
85 	int ret;
86 
87 	xe_pm_runtime_get(xe);
88 	ret = xe_tile_debugfs_simple_show(m, data);
89 	xe_pm_runtime_put(xe);
90 
91 	return ret;
92 }
93 
94 static int ggtt(struct xe_tile *tile, struct drm_printer *p)
95 {
96 	return xe_ggtt_dump(tile->mem.ggtt, p);
97 }
98 
99 static int sa_info(struct xe_tile *tile, struct drm_printer *p)
100 {
101 	drm_suballoc_dump_debug_info(&tile->mem.kernel_bb_pool->base, p,
102 				     xe_sa_manager_gpu_addr(tile->mem.kernel_bb_pool));
103 
104 	return 0;
105 }
106 
107 /* only for debugfs files which can be safely used on the VF */
108 static const struct drm_info_list vf_safe_debugfs_list[] = {
109 	{ "ggtt", .show = xe_tile_debugfs_show_with_rpm, .data = ggtt },
110 	{ "sa_info", .show = xe_tile_debugfs_show_with_rpm, .data = sa_info },
111 };
112 
113 /**
114  * xe_tile_debugfs_register - Register tile's debugfs attributes
115  * @tile: the &xe_tile to register
116  *
117  * Create debugfs sub-directory with a name that includes a tile ID and
118  * then creates set of debugfs files (attributes) specific to this tile.
119  */
120 void xe_tile_debugfs_register(struct xe_tile *tile)
121 {
122 	struct xe_device *xe = tile_to_xe(tile);
123 	struct drm_minor *minor = xe->drm.primary;
124 	struct dentry *root = minor->debugfs_root;
125 	char name[8];
126 
127 	snprintf(name, sizeof(name), "tile%u", tile->id);
128 	tile->debugfs = debugfs_create_dir(name, root);
129 	if (IS_ERR(tile->debugfs))
130 		return;
131 
132 	/*
133 	 * Store the xe_tile pointer as private data of the tile/ directory
134 	 * node so other tile specific attributes under that directory may
135 	 * refer to it by looking at its parent node private data.
136 	 */
137 	tile->debugfs->d_inode->i_private = tile;
138 
139 	drm_debugfs_create_files(vf_safe_debugfs_list,
140 				 ARRAY_SIZE(vf_safe_debugfs_list),
141 				 tile->debugfs, minor);
142 }
143