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 * @prev: the pointer to the previous parameter to iterate from or NULL
70 * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
71 *
72 * This function prepares struct xe_pci_fake_data parameter.
73 *
74 * To be used only as a parameter generator function in &KUNIT_CASE_PARAM.
75 *
76 * Return: pointer to the next parameter or NULL if no more parameters
77 */
xe_pci_fake_data_gen_params(struct kunit * test,const void * prev,char * desc)78 const void *xe_pci_fake_data_gen_params(struct kunit *test, const void *prev, char *desc)
79 {
80 return platform_gen_params(test, prev, desc);
81 }
82 EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_data_gen_params);
83
lookup_desc(enum xe_platform p)84 static const struct xe_device_desc *lookup_desc(enum xe_platform p)
85 {
86 const struct xe_device_desc *desc;
87 const struct pci_device_id *ids;
88
89 for (ids = pciidlist; ids->driver_data; ids++) {
90 desc = (const void *)ids->driver_data;
91 if (desc->platform == p)
92 return desc;
93 }
94 return NULL;
95 }
96
lookup_sub_desc(enum xe_platform p,enum xe_subplatform s)97 static const struct xe_subplatform_desc *lookup_sub_desc(enum xe_platform p, enum xe_subplatform s)
98 {
99 const struct xe_device_desc *desc = lookup_desc(p);
100 const struct xe_subplatform_desc *spd;
101
102 if (desc && desc->subplatforms)
103 for (spd = desc->subplatforms; spd->subplatform; spd++)
104 if (spd->subplatform == s)
105 return spd;
106 return NULL;
107 }
108
lookup_platform_name(enum xe_platform p)109 static const char *lookup_platform_name(enum xe_platform p)
110 {
111 const struct xe_device_desc *desc = lookup_desc(p);
112
113 return desc ? desc->platform_name : "INVALID";
114 }
115
__lookup_subplatform_name(enum xe_platform p,enum xe_subplatform s)116 static const char *__lookup_subplatform_name(enum xe_platform p, enum xe_subplatform s)
117 {
118 const struct xe_subplatform_desc *desc = lookup_sub_desc(p, s);
119
120 return desc ? desc->name : "INVALID";
121 }
122
lookup_subplatform_name(enum xe_platform p,enum xe_subplatform s)123 static const char *lookup_subplatform_name(enum xe_platform p, enum xe_subplatform s)
124 {
125 return s == XE_SUBPLATFORM_NONE ? "" : __lookup_subplatform_name(p, s);
126 }
127
subplatform_prefix(enum xe_subplatform s)128 static const char *subplatform_prefix(enum xe_subplatform s)
129 {
130 return s == XE_SUBPLATFORM_NONE ? "" : " ";
131 }
132
step_prefix(enum xe_step step)133 static const char *step_prefix(enum xe_step step)
134 {
135 return step == STEP_NONE ? "" : " ";
136 }
137
step_name(enum xe_step step)138 static const char *step_name(enum xe_step step)
139 {
140 return step == STEP_NONE ? "" : xe_step_name(step);
141 }
142
sriov_prefix(enum xe_sriov_mode mode)143 static const char *sriov_prefix(enum xe_sriov_mode mode)
144 {
145 return mode <= XE_SRIOV_MODE_NONE ? "" : " ";
146 }
147
sriov_name(enum xe_sriov_mode mode)148 static const char *sriov_name(enum xe_sriov_mode mode)
149 {
150 return mode <= XE_SRIOV_MODE_NONE ? "" : xe_sriov_mode_to_string(mode);
151 }
152
lookup_graphics_name(unsigned int verx100)153 static const char *lookup_graphics_name(unsigned int verx100)
154 {
155 const struct xe_ip *ip = find_graphics_ip(verx100);
156
157 return ip ? ip->name : "";
158 }
159
lookup_media_name(unsigned int verx100)160 static const char *lookup_media_name(unsigned int verx100)
161 {
162 const struct xe_ip *ip = find_media_ip(verx100);
163
164 return ip ? ip->name : "";
165 }
166
167 /**
168 * xe_pci_fake_data_desc - Describe struct xe_pci_fake_data parameter
169 * @param: the &struct xe_pci_fake_data parameter to describe
170 * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
171 *
172 * This function prepares description of the struct xe_pci_fake_data parameter.
173 *
174 * It is tailored for use in parameterized KUnit tests where parameter generator
175 * is based on the struct xe_pci_fake_data arrays.
176 */
xe_pci_fake_data_desc(const struct xe_pci_fake_data * param,char * desc)177 void xe_pci_fake_data_desc(const struct xe_pci_fake_data *param, char *desc)
178 {
179 if (param->graphics_verx100 || param->media_verx100)
180 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s%s%s %u.%02u(%s)%s%s %u.%02u(%s)%s%s%s%s",
181 lookup_platform_name(param->platform),
182 subplatform_prefix(param->subplatform),
183 lookup_subplatform_name(param->platform, param->subplatform),
184 param->graphics_verx100 / 100, param->graphics_verx100 % 100,
185 lookup_graphics_name(param->graphics_verx100),
186 step_prefix(param->step.graphics), step_name(param->step.graphics),
187 param->media_verx100 / 100, param->media_verx100 % 100,
188 lookup_media_name(param->media_verx100),
189 step_prefix(param->step.media), step_name(param->step.media),
190 sriov_prefix(param->sriov_mode), sriov_name(param->sriov_mode));
191 else
192 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s%s%s%s%s%s%s",
193 lookup_platform_name(param->platform),
194 subplatform_prefix(param->subplatform),
195 lookup_subplatform_name(param->platform, param->subplatform),
196 step_prefix(param->step.graphics), step_name(param->step.graphics),
197 sriov_prefix(param->sriov_mode), sriov_name(param->sriov_mode));
198 }
199 EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_data_desc);
200
xe_ip_kunit_desc(const struct xe_ip * param,char * desc)201 static void xe_ip_kunit_desc(const struct xe_ip *param, char *desc)
202 {
203 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%u.%02u %s",
204 param->verx100 / 100, param->verx100 % 100, param->name);
205 }
206
207 /*
208 * Pre-GMDID Graphics and Media IPs definitions.
209 *
210 * Mimic the way GMDID IPs are declared so the same
211 * param generator can be used for both
212 */
213 static const struct xe_ip pre_gmdid_graphics_ips[] = {
214 { 1200, "Xe_LP", &graphics_xelp },
215 { 1210, "Xe_LP+", &graphics_xelp },
216 { 1255, "Xe_HPG", &graphics_xehpg },
217 { 1260, "Xe_HPC", &graphics_xehpc },
218 };
219
220 static const struct xe_ip pre_gmdid_media_ips[] = {
221 { 1200, "Xe_M", &media_xem },
222 { 1255, "Xe_HPM", &media_xem },
223 };
224
225 KUNIT_ARRAY_PARAM(pre_gmdid_graphics_ip, pre_gmdid_graphics_ips, xe_ip_kunit_desc);
226 KUNIT_ARRAY_PARAM(pre_gmdid_media_ip, pre_gmdid_media_ips, xe_ip_kunit_desc);
227
228 KUNIT_ARRAY_PARAM(graphics_ip, graphics_ips, xe_ip_kunit_desc);
229 KUNIT_ARRAY_PARAM(media_ip, media_ips, xe_ip_kunit_desc);
230
xe_pci_id_kunit_desc(const struct pci_device_id * param,char * desc)231 static void xe_pci_id_kunit_desc(const struct pci_device_id *param, char *desc)
232 {
233 const struct xe_device_desc *dev_desc =
234 (const struct xe_device_desc *)param->driver_data;
235
236 if (dev_desc)
237 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "0x%X (%s)",
238 param->device, dev_desc->platform_name);
239 }
240
241 KUNIT_ARRAY_PARAM(pci_id, pciidlist, xe_pci_id_kunit_desc);
242
243 /**
244 * xe_pci_graphics_ip_gen_param - Generate graphics struct xe_ip parameters
245 * @prev: the pointer to the previous parameter to iterate from or NULL
246 * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
247 *
248 * This function prepares struct xe_ip parameter.
249 *
250 * To be used only as a parameter generator function in &KUNIT_CASE_PARAM.
251 *
252 * Return: pointer to the next parameter or NULL if no more parameters
253 */
xe_pci_graphics_ip_gen_param(struct kunit * test,const void * prev,char * desc)254 const void *xe_pci_graphics_ip_gen_param(struct kunit *test, const void *prev, char *desc)
255 {
256 const void *next = pre_gmdid_graphics_ip_gen_params(test, prev, desc);
257
258 if (next)
259 return next;
260 if (is_insidevar(prev, pre_gmdid_graphics_ips))
261 prev = NULL;
262
263 return graphics_ip_gen_params(test, prev, desc);
264 }
265 EXPORT_SYMBOL_IF_KUNIT(xe_pci_graphics_ip_gen_param);
266
267 /**
268 * xe_pci_media_ip_gen_param - Generate media struct xe_ip parameters
269 * @prev: the pointer to the previous parameter to iterate from or NULL
270 * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
271 *
272 * This function prepares struct xe_ip parameter.
273 *
274 * To be used only as a parameter generator function in &KUNIT_CASE_PARAM.
275 *
276 * Return: pointer to the next parameter or NULL if no more parameters
277 */
xe_pci_media_ip_gen_param(struct kunit * test,const void * prev,char * desc)278 const void *xe_pci_media_ip_gen_param(struct kunit *test, const void *prev, char *desc)
279 {
280 const void *next = pre_gmdid_media_ip_gen_params(test, prev, desc);
281
282 if (next)
283 return next;
284 if (is_insidevar(prev, pre_gmdid_media_ips))
285 prev = NULL;
286
287 return media_ip_gen_params(test, prev, desc);
288 }
289 EXPORT_SYMBOL_IF_KUNIT(xe_pci_media_ip_gen_param);
290
291 /**
292 * xe_pci_id_gen_param - Generate struct pci_device_id parameters
293 * @prev: the pointer to the previous parameter to iterate from or NULL
294 * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE
295 *
296 * This function prepares struct pci_device_id parameter.
297 *
298 * To be used only as a parameter generator function in &KUNIT_CASE_PARAM.
299 *
300 * Return: pointer to the next parameter or NULL if no more parameters
301 */
xe_pci_id_gen_param(struct kunit * test,const void * prev,char * desc)302 const void *xe_pci_id_gen_param(struct kunit *test, const void *prev, char *desc)
303 {
304 const struct pci_device_id *pci = pci_id_gen_params(test, prev, desc);
305
306 return pci->driver_data ? pci : NULL;
307 }
308 EXPORT_SYMBOL_IF_KUNIT(xe_pci_id_gen_param);
309
fake_read_gmdid(struct xe_device * xe,enum xe_gmdid_type type,u32 * ver,u32 * revid)310 static void fake_read_gmdid(struct xe_device *xe, enum xe_gmdid_type type,
311 u32 *ver, u32 *revid)
312 {
313 struct kunit *test = kunit_get_current_test();
314 struct xe_pci_fake_data *data = test->priv;
315
316 if (type == GMDID_MEDIA) {
317 *ver = data->media_verx100;
318 *revid = xe_step_to_gmdid(data->step.media);
319 } else {
320 *ver = data->graphics_verx100;
321 *revid = xe_step_to_gmdid(data->step.graphics);
322 }
323 }
324
fake_xe_info_probe_tile_count(struct xe_device * xe)325 static void fake_xe_info_probe_tile_count(struct xe_device *xe)
326 {
327 /* Nothing to do, just use the statically defined value. */
328 }
329
xe_pci_fake_device_init(struct xe_device * xe)330 int xe_pci_fake_device_init(struct xe_device *xe)
331 {
332 struct kunit *test = kunit_get_current_test();
333 struct xe_pci_fake_data *data = test->priv;
334 const struct pci_device_id *ent = pciidlist;
335 const struct xe_device_desc *desc;
336 const struct xe_subplatform_desc *subplatform_desc;
337
338 if (!data) {
339 desc = (const void *)ent->driver_data;
340 subplatform_desc = NULL;
341 goto done;
342 }
343
344 for (ent = pciidlist; ent->device; ent++) {
345 desc = (const void *)ent->driver_data;
346 if (desc->platform == data->platform)
347 break;
348 }
349
350 if (!ent->device)
351 return -ENODEV;
352
353 for (subplatform_desc = desc->subplatforms;
354 subplatform_desc && subplatform_desc->subplatform;
355 subplatform_desc++)
356 if (subplatform_desc->subplatform == data->subplatform)
357 break;
358
359 if (data->subplatform != XE_SUBPLATFORM_NONE && !subplatform_desc)
360 return -ENODEV;
361
362 done:
363 xe->sriov.__mode = data && data->sriov_mode ?
364 data->sriov_mode : XE_SRIOV_MODE_NONE;
365
366 kunit_activate_static_stub(test, read_gmdid, fake_read_gmdid);
367 kunit_activate_static_stub(test, xe_info_probe_tile_count,
368 fake_xe_info_probe_tile_count);
369
370 xe_info_init_early(xe, desc, subplatform_desc);
371 xe_info_init(xe, desc);
372
373 return 0;
374 }
375 EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_device_init);
376
377 /**
378 * xe_pci_live_device_gen_param - Helper to iterate Xe devices as KUnit parameters
379 * @prev: the previously returned value, or NULL for the first iteration
380 * @desc: the buffer for a parameter name
381 *
382 * Iterates over the available Xe devices on the system. Uses the device name
383 * as the parameter name.
384 *
385 * To be used only as a parameter generator function in &KUNIT_CASE_PARAM.
386 *
387 * Return: pointer to the next &struct xe_device ready to be used as a parameter
388 * or NULL if there are no more Xe devices on the system.
389 */
xe_pci_live_device_gen_param(struct kunit * test,const void * prev,char * desc)390 const void *xe_pci_live_device_gen_param(struct kunit *test, const void *prev, char *desc)
391 {
392 const struct xe_device *xe = prev;
393 struct device *dev = xe ? xe->drm.dev : NULL;
394 struct device *next;
395
396 next = driver_find_next_device(&xe_pci_driver.driver, dev);
397 if (dev)
398 put_device(dev);
399 if (!next)
400 return NULL;
401
402 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s", dev_name(next));
403 return pdev_to_xe_device(to_pci_dev(next));
404 }
405 EXPORT_SYMBOL_IF_KUNIT(xe_pci_live_device_gen_param);
406