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 xe_step step) 135 { 136 return step == STEP_NONE ? "" : " "; 137 } 138 139 static const char *step_name(enum xe_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_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 329 static void fake_xe_info_probe_tile_count(struct xe_device *xe) 330 { 331 /* Nothing to do, just use the statically defined value. */ 332 } 333 334 int xe_pci_fake_device_init(struct xe_device *xe) 335 { 336 struct kunit *test = kunit_get_current_test(); 337 struct xe_pci_fake_data *data = test->priv; 338 const struct pci_device_id *ent = pciidlist; 339 const struct xe_device_desc *desc; 340 const struct xe_subplatform_desc *subplatform_desc; 341 342 if (!data) { 343 desc = (const void *)ent->driver_data; 344 subplatform_desc = NULL; 345 goto done; 346 } 347 348 for (ent = pciidlist; ent->device; ent++) { 349 desc = (const void *)ent->driver_data; 350 if (desc->platform == data->platform) 351 break; 352 } 353 354 if (!ent->device) 355 return -ENODEV; 356 357 for (subplatform_desc = desc->subplatforms; 358 subplatform_desc && subplatform_desc->subplatform; 359 subplatform_desc++) 360 if (subplatform_desc->subplatform == data->subplatform) 361 break; 362 363 if (data->subplatform != XE_SUBPLATFORM_NONE && !subplatform_desc) 364 return -ENODEV; 365 366 done: 367 xe->sriov.__mode = data && data->sriov_mode ? 368 data->sriov_mode : XE_SRIOV_MODE_NONE; 369 370 kunit_activate_static_stub(test, read_gmdid, fake_read_gmdid); 371 kunit_activate_static_stub(test, xe_info_probe_tile_count, 372 fake_xe_info_probe_tile_count); 373 374 xe_info_init_early(xe, desc, subplatform_desc); 375 xe_info_init(xe, desc); 376 377 return 0; 378 } 379 EXPORT_SYMBOL_IF_KUNIT(xe_pci_fake_device_init); 380 381 /** 382 * xe_pci_live_device_gen_param - Helper to iterate Xe devices as KUnit parameters 383 * @test: test context object 384 * @prev: the previously returned value, or NULL for the first iteration 385 * @desc: the buffer for a parameter name 386 * 387 * Iterates over the available Xe devices on the system. Uses the device name 388 * as the parameter name. 389 * 390 * To be used only as a parameter generator function in &KUNIT_CASE_PARAM. 391 * 392 * Return: pointer to the next &struct xe_device ready to be used as a parameter 393 * or NULL if there are no more Xe devices on the system. 394 */ 395 const void *xe_pci_live_device_gen_param(struct kunit *test, const void *prev, char *desc) 396 { 397 const struct xe_device *xe = prev; 398 struct device *dev = xe ? xe->drm.dev : NULL; 399 struct device *next; 400 401 next = driver_find_next_device(&xe_pci_driver.driver, dev); 402 if (dev) 403 put_device(dev); 404 if (!next) 405 return NULL; 406 407 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s", dev_name(next)); 408 return pdev_to_xe_device(to_pci_dev(next)); 409 } 410 EXPORT_SYMBOL_IF_KUNIT(xe_pci_live_device_gen_param); 411