xref: /linux/drivers/gpu/drm/xe/xe_guc_debugfs.c (revision fb7399cf2d0b33825b8039f95c45395c7deba25c)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2022 Intel Corporation
4  */
5 
6 #include "xe_guc_debugfs.h"
7 
8 #include <drm/drm_debugfs.h>
9 #include <drm/drm_managed.h>
10 
11 #include "xe_device.h"
12 #include "xe_gt.h"
13 #include "xe_guc.h"
14 #include "xe_guc_ct.h"
15 #include "xe_guc_log.h"
16 #include "xe_guc_pc.h"
17 #include "xe_macros.h"
18 #include "xe_pm.h"
19 
20 /*
21  * guc_debugfs_show - A show callback for struct drm_info_list
22  * @m: the &seq_file
23  * @data: data used by the drm debugfs helpers
24  *
25  * This callback can be used in struct drm_info_list to describe debugfs
26  * files that are &xe_guc specific in similar way how we handle &xe_gt
27  * specific files using &xe_gt_debugfs_simple_show.
28  *
29  * It is assumed that those debugfs files will be created on directory entry
30  * which grandparent struct dentry d_inode->i_private points to &xe_gt.
31  *
32  *      /sys/kernel/debug/dri/0/
33  *      ├── gt0			# dent->d_parent->d_parent (d_inode->i_private == gt)
34  *      │   ├── uc		# dent->d_parent
35  *      │   │   ├── guc_info	# dent
36  *      │   │   ├── guc_...
37  *
38  * This function assumes that &m->private will be set to the &struct
39  * drm_info_node corresponding to the instance of the info on a given &struct
40  * drm_minor (see struct drm_info_list.show for details).
41  *
42  * This function also assumes that struct drm_info_list.data will point to the
43  * function code that will actually print a file content::
44  *
45  *    int (*print)(struct xe_guc *, struct drm_printer *)
46  *
47  * Example::
48  *
49  *    int foo(struct xe_guc *guc, struct drm_printer *p)
50  *    {
51  *        drm_printf(p, "enabled %d\n", guc->submission_state.enabled);
52  *        return 0;
53  *    }
54  *
55  *    static const struct drm_info_list bar[] = {
56  *        { name = "foo", .show = guc_debugfs_show, .data = foo },
57  *    };
58  *
59  *    parent = debugfs_create_dir("uc", gtdir);
60  *    drm_debugfs_create_files(bar, ARRAY_SIZE(bar), parent, minor);
61  *
62  * Return: 0 on success or a negative error code on failure.
63  */
64 static int guc_debugfs_show(struct seq_file *m, void *data)
65 {
66 	struct drm_printer p = drm_seq_file_printer(m);
67 	struct drm_info_node *node = m->private;
68 	struct dentry *parent = node->dent->d_parent;
69 	struct dentry *grandparent = parent->d_parent;
70 	struct xe_gt *gt = grandparent->d_inode->i_private;
71 	struct xe_device *xe = gt_to_xe(gt);
72 	int (*print)(struct xe_guc *, struct drm_printer *) = node->info_ent->data;
73 	int ret;
74 
75 	xe_pm_runtime_get(xe);
76 	ret = print(&gt->uc.guc, &p);
77 	xe_pm_runtime_put(xe);
78 
79 	return ret;
80 }
81 
82 static int guc_log(struct xe_guc *guc, struct drm_printer *p)
83 {
84 	xe_guc_log_print(&guc->log, p);
85 	return 0;
86 }
87 
88 static int guc_log_dmesg(struct xe_guc *guc, struct drm_printer *p)
89 {
90 	xe_guc_log_print_dmesg(&guc->log);
91 	return 0;
92 }
93 
94 static int guc_ctb(struct xe_guc *guc, struct drm_printer *p)
95 {
96 	xe_guc_ct_print(&guc->ct, p, true);
97 	return 0;
98 }
99 
100 static int guc_pc(struct xe_guc *guc, struct drm_printer *p)
101 {
102 	xe_guc_pc_print(&guc->pc, p);
103 	return 0;
104 }
105 
106 /*
107  * only for GuC debugfs files which can be safely used on the VF as well:
108  * - without access to the GuC privileged registers
109  * - without access to the PF specific GuC objects
110  */
111 static const struct drm_info_list vf_safe_debugfs_list[] = {
112 	{ "guc_info", .show = guc_debugfs_show, .data = xe_guc_print_info },
113 	{ "guc_ctb", .show = guc_debugfs_show, .data = guc_ctb },
114 };
115 
116 /* For GuC debugfs files that require the SLPC support */
117 static const struct drm_info_list slpc_debugfs_list[] = {
118 	{ "guc_pc", .show = guc_debugfs_show, .data = guc_pc },
119 };
120 
121 /* everything else should be added here */
122 static const struct drm_info_list pf_only_debugfs_list[] = {
123 	{ "guc_log", .show = guc_debugfs_show, .data = guc_log },
124 	{ "guc_log_dmesg", .show = guc_debugfs_show, .data = guc_log_dmesg },
125 };
126 
127 void xe_guc_debugfs_register(struct xe_guc *guc, struct dentry *parent)
128 {
129 	struct xe_device *xe =  guc_to_xe(guc);
130 	struct drm_minor *minor = xe->drm.primary;
131 
132 	drm_debugfs_create_files(vf_safe_debugfs_list,
133 				 ARRAY_SIZE(vf_safe_debugfs_list),
134 				 parent, minor);
135 
136 	if (!IS_SRIOV_VF(xe)) {
137 		drm_debugfs_create_files(pf_only_debugfs_list,
138 					 ARRAY_SIZE(pf_only_debugfs_list),
139 					 parent, minor);
140 
141 		if (!xe->info.skip_guc_pc)
142 			drm_debugfs_create_files(slpc_debugfs_list,
143 						 ARRAY_SIZE(slpc_debugfs_list),
144 						 parent, minor);
145 	}
146 }
147