xref: /linux/drivers/gpu/drm/xe/xe_sriov.c (revision 68a052239fc4b351e961f698b824f7654a346091)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2023 Intel Corporation
4  */
5 
6 #include <linux/fault-inject.h>
7 
8 #include <drm/drm_managed.h>
9 
10 #include "regs/xe_regs.h"
11 
12 #include "xe_assert.h"
13 #include "xe_device.h"
14 #include "xe_mmio.h"
15 #include "xe_sriov.h"
16 #include "xe_sriov_pf.h"
17 #include "xe_sriov_vf.h"
18 #include "xe_sriov_vf_ccs.h"
19 
20 /**
21  * xe_sriov_mode_to_string - Convert enum value to string.
22  * @mode: the &xe_sriov_mode to convert
23  *
24  * Returns: SR-IOV mode as a user friendly string.
25  */
26 const char *xe_sriov_mode_to_string(enum xe_sriov_mode mode)
27 {
28 	switch (mode) {
29 	case XE_SRIOV_MODE_NONE:
30 		return "none";
31 	case XE_SRIOV_MODE_PF:
32 		return "SR-IOV PF";
33 	case XE_SRIOV_MODE_VF:
34 		return "SR-IOV VF";
35 	default:
36 		return "<invalid>";
37 	}
38 }
39 
40 static bool test_is_vf(struct xe_device *xe)
41 {
42 	u32 value = xe_mmio_read32(xe_root_tile_mmio(xe), VF_CAP_REG);
43 
44 	return value & VF_CAP;
45 }
46 
47 /**
48  * xe_sriov_probe_early - Probe a SR-IOV mode.
49  * @xe: the &xe_device to probe mode on
50  *
51  * This function should be called only once and as soon as possible during
52  * driver probe to detect whether we are running a SR-IOV Physical Function
53  * (PF) or a Virtual Function (VF) device.
54  *
55  * SR-IOV PF mode detection is based on PCI @dev_is_pf() function.
56  * SR-IOV VF mode detection is based on dedicated MMIO register read.
57  */
58 void xe_sriov_probe_early(struct xe_device *xe)
59 {
60 	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
61 	enum xe_sriov_mode mode = XE_SRIOV_MODE_NONE;
62 	bool has_sriov = xe->info.has_sriov;
63 
64 	if (has_sriov) {
65 		if (test_is_vf(xe))
66 			mode = XE_SRIOV_MODE_VF;
67 		else if (xe_sriov_pf_readiness(xe))
68 			mode = XE_SRIOV_MODE_PF;
69 	} else if (pci_sriov_get_totalvfs(pdev)) {
70 		/*
71 		 * Even if we have not enabled SR-IOV support using the
72 		 * platform specific has_sriov flag, the hardware may still
73 		 * report SR-IOV capability and the PCI layer may wrongly
74 		 * advertise driver support to enable VFs. Explicitly reset
75 		 * the number of supported VFs to zero to avoid confusion.
76 		 */
77 		drm_info(&xe->drm, "Support for SR-IOV is not available\n");
78 		pci_sriov_set_totalvfs(pdev, 0);
79 	}
80 
81 	xe_assert(xe, !xe->sriov.__mode);
82 	xe->sriov.__mode = mode;
83 	xe_assert(xe, xe->sriov.__mode);
84 
85 	if (IS_SRIOV(xe))
86 		drm_info(&xe->drm, "Running in %s mode\n",
87 			 xe_sriov_mode_to_string(xe_device_sriov_mode(xe)));
88 }
89 
90 static void fini_sriov(struct drm_device *drm, void *arg)
91 {
92 	struct xe_device *xe = arg;
93 
94 	destroy_workqueue(xe->sriov.wq);
95 	xe->sriov.wq = NULL;
96 }
97 
98 /**
99  * xe_sriov_init - Initialize SR-IOV specific data.
100  * @xe: the &xe_device to initialize
101  *
102  * In this function we create dedicated workqueue that will be used
103  * by the SR-IOV specific workers.
104  *
105  * Return: 0 on success or a negative error code on failure.
106  */
107 int xe_sriov_init(struct xe_device *xe)
108 {
109 	if (!IS_SRIOV(xe))
110 		return 0;
111 
112 	if (IS_SRIOV_PF(xe)) {
113 		int err = xe_sriov_pf_init_early(xe);
114 
115 		if (err)
116 			return err;
117 	}
118 
119 	if (IS_SRIOV_VF(xe))
120 		xe_sriov_vf_init_early(xe);
121 
122 	xe_assert(xe, !xe->sriov.wq);
123 	xe->sriov.wq = alloc_workqueue("xe-sriov-wq", 0, 0);
124 	if (!xe->sriov.wq)
125 		return -ENOMEM;
126 
127 	return drmm_add_action_or_reset(&xe->drm, fini_sriov, xe);
128 }
129 ALLOW_ERROR_INJECTION(xe_sriov_init, ERRNO); /* See xe_pci_probe() */
130 
131 /**
132  * xe_sriov_print_info - Print basic SR-IOV information.
133  * @xe: the &xe_device to print info from
134  * @p: the &drm_printer
135  *
136  * Print SR-IOV related information into provided DRM printer.
137  */
138 void xe_sriov_print_info(struct xe_device *xe, struct drm_printer *p)
139 {
140 	drm_printf(p, "supported: %s\n", str_yes_no(xe_device_has_sriov(xe)));
141 	drm_printf(p, "enabled: %s\n", str_yes_no(IS_SRIOV(xe)));
142 	drm_printf(p, "mode: %s\n", xe_sriov_mode_to_string(xe_device_sriov_mode(xe)));
143 }
144 
145 /**
146  * xe_sriov_function_name() - Get SR-IOV Function name.
147  * @n: the Function number (identifier) to get name of
148  * @buf: the buffer to format to
149  * @size: size of the buffer (shall be at least 5 bytes)
150  *
151  * Return: formatted function name ("PF" or "VF%u").
152  */
153 const char *xe_sriov_function_name(unsigned int n, char *buf, size_t size)
154 {
155 	if (n)
156 		snprintf(buf, size, "VF%u", n);
157 	else
158 		strscpy(buf, "PF", size);
159 	return buf;
160 }
161 
162 /**
163  * xe_sriov_init_late() - SR-IOV late initialization functions.
164  * @xe: the &xe_device to initialize
165  *
166  * Return: 0 on success or a negative error code on failure.
167  */
168 int xe_sriov_init_late(struct xe_device *xe)
169 {
170 	if (IS_SRIOV_VF(xe))
171 		return xe_sriov_vf_init_late(xe);
172 
173 	return 0;
174 }
175