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 int fake_probe_info(struct xe_device *xe, 315 const struct xe_device_desc *desc, 316 struct xe_pci_fake_data *data, 317 struct xe_probed_info *probed_info) 318 { 319 probed_info->tile_count = 1 + desc->max_remote_tiles; 320 321 if (!data || desc->pre_gmdid_graphics_ip) { 322 probed_info->graphics_ip = desc->pre_gmdid_graphics_ip; 323 probed_info->media_ip = desc->pre_gmdid_media_ip; 324 } else { 325 probed_info->graphics_ip = find_graphics_ip(data->graphics_verx100); 326 327 if (data->media_verx100) { 328 probed_info->media_ip = find_media_ip(data->media_verx100); 329 xe_assert(xe, probed_info->media_ip); 330 } 331 } 332 333 xe_assert(xe, probed_info->graphics_ip); 334 if (!probed_info->graphics_ip) 335 return -ENODEV; 336 337 if (data) 338 probed_info->step = data->step; 339 340 return 0; 341 } 342 343 int xe_pci_fake_device_init(struct xe_device *xe) 344 { 345 struct kunit *test = kunit_get_current_test(); 346 struct xe_pci_fake_data *data = test->priv; 347 struct xe_probed_info probed_info = {}; 348 const struct pci_device_id *ent = pciidlist; 349 const struct xe_device_desc *desc; 350 const struct xe_subplatform_desc *subplatform_desc; 351 int err; 352 353 if (!data) { 354 desc = (const void *)ent->driver_data; 355 subplatform_desc = NULL; 356 goto done; 357 } 358 359 for (ent = pciidlist; ent->device; ent++) { 360 desc = (const void *)ent->driver_data; 361 if (desc->platform == data->platform) 362 break; 363 } 364 365 if (!ent->device) 366 return -ENODEV; 367 368 for (subplatform_desc = desc->subplatforms; 369 subplatform_desc && subplatform_desc->subplatform; 370 subplatform_desc++) 371 if (subplatform_desc->subplatform == data->subplatform) 372 break; 373 374 if (data->subplatform != XE_SUBPLATFORM_NONE && !subplatform_desc) 375 return -ENODEV; 376 377 done: 378 xe->sriov.__mode = data && data->sriov_mode ? 379 data->sriov_mode : XE_SRIOV_MODE_NONE; 380 381 err = fake_probe_info(xe, desc, data, &probed_info); 382 if (err) 383 return err; 384 385 xe_info_init_early(xe, desc, subplatform_desc, &probed_info); 386 xe_info_init(xe, desc, &probed_info); 387 388 return 0; 389 } 390 EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_device_init); 391 392 /** 393 * xe_pci_live_device_gen_param - Helper to iterate Xe devices as KUnit parameters 394 * @test: test context object 395 * @prev: the previously returned value, or NULL for the first iteration 396 * @desc: the buffer for a parameter name 397 * 398 * Iterates over the available Xe devices on the system. Uses the device name 399 * as the parameter name. 400 * 401 * To be used only as a parameter generator function in &KUNIT_CASE_PARAM. 402 * 403 * Return: pointer to the next &struct xe_device ready to be used as a parameter 404 * or NULL if there are no more Xe devices on the system. 405 */ 406 const void *xe_pci_live_device_gen_param(struct kunit *test, const void *prev, char *desc) 407 { 408 const struct xe_device *xe = prev; 409 struct device *dev = xe ? xe->drm.dev : NULL; 410 struct device *next; 411 412 next = driver_find_next_device(&xe_pci_driver.driver, dev); 413 if (dev) 414 put_device(dev); 415 if (!next) 416 return NULL; 417 418 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s", dev_name(next)); 419 return pdev_to_xe_device(to_pci_dev(next)); 420 } 421 EXPORT_SYMBOL_IF_KUNIT(xe_pci_live_device_gen_param); 422