xref: /linux/drivers/gpu/drm/xe/xe_guc_debugfs.c (revision 1b5d39e6672fdee158c3306f5cb2df8975c77e5a)
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 
74 	guard(xe_pm_runtime)(xe);
75 	return print(&gt->uc.guc, &p);
76 }
77 
78 static int guc_log(struct xe_guc *guc, struct drm_printer *p)
79 {
80 	xe_guc_log_print(&guc->log, p);
81 	return 0;
82 }
83 
84 static int guc_log_lfd(struct xe_guc *guc, struct drm_printer *p)
85 {
86 	xe_guc_log_print_lfd(&guc->log, p);
87 	return 0;
88 }
89 
90 static int guc_log_dmesg(struct xe_guc *guc, struct drm_printer *p)
91 {
92 	xe_guc_log_print_dmesg(&guc->log);
93 	return 0;
94 }
95 
96 static int guc_ctb(struct xe_guc *guc, struct drm_printer *p)
97 {
98 	xe_guc_ct_print(&guc->ct, p, true);
99 	return 0;
100 }
101 
102 static int guc_pc(struct xe_guc *guc, struct drm_printer *p)
103 {
104 	xe_guc_pc_print(&guc->pc, p);
105 	return 0;
106 }
107 
108 /*
109  * only for GuC debugfs files which can be safely used on the VF as well:
110  * - without access to the GuC privileged registers
111  * - without access to the PF specific GuC objects
112  */
113 static const struct drm_info_list vf_safe_debugfs_list[] = {
114 	{ "guc_info", .show = guc_debugfs_show, .data = xe_guc_print_info },
115 	{ "guc_ctb", .show = guc_debugfs_show, .data = guc_ctb },
116 };
117 
118 /* For GuC debugfs files that require the SLPC support */
119 static const struct drm_info_list slpc_debugfs_list[] = {
120 	{ "guc_pc", .show = guc_debugfs_show, .data = guc_pc },
121 };
122 
123 /* everything else should be added here */
124 static const struct drm_info_list pf_only_debugfs_list[] = {
125 	{ "guc_log", .show = guc_debugfs_show, .data = guc_log },
126 	{ "guc_log_lfd", .show = guc_debugfs_show, .data = guc_log_lfd },
127 	{ "guc_log_dmesg", .show = guc_debugfs_show, .data = guc_log_dmesg },
128 };
129 
130 void xe_guc_debugfs_register(struct xe_guc *guc, struct dentry *parent)
131 {
132 	struct xe_device *xe =  guc_to_xe(guc);
133 	struct drm_minor *minor = xe->drm.primary;
134 
135 	drm_debugfs_create_files(vf_safe_debugfs_list,
136 				 ARRAY_SIZE(vf_safe_debugfs_list),
137 				 parent, minor);
138 
139 	if (!IS_SRIOV_VF(xe)) {
140 		drm_debugfs_create_files(pf_only_debugfs_list,
141 					 ARRAY_SIZE(pf_only_debugfs_list),
142 					 parent, minor);
143 
144 		if (!xe->info.skip_guc_pc)
145 			drm_debugfs_create_files(slpc_debugfs_list,
146 						 ARRAY_SIZE(slpc_debugfs_list),
147 						 parent, minor);
148 	}
149 }
150