xref: /linux/drivers/gpu/drm/xe/tests/xe_pci.c (revision bba2c3615bd6cfee7456d1130f2e6b01b3f4e9ba)
1 // SPDX-License-Identifier: GPL-2.0 AND MIT
2 /*
3  * Copyright © 2023 Intel Corporation
4  */
5 
6 #include "tests/xe_pci_test.h"
7 
8 #include "tests/xe_test.h"
9 
10 #include <kunit/test-bug.h>
11 #include <kunit/test.h>
12 #include <kunit/test-bug.h>
13 #include <kunit/visibility.h>
14 
15 #define PLATFORM_CASE(platform__, graphics_step__)					\
16 	{										\
17 		.platform = XE_ ## platform__,						\
18 		.subplatform = XE_SUBPLATFORM_NONE,					\
19 		.step = { .graphics = STEP_ ## graphics_step__ }			\
20 	}
21 
22 #define SUBPLATFORM_CASE(platform__, subplatform__, graphics_step__)			\
23 	{										\
24 		.platform = XE_ ## platform__,						\
25 		.subplatform = XE_SUBPLATFORM_ ## platform__ ## _ ## subplatform__,	\
26 		.step = { .graphics = STEP_ ## graphics_step__ }			\
27 	}
28 
29 #define GMDID_CASE(platform__, graphics_verx100__, graphics_step__,			\
30 		   media_verx100__, media_step__)					\
31 	{										\
32 		.platform = XE_ ## platform__,						\
33 		.subplatform = XE_SUBPLATFORM_NONE,					\
34 		.graphics_verx100 = graphics_verx100__,					\
35 		.media_verx100 = media_verx100__,					\
36 		.step = { .graphics = STEP_ ## graphics_step__,				\
37 			   .media = STEP_ ## media_step__ }				\
38 	}
39 
40 static const struct xe_pci_fake_data cases[] = {
41 	PLATFORM_CASE(TIGERLAKE, B0),
42 	PLATFORM_CASE(DG1, A0),
43 	PLATFORM_CASE(DG1, B0),
44 	PLATFORM_CASE(ALDERLAKE_S, A0),
45 	PLATFORM_CASE(ALDERLAKE_S, B0),
46 	PLATFORM_CASE(ALDERLAKE_S, C0),
47 	PLATFORM_CASE(ALDERLAKE_S, D0),
48 	PLATFORM_CASE(ALDERLAKE_P, A0),
49 	PLATFORM_CASE(ALDERLAKE_P, B0),
50 	PLATFORM_CASE(ALDERLAKE_P, C0),
51 	SUBPLATFORM_CASE(ALDERLAKE_S, RPLS, D0),
52 	SUBPLATFORM_CASE(ALDERLAKE_P, RPLU, E0),
53 	SUBPLATFORM_CASE(DG2, G10, C0),
54 	SUBPLATFORM_CASE(DG2, G11, B1),
55 	SUBPLATFORM_CASE(DG2, G12, A1),
56 	GMDID_CASE(METEORLAKE, 1270, A0, 1300, A0),
57 	GMDID_CASE(METEORLAKE, 1271, A0, 1300, A0),
58 	GMDID_CASE(METEORLAKE, 1274, A0, 1300, A0),
59 	GMDID_CASE(LUNARLAKE, 2004, A0, 2000, A0),
60 	GMDID_CASE(LUNARLAKE, 2004, B0, 2000, A0),
61 	GMDID_CASE(BATTLEMAGE, 2001, A0, 1301, A1),
62 	GMDID_CASE(PANTHERLAKE, 3000, A0, 3000, A0),
63 };
64 
65 KUNIT_ARRAY_PARAM(platform, cases, xe_pci_fake_data_desc);
66 
67 /**
68  * xe_pci_fake_data_gen_params - Generate struct xe_pci_fake_data parameters
69  * @test: test context object
70  * @prev: the pointer to the previous parameter to iterate from or NULL
71  * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
72  *
73  * This function prepares struct xe_pci_fake_data parameter.
74  *
75  * To be used only as a parameter generator function in &KUNIT_CASE_PARAM.
76  *
77  * Return: pointer to the next parameter or NULL if no more parameters
78  */
79 const void *xe_pci_fake_data_gen_params(struct kunit *test, const void *prev, char *desc)
80 {
81 	return platform_gen_params(test, prev, desc);
82 }
83 EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_data_gen_params);
84 
85 static const struct xe_device_desc *lookup_desc(enum xe_platform p)
86 {
87 	const struct xe_device_desc *desc;
88 	const struct pci_device_id *ids;
89 
90 	for (ids = pciidlist; ids->driver_data; ids++) {
91 		desc = (const void *)ids->driver_data;
92 		if (desc->platform == p)
93 			return desc;
94 	}
95 	return NULL;
96 }
97 
98 static const struct xe_subplatform_desc *lookup_sub_desc(enum xe_platform p, enum xe_subplatform s)
99 {
100 	const struct xe_device_desc *desc = lookup_desc(p);
101 	const struct xe_subplatform_desc *spd;
102 
103 	if (desc && desc->subplatforms)
104 		for (spd = desc->subplatforms; spd->subplatform; spd++)
105 			if (spd->subplatform == s)
106 				return spd;
107 	return NULL;
108 }
109 
110 static const char *lookup_platform_name(enum xe_platform p)
111 {
112 	const struct xe_device_desc *desc = lookup_desc(p);
113 
114 	return desc ? desc->platform_name : "INVALID";
115 }
116 
117 static const char *__lookup_subplatform_name(enum xe_platform p, enum xe_subplatform s)
118 {
119 	const struct xe_subplatform_desc *desc = lookup_sub_desc(p, s);
120 
121 	return desc ? desc->name : "INVALID";
122 }
123 
124 static const char *lookup_subplatform_name(enum xe_platform p, enum xe_subplatform s)
125 {
126 	return s == XE_SUBPLATFORM_NONE ? "" : __lookup_subplatform_name(p, s);
127 }
128 
129 static const char *subplatform_prefix(enum xe_subplatform s)
130 {
131 	return s == XE_SUBPLATFORM_NONE ? "" : " ";
132 }
133 
134 static const char *step_prefix(enum intel_step step)
135 {
136 	return step == STEP_NONE ? "" : " ";
137 }
138 
139 static const char *step_name(enum intel_step step)
140 {
141 	return step == STEP_NONE ? "" : xe_step_name(step);
142 }
143 
144 static const char *sriov_prefix(enum xe_sriov_mode mode)
145 {
146 	return mode <= XE_SRIOV_MODE_NONE ? "" : " ";
147 }
148 
149 static const char *sriov_name(enum xe_sriov_mode mode)
150 {
151 	return mode <= XE_SRIOV_MODE_NONE ? "" : xe_sriov_mode_to_string(mode);
152 }
153 
154 static const char *lookup_graphics_name(unsigned int verx100)
155 {
156 	const struct xe_ip *ip = find_graphics_ip(verx100);
157 
158 	return ip ? ip->name : "";
159 }
160 
161 static const char *lookup_media_name(unsigned int verx100)
162 {
163 	const struct xe_ip *ip = find_media_ip(verx100);
164 
165 	return ip ? ip->name : "";
166 }
167 
168 /**
169  * xe_pci_fake_data_desc - Describe struct xe_pci_fake_data parameter
170  * @param: the &struct xe_pci_fake_data parameter to describe
171  * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
172  *
173  * This function prepares description of the struct xe_pci_fake_data parameter.
174  *
175  * It is tailored for use in parameterized KUnit tests where parameter generator
176  * is based on the struct xe_pci_fake_data arrays.
177  */
178 void xe_pci_fake_data_desc(const struct xe_pci_fake_data *param, char *desc)
179 {
180 	if (param->graphics_verx100 || param->media_verx100)
181 		snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s%s%s %u.%02u(%s)%s%s %u.%02u(%s)%s%s%s%s",
182 			 lookup_platform_name(param->platform),
183 			 subplatform_prefix(param->subplatform),
184 			 lookup_subplatform_name(param->platform, param->subplatform),
185 			 param->graphics_verx100 / 100, param->graphics_verx100 % 100,
186 			 lookup_graphics_name(param->graphics_verx100),
187 			 step_prefix(param->step.graphics), step_name(param->step.graphics),
188 			 param->media_verx100 / 100, param->media_verx100 % 100,
189 			 lookup_media_name(param->media_verx100),
190 			 step_prefix(param->step.media), step_name(param->step.media),
191 			 sriov_prefix(param->sriov_mode), sriov_name(param->sriov_mode));
192 	else
193 		snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s%s%s%s%s%s%s",
194 			 lookup_platform_name(param->platform),
195 			 subplatform_prefix(param->subplatform),
196 			 lookup_subplatform_name(param->platform, param->subplatform),
197 			 step_prefix(param->step.graphics), step_name(param->step.graphics),
198 			 sriov_prefix(param->sriov_mode), sriov_name(param->sriov_mode));
199 }
200 EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_data_desc);
201 
202 static void xe_ip_kunit_desc(const struct xe_ip *param, char *desc)
203 {
204 	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%u.%02u %s",
205 		 param->verx100 / 100, param->verx100 % 100, param->name);
206 }
207 
208 /*
209  * Pre-GMDID Graphics and Media IPs definitions.
210  *
211  * Mimic the way GMDID IPs are declared so the same
212  * param generator can be used for both
213  */
214 static const struct xe_ip pre_gmdid_graphics_ips[] = {
215 	{ 1200, "Xe_LP", &graphics_xelp },
216 	{ 1210, "Xe_LP+", &graphics_xelp },
217 	{ 1255, "Xe_HPG", &graphics_xehpg },
218 	{ 1260, "Xe_HPC", &graphics_xehpc },
219 };
220 
221 static const struct xe_ip pre_gmdid_media_ips[] = {
222 	{ 1200, "Xe_M", &media_xem },
223 	{ 1255, "Xe_HPM", &media_xem },
224 };
225 
226 KUNIT_ARRAY_PARAM(pre_gmdid_graphics_ip, pre_gmdid_graphics_ips, xe_ip_kunit_desc);
227 KUNIT_ARRAY_PARAM(pre_gmdid_media_ip, pre_gmdid_media_ips, xe_ip_kunit_desc);
228 
229 KUNIT_ARRAY_PARAM(graphics_ip, graphics_ips, xe_ip_kunit_desc);
230 KUNIT_ARRAY_PARAM(media_ip, media_ips, xe_ip_kunit_desc);
231 
232 static void xe_pci_id_kunit_desc(const struct pci_device_id *param, char *desc)
233 {
234 	const struct xe_device_desc *dev_desc =
235 		(const struct xe_device_desc *)param->driver_data;
236 
237 	if (dev_desc)
238 		snprintf(desc, KUNIT_PARAM_DESC_SIZE, "0x%X (%s)",
239 			 param->device, dev_desc->platform_name);
240 }
241 
242 KUNIT_ARRAY_PARAM(pci_id, pciidlist, xe_pci_id_kunit_desc);
243 
244 /**
245  * xe_pci_graphics_ip_gen_param - Generate graphics struct xe_ip parameters
246  * @test: test context object
247  * @prev: the pointer to the previous parameter to iterate from or NULL
248  * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
249  *
250  * This function prepares struct xe_ip parameter.
251  *
252  * To be used only as a parameter generator function in &KUNIT_CASE_PARAM.
253  *
254  * Return: pointer to the next parameter or NULL if no more parameters
255  */
256 const void *xe_pci_graphics_ip_gen_param(struct kunit *test, const void *prev, char *desc)
257 {
258 	const void *next = pre_gmdid_graphics_ip_gen_params(test, prev, desc);
259 
260 	if (next)
261 		return next;
262 	if (is_insidevar(prev, pre_gmdid_graphics_ips))
263 		prev = NULL;
264 
265 	return graphics_ip_gen_params(test, prev, desc);
266 }
267 EXPORT_SYMBOL_IF_KUNIT(xe_pci_graphics_ip_gen_param);
268 
269 /**
270  * xe_pci_media_ip_gen_param - Generate media struct xe_ip parameters
271  * @test: test context object
272  * @prev: the pointer to the previous parameter to iterate from or NULL
273  * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
274  *
275  * This function prepares struct xe_ip parameter.
276  *
277  * To be used only as a parameter generator function in &KUNIT_CASE_PARAM.
278  *
279  * Return: pointer to the next parameter or NULL if no more parameters
280  */
281 const void *xe_pci_media_ip_gen_param(struct kunit *test, const void *prev, char *desc)
282 {
283 	const void *next = pre_gmdid_media_ip_gen_params(test, prev, desc);
284 
285 	if (next)
286 		return next;
287 	if (is_insidevar(prev, pre_gmdid_media_ips))
288 		prev = NULL;
289 
290 	return media_ip_gen_params(test, prev, desc);
291 }
292 EXPORT_SYMBOL_IF_KUNIT(xe_pci_media_ip_gen_param);
293 
294 /**
295  * xe_pci_id_gen_param - Generate struct pci_device_id parameters
296  * @test: test context object
297  * @prev: the pointer to the previous parameter to iterate from or NULL
298  * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
299  *
300  * This function prepares struct pci_device_id parameter.
301  *
302  * To be used only as a parameter generator function in &KUNIT_CASE_PARAM.
303  *
304  * Return: pointer to the next parameter or NULL if no more parameters
305  */
306 const void *xe_pci_id_gen_param(struct kunit *test, const void *prev, char *desc)
307 {
308 	const struct pci_device_id *pci = pci_id_gen_params(test, prev, desc);
309 
310 	return pci->driver_data ? pci : NULL;
311 }
312 EXPORT_SYMBOL_IF_KUNIT(xe_pci_id_gen_param);
313 
314 static void fake_init_devid(struct xe_device *xe)
315 {
316 	/* Nothing to do, just keep zero. */
317 }
318 
319 static int fake_read_gmdid(struct xe_device *xe, enum xe_gmdid_type type,
320 			   u32 *ver, u32 *revid)
321 {
322 	struct kunit *test = kunit_get_current_test();
323 	struct xe_pci_fake_data *data = test->priv;
324 
325 	if (type == GMDID_MEDIA) {
326 		*ver = data->media_verx100;
327 		*revid = xe_step_to_gmdid(data->step.media);
328 	} else {
329 		*ver = data->graphics_verx100;
330 		*revid = xe_step_to_gmdid(data->step.graphics);
331 	}
332 
333 	return 0;
334 }
335 
336 static void fake_xe_info_probe_tile_count(struct xe_device *xe)
337 {
338 	/* Nothing to do, just use the statically defined value. */
339 }
340 
341 int xe_pci_fake_device_init(struct xe_device *xe)
342 {
343 	struct kunit *test = kunit_get_current_test();
344 	struct xe_pci_fake_data *data = test->priv;
345 	const struct pci_device_id *ent = pciidlist;
346 	const struct xe_device_desc *desc;
347 	const struct xe_subplatform_desc *subplatform_desc;
348 
349 	if (!data) {
350 		desc = (const void *)ent->driver_data;
351 		subplatform_desc = NULL;
352 		goto done;
353 	}
354 
355 	for (ent = pciidlist; ent->device; ent++) {
356 		desc = (const void *)ent->driver_data;
357 		if (desc->platform == data->platform)
358 			break;
359 	}
360 
361 	if (!ent->device)
362 		return -ENODEV;
363 
364 	for (subplatform_desc = desc->subplatforms;
365 	     subplatform_desc && subplatform_desc->subplatform;
366 	     subplatform_desc++)
367 		if (subplatform_desc->subplatform == data->subplatform)
368 			break;
369 
370 	if (data->subplatform != XE_SUBPLATFORM_NONE && !subplatform_desc)
371 		return -ENODEV;
372 
373 done:
374 	xe->sriov.__mode = data && data->sriov_mode ?
375 			   data->sriov_mode : XE_SRIOV_MODE_NONE;
376 
377 	kunit_activate_static_stub(test, init_devid, fake_init_devid);
378 	kunit_activate_static_stub(test, read_gmdid, fake_read_gmdid);
379 	kunit_activate_static_stub(test, xe_info_probe_tile_count,
380 				   fake_xe_info_probe_tile_count);
381 
382 	xe_info_init_early(xe, desc, subplatform_desc);
383 	xe_info_init(xe, desc);
384 
385 	return 0;
386 }
387 EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_device_init);
388 
389 /**
390  * xe_pci_live_device_gen_param - Helper to iterate Xe devices as KUnit parameters
391  * @test: test context object
392  * @prev: the previously returned value, or NULL for the first iteration
393  * @desc: the buffer for a parameter name
394  *
395  * Iterates over the available Xe devices on the system. Uses the device name
396  * as the parameter name.
397  *
398  * To be used only as a parameter generator function in &KUNIT_CASE_PARAM.
399  *
400  * Return: pointer to the next &struct xe_device ready to be used as a parameter
401  *         or NULL if there are no more Xe devices on the system.
402  */
403 const void *xe_pci_live_device_gen_param(struct kunit *test, const void *prev, char *desc)
404 {
405 	const struct xe_device *xe = prev;
406 	struct device *dev = xe ? xe->drm.dev : NULL;
407 	struct device *next;
408 
409 	next = driver_find_next_device(&xe_pci_driver.driver, dev);
410 	if (dev)
411 		put_device(dev);
412 	if (!next)
413 		return NULL;
414 
415 	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s", dev_name(next));
416 	return pdev_to_xe_device(to_pci_dev(next));
417 }
418 EXPORT_SYMBOL_IF_KUNIT(xe_pci_live_device_gen_param);
419