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/visibility.h> 13 14 #define PLATFORM_CASE(platform__, graphics_step__) \ 15 { \ 16 .platform = XE_ ## platform__, \ 17 .subplatform = XE_SUBPLATFORM_NONE, \ 18 .step = { .graphics = STEP_ ## graphics_step__ } \ 19 } 20 21 #define SUBPLATFORM_CASE(platform__, subplatform__, graphics_step__) \ 22 { \ 23 .platform = XE_ ## platform__, \ 24 .subplatform = XE_SUBPLATFORM_ ## platform__ ## _ ## subplatform__, \ 25 .step = { .graphics = STEP_ ## graphics_step__ } \ 26 } 27 28 #define GMDID_CASE(platform__, graphics_verx100__, graphics_step__, \ 29 media_verx100__, media_step__) \ 30 { \ 31 .platform = XE_ ## platform__, \ 32 .subplatform = XE_SUBPLATFORM_NONE, \ 33 .graphics_verx100 = graphics_verx100__, \ 34 .media_verx100 = media_verx100__, \ 35 .step = { .graphics = STEP_ ## graphics_step__, \ 36 .media = STEP_ ## media_step__ } \ 37 } 38 39 static const struct xe_pci_fake_data cases[] = { 40 PLATFORM_CASE(TIGERLAKE, B0), 41 PLATFORM_CASE(DG1, A0), 42 PLATFORM_CASE(DG1, B0), 43 PLATFORM_CASE(ALDERLAKE_S, A0), 44 PLATFORM_CASE(ALDERLAKE_S, B0), 45 PLATFORM_CASE(ALDERLAKE_S, C0), 46 PLATFORM_CASE(ALDERLAKE_S, D0), 47 PLATFORM_CASE(ALDERLAKE_P, A0), 48 PLATFORM_CASE(ALDERLAKE_P, B0), 49 PLATFORM_CASE(ALDERLAKE_P, C0), 50 SUBPLATFORM_CASE(ALDERLAKE_S, RPLS, D0), 51 SUBPLATFORM_CASE(ALDERLAKE_P, RPLU, E0), 52 SUBPLATFORM_CASE(DG2, G10, C0), 53 SUBPLATFORM_CASE(DG2, G11, B1), 54 SUBPLATFORM_CASE(DG2, G12, A1), 55 GMDID_CASE(METEORLAKE, 1270, A0, 1300, A0), 56 GMDID_CASE(METEORLAKE, 1271, A0, 1300, A0), 57 GMDID_CASE(METEORLAKE, 1274, A0, 1300, A0), 58 GMDID_CASE(LUNARLAKE, 2004, A0, 2000, A0), 59 GMDID_CASE(LUNARLAKE, 2004, B0, 2000, A0), 60 GMDID_CASE(BATTLEMAGE, 2001, A0, 1301, A1), 61 GMDID_CASE(PANTHERLAKE, 3000, A0, 3000, A0), 62 }; 63 64 KUNIT_ARRAY_PARAM(platform, cases, xe_pci_fake_data_desc); 65 66 /** 67 * xe_pci_fake_data_gen_params - Generate struct xe_pci_fake_data parameters 68 * @test: test context object 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 */ 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 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 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 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 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 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 128 static const char *subplatform_prefix(enum xe_subplatform s) 129 { 130 return s == XE_SUBPLATFORM_NONE ? "" : " "; 131 } 132 133 static const char *step_prefix(enum intel_step step) 134 { 135 return step == STEP_NONE ? "" : " "; 136 } 137 138 static const char *step_name(enum intel_step step) 139 { 140 return step == STEP_NONE ? "" : xe_step_name(step); 141 } 142 143 static const char *sriov_prefix(enum xe_sriov_mode mode) 144 { 145 return mode <= XE_SRIOV_MODE_NONE ? "" : " "; 146 } 147 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 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 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 */ 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 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 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 * @test: test context object 246 * @prev: the pointer to the previous parameter to iterate from or NULL 247 * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE 248 * 249 * This function prepares struct xe_ip parameter. 250 * 251 * To be used only as a parameter generator function in &KUNIT_CASE_PARAM. 252 * 253 * Return: pointer to the next parameter or NULL if no more parameters 254 */ 255 const void *xe_pci_graphics_ip_gen_param(struct kunit *test, const void *prev, char *desc) 256 { 257 const void *next = pre_gmdid_graphics_ip_gen_params(test, prev, desc); 258 259 if (next) 260 return next; 261 if (is_insidevar(prev, pre_gmdid_graphics_ips)) 262 prev = NULL; 263 264 return graphics_ip_gen_params(test, prev, desc); 265 } 266 EXPORT_SYMBOL_IF_KUNIT(xe_pci_graphics_ip_gen_param); 267 268 /** 269 * xe_pci_media_ip_gen_param - Generate media struct xe_ip parameters 270 * @test: test context object 271 * @prev: the pointer to the previous parameter to iterate from or NULL 272 * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE 273 * 274 * This function prepares struct xe_ip parameter. 275 * 276 * To be used only as a parameter generator function in &KUNIT_CASE_PARAM. 277 * 278 * Return: pointer to the next parameter or NULL if no more parameters 279 */ 280 const void *xe_pci_media_ip_gen_param(struct kunit *test, const void *prev, char *desc) 281 { 282 const void *next = pre_gmdid_media_ip_gen_params(test, prev, desc); 283 284 if (next) 285 return next; 286 if (is_insidevar(prev, pre_gmdid_media_ips)) 287 prev = NULL; 288 289 return media_ip_gen_params(test, prev, desc); 290 } 291 EXPORT_SYMBOL_IF_KUNIT(xe_pci_media_ip_gen_param); 292 293 /** 294 * xe_pci_id_gen_param - Generate struct pci_device_id parameters 295 * @test: test context object 296 * @prev: the pointer to the previous parameter to iterate from or NULL 297 * @desc: output buffer with minimum size of KUNIT_PARAM_DESC_SIZE 298 * 299 * This function prepares struct pci_device_id parameter. 300 * 301 * To be used only as a parameter generator function in &KUNIT_CASE_PARAM. 302 * 303 * Return: pointer to the next parameter or NULL if no more parameters 304 */ 305 const void *xe_pci_id_gen_param(struct kunit *test, const void *prev, char *desc) 306 { 307 const struct pci_device_id *pci = pci_id_gen_params(test, prev, desc); 308 309 return pci->driver_data ? pci : NULL; 310 } 311 EXPORT_SYMBOL_IF_KUNIT(xe_pci_id_gen_param); 312 313 static int fake_probe_info(struct xe_device *xe, 314 const struct xe_device_desc *desc, 315 struct xe_pci_fake_data *data, 316 struct xe_probed_info *probed_info) 317 { 318 probed_info->tile_count = 1 + desc->max_remote_tiles; 319 320 if (!data || desc->pre_gmdid_graphics_ip) { 321 probed_info->graphics_ip = desc->pre_gmdid_graphics_ip; 322 probed_info->media_ip = desc->pre_gmdid_media_ip; 323 } else { 324 probed_info->graphics_ip = find_graphics_ip(data->graphics_verx100); 325 326 if (data->media_verx100) { 327 probed_info->media_ip = find_media_ip(data->media_verx100); 328 xe_assert(xe, probed_info->media_ip); 329 } 330 } 331 332 xe_assert(xe, probed_info->graphics_ip); 333 if (!probed_info->graphics_ip) 334 return -ENODEV; 335 336 if (data) 337 probed_info->step = data->step; 338 339 return 0; 340 } 341 342 int xe_pci_fake_device_init(struct xe_device *xe) 343 { 344 struct kunit *test = kunit_get_current_test(); 345 struct xe_pci_fake_data *data = test->priv; 346 struct xe_probed_info probed_info = {}; 347 const struct pci_device_id *ent = pciidlist; 348 const struct xe_device_desc *desc; 349 const struct xe_subplatform_desc *subplatform_desc; 350 int err; 351 352 if (!data) { 353 desc = (const void *)ent->driver_data; 354 subplatform_desc = NULL; 355 goto done; 356 } 357 358 for (ent = pciidlist; ent->device; ent++) { 359 desc = (const void *)ent->driver_data; 360 if (desc->platform == data->platform) 361 break; 362 } 363 364 if (!ent->device) 365 return -ENODEV; 366 367 for (subplatform_desc = desc->subplatforms; 368 subplatform_desc && subplatform_desc->subplatform; 369 subplatform_desc++) 370 if (subplatform_desc->subplatform == data->subplatform) 371 break; 372 373 if (data->subplatform != XE_SUBPLATFORM_NONE && !subplatform_desc) 374 return -ENODEV; 375 376 done: 377 xe->sriov.__mode = data && data->sriov_mode ? 378 data->sriov_mode : XE_SRIOV_MODE_NONE; 379 380 err = fake_probe_info(xe, desc, data, &probed_info); 381 if (err) 382 return err; 383 384 xe_info_init_early(xe, desc, subplatform_desc, &probed_info); 385 xe_info_init(xe, desc, &probed_info); 386 387 return 0; 388 } 389 EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_device_init); 390 391 /** 392 * xe_pci_live_device_gen_param - Helper to iterate Xe devices as KUnit parameters 393 * @test: test context object 394 * @prev: the previously returned value, or NULL for the first iteration 395 * @desc: the buffer for a parameter name 396 * 397 * Iterates over the available Xe devices on the system. Uses the device name 398 * as the parameter name. 399 * 400 * To be used only as a parameter generator function in &KUNIT_CASE_PARAM. 401 * 402 * Return: pointer to the next &struct xe_device ready to be used as a parameter 403 * or NULL if there are no more Xe devices on the system. 404 */ 405 const void *xe_pci_live_device_gen_param(struct kunit *test, const void *prev, char *desc) 406 { 407 const struct xe_device *xe = prev; 408 struct device *dev = xe ? xe->drm.dev : NULL; 409 struct device *next; 410 411 next = driver_find_next_device(&xe_pci_driver.driver, dev); 412 if (dev) 413 put_device(dev); 414 if (!next) 415 return NULL; 416 417 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s", dev_name(next)); 418 return pdev_to_xe_device(to_pci_dev(next)); 419 } 420 EXPORT_SYMBOL_IF_KUNIT(xe_pci_live_device_gen_param); 421