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