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 */ 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 xe_step step) 134 { 135 return step == STEP_NONE ? "" : " "; 136 } 137 138 static const char *step_name(enum xe_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 graphics_ip_xelp, 215 graphics_ip_xelpp, 216 graphics_ip_xehpg, 217 graphics_ip_xehpc, 218 }; 219 220 static const struct xe_ip pre_gmdid_media_ips[] = { 221 media_ip_xem, 222 media_ip_xehpm, 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 * @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 */ 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 */ 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 */ 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 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 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 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 */ 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