Linux Audio

Check our new training course

Loading...
Note: File does not exist in v4.6.
  1// SPDX-License-Identifier: MIT
  2/*
  3 * Copyright © 2022 Intel Corporation
  4 */
  5
  6#include "xe_gt_debugfs.h"
  7
  8#include <linux/debugfs.h>
  9
 10#include <drm/drm_debugfs.h>
 11#include <drm/drm_managed.h>
 12
 13#include "xe_device.h"
 14#include "xe_force_wake.h"
 15#include "xe_ggtt.h"
 16#include "xe_gt.h"
 17#include "xe_gt_mcr.h"
 18#include "xe_gt_idle.h"
 19#include "xe_gt_sriov_pf_debugfs.h"
 20#include "xe_gt_sriov_vf_debugfs.h"
 21#include "xe_gt_stats.h"
 22#include "xe_gt_topology.h"
 23#include "xe_guc_hwconfig.h"
 24#include "xe_hw_engine.h"
 25#include "xe_lrc.h"
 26#include "xe_macros.h"
 27#include "xe_mocs.h"
 28#include "xe_pat.h"
 29#include "xe_pm.h"
 30#include "xe_reg_sr.h"
 31#include "xe_reg_whitelist.h"
 32#include "xe_sriov.h"
 33#include "xe_uc_debugfs.h"
 34#include "xe_wa.h"
 35
 36/**
 37 * xe_gt_debugfs_simple_show - A show callback for struct drm_info_list
 38 * @m: the &seq_file
 39 * @data: data used by the drm debugfs helpers
 40 *
 41 * This callback can be used in struct drm_info_list to describe debugfs
 42 * files that are &xe_gt specific.
 43 *
 44 * It is assumed that those debugfs files will be created on directory entry
 45 * which struct dentry d_inode->i_private points to &xe_gt.
 46 *
 47 * This function assumes that &m->private will be set to the &struct
 48 * drm_info_node corresponding to the instance of the info on a given &struct
 49 * drm_minor (see struct drm_info_list.show for details).
 50 *
 51 * This function also assumes that struct drm_info_list.data will point to the
 52 * function code that will actually print a file content::
 53 *
 54 *   int (*print)(struct xe_gt *, struct drm_printer *)
 55 *
 56 * Example::
 57 *
 58 *    int foo(struct xe_gt *gt, struct drm_printer *p)
 59 *    {
 60 *        drm_printf(p, "GT%u\n", gt->info.id);
 61 *        return 0;
 62 *    }
 63 *
 64 *    static const struct drm_info_list bar[] = {
 65 *        { name = "foo", .show = xe_gt_debugfs_simple_show, .data = foo },
 66 *    };
 67 *
 68 *    dir = debugfs_create_dir("gt", parent);
 69 *    dir->d_inode->i_private = gt;
 70 *    drm_debugfs_create_files(bar, ARRAY_SIZE(bar), dir, minor);
 71 *
 72 * Return: 0 on success or a negative error code on failure.
 73 */
 74int xe_gt_debugfs_simple_show(struct seq_file *m, void *data)
 75{
 76	struct drm_printer p = drm_seq_file_printer(m);
 77	struct drm_info_node *node = m->private;
 78	struct dentry *parent = node->dent->d_parent;
 79	struct xe_gt *gt = parent->d_inode->i_private;
 80	int (*print)(struct xe_gt *, struct drm_printer *) = node->info_ent->data;
 81
 82	if (WARN_ON(!print))
 83		return -EINVAL;
 84
 85	return print(gt, &p);
 86}
 87
 88static int hw_engines(struct xe_gt *gt, struct drm_printer *p)
 89{
 90	struct xe_device *xe = gt_to_xe(gt);
 91	struct xe_hw_engine *hwe;
 92	enum xe_hw_engine_id id;
 93	unsigned int fw_ref;
 94
 95	xe_pm_runtime_get(xe);
 96	fw_ref = xe_force_wake_get(gt_to_fw(gt), XE_FORCEWAKE_ALL);
 97	if (!xe_force_wake_ref_has_domain(fw_ref, XE_FORCEWAKE_ALL)) {
 98		xe_pm_runtime_put(xe);
 99		xe_force_wake_put(gt_to_fw(gt), fw_ref);
100		return -ETIMEDOUT;
101	}
102
103	for_each_hw_engine(hwe, gt, id)
104		xe_hw_engine_print(hwe, p);
105
106	xe_force_wake_put(gt_to_fw(gt), fw_ref);
107	xe_pm_runtime_put(xe);
108
109	return 0;
110}
111
112static int powergate_info(struct xe_gt *gt, struct drm_printer *p)
113{
114	int ret;
115
116	xe_pm_runtime_get(gt_to_xe(gt));
117	ret = xe_gt_idle_pg_print(gt, p);
118	xe_pm_runtime_put(gt_to_xe(gt));
119
120	return ret;
121}
122
123static int force_reset(struct xe_gt *gt, struct drm_printer *p)
124{
125	xe_pm_runtime_get(gt_to_xe(gt));
126	xe_gt_reset_async(gt);
127	xe_pm_runtime_put(gt_to_xe(gt));
128
129	return 0;
130}
131
132static int force_reset_sync(struct xe_gt *gt, struct drm_printer *p)
133{
134	xe_pm_runtime_get(gt_to_xe(gt));
135	xe_gt_reset(gt);
136	xe_pm_runtime_put(gt_to_xe(gt));
137
138	return 0;
139}
140
141static int sa_info(struct xe_gt *gt, struct drm_printer *p)
142{
143	struct xe_tile *tile = gt_to_tile(gt);
144
145	xe_pm_runtime_get(gt_to_xe(gt));
146	drm_suballoc_dump_debug_info(&tile->mem.kernel_bb_pool->base, p,
147				     tile->mem.kernel_bb_pool->gpu_addr);
148	xe_pm_runtime_put(gt_to_xe(gt));
149
150	return 0;
151}
152
153static int topology(struct xe_gt *gt, struct drm_printer *p)
154{
155	xe_pm_runtime_get(gt_to_xe(gt));
156	xe_gt_topology_dump(gt, p);
157	xe_pm_runtime_put(gt_to_xe(gt));
158
159	return 0;
160}
161
162static int steering(struct xe_gt *gt, struct drm_printer *p)
163{
164	xe_pm_runtime_get(gt_to_xe(gt));
165	xe_gt_mcr_steering_dump(gt, p);
166	xe_pm_runtime_put(gt_to_xe(gt));
167
168	return 0;
169}
170
171static int ggtt(struct xe_gt *gt, struct drm_printer *p)
172{
173	int ret;
174
175	xe_pm_runtime_get(gt_to_xe(gt));
176	ret = xe_ggtt_dump(gt_to_tile(gt)->mem.ggtt, p);
177	xe_pm_runtime_put(gt_to_xe(gt));
178
179	return ret;
180}
181
182static int register_save_restore(struct xe_gt *gt, struct drm_printer *p)
183{
184	struct xe_hw_engine *hwe;
185	enum xe_hw_engine_id id;
186
187	xe_pm_runtime_get(gt_to_xe(gt));
188
189	xe_reg_sr_dump(&gt->reg_sr, p);
190	drm_printf(p, "\n");
191
192	drm_printf(p, "Engine\n");
193	for_each_hw_engine(hwe, gt, id)
194		xe_reg_sr_dump(&hwe->reg_sr, p);
195	drm_printf(p, "\n");
196
197	drm_printf(p, "LRC\n");
198	for_each_hw_engine(hwe, gt, id)
199		xe_reg_sr_dump(&hwe->reg_lrc, p);
200	drm_printf(p, "\n");
201
202	drm_printf(p, "Whitelist\n");
203	for_each_hw_engine(hwe, gt, id)
204		xe_reg_whitelist_dump(&hwe->reg_whitelist, p);
205
206	xe_pm_runtime_put(gt_to_xe(gt));
207
208	return 0;
209}
210
211static int workarounds(struct xe_gt *gt, struct drm_printer *p)
212{
213	xe_pm_runtime_get(gt_to_xe(gt));
214	xe_wa_dump(gt, p);
215	xe_pm_runtime_put(gt_to_xe(gt));
216
217	return 0;
218}
219
220static int pat(struct xe_gt *gt, struct drm_printer *p)
221{
222	xe_pm_runtime_get(gt_to_xe(gt));
223	xe_pat_dump(gt, p);
224	xe_pm_runtime_put(gt_to_xe(gt));
225
226	return 0;
227}
228
229static int mocs(struct xe_gt *gt, struct drm_printer *p)
230{
231	xe_pm_runtime_get(gt_to_xe(gt));
232	xe_mocs_dump(gt, p);
233	xe_pm_runtime_put(gt_to_xe(gt));
234
235	return 0;
236}
237
238static int rcs_default_lrc(struct xe_gt *gt, struct drm_printer *p)
239{
240	xe_pm_runtime_get(gt_to_xe(gt));
241	xe_lrc_dump_default(p, gt, XE_ENGINE_CLASS_RENDER);
242	xe_pm_runtime_put(gt_to_xe(gt));
243
244	return 0;
245}
246
247static int ccs_default_lrc(struct xe_gt *gt, struct drm_printer *p)
248{
249	xe_pm_runtime_get(gt_to_xe(gt));
250	xe_lrc_dump_default(p, gt, XE_ENGINE_CLASS_COMPUTE);
251	xe_pm_runtime_put(gt_to_xe(gt));
252
253	return 0;
254}
255
256static int bcs_default_lrc(struct xe_gt *gt, struct drm_printer *p)
257{
258	xe_pm_runtime_get(gt_to_xe(gt));
259	xe_lrc_dump_default(p, gt, XE_ENGINE_CLASS_COPY);
260	xe_pm_runtime_put(gt_to_xe(gt));
261
262	return 0;
263}
264
265static int vcs_default_lrc(struct xe_gt *gt, struct drm_printer *p)
266{
267	xe_pm_runtime_get(gt_to_xe(gt));
268	xe_lrc_dump_default(p, gt, XE_ENGINE_CLASS_VIDEO_DECODE);
269	xe_pm_runtime_put(gt_to_xe(gt));
270
271	return 0;
272}
273
274static int vecs_default_lrc(struct xe_gt *gt, struct drm_printer *p)
275{
276	xe_pm_runtime_get(gt_to_xe(gt));
277	xe_lrc_dump_default(p, gt, XE_ENGINE_CLASS_VIDEO_ENHANCE);
278	xe_pm_runtime_put(gt_to_xe(gt));
279
280	return 0;
281}
282
283static int hwconfig(struct xe_gt *gt, struct drm_printer *p)
284{
285	xe_pm_runtime_get(gt_to_xe(gt));
286	xe_guc_hwconfig_dump(&gt->uc.guc, p);
287	xe_pm_runtime_put(gt_to_xe(gt));
288
289	return 0;
290}
291
292static const struct drm_info_list debugfs_list[] = {
293	{"hw_engines", .show = xe_gt_debugfs_simple_show, .data = hw_engines},
294	{"force_reset", .show = xe_gt_debugfs_simple_show, .data = force_reset},
295	{"force_reset_sync", .show = xe_gt_debugfs_simple_show, .data = force_reset_sync},
296	{"sa_info", .show = xe_gt_debugfs_simple_show, .data = sa_info},
297	{"topology", .show = xe_gt_debugfs_simple_show, .data = topology},
298	{"steering", .show = xe_gt_debugfs_simple_show, .data = steering},
299	{"ggtt", .show = xe_gt_debugfs_simple_show, .data = ggtt},
300	{"powergate_info", .show = xe_gt_debugfs_simple_show, .data = powergate_info},
301	{"register-save-restore", .show = xe_gt_debugfs_simple_show, .data = register_save_restore},
302	{"workarounds", .show = xe_gt_debugfs_simple_show, .data = workarounds},
303	{"pat", .show = xe_gt_debugfs_simple_show, .data = pat},
304	{"mocs", .show = xe_gt_debugfs_simple_show, .data = mocs},
305	{"default_lrc_rcs", .show = xe_gt_debugfs_simple_show, .data = rcs_default_lrc},
306	{"default_lrc_ccs", .show = xe_gt_debugfs_simple_show, .data = ccs_default_lrc},
307	{"default_lrc_bcs", .show = xe_gt_debugfs_simple_show, .data = bcs_default_lrc},
308	{"default_lrc_vcs", .show = xe_gt_debugfs_simple_show, .data = vcs_default_lrc},
309	{"default_lrc_vecs", .show = xe_gt_debugfs_simple_show, .data = vecs_default_lrc},
310	{"stats", .show = xe_gt_debugfs_simple_show, .data = xe_gt_stats_print_info},
311	{"hwconfig", .show = xe_gt_debugfs_simple_show, .data = hwconfig},
312};
313
314void xe_gt_debugfs_register(struct xe_gt *gt)
315{
316	struct xe_device *xe = gt_to_xe(gt);
317	struct drm_minor *minor = gt_to_xe(gt)->drm.primary;
318	struct dentry *root;
319	char name[8];
320
321	xe_gt_assert(gt, minor->debugfs_root);
322
323	snprintf(name, sizeof(name), "gt%d", gt->info.id);
324	root = debugfs_create_dir(name, minor->debugfs_root);
325	if (IS_ERR(root)) {
326		drm_warn(&xe->drm, "Create GT directory failed");
327		return;
328	}
329
330	/*
331	 * Store the xe_gt pointer as private data of the gt/ directory node
332	 * so other GT specific attributes under that directory may refer to
333	 * it by looking at its parent node private data.
334	 */
335	root->d_inode->i_private = gt;
336
337	drm_debugfs_create_files(debugfs_list,
338				 ARRAY_SIZE(debugfs_list),
339				 root, minor);
340
341	xe_uc_debugfs_register(&gt->uc, root);
342
343	if (IS_SRIOV_PF(xe))
344		xe_gt_sriov_pf_debugfs_register(gt, root);
345	else if (IS_SRIOV_VF(xe))
346		xe_gt_sriov_vf_debugfs_register(gt, root);
347}