1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // KUnit tests for cs_dsp. 4 // 5 // Copyright (C) 2024 Cirrus Logic, Inc. and 6 // Cirrus Logic International Semiconductor Ltd. 7 // 8 9 #include <kunit/device.h> 10 #include <kunit/resource.h> 11 #include <kunit/test.h> 12 #include <kunit/test-bug.h> 13 #include <linux/build_bug.h> 14 #include <linux/firmware/cirrus/cs_dsp.h> 15 #include <linux/firmware/cirrus/cs_dsp_test_utils.h> 16 #include <linux/firmware/cirrus/wmfw.h> 17 #include <linux/random.h> 18 #include <linux/regmap.h> 19 #include <linux/string.h> 20 #include <linux/vmalloc.h> 21 22 #define ADSP2_LOCK_REGION_CTRL 0x7A 23 #define ADSP2_WDT_TIMEOUT_STS_MASK 0x2000 24 25 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *) 26 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *) 27 28 struct cs_dsp_test_local { 29 struct cs_dsp_mock_wmfw_builder *wmfw_builder; 30 31 int num_control_add; 32 int num_control_remove; 33 int num_pre_run; 34 int num_post_run; 35 int num_pre_stop; 36 int num_post_stop; 37 int num_watchdog_expired; 38 39 struct cs_dsp_coeff_ctl *passed_ctl[16]; 40 struct cs_dsp *passed_dsp; 41 }; 42 43 struct cs_dsp_callbacks_test_param { 44 const struct cs_dsp_client_ops *ops; 45 const char *case_name; 46 }; 47 48 static const struct cs_dsp_mock_alg_def cs_dsp_callbacks_test_mock_algs[] = { 49 { 50 .id = 0xfafa, 51 .ver = 0x100000, 52 .xm_size_words = 164, 53 .ym_size_words = 164, 54 .zm_size_words = 164, 55 }, 56 }; 57 58 static const struct cs_dsp_mock_coeff_def mock_coeff_template = { 59 .shortname = "Dummy Coeff", 60 .type = WMFW_CTL_TYPE_BYTES, 61 .mem_type = WMFW_ADSP2_YM, 62 .flags = WMFW_CTL_FLAG_VOLATILE, 63 .length_bytes = 4, 64 }; 65 66 static int cs_dsp_test_control_add_callback(struct cs_dsp_coeff_ctl *ctl) 67 { 68 struct kunit *test = kunit_get_current_test(); 69 struct cs_dsp_test *priv = test->priv; 70 struct cs_dsp_test_local *local = priv->local; 71 72 local->passed_ctl[local->num_control_add] = ctl; 73 local->num_control_add++; 74 75 return 0; 76 } 77 78 static void cs_dsp_test_control_remove_callback(struct cs_dsp_coeff_ctl *ctl) 79 { 80 struct kunit *test = kunit_get_current_test(); 81 struct cs_dsp_test *priv = test->priv; 82 struct cs_dsp_test_local *local = priv->local; 83 84 local->passed_ctl[local->num_control_remove] = ctl; 85 local->num_control_remove++; 86 } 87 88 static int cs_dsp_test_pre_run_callback(struct cs_dsp *dsp) 89 { 90 struct kunit *test = kunit_get_current_test(); 91 struct cs_dsp_test *priv = test->priv; 92 struct cs_dsp_test_local *local = priv->local; 93 94 local->passed_dsp = dsp; 95 local->num_pre_run++; 96 97 return 0; 98 } 99 100 static int cs_dsp_test_post_run_callback(struct cs_dsp *dsp) 101 { 102 struct kunit *test = kunit_get_current_test(); 103 struct cs_dsp_test *priv = test->priv; 104 struct cs_dsp_test_local *local = priv->local; 105 106 local->passed_dsp = dsp; 107 local->num_post_run++; 108 109 return 0; 110 } 111 112 static void cs_dsp_test_pre_stop_callback(struct cs_dsp *dsp) 113 { 114 struct kunit *test = kunit_get_current_test(); 115 struct cs_dsp_test *priv = test->priv; 116 struct cs_dsp_test_local *local = priv->local; 117 118 local->passed_dsp = dsp; 119 local->num_pre_stop++; 120 } 121 122 static void cs_dsp_test_post_stop_callback(struct cs_dsp *dsp) 123 { 124 struct kunit *test = kunit_get_current_test(); 125 struct cs_dsp_test *priv = test->priv; 126 struct cs_dsp_test_local *local = priv->local; 127 128 local->passed_dsp = dsp; 129 local->num_post_stop++; 130 } 131 132 static void cs_dsp_test_watchdog_expired_callback(struct cs_dsp *dsp) 133 { 134 struct kunit *test = kunit_get_current_test(); 135 struct cs_dsp_test *priv = test->priv; 136 struct cs_dsp_test_local *local = priv->local; 137 138 local->passed_dsp = dsp; 139 local->num_watchdog_expired++; 140 } 141 142 static const struct cs_dsp_client_ops cs_dsp_callback_test_client_ops = { 143 .control_add = cs_dsp_test_control_add_callback, 144 .control_remove = cs_dsp_test_control_remove_callback, 145 .pre_run = cs_dsp_test_pre_run_callback, 146 .post_run = cs_dsp_test_post_run_callback, 147 .pre_stop = cs_dsp_test_pre_stop_callback, 148 .post_stop = cs_dsp_test_post_stop_callback, 149 .watchdog_expired = cs_dsp_test_watchdog_expired_callback, 150 }; 151 152 static const struct cs_dsp_client_ops cs_dsp_callback_test_empty_client_ops = { 153 /* No entries */ 154 }; 155 156 static void cs_dsp_test_run_stop_callbacks(struct kunit *test) 157 { 158 struct cs_dsp_test *priv = test->priv; 159 struct cs_dsp_test_local *local = priv->local; 160 struct firmware *wmfw; 161 162 wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder); 163 164 KUNIT_EXPECT_EQ(test, 165 cs_dsp_power_up(priv->dsp, wmfw, "wmfw", NULL, NULL, "misc"), 166 0); 167 168 KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), 0); 169 KUNIT_EXPECT_EQ(test, local->num_pre_run, 1); 170 KUNIT_EXPECT_EQ(test, local->num_post_run, 1); 171 KUNIT_EXPECT_EQ(test, local->num_pre_stop, 0); 172 KUNIT_EXPECT_EQ(test, local->num_post_stop, 0); 173 KUNIT_EXPECT_PTR_EQ(test, local->passed_dsp, priv->dsp); 174 local->passed_dsp = NULL; 175 176 cs_dsp_stop(priv->dsp); 177 KUNIT_EXPECT_EQ(test, local->num_pre_run, 1); 178 KUNIT_EXPECT_EQ(test, local->num_post_run, 1); 179 KUNIT_EXPECT_EQ(test, local->num_pre_stop, 1); 180 KUNIT_EXPECT_EQ(test, local->num_post_stop, 1); 181 KUNIT_EXPECT_PTR_EQ(test, local->passed_dsp, priv->dsp); 182 local->passed_dsp = NULL; 183 184 KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), 0); 185 KUNIT_EXPECT_EQ(test, local->num_pre_run, 2); 186 KUNIT_EXPECT_EQ(test, local->num_post_run, 2); 187 KUNIT_EXPECT_EQ(test, local->num_pre_stop, 1); 188 KUNIT_EXPECT_EQ(test, local->num_post_stop, 1); 189 KUNIT_EXPECT_PTR_EQ(test, local->passed_dsp, priv->dsp); 190 local->passed_dsp = NULL; 191 192 cs_dsp_stop(priv->dsp); 193 KUNIT_EXPECT_EQ(test, local->num_pre_run, 2); 194 KUNIT_EXPECT_EQ(test, local->num_post_run, 2); 195 KUNIT_EXPECT_EQ(test, local->num_pre_stop, 2); 196 KUNIT_EXPECT_EQ(test, local->num_post_stop, 2); 197 KUNIT_EXPECT_PTR_EQ(test, local->passed_dsp, priv->dsp); 198 local->passed_dsp = NULL; 199 } 200 201 static void cs_dsp_test_ctl_v1_callbacks(struct kunit *test) 202 { 203 struct cs_dsp_test *priv = test->priv; 204 struct cs_dsp_test_local *local = priv->local; 205 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 206 struct cs_dsp_coeff_ctl *ctl; 207 struct firmware *wmfw; 208 int i; 209 210 /* Add a control for each memory */ 211 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 212 cs_dsp_callbacks_test_mock_algs[0].id, 213 "dummyalg", NULL); 214 def.shortname = "zm"; 215 def.mem_type = WMFW_ADSP2_ZM; 216 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 217 218 def.shortname = "ym"; 219 def.mem_type = WMFW_ADSP2_YM; 220 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 221 222 def.shortname = "xm"; 223 def.mem_type = WMFW_ADSP2_XM; 224 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 225 226 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 227 228 wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder); 229 KUNIT_EXPECT_EQ(test, 230 cs_dsp_power_up(priv->dsp, wmfw, "wmfw", NULL, NULL, "misc"), 231 0); 232 233 /* There should have been an add callback for each control */ 234 KUNIT_EXPECT_EQ(test, list_count_nodes(&priv->dsp->ctl_list), 3); 235 KUNIT_EXPECT_EQ(test, local->num_control_add, 3); 236 KUNIT_EXPECT_EQ(test, local->num_control_remove, 0); 237 238 i = 0; 239 list_for_each_entry_reverse(ctl, &priv->dsp->ctl_list, list) 240 KUNIT_EXPECT_PTR_EQ(test, local->passed_ctl[i++], ctl); 241 242 /* 243 * Call cs_dsp_remove() and there should be a remove callback 244 * for each control 245 */ 246 memset(local->passed_ctl, 0, sizeof(local->passed_ctl)); 247 cs_dsp_remove(priv->dsp); 248 249 /* Prevent double cleanup */ 250 kunit_remove_action(priv->test, _cs_dsp_remove_wrapper, priv->dsp); 251 252 KUNIT_EXPECT_EQ(test, local->num_control_add, 3); 253 KUNIT_EXPECT_EQ(test, local->num_control_remove, 3); 254 255 i = 0; 256 list_for_each_entry_reverse(ctl, &priv->dsp->ctl_list, list) 257 KUNIT_EXPECT_PTR_EQ(test, local->passed_ctl[i++], ctl); 258 } 259 260 static void cs_dsp_test_ctl_v2_callbacks(struct kunit *test) 261 { 262 struct cs_dsp_test *priv = test->priv; 263 struct cs_dsp_test_local *local = priv->local; 264 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 265 struct cs_dsp_coeff_ctl *ctl; 266 struct firmware *wmfw; 267 char name[2] = { }; 268 int i; 269 270 /* Add some controls */ 271 def.shortname = name; 272 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 273 cs_dsp_callbacks_test_mock_algs[0].id, 274 "dummyalg", NULL); 275 for (i = 0; i < ARRAY_SIZE(local->passed_ctl); ++i) { 276 name[0] = 'A' + i; 277 def.offset_dsp_words = i; 278 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 279 } 280 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 281 282 wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder); 283 KUNIT_EXPECT_EQ(test, 284 cs_dsp_power_up(priv->dsp, wmfw, "wmfw", NULL, NULL, "misc"), 285 0); 286 287 /* There should have been an add callback for each control */ 288 KUNIT_EXPECT_EQ(test, list_count_nodes(&priv->dsp->ctl_list), 289 ARRAY_SIZE(local->passed_ctl)); 290 KUNIT_EXPECT_EQ(test, local->num_control_add, ARRAY_SIZE(local->passed_ctl)); 291 KUNIT_EXPECT_EQ(test, local->num_control_remove, 0); 292 293 i = 0; 294 list_for_each_entry_reverse(ctl, &priv->dsp->ctl_list, list) 295 KUNIT_EXPECT_PTR_EQ(test, local->passed_ctl[i++], ctl); 296 297 /* 298 * Call cs_dsp_remove() and there should be a remove callback 299 * for each control 300 */ 301 memset(local->passed_ctl, 0, sizeof(local->passed_ctl)); 302 cs_dsp_remove(priv->dsp); 303 304 /* Prevent double cleanup */ 305 kunit_remove_action(priv->test, _cs_dsp_remove_wrapper, priv->dsp); 306 307 KUNIT_EXPECT_EQ(test, local->num_control_add, ARRAY_SIZE(local->passed_ctl)); 308 KUNIT_EXPECT_EQ(test, local->num_control_remove, ARRAY_SIZE(local->passed_ctl)); 309 310 i = 0; 311 list_for_each_entry_reverse(ctl, &priv->dsp->ctl_list, list) 312 KUNIT_EXPECT_PTR_EQ(test, local->passed_ctl[i++], ctl); 313 } 314 315 static void cs_dsp_test_no_callbacks(struct kunit *test) 316 { 317 struct cs_dsp_test *priv = test->priv; 318 struct cs_dsp_test_local *local = priv->local; 319 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 320 struct firmware *wmfw; 321 322 /* Add a controls */ 323 def.shortname = "A"; 324 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 325 cs_dsp_callbacks_test_mock_algs[0].id, 326 "dummyalg", NULL); 327 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 328 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 329 330 wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder); 331 332 /* Run a sequence of ops that would invoke callbacks */ 333 KUNIT_EXPECT_EQ(test, 334 cs_dsp_power_up(priv->dsp, wmfw, "wmfw", NULL, NULL, "misc"), 335 0); 336 KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), 0); 337 cs_dsp_stop(priv->dsp); 338 cs_dsp_remove(priv->dsp); 339 340 /* Prevent double cleanup */ 341 kunit_remove_action(priv->test, _cs_dsp_remove_wrapper, priv->dsp); 342 343 /* Something went very wrong if any of our callbacks were called */ 344 KUNIT_EXPECT_EQ(test, local->num_control_add, 0); 345 KUNIT_EXPECT_EQ(test, local->num_control_remove, 0); 346 KUNIT_EXPECT_EQ(test, local->num_pre_run, 0); 347 KUNIT_EXPECT_EQ(test, local->num_post_run, 0); 348 KUNIT_EXPECT_EQ(test, local->num_pre_stop, 0); 349 KUNIT_EXPECT_EQ(test, local->num_post_stop, 0); 350 } 351 352 static void cs_dsp_test_adsp2v2_watchdog_callback(struct kunit *test) 353 { 354 struct cs_dsp_test *priv = test->priv; 355 struct cs_dsp_test_local *local = priv->local; 356 struct firmware *wmfw; 357 358 wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder); 359 360 KUNIT_EXPECT_EQ(test, 361 cs_dsp_power_up(priv->dsp, wmfw, "wmfw", NULL, NULL, "misc"), 362 0); 363 364 KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), 0); 365 366 /* Set the watchdog timeout bit */ 367 regmap_write(priv->dsp->regmap, priv->dsp->base + ADSP2_LOCK_REGION_CTRL, 368 ADSP2_WDT_TIMEOUT_STS_MASK); 369 370 /* Notify an interrupt and the watchdog callback should be called */ 371 cs_dsp_adsp2_bus_error(priv->dsp); 372 KUNIT_EXPECT_EQ(test, local->num_watchdog_expired, 1); 373 KUNIT_EXPECT_PTR_EQ(test, local->passed_dsp, priv->dsp); 374 } 375 376 static void cs_dsp_test_adsp2v2_watchdog_no_callbacks(struct kunit *test) 377 { 378 struct cs_dsp_test *priv = test->priv; 379 struct cs_dsp_test_local *local = priv->local; 380 struct firmware *wmfw; 381 382 wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder); 383 KUNIT_EXPECT_EQ(test, 384 cs_dsp_power_up(priv->dsp, wmfw, "wmfw", NULL, NULL, "misc"), 385 0); 386 KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), 0); 387 388 /* Set the watchdog timeout bit */ 389 regmap_write(priv->dsp->regmap, priv->dsp->base + ADSP2_LOCK_REGION_CTRL, 390 ADSP2_WDT_TIMEOUT_STS_MASK); 391 392 /* Notify an interrupt, which will look for a watchdog callback */ 393 cs_dsp_adsp2_bus_error(priv->dsp); 394 KUNIT_EXPECT_EQ(test, local->num_watchdog_expired, 0); 395 } 396 397 static void cs_dsp_test_halo_watchdog_callback(struct kunit *test) 398 { 399 struct cs_dsp_test *priv = test->priv; 400 struct cs_dsp_test_local *local = priv->local; 401 struct firmware *wmfw; 402 403 wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder); 404 405 KUNIT_EXPECT_EQ(test, 406 cs_dsp_power_up(priv->dsp, wmfw, "wmfw", NULL, NULL, "misc"), 407 0); 408 409 KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), 0); 410 411 /* Notify an interrupt and the watchdog callback should be called */ 412 cs_dsp_halo_wdt_expire(priv->dsp); 413 KUNIT_EXPECT_EQ(test, local->num_watchdog_expired, 1); 414 KUNIT_EXPECT_PTR_EQ(test, local->passed_dsp, priv->dsp); 415 } 416 417 static void cs_dsp_test_halo_watchdog_no_callbacks(struct kunit *test) 418 { 419 struct cs_dsp_test *priv = test->priv; 420 struct cs_dsp_test_local *local = priv->local; 421 struct firmware *wmfw; 422 423 wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder); 424 KUNIT_EXPECT_EQ(test, 425 cs_dsp_power_up(priv->dsp, wmfw, "wmfw", NULL, NULL, "misc"), 426 0); 427 KUNIT_EXPECT_EQ(test, cs_dsp_run(priv->dsp), 0); 428 429 /* Notify an interrupt, which will look for a watchdog callback */ 430 cs_dsp_halo_wdt_expire(priv->dsp); 431 KUNIT_EXPECT_EQ(test, local->num_watchdog_expired, 0); 432 } 433 434 static int cs_dsp_callbacks_test_common_init(struct kunit *test, struct cs_dsp *dsp, 435 int wmfw_version) 436 { 437 const struct cs_dsp_callbacks_test_param *param = test->param_value; 438 struct cs_dsp_test *priv; 439 struct cs_dsp_test_local *local; 440 struct device *test_dev; 441 struct cs_dsp_mock_xm_header *xm_header; 442 int ret; 443 444 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); 445 if (!priv) 446 return -ENOMEM; 447 448 local = kunit_kzalloc(test, sizeof(struct cs_dsp_test_local), GFP_KERNEL); 449 if (!local) 450 return -ENOMEM; 451 452 priv->test = test; 453 priv->dsp = dsp; 454 test->priv = priv; 455 priv->local = local; 456 457 /* Create dummy struct device */ 458 test_dev = kunit_device_register(test, "cs_dsp_test_drv"); 459 if (IS_ERR(test_dev)) 460 return PTR_ERR(test_dev); 461 462 dsp->dev = get_device(test_dev); 463 if (!dsp->dev) 464 return -ENODEV; 465 466 ret = kunit_add_action_or_reset(test, _put_device_wrapper, dsp->dev); 467 if (ret) 468 return ret; 469 470 dev_set_drvdata(dsp->dev, priv); 471 472 /* Allocate regmap */ 473 ret = cs_dsp_mock_regmap_init(priv); 474 if (ret) 475 return ret; 476 477 /* 478 * There must always be a XM header with at least 1 algorithm, 479 * so create a dummy one and pre-populate XM so the wmfw doesn't 480 * have to contain an XM blob. 481 */ 482 xm_header = cs_dsp_create_mock_xm_header(priv, 483 cs_dsp_callbacks_test_mock_algs, 484 ARRAY_SIZE(cs_dsp_callbacks_test_mock_algs)); 485 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xm_header); 486 cs_dsp_mock_xm_header_write_to_regmap(xm_header); 487 488 local->wmfw_builder = cs_dsp_mock_wmfw_init(priv, wmfw_version); 489 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->wmfw_builder); 490 491 /* Add dummy XM header payload to wmfw */ 492 cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder, 493 WMFW_ADSP2_XM, 0, 494 xm_header->blob_data, 495 xm_header->blob_size_bytes); 496 497 /* Init cs_dsp */ 498 dsp->client_ops = param->ops; 499 500 switch (dsp->type) { 501 case WMFW_ADSP2: 502 ret = cs_dsp_adsp2_init(dsp); 503 break; 504 case WMFW_HALO: 505 ret = cs_dsp_halo_init(dsp); 506 break; 507 default: 508 KUNIT_FAIL(test, "Untested DSP type %d\n", dsp->type); 509 return -EINVAL; 510 } 511 512 if (ret) 513 return ret; 514 515 /* Automatically call cs_dsp_remove() when test case ends */ 516 return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); 517 } 518 519 static int cs_dsp_callbacks_test_halo_init(struct kunit *test) 520 { 521 struct cs_dsp *dsp; 522 523 /* Fill in cs_dsp and initialize */ 524 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL); 525 if (!dsp) 526 return -ENOMEM; 527 528 dsp->num = 1; 529 dsp->type = WMFW_HALO; 530 dsp->mem = cs_dsp_mock_halo_dsp1_regions; 531 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_halo_dsp1_region_sizes); 532 dsp->base = cs_dsp_mock_halo_core_base; 533 dsp->base_sysinfo = cs_dsp_mock_halo_sysinfo_base; 534 535 return cs_dsp_callbacks_test_common_init(test, dsp, 3); 536 } 537 538 static int cs_dsp_callbacks_test_adsp2_32bit_init(struct kunit *test, int rev) 539 { 540 struct cs_dsp *dsp; 541 542 /* Fill in cs_dsp and initialize */ 543 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL); 544 if (!dsp) 545 return -ENOMEM; 546 547 dsp->num = 1; 548 dsp->type = WMFW_ADSP2; 549 dsp->rev = rev; 550 dsp->mem = cs_dsp_mock_adsp2_32bit_dsp1_regions; 551 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_32bit_dsp1_region_sizes); 552 dsp->base = cs_dsp_mock_adsp2_32bit_sysbase; 553 554 return cs_dsp_callbacks_test_common_init(test, dsp, 2); 555 } 556 557 static int cs_dsp_callbacks_test_adsp2v2_32bit_init(struct kunit *test) 558 { 559 return cs_dsp_callbacks_test_adsp2_32bit_init(test, 2); 560 } 561 562 static int cs_dsp_callbacks_test_adsp2v1_32bit_init(struct kunit *test) 563 { 564 return cs_dsp_callbacks_test_adsp2_32bit_init(test, 1); 565 } 566 567 static int cs_dsp_callbacks_test_adsp2_16bit_init(struct kunit *test) 568 { 569 struct cs_dsp *dsp; 570 571 /* Fill in cs_dsp and initialize */ 572 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL); 573 if (!dsp) 574 return -ENOMEM; 575 576 dsp->num = 1; 577 dsp->type = WMFW_ADSP2; 578 dsp->rev = 0; 579 dsp->mem = cs_dsp_mock_adsp2_16bit_dsp1_regions; 580 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_16bit_dsp1_region_sizes); 581 dsp->base = cs_dsp_mock_adsp2_16bit_sysbase; 582 583 return cs_dsp_callbacks_test_common_init(test, dsp, 1); 584 } 585 586 static void cs_dsp_callbacks_param_desc(const struct cs_dsp_callbacks_test_param *param, 587 char *desc) 588 { 589 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s", param->case_name); 590 } 591 592 /* Parameterize on different client callback ops tables */ 593 static const struct cs_dsp_callbacks_test_param cs_dsp_callbacks_ops_cases[] = { 594 { .ops = &cs_dsp_callback_test_client_ops, .case_name = "all ops" }, 595 }; 596 597 KUNIT_ARRAY_PARAM(cs_dsp_callbacks_ops, 598 cs_dsp_callbacks_ops_cases, 599 cs_dsp_callbacks_param_desc); 600 601 static const struct cs_dsp_callbacks_test_param cs_dsp_no_callbacks_cases[] = { 602 { .ops = &cs_dsp_callback_test_empty_client_ops, .case_name = "empty ops" }, 603 }; 604 605 KUNIT_ARRAY_PARAM(cs_dsp_no_callbacks, 606 cs_dsp_no_callbacks_cases, 607 cs_dsp_callbacks_param_desc); 608 609 static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv1_test_cases[] = { 610 KUNIT_CASE_PARAM(cs_dsp_test_run_stop_callbacks, cs_dsp_callbacks_ops_gen_params), 611 KUNIT_CASE_PARAM(cs_dsp_test_ctl_v1_callbacks, cs_dsp_callbacks_ops_gen_params), 612 KUNIT_CASE_PARAM(cs_dsp_test_no_callbacks, cs_dsp_no_callbacks_gen_params), 613 614 { } /* terminator */ 615 }; 616 617 static struct kunit_case cs_dsp_callbacks_adsp2_wmfwv2_test_cases[] = { 618 KUNIT_CASE_PARAM(cs_dsp_test_run_stop_callbacks, cs_dsp_callbacks_ops_gen_params), 619 KUNIT_CASE_PARAM(cs_dsp_test_ctl_v2_callbacks, cs_dsp_callbacks_ops_gen_params), 620 KUNIT_CASE_PARAM(cs_dsp_test_no_callbacks, cs_dsp_no_callbacks_gen_params), 621 622 { } /* terminator */ 623 }; 624 625 static struct kunit_case cs_dsp_callbacks_halo_test_cases[] = { 626 KUNIT_CASE_PARAM(cs_dsp_test_run_stop_callbacks, cs_dsp_callbacks_ops_gen_params), 627 KUNIT_CASE_PARAM(cs_dsp_test_ctl_v2_callbacks, cs_dsp_callbacks_ops_gen_params), 628 KUNIT_CASE_PARAM(cs_dsp_test_no_callbacks, cs_dsp_no_callbacks_gen_params), 629 630 { } /* terminator */ 631 }; 632 633 static struct kunit_case cs_dsp_watchdog_adsp2v2_test_cases[] = { 634 KUNIT_CASE_PARAM(cs_dsp_test_adsp2v2_watchdog_callback, cs_dsp_callbacks_ops_gen_params), 635 KUNIT_CASE_PARAM(cs_dsp_test_adsp2v2_watchdog_no_callbacks, cs_dsp_no_callbacks_gen_params), 636 637 { } /* terminator */ 638 }; 639 640 static struct kunit_case cs_dsp_watchdog_halo_test_cases[] = { 641 KUNIT_CASE_PARAM(cs_dsp_test_halo_watchdog_callback, cs_dsp_callbacks_ops_gen_params), 642 KUNIT_CASE_PARAM(cs_dsp_test_halo_watchdog_no_callbacks, cs_dsp_no_callbacks_gen_params), 643 644 { } /* terminator */ 645 }; 646 647 static struct kunit_suite cs_dsp_callbacks_test_halo = { 648 .name = "cs_dsp_callbacks_halo", 649 .init = cs_dsp_callbacks_test_halo_init, 650 .test_cases = cs_dsp_callbacks_halo_test_cases, 651 }; 652 653 static struct kunit_suite cs_dsp_callbacks_test_adsp2v2_32bit = { 654 .name = "cs_dsp_callbacks_adsp2v2_32bit_wmfwv2", 655 .init = cs_dsp_callbacks_test_adsp2v2_32bit_init, 656 .test_cases = cs_dsp_callbacks_adsp2_wmfwv2_test_cases, 657 }; 658 659 static struct kunit_suite cs_dsp_callbacks_test_adsp2v1_32bit = { 660 .name = "cs_dsp_callbacks_adsp2v1_32bit_wmfwv2", 661 .init = cs_dsp_callbacks_test_adsp2v1_32bit_init, 662 .test_cases = cs_dsp_callbacks_adsp2_wmfwv2_test_cases, 663 }; 664 665 static struct kunit_suite cs_dsp_callbacks_test_adsp2_16bit = { 666 .name = "cs_dsp_callbacks_adsp2_16bit_wmfwv1", 667 .init = cs_dsp_callbacks_test_adsp2_16bit_init, 668 .test_cases = cs_dsp_callbacks_adsp2_wmfwv1_test_cases, 669 }; 670 671 static struct kunit_suite cs_dsp_watchdog_test_adsp2v2_32bit = { 672 .name = "cs_dsp_watchdog_adsp2v2_32bit", 673 .init = cs_dsp_callbacks_test_adsp2v2_32bit_init, 674 .test_cases = cs_dsp_watchdog_adsp2v2_test_cases, 675 }; 676 677 static struct kunit_suite cs_dsp_watchdog_test_halo_32bit = { 678 .name = "cs_dsp_watchdog_halo", 679 .init = cs_dsp_callbacks_test_halo_init, 680 .test_cases = cs_dsp_watchdog_halo_test_cases, 681 }; 682 683 kunit_test_suites(&cs_dsp_callbacks_test_halo, 684 &cs_dsp_callbacks_test_adsp2v2_32bit, 685 &cs_dsp_callbacks_test_adsp2v1_32bit, 686 &cs_dsp_callbacks_test_adsp2_16bit, 687 &cs_dsp_watchdog_test_adsp2v2_32bit, 688 &cs_dsp_watchdog_test_halo_32bit); 689