File Index
Files and directories
Sign in
FILE

xe_pci.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/xe/tests/xe_pci.c C
  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
 40static 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
 65KUNIT_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 */
 79const 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}
 83EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_data_gen_params);
 84
 85static 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
 98static 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
110static 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
117static 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
124static 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
129static const char *subplatform_prefix(enum xe_subplatform s)
130{
131	return s == XE_SUBPLATFORM_NONE ? "" : " ";
132}
133
134static const char *step_prefix(enum xe_step step)
135{
136	return step == STEP_NONE ? "" : " ";
137}
138
139static const char *step_name(enum xe_step step)
140{
141	return step == STEP_NONE ? "" : xe_step_name(step);
142}
143
144static const char *sriov_prefix(enum xe_sriov_mode mode)
145{
146	return mode <= XE_SRIOV_MODE_NONE ? "" : " ";
147}
148
149static 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
154static 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
161static 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 */
178void 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}
200EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_data_desc);
201
202static 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 */
214static 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
221static const struct xe_ip pre_gmdid_media_ips[] = {
222	{ 1200, "Xe_M", &media_xem },
223	{ 1255, "Xe_HPM", &media_xem },
224};
225
226KUNIT_ARRAY_PARAM(pre_gmdid_graphics_ip, pre_gmdid_graphics_ips, xe_ip_kunit_desc);
227KUNIT_ARRAY_PARAM(pre_gmdid_media_ip, pre_gmdid_media_ips, xe_ip_kunit_desc);
228
229KUNIT_ARRAY_PARAM(graphics_ip, graphics_ips, xe_ip_kunit_desc);
230KUNIT_ARRAY_PARAM(media_ip, media_ips, xe_ip_kunit_desc);
231
232static 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
242KUNIT_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 */
256const 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}
267EXPORT_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 */
281const 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}
292EXPORT_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 */
306const 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}
312EXPORT_SYMBOL_IF_KUNIT(xe_pci_id_gen_param);
313
314static int fake_read_gmdid(struct xe_device *xe, enum xe_gmdid_type type,
315			   u32 *ver, u32 *revid)
316{
317	struct kunit *test = kunit_get_current_test();
318	struct xe_pci_fake_data *data = test->priv;
319
320	if (type == GMDID_MEDIA) {
321		*ver = data->media_verx100;
322		*revid = xe_step_to_gmdid(data->step.media);
323	} else {
324		*ver = data->graphics_verx100;
325		*revid = xe_step_to_gmdid(data->step.graphics);
326	}
327
328	return 0;
329}
330
331static void fake_xe_info_probe_tile_count(struct xe_device *xe)
332{
333	/* Nothing to do, just use the statically defined value. */
334}
335
336int xe_pci_fake_device_init(struct xe_device *xe)
337{
338	struct kunit *test = kunit_get_current_test();
339	struct xe_pci_fake_data *data = test->priv;
340	const struct pci_device_id *ent = pciidlist;
341	const struct xe_device_desc *desc;
342	const struct xe_subplatform_desc *subplatform_desc;
343
344	if (!data) {
345		desc = (const void *)ent->driver_data;
346		subplatform_desc = NULL;
347		goto done;
348	}
349
350	for (ent = pciidlist; ent->device; ent++) {
351		desc = (const void *)ent->driver_data;
352		if (desc->platform == data->platform)
353			break;
354	}
355
356	if (!ent->device)
357		return -ENODEV;
358
359	for (subplatform_desc = desc->subplatforms;
360	     subplatform_desc && subplatform_desc->subplatform;
361	     subplatform_desc++)
362		if (subplatform_desc->subplatform == data->subplatform)
363			break;
364
365	if (data->subplatform != XE_SUBPLATFORM_NONE && !subplatform_desc)
366		return -ENODEV;
367
368done:
369	xe->sriov.__mode = data && data->sriov_mode ?
370			   data->sriov_mode : XE_SRIOV_MODE_NONE;
371
372	kunit_activate_static_stub(test, read_gmdid, fake_read_gmdid);
373	kunit_activate_static_stub(test, xe_info_probe_tile_count,
374				   fake_xe_info_probe_tile_count);
375
376	xe_info_init_early(xe, desc, subplatform_desc);
377	xe_info_init(xe, desc);
378
379	return 0;
380}
381EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_device_init);
382
383/**
384 * xe_pci_live_device_gen_param - Helper to iterate Xe devices as KUnit parameters
385 * @test: test context object
386 * @prev: the previously returned value, or NULL for the first iteration
387 * @desc: the buffer for a parameter name
388 *
389 * Iterates over the available Xe devices on the system. Uses the device name
390 * as the parameter name.
391 *
392 * To be used only as a parameter generator function in &KUNIT_CASE_PARAM.
393 *
394 * Return: pointer to the next &struct xe_device ready to be used as a parameter
395 *         or NULL if there are no more Xe devices on the system.
396 */
397const void *xe_pci_live_device_gen_param(struct kunit *test, const void *prev, char *desc)
398{
399	const struct xe_device *xe = prev;
400	struct device *dev = xe ? xe->drm.dev : NULL;
401	struct device *next;
402
403	next = driver_find_next_device(&xe_pci_driver.driver, dev);
404	if (dev)
405		put_device(dev);
406	if (!next)
407		return NULL;
408
409	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s", dev_name(next));
410	return pdev_to_xe_device(to_pci_dev(next));
411}
412EXPORT_SYMBOL_IF_KUNIT(xe_pci_live_device_gen_param);
~/ Read-only file preview.