Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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 */
63static 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(>->uc.guc, &p);
75}
76
77static 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
83static 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
89static 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
95static 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
101static 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 */
112static 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 */
118static 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 */
123static 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
129void 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}