xref: /linux/drivers/gpu/drm/xe/xe_sriov_pf_debugfs.c (revision 24f171c7e145f43b9f187578e89b0982ce87e54c)
11238b84eSMichal Wajdeczko // SPDX-License-Identifier: MIT
21238b84eSMichal Wajdeczko /*
31238b84eSMichal Wajdeczko  * Copyright © 2025 Intel Corporation
41238b84eSMichal Wajdeczko  */
51238b84eSMichal Wajdeczko 
61238b84eSMichal Wajdeczko #include <linux/debugfs.h>
71238b84eSMichal Wajdeczko #include <drm/drm_debugfs.h>
81238b84eSMichal Wajdeczko 
95489e7d4SMichal Wajdeczko #include "xe_device.h"
101238b84eSMichal Wajdeczko #include "xe_device_types.h"
115b7451fdSMichal Wajdeczko #include "xe_pm.h"
121238b84eSMichal Wajdeczko #include "xe_sriov_pf.h"
135b7451fdSMichal Wajdeczko #include "xe_sriov_pf_control.h"
141238b84eSMichal Wajdeczko #include "xe_sriov_pf_debugfs.h"
154d4af0d6SMichal Wajdeczko #include "xe_sriov_pf_helpers.h"
161ed30397SMichał Winiarski #include "xe_sriov_pf_migration.h"
17ee746346SMichal Wajdeczko #include "xe_sriov_pf_provision.h"
181238b84eSMichal Wajdeczko #include "xe_sriov_pf_service.h"
194d4af0d6SMichal Wajdeczko #include "xe_sriov_printk.h"
205489e7d4SMichal Wajdeczko #include "xe_tile_sriov_pf_debugfs.h"
211238b84eSMichal Wajdeczko 
225b7451fdSMichal Wajdeczko /*
235b7451fdSMichal Wajdeczko  *      /sys/kernel/debug/dri/BDF/
245b7451fdSMichal Wajdeczko  *      ├── sriov		# d_inode->i_private = (xe_device*)
255b7451fdSMichal Wajdeczko  *      │   ├── pf		# d_inode->i_private = (xe_device*)
265b7451fdSMichal Wajdeczko  *      │   ├── vf1		# d_inode->i_private = VFID(1)
275b7451fdSMichal Wajdeczko  *      :   :
285b7451fdSMichal Wajdeczko  *      │   ├── vfN		# d_inode->i_private = VFID(N)
295b7451fdSMichal Wajdeczko  */
305b7451fdSMichal Wajdeczko 
315b7451fdSMichal Wajdeczko static void *extract_priv(struct dentry *d)
325b7451fdSMichal Wajdeczko {
335b7451fdSMichal Wajdeczko 	return d->d_inode->i_private;
345b7451fdSMichal Wajdeczko }
355b7451fdSMichal Wajdeczko 
365b7451fdSMichal Wajdeczko static struct xe_device *extract_xe(struct dentry *d)
375b7451fdSMichal Wajdeczko {
385b7451fdSMichal Wajdeczko 	return extract_priv(d->d_parent);
395b7451fdSMichal Wajdeczko }
405b7451fdSMichal Wajdeczko 
415b7451fdSMichal Wajdeczko static unsigned int extract_vfid(struct dentry *d)
425b7451fdSMichal Wajdeczko {
435b7451fdSMichal Wajdeczko 	void *p = extract_priv(d);
445b7451fdSMichal Wajdeczko 
455b7451fdSMichal Wajdeczko 	return p == extract_xe(d) ? PFID : (uintptr_t)p;
465b7451fdSMichal Wajdeczko }
475b7451fdSMichal Wajdeczko 
48ee746346SMichal Wajdeczko /*
49ee746346SMichal Wajdeczko  *      /sys/kernel/debug/dri/BDF/
50ee746346SMichal Wajdeczko  *      ├── sriov
51ee746346SMichal Wajdeczko  *      │   ├── restore_auto_provisioning
52ee746346SMichal Wajdeczko  *      │   :
53ee746346SMichal Wajdeczko  *      │   ├── pf/
54ee746346SMichal Wajdeczko  *      │   ├── vf1
55ee746346SMichal Wajdeczko  *      │   │   ├── ...
56ee746346SMichal Wajdeczko  */
57ee746346SMichal Wajdeczko 
58ee746346SMichal Wajdeczko static ssize_t from_file_write_to_xe_call(struct file *file, const char __user *userbuf,
59ee746346SMichal Wajdeczko 					  size_t count, loff_t *ppos,
60ee746346SMichal Wajdeczko 					  int (*call)(struct xe_device *))
61ee746346SMichal Wajdeczko {
62ee746346SMichal Wajdeczko 	struct dentry *dent = file_dentry(file);
63ee746346SMichal Wajdeczko 	struct xe_device *xe = extract_xe(dent);
64ee746346SMichal Wajdeczko 	bool yes;
65ee746346SMichal Wajdeczko 	int ret;
66ee746346SMichal Wajdeczko 
67ee746346SMichal Wajdeczko 	if (*ppos)
68ee746346SMichal Wajdeczko 		return -EINVAL;
69ee746346SMichal Wajdeczko 	ret = kstrtobool_from_user(userbuf, count, &yes);
70ee746346SMichal Wajdeczko 	if (ret < 0)
71ee746346SMichal Wajdeczko 		return ret;
72ee746346SMichal Wajdeczko 	if (yes) {
73ee746346SMichal Wajdeczko 		xe_pm_runtime_get(xe);
74ee746346SMichal Wajdeczko 		ret = call(xe);
75ee746346SMichal Wajdeczko 		xe_pm_runtime_put(xe);
76ee746346SMichal Wajdeczko 	}
77ee746346SMichal Wajdeczko 	if (ret < 0)
78ee746346SMichal Wajdeczko 		return ret;
79ee746346SMichal Wajdeczko 	return count;
80ee746346SMichal Wajdeczko }
81ee746346SMichal Wajdeczko 
82ee746346SMichal Wajdeczko #define DEFINE_SRIOV_ATTRIBUTE(OP)						\
83ee746346SMichal Wajdeczko static int OP##_show(struct seq_file *s, void *unused)				\
84ee746346SMichal Wajdeczko {										\
85ee746346SMichal Wajdeczko 	return 0;								\
86ee746346SMichal Wajdeczko }										\
87ee746346SMichal Wajdeczko static ssize_t OP##_write(struct file *file, const char __user *userbuf,	\
88ee746346SMichal Wajdeczko 			  size_t count, loff_t *ppos)				\
89ee746346SMichal Wajdeczko {										\
90ee746346SMichal Wajdeczko 	return from_file_write_to_xe_call(file, userbuf, count, ppos,		\
91ee746346SMichal Wajdeczko 					  xe_sriov_pf_##OP);			\
92ee746346SMichal Wajdeczko }										\
93ee746346SMichal Wajdeczko DEFINE_SHOW_STORE_ATTRIBUTE(OP)
94ee746346SMichal Wajdeczko 
95ee746346SMichal Wajdeczko static inline int xe_sriov_pf_restore_auto_provisioning(struct xe_device *xe)
96ee746346SMichal Wajdeczko {
97ee746346SMichal Wajdeczko 	return xe_sriov_pf_provision_set_mode(xe, XE_SRIOV_PROVISIONING_MODE_AUTO);
98ee746346SMichal Wajdeczko }
99ee746346SMichal Wajdeczko 
100ee746346SMichal Wajdeczko DEFINE_SRIOV_ATTRIBUTE(restore_auto_provisioning);
101ee746346SMichal Wajdeczko 
102387aba39SMichal Wajdeczko static int lockdown_vfs_enabling_open(struct inode *inode, struct file *file)
103387aba39SMichal Wajdeczko {
104387aba39SMichal Wajdeczko 	struct dentry *dent = file_dentry(file);
105387aba39SMichal Wajdeczko 	struct xe_device *xe = extract_xe(dent);
106387aba39SMichal Wajdeczko 	ssize_t ret;
107387aba39SMichal Wajdeczko 
108387aba39SMichal Wajdeczko 	ret = xe_sriov_pf_lockdown(xe);
109387aba39SMichal Wajdeczko 	if (ret < 0)
110387aba39SMichal Wajdeczko 		return ret;
111387aba39SMichal Wajdeczko 
112387aba39SMichal Wajdeczko 	file->private_data = xe;
113387aba39SMichal Wajdeczko 	return nonseekable_open(inode, file);
114387aba39SMichal Wajdeczko }
115387aba39SMichal Wajdeczko 
116387aba39SMichal Wajdeczko static int lockdown_vfs_enabling_release(struct inode *inode, struct file *file)
117387aba39SMichal Wajdeczko {
118387aba39SMichal Wajdeczko 	struct xe_device *xe = file->private_data;
119387aba39SMichal Wajdeczko 
120387aba39SMichal Wajdeczko 	xe_sriov_pf_end_lockdown(xe);
121387aba39SMichal Wajdeczko 	return 0;
122387aba39SMichal Wajdeczko }
123387aba39SMichal Wajdeczko 
124387aba39SMichal Wajdeczko static const struct file_operations lockdown_vfs_enabling_fops = {
125387aba39SMichal Wajdeczko 	.owner		= THIS_MODULE,
126387aba39SMichal Wajdeczko 	.open		= lockdown_vfs_enabling_open,
127387aba39SMichal Wajdeczko 	.release	= lockdown_vfs_enabling_release,
128387aba39SMichal Wajdeczko };
129387aba39SMichal Wajdeczko 
130ee746346SMichal Wajdeczko static void pf_populate_root(struct xe_device *xe, struct dentry *dent)
131ee746346SMichal Wajdeczko {
132ee746346SMichal Wajdeczko 	debugfs_create_file("restore_auto_provisioning", 0200, dent, xe,
133ee746346SMichal Wajdeczko 			    &restore_auto_provisioning_fops);
134387aba39SMichal Wajdeczko 	debugfs_create_file("lockdown_vfs_enabling", 0400, dent, xe,
135387aba39SMichal Wajdeczko 			    &lockdown_vfs_enabling_fops);
136ee746346SMichal Wajdeczko }
137ee746346SMichal Wajdeczko 
1381238b84eSMichal Wajdeczko static int simple_show(struct seq_file *m, void *data)
1391238b84eSMichal Wajdeczko {
1401238b84eSMichal Wajdeczko 	struct drm_printer p = drm_seq_file_printer(m);
1411238b84eSMichal Wajdeczko 	struct drm_info_node *node = m->private;
1421238b84eSMichal Wajdeczko 	struct dentry *parent = node->dent->d_parent;
1431238b84eSMichal Wajdeczko 	struct xe_device *xe = parent->d_inode->i_private;
1441238b84eSMichal Wajdeczko 	void (*print)(struct xe_device *, struct drm_printer *) = node->info_ent->data;
1451238b84eSMichal Wajdeczko 
1461238b84eSMichal Wajdeczko 	print(xe, &p);
1471238b84eSMichal Wajdeczko 	return 0;
1481238b84eSMichal Wajdeczko }
1491238b84eSMichal Wajdeczko 
1501238b84eSMichal Wajdeczko static const struct drm_info_list debugfs_list[] = {
1511238b84eSMichal Wajdeczko 	{ .name = "vfs", .show = simple_show, .data = xe_sriov_pf_print_vfs_summary },
1521238b84eSMichal Wajdeczko 	{ .name = "versions", .show = simple_show, .data = xe_sriov_pf_service_print_versions },
1531238b84eSMichal Wajdeczko };
1541238b84eSMichal Wajdeczko 
1554d4af0d6SMichal Wajdeczko static void pf_populate_pf(struct xe_device *xe, struct dentry *pfdent)
1564d4af0d6SMichal Wajdeczko {
1574d4af0d6SMichal Wajdeczko 	struct drm_minor *minor = xe->drm.primary;
1584d4af0d6SMichal Wajdeczko 
1594d4af0d6SMichal Wajdeczko 	drm_debugfs_create_files(debugfs_list, ARRAY_SIZE(debugfs_list), pfdent, minor);
1604d4af0d6SMichal Wajdeczko }
1614d4af0d6SMichal Wajdeczko 
1625b7451fdSMichal Wajdeczko /*
1635b7451fdSMichal Wajdeczko  *      /sys/kernel/debug/dri/BDF/
1645b7451fdSMichal Wajdeczko  *      ├── sriov
1655b7451fdSMichal Wajdeczko  *      │   ├── vf1
1661ed30397SMichał Winiarski  *      │   │   ├── migration_data
1675b7451fdSMichal Wajdeczko  *      │   │   ├── pause
1685b7451fdSMichal Wajdeczko  *      │   │   ├── reset
1695b7451fdSMichal Wajdeczko  *      │   │   ├── resume
1705b7451fdSMichal Wajdeczko  *      │   │   ├── stop
171ed46ff0dSMichał Winiarski  *      │   │   ├── save
172ed46ff0dSMichał Winiarski  *      │   │   ├── restore
1735b7451fdSMichal Wajdeczko  *      │   │   :
1745b7451fdSMichal Wajdeczko  *      │   ├── vf2
1755b7451fdSMichal Wajdeczko  *      │   │   ├── ...
1765b7451fdSMichal Wajdeczko  */
1775b7451fdSMichal Wajdeczko 
178ed46ff0dSMichał Winiarski static int from_file_read_to_vf_call(struct seq_file *s,
179ed46ff0dSMichał Winiarski 				     int (*call)(struct xe_device *, unsigned int))
180ed46ff0dSMichał Winiarski {
181ed46ff0dSMichał Winiarski 	struct dentry *dent = file_dentry(s->file)->d_parent;
182ed46ff0dSMichał Winiarski 	struct xe_device *xe = extract_xe(dent);
183ed46ff0dSMichał Winiarski 	unsigned int vfid = extract_vfid(dent);
184ed46ff0dSMichał Winiarski 	int ret;
185ed46ff0dSMichał Winiarski 
186ed46ff0dSMichał Winiarski 	xe_pm_runtime_get(xe);
187ed46ff0dSMichał Winiarski 	ret = call(xe, vfid);
188ed46ff0dSMichał Winiarski 	xe_pm_runtime_put(xe);
189ed46ff0dSMichał Winiarski 
190ed46ff0dSMichał Winiarski 	if (ret < 0)
191ed46ff0dSMichał Winiarski 		return ret;
192ed46ff0dSMichał Winiarski 
193ed46ff0dSMichał Winiarski 	return 0;
194ed46ff0dSMichał Winiarski }
195ed46ff0dSMichał Winiarski 
1965b7451fdSMichal Wajdeczko static ssize_t from_file_write_to_vf_call(struct file *file, const char __user *userbuf,
1975b7451fdSMichal Wajdeczko 					  size_t count, loff_t *ppos,
1985b7451fdSMichal Wajdeczko 					  int (*call)(struct xe_device *, unsigned int))
1995b7451fdSMichal Wajdeczko {
2005b7451fdSMichal Wajdeczko 	struct dentry *dent = file_dentry(file)->d_parent;
2015b7451fdSMichal Wajdeczko 	struct xe_device *xe = extract_xe(dent);
2025b7451fdSMichal Wajdeczko 	unsigned int vfid = extract_vfid(dent);
2035b7451fdSMichal Wajdeczko 	bool yes;
2045b7451fdSMichal Wajdeczko 	int ret;
2055b7451fdSMichal Wajdeczko 
2065b7451fdSMichal Wajdeczko 	if (*ppos)
2075b7451fdSMichal Wajdeczko 		return -EINVAL;
2085b7451fdSMichal Wajdeczko 	ret = kstrtobool_from_user(userbuf, count, &yes);
2095b7451fdSMichal Wajdeczko 	if (ret < 0)
2105b7451fdSMichal Wajdeczko 		return ret;
2115b7451fdSMichal Wajdeczko 	if (yes) {
2125b7451fdSMichal Wajdeczko 		xe_pm_runtime_get(xe);
2135b7451fdSMichal Wajdeczko 		ret = call(xe, vfid);
2145b7451fdSMichal Wajdeczko 		xe_pm_runtime_put(xe);
2155b7451fdSMichal Wajdeczko 	}
2165b7451fdSMichal Wajdeczko 	if (ret < 0)
2175b7451fdSMichal Wajdeczko 		return ret;
2185b7451fdSMichal Wajdeczko 	return count;
2195b7451fdSMichal Wajdeczko }
2205b7451fdSMichal Wajdeczko 
2215b7451fdSMichal Wajdeczko #define DEFINE_VF_CONTROL_ATTRIBUTE(OP)						\
2225b7451fdSMichal Wajdeczko static int OP##_show(struct seq_file *s, void *unused)				\
2235b7451fdSMichal Wajdeczko {										\
2245b7451fdSMichal Wajdeczko 	return 0;								\
2255b7451fdSMichal Wajdeczko }										\
2265b7451fdSMichal Wajdeczko static ssize_t OP##_write(struct file *file, const char __user *userbuf,	\
2275b7451fdSMichal Wajdeczko 			  size_t count, loff_t *ppos)				\
2285b7451fdSMichal Wajdeczko {										\
2295b7451fdSMichal Wajdeczko 	return from_file_write_to_vf_call(file, userbuf, count, ppos,		\
2305b7451fdSMichal Wajdeczko 					  xe_sriov_pf_control_##OP);		\
2315b7451fdSMichal Wajdeczko }										\
2325b7451fdSMichal Wajdeczko DEFINE_SHOW_STORE_ATTRIBUTE(OP)
2335b7451fdSMichal Wajdeczko 
234ed46ff0dSMichał Winiarski #define DEFINE_VF_CONTROL_ATTRIBUTE_RW(OP)					\
235ed46ff0dSMichał Winiarski static int OP##_show(struct seq_file *s, void *unused)				\
236ed46ff0dSMichał Winiarski {										\
237ed46ff0dSMichał Winiarski 	return from_file_read_to_vf_call(s,					\
238ed46ff0dSMichał Winiarski 					 xe_sriov_pf_control_finish_##OP);	\
239ed46ff0dSMichał Winiarski }										\
240ed46ff0dSMichał Winiarski static ssize_t OP##_write(struct file *file, const char __user *userbuf,	\
241ed46ff0dSMichał Winiarski 			  size_t count, loff_t *ppos)				\
242ed46ff0dSMichał Winiarski {										\
243ed46ff0dSMichał Winiarski 	return from_file_write_to_vf_call(file, userbuf, count, ppos,		\
244ed46ff0dSMichał Winiarski 					  xe_sriov_pf_control_trigger_##OP);	\
245ed46ff0dSMichał Winiarski }										\
246ed46ff0dSMichał Winiarski DEFINE_SHOW_STORE_ATTRIBUTE(OP)
247ed46ff0dSMichał Winiarski 
2485b7451fdSMichal Wajdeczko DEFINE_VF_CONTROL_ATTRIBUTE(pause_vf);
2495b7451fdSMichal Wajdeczko DEFINE_VF_CONTROL_ATTRIBUTE(resume_vf);
2505b7451fdSMichal Wajdeczko DEFINE_VF_CONTROL_ATTRIBUTE(stop_vf);
2515b7451fdSMichal Wajdeczko DEFINE_VF_CONTROL_ATTRIBUTE(reset_vf);
252ed46ff0dSMichał Winiarski DEFINE_VF_CONTROL_ATTRIBUTE_RW(save_vf);
253ed46ff0dSMichał Winiarski DEFINE_VF_CONTROL_ATTRIBUTE_RW(restore_vf);
2545b7451fdSMichal Wajdeczko 
2551ed30397SMichał Winiarski static ssize_t data_write(struct file *file, const char __user *buf, size_t count, loff_t *pos)
2561ed30397SMichał Winiarski {
2571ed30397SMichał Winiarski 	struct dentry *dent = file_dentry(file)->d_parent;
2581ed30397SMichał Winiarski 	struct xe_device *xe = extract_xe(dent);
2591ed30397SMichał Winiarski 	unsigned int vfid = extract_vfid(dent);
2601ed30397SMichał Winiarski 
2611ed30397SMichał Winiarski 	if (*pos)
2621ed30397SMichał Winiarski 		return -ESPIPE;
2631ed30397SMichał Winiarski 
2641ed30397SMichał Winiarski 	return xe_sriov_pf_migration_write(xe, vfid, buf, count);
2651ed30397SMichał Winiarski }
2661ed30397SMichał Winiarski 
2671ed30397SMichał Winiarski static ssize_t data_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
2681ed30397SMichał Winiarski {
2691ed30397SMichał Winiarski 	struct dentry *dent = file_dentry(file)->d_parent;
2701ed30397SMichał Winiarski 	struct xe_device *xe = extract_xe(dent);
2711ed30397SMichał Winiarski 	unsigned int vfid = extract_vfid(dent);
2721ed30397SMichał Winiarski 
2731ed30397SMichał Winiarski 	if (*ppos)
2741ed30397SMichał Winiarski 		return -ESPIPE;
2751ed30397SMichał Winiarski 
2761ed30397SMichał Winiarski 	return xe_sriov_pf_migration_read(xe, vfid, buf, count);
2771ed30397SMichał Winiarski }
2781ed30397SMichał Winiarski 
2791ed30397SMichał Winiarski static const struct file_operations data_vf_fops = {
2801ed30397SMichał Winiarski 	.owner		= THIS_MODULE,
2811ed30397SMichał Winiarski 	.open		= simple_open,
2821ed30397SMichał Winiarski 	.write		= data_write,
2831ed30397SMichał Winiarski 	.read		= data_read,
2841ed30397SMichał Winiarski 	.llseek		= default_llseek,
2851ed30397SMichał Winiarski };
2861ed30397SMichał Winiarski 
287*20cfef3aSMichał Winiarski static ssize_t size_read(struct file *file, char __user *ubuf, size_t count, loff_t *ppos)
288*20cfef3aSMichał Winiarski {
289*20cfef3aSMichał Winiarski 	struct dentry *dent = file_dentry(file)->d_parent;
290*20cfef3aSMichał Winiarski 	struct xe_device *xe = extract_xe(dent);
291*20cfef3aSMichał Winiarski 	unsigned int vfid = extract_vfid(dent);
292*20cfef3aSMichał Winiarski 	char buf[21];
293*20cfef3aSMichał Winiarski 	ssize_t ret;
294*20cfef3aSMichał Winiarski 	int len;
295*20cfef3aSMichał Winiarski 
296*20cfef3aSMichał Winiarski 	xe_pm_runtime_get(xe);
297*20cfef3aSMichał Winiarski 	ret = xe_sriov_pf_migration_size(xe, vfid);
298*20cfef3aSMichał Winiarski 	xe_pm_runtime_put(xe);
299*20cfef3aSMichał Winiarski 	if (ret < 0)
300*20cfef3aSMichał Winiarski 		return ret;
301*20cfef3aSMichał Winiarski 
302*20cfef3aSMichał Winiarski 	len = scnprintf(buf, sizeof(buf), "%zd\n", ret);
303*20cfef3aSMichał Winiarski 
304*20cfef3aSMichał Winiarski 	return simple_read_from_buffer(ubuf, count, ppos, buf, len);
305*20cfef3aSMichał Winiarski }
306*20cfef3aSMichał Winiarski 
307*20cfef3aSMichał Winiarski static const struct file_operations size_vf_fops = {
308*20cfef3aSMichał Winiarski 	.owner		= THIS_MODULE,
309*20cfef3aSMichał Winiarski 	.open		= simple_open,
310*20cfef3aSMichał Winiarski 	.read		= size_read,
311*20cfef3aSMichał Winiarski 	.llseek		= default_llseek,
312*20cfef3aSMichał Winiarski };
313*20cfef3aSMichał Winiarski 
3145b7451fdSMichal Wajdeczko static void pf_populate_vf(struct xe_device *xe, struct dentry *vfdent)
3155b7451fdSMichal Wajdeczko {
3165b7451fdSMichal Wajdeczko 	debugfs_create_file("pause", 0200, vfdent, xe, &pause_vf_fops);
3175b7451fdSMichal Wajdeczko 	debugfs_create_file("resume", 0200, vfdent, xe, &resume_vf_fops);
3185b7451fdSMichal Wajdeczko 	debugfs_create_file("stop", 0200, vfdent, xe, &stop_vf_fops);
3195b7451fdSMichal Wajdeczko 	debugfs_create_file("reset", 0200, vfdent, xe, &reset_vf_fops);
320ed46ff0dSMichał Winiarski 	debugfs_create_file("save", 0600, vfdent, xe, &save_vf_fops);
321ed46ff0dSMichał Winiarski 	debugfs_create_file("restore", 0600, vfdent, xe, &restore_vf_fops);
3221ed30397SMichał Winiarski 	debugfs_create_file("migration_data", 0600, vfdent, xe, &data_vf_fops);
323*20cfef3aSMichał Winiarski 	debugfs_create_file("migration_size", 0400, vfdent, xe, &size_vf_fops);
3245b7451fdSMichal Wajdeczko }
3255b7451fdSMichal Wajdeczko 
3265489e7d4SMichal Wajdeczko static void pf_populate_with_tiles(struct xe_device *xe, struct dentry *dent, unsigned int vfid)
3275489e7d4SMichal Wajdeczko {
3285489e7d4SMichal Wajdeczko 	struct xe_tile *tile;
3295489e7d4SMichal Wajdeczko 	unsigned int id;
3305489e7d4SMichal Wajdeczko 
3315489e7d4SMichal Wajdeczko 	for_each_tile(tile, xe, id)
3325489e7d4SMichal Wajdeczko 		xe_tile_sriov_pf_debugfs_populate(tile, dent, vfid);
3335489e7d4SMichal Wajdeczko }
3345489e7d4SMichal Wajdeczko 
3351238b84eSMichal Wajdeczko /**
3361238b84eSMichal Wajdeczko  * xe_sriov_pf_debugfs_register - Register PF debugfs attributes.
3371238b84eSMichal Wajdeczko  * @xe: the &xe_device
3381238b84eSMichal Wajdeczko  * @root: the root &dentry
3391238b84eSMichal Wajdeczko  *
3404d4af0d6SMichal Wajdeczko  * Create separate directory that will contain all SR-IOV related files,
3414d4af0d6SMichal Wajdeczko  * organized per each SR-IOV function (PF, VF1, VF2, ..., VFn).
3421238b84eSMichal Wajdeczko  */
3431238b84eSMichal Wajdeczko void xe_sriov_pf_debugfs_register(struct xe_device *xe, struct dentry *root)
3441238b84eSMichal Wajdeczko {
3454d4af0d6SMichal Wajdeczko 	int totalvfs = xe_sriov_pf_get_totalvfs(xe);
3464d4af0d6SMichal Wajdeczko 	struct dentry *pfdent;
3474d4af0d6SMichal Wajdeczko 	struct dentry *vfdent;
3484d4af0d6SMichal Wajdeczko 	struct dentry *dent;
3494d4af0d6SMichal Wajdeczko 	char vfname[16]; /* should be more than enough for "vf%u\0" and VFID(UINT_MAX) */
3504d4af0d6SMichal Wajdeczko 	unsigned int n;
3511238b84eSMichal Wajdeczko 
3521238b84eSMichal Wajdeczko 	/*
3534d4af0d6SMichal Wajdeczko 	 *      /sys/kernel/debug/dri/BDF/
3544d4af0d6SMichal Wajdeczko 	 *      ├── sriov		# d_inode->i_private = (xe_device*)
3551238b84eSMichal Wajdeczko 	 *      │   ├── ...
3561238b84eSMichal Wajdeczko 	 */
3574d4af0d6SMichal Wajdeczko 	dent = debugfs_create_dir("sriov", root);
3584d4af0d6SMichal Wajdeczko 	if (IS_ERR(dent))
3591238b84eSMichal Wajdeczko 		return;
3604d4af0d6SMichal Wajdeczko 	dent->d_inode->i_private = xe;
3611238b84eSMichal Wajdeczko 
362ee746346SMichal Wajdeczko 	pf_populate_root(xe, dent);
363ee746346SMichal Wajdeczko 
3644d4af0d6SMichal Wajdeczko 	/*
3654d4af0d6SMichal Wajdeczko 	 *      /sys/kernel/debug/dri/BDF/
3664d4af0d6SMichal Wajdeczko 	 *      ├── sriov		# d_inode->i_private = (xe_device*)
3674d4af0d6SMichal Wajdeczko 	 *      │   ├── pf		# d_inode->i_private = (xe_device*)
3684d4af0d6SMichal Wajdeczko 	 *      │   │   ├── ...
3694d4af0d6SMichal Wajdeczko 	 */
3704d4af0d6SMichal Wajdeczko 	pfdent = debugfs_create_dir("pf", dent);
3714d4af0d6SMichal Wajdeczko 	if (IS_ERR(pfdent))
3724d4af0d6SMichal Wajdeczko 		return;
3734d4af0d6SMichal Wajdeczko 	pfdent->d_inode->i_private = xe;
3744d4af0d6SMichal Wajdeczko 
3754d4af0d6SMichal Wajdeczko 	pf_populate_pf(xe, pfdent);
3765489e7d4SMichal Wajdeczko 	pf_populate_with_tiles(xe, pfdent, PFID);
3774d4af0d6SMichal Wajdeczko 
3784d4af0d6SMichal Wajdeczko 	/*
3794d4af0d6SMichal Wajdeczko 	 *      /sys/kernel/debug/dri/BDF/
3804d4af0d6SMichal Wajdeczko 	 *      ├── sriov		# d_inode->i_private = (xe_device*)
3814d4af0d6SMichal Wajdeczko 	 *      │   ├── vf1		# d_inode->i_private = VFID(1)
3824d4af0d6SMichal Wajdeczko 	 *      │   ├── vf2		# d_inode->i_private = VFID(2)
3834d4af0d6SMichal Wajdeczko 	 *      │   ├── ...
3844d4af0d6SMichal Wajdeczko 	 */
3854d4af0d6SMichal Wajdeczko 	for (n = 1; n <= totalvfs; n++) {
3864d4af0d6SMichal Wajdeczko 		snprintf(vfname, sizeof(vfname), "vf%u", VFID(n));
3874d4af0d6SMichal Wajdeczko 		vfdent = debugfs_create_dir(vfname, dent);
3884d4af0d6SMichal Wajdeczko 		if (IS_ERR(vfdent))
3894d4af0d6SMichal Wajdeczko 			return;
3904d4af0d6SMichal Wajdeczko 		vfdent->d_inode->i_private = (void *)(uintptr_t)VFID(n);
3915489e7d4SMichal Wajdeczko 
3925b7451fdSMichal Wajdeczko 		pf_populate_vf(xe, vfdent);
3935489e7d4SMichal Wajdeczko 		pf_populate_with_tiles(xe, vfdent, VFID(n));
3944d4af0d6SMichal Wajdeczko 	}
3951238b84eSMichal Wajdeczko }
396