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 #include <kunit/device.h> 9 #include <kunit/resource.h> 10 #include <kunit/test.h> 11 #include <linux/build_bug.h> 12 #include <linux/firmware/cirrus/cs_dsp.h> 13 #include <linux/firmware/cirrus/cs_dsp_test_utils.h> 14 #include <linux/firmware/cirrus/wmfw.h> 15 #include <linux/list.h> 16 #include <linux/random.h> 17 #include <linux/regmap.h> 18 19 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *); 20 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_stop_wrapper, cs_dsp_stop, struct cs_dsp *); 21 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *); 22 23 struct cs_dsp_test_local { 24 struct cs_dsp_mock_xm_header *xm_header; 25 struct cs_dsp_mock_wmfw_builder *wmfw_builder; 26 int wmfw_version; 27 }; 28 29 struct cs_dsp_ctl_cache_test_param { 30 int mem_type; 31 int alg_id; 32 unsigned int offs_words; 33 unsigned int len_bytes; 34 u16 ctl_type; 35 u16 flags; 36 }; 37 38 static const struct cs_dsp_mock_alg_def cs_dsp_ctl_cache_test_algs[] = { 39 { 40 .id = 0xfafa, 41 .ver = 0x100000, 42 .xm_base_words = 60, 43 .xm_size_words = 1000, 44 .ym_base_words = 0, 45 .ym_size_words = 1000, 46 .zm_base_words = 0, 47 .zm_size_words = 1000, 48 }, 49 { 50 .id = 0xb, 51 .ver = 0x100001, 52 .xm_base_words = 1060, 53 .xm_size_words = 1000, 54 .ym_base_words = 1000, 55 .ym_size_words = 1000, 56 .zm_base_words = 1000, 57 .zm_size_words = 1000, 58 }, 59 { 60 .id = 0x9f1234, 61 .ver = 0x100500, 62 .xm_base_words = 2060, 63 .xm_size_words = 32, 64 .ym_base_words = 2000, 65 .ym_size_words = 32, 66 .zm_base_words = 2000, 67 .zm_size_words = 32, 68 }, 69 { 70 .id = 0xff00ff, 71 .ver = 0x300113, 72 .xm_base_words = 2100, 73 .xm_size_words = 32, 74 .ym_base_words = 2032, 75 .ym_size_words = 32, 76 .zm_base_words = 2032, 77 .zm_size_words = 32, 78 }, 79 }; 80 81 static const struct cs_dsp_mock_coeff_def mock_coeff_template = { 82 .shortname = "Dummy Coeff", 83 .type = WMFW_CTL_TYPE_BYTES, 84 .mem_type = WMFW_ADSP2_YM, 85 .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 86 .length_bytes = 4, 87 }; 88 89 static const char * const cs_dsp_ctl_cache_test_fw_names[] = { 90 "misc", "mbc/vss", "haps", 91 }; 92 93 static int _find_alg_entry(struct kunit *test, unsigned int alg_id) 94 { 95 int i; 96 97 for (i = 0; i < ARRAY_SIZE(cs_dsp_ctl_cache_test_algs); ++i) { 98 if (cs_dsp_ctl_cache_test_algs[i].id == alg_id) 99 break; 100 } 101 102 KUNIT_ASSERT_LT(test, i, ARRAY_SIZE(cs_dsp_ctl_cache_test_algs)); 103 104 return i; 105 } 106 107 static int _get_alg_mem_base_words(struct kunit *test, int alg_index, int mem_type) 108 { 109 switch (mem_type) { 110 case WMFW_ADSP2_XM: 111 return cs_dsp_ctl_cache_test_algs[alg_index].xm_base_words; 112 case WMFW_ADSP2_YM: 113 return cs_dsp_ctl_cache_test_algs[alg_index].ym_base_words; 114 case WMFW_ADSP2_ZM: 115 return cs_dsp_ctl_cache_test_algs[alg_index].zm_base_words; 116 default: 117 KUNIT_FAIL(test, "Bug in test: illegal memory type %d\n", mem_type); 118 return 0; 119 } 120 } 121 122 static struct cs_dsp_mock_wmfw_builder *_create_dummy_wmfw(struct kunit *test) 123 { 124 struct cs_dsp_test *priv = test->priv; 125 struct cs_dsp_test_local *local = priv->local; 126 struct cs_dsp_mock_wmfw_builder *builder; 127 128 builder = cs_dsp_mock_wmfw_init(priv, local->wmfw_version); 129 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, builder); 130 131 /* Init an XM header */ 132 cs_dsp_mock_wmfw_add_data_block(builder, 133 WMFW_ADSP2_XM, 0, 134 local->xm_header->blob_data, 135 local->xm_header->blob_size_bytes); 136 137 return builder; 138 } 139 140 /* 141 * Memory allocated for control cache must be large enough. 142 * This creates multiple controls of different sizes so only works on 143 * wmfw V2 and later. 144 */ 145 static void cs_dsp_ctl_v2_cache_alloc(struct kunit *test) 146 { 147 struct cs_dsp_test *priv = test->priv; 148 struct cs_dsp_test_local *local = priv->local; 149 struct cs_dsp *dsp = priv->dsp; 150 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 151 unsigned int reg, alg_base_words, alg_size_bytes; 152 struct cs_dsp_coeff_ctl *ctl; 153 struct firmware *wmfw; 154 char ctl_name[4]; 155 u32 *reg_vals; 156 int num_ctls; 157 158 /* Create some DSP data to initialize the control cache */ 159 alg_base_words = _get_alg_mem_base_words(test, 0, WMFW_ADSP2_YM); 160 alg_size_bytes = cs_dsp_ctl_cache_test_algs[0].ym_size_words * 161 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 162 reg_vals = kunit_kzalloc(test, alg_size_bytes, GFP_KERNEL); 163 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 164 reg = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_YM); 165 reg += alg_base_words * cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 166 regmap_raw_write(dsp->regmap, reg, reg_vals, alg_size_bytes); 167 168 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 169 cs_dsp_ctl_cache_test_algs[0].id, 170 "dummyalg", NULL); 171 172 /* Create controls of different sizes */ 173 def.mem_type = WMFW_ADSP2_YM; 174 def.shortname = ctl_name; 175 num_ctls = 0; 176 for (def.length_bytes = 4; def.length_bytes <= 64; def.length_bytes += 4) { 177 snprintf(ctl_name, ARRAY_SIZE(ctl_name), "%x", def.length_bytes); 178 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 179 num_ctls++; 180 def.offset_dsp_words += def.length_bytes / sizeof(u32); 181 } 182 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 183 184 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 185 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 186 187 KUNIT_EXPECT_EQ(test, list_count_nodes(&dsp->ctl_list), num_ctls); 188 189 /* Check that the block allocated for the cache is large enough */ 190 list_for_each_entry(ctl, &dsp->ctl_list, list) 191 KUNIT_EXPECT_GE(test, ksize(ctl->cache), ctl->len); 192 } 193 194 /* 195 * Content of registers backing a control should be read into the 196 * control cache when the firmware is downloaded. 197 */ 198 static void cs_dsp_ctl_cache_init(struct kunit *test) 199 { 200 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 201 struct cs_dsp_test *priv = test->priv; 202 struct cs_dsp_test_local *local = priv->local; 203 struct cs_dsp *dsp = priv->dsp; 204 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 205 int alg_idx = _find_alg_entry(test, param->alg_id); 206 unsigned int reg, alg_base_words; 207 struct cs_dsp_coeff_ctl *ctl; 208 struct firmware *wmfw; 209 u32 *reg_vals, *readback; 210 211 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 212 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 213 214 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 215 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 216 217 /* Create some DSP data to be read into the control cache */ 218 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 219 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 220 reg += (alg_base_words + param->offs_words) * 221 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 222 get_random_bytes(reg_vals, param->len_bytes); 223 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 224 225 /* Create control pointing to this data */ 226 def.flags = param->flags; 227 def.mem_type = param->mem_type; 228 def.offset_dsp_words = param->offs_words; 229 def.length_bytes = param->len_bytes; 230 231 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 232 cs_dsp_ctl_cache_test_algs[alg_idx].id, 233 "dummyalg", NULL); 234 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 235 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 236 237 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 238 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 239 240 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 241 KUNIT_ASSERT_NOT_NULL(test, ctl); 242 243 /* 244 * The data should have been populated into the control cache 245 * so should be readable through the control. 246 */ 247 KUNIT_EXPECT_EQ(test, 248 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 249 0); 250 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 251 } 252 253 /* 254 * For a non-volatile write-only control the cache should be zero-filled 255 * when the firmware is downloaded. 256 */ 257 static void cs_dsp_ctl_cache_init_write_only(struct kunit *test) 258 { 259 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 260 struct cs_dsp_test *priv = test->priv; 261 struct cs_dsp_test_local *local = priv->local; 262 struct cs_dsp *dsp = priv->dsp; 263 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 264 int alg_idx = _find_alg_entry(test, param->alg_id); 265 struct cs_dsp_coeff_ctl *ctl; 266 struct firmware *wmfw; 267 u32 *readback, *zeros; 268 269 zeros = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 270 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, zeros); 271 272 readback = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 273 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 274 275 /* Create a non-volatile write-only control */ 276 def.flags = param->flags & ~WMFW_CTL_FLAG_VOLATILE; 277 def.mem_type = param->mem_type; 278 def.offset_dsp_words = param->offs_words; 279 def.length_bytes = param->len_bytes; 280 281 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 282 cs_dsp_ctl_cache_test_algs[alg_idx].id, 283 "dummyalg", NULL); 284 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 285 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 286 287 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 288 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 289 290 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 291 KUNIT_ASSERT_NOT_NULL(test, ctl); 292 293 /* 294 * The control cache should have been zero-filled so should be 295 * readable through the control. 296 */ 297 get_random_bytes(readback, param->len_bytes); 298 KUNIT_EXPECT_EQ(test, 299 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 300 0); 301 KUNIT_EXPECT_MEMEQ(test, readback, zeros, param->len_bytes); 302 } 303 304 /* 305 * Multiple different firmware with identical controls. 306 * This is legal because different firmwares could contain the same 307 * algorithm. 308 * The control cache should be initialized only with the data from 309 * the firmware containing it. 310 */ 311 static void cs_dsp_ctl_cache_init_multiple_fw_same_controls(struct kunit *test) 312 { 313 struct cs_dsp_test *priv = test->priv; 314 struct cs_dsp *dsp = priv->dsp; 315 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 316 struct cs_dsp_mock_wmfw_builder *builder[3]; 317 unsigned int reg, alg_base_words; 318 struct cs_dsp_coeff_ctl *walkctl, *ctl[3]; 319 struct firmware *wmfw; 320 u32 *reg_vals[3], *readback; 321 int i; 322 323 static_assert(ARRAY_SIZE(ctl) == ARRAY_SIZE(builder)); 324 static_assert(ARRAY_SIZE(reg_vals) == ARRAY_SIZE(builder)); 325 static_assert(ARRAY_SIZE(cs_dsp_ctl_cache_test_fw_names) >= ARRAY_SIZE(builder)); 326 327 /* Create an identical control in each firmware but with different alg id */ 328 for (i = 0; i < ARRAY_SIZE(builder); i++) { 329 builder[i] = _create_dummy_wmfw(test); 330 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, builder[i]); 331 332 cs_dsp_mock_wmfw_start_alg_info_block(builder[i], 333 cs_dsp_ctl_cache_test_algs[0].id, 334 "dummyalg", NULL); 335 cs_dsp_mock_wmfw_add_coeff_desc(builder[i], &def); 336 cs_dsp_mock_wmfw_end_alg_info_block(builder[i]); 337 } 338 339 for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { 340 reg_vals[i] = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 341 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals[i]); 342 } 343 344 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 345 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 346 347 /* 348 * For each firmware create random content in the register backing 349 * the control. Then download, start, stop and power-down. 350 */ 351 for (i = 0; i < ARRAY_SIZE(builder); i++) { 352 alg_base_words = _get_alg_mem_base_words(test, 0, def.mem_type); 353 reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type); 354 reg += (alg_base_words + def.offset_dsp_words) * 355 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 356 357 get_random_bytes(reg_vals[i], def.length_bytes); 358 regmap_raw_write(dsp->regmap, reg, reg_vals[i], def.length_bytes); 359 wmfw = cs_dsp_mock_wmfw_get_firmware(builder[i]); 360 KUNIT_ASSERT_EQ(test, 361 cs_dsp_power_up(dsp, wmfw, 362 cs_dsp_ctl_cache_test_fw_names[i], 363 NULL, NULL, 364 cs_dsp_ctl_cache_test_fw_names[i]), 365 0); 366 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 367 cs_dsp_stop(dsp); 368 cs_dsp_power_down(dsp); 369 } 370 371 /* There should now be 3 controls */ 372 KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3); 373 374 /* 375 * There's no requirement for the control list to be in any 376 * particular order, so don't assume the order. 377 */ 378 for (i = 0; i < ARRAY_SIZE(ctl); i++) 379 ctl[i] = NULL; 380 381 list_for_each_entry(walkctl, &dsp->ctl_list, list) { 382 if (strcmp(walkctl->fw_name, cs_dsp_ctl_cache_test_fw_names[0]) == 0) 383 ctl[0] = walkctl; 384 else if (strcmp(walkctl->fw_name, cs_dsp_ctl_cache_test_fw_names[1]) == 0) 385 ctl[1] = walkctl; 386 else if (strcmp(walkctl->fw_name, cs_dsp_ctl_cache_test_fw_names[2]) == 0) 387 ctl[2] = walkctl; 388 } 389 390 KUNIT_ASSERT_NOT_NULL(test, ctl[0]); 391 KUNIT_ASSERT_NOT_NULL(test, ctl[1]); 392 KUNIT_ASSERT_NOT_NULL(test, ctl[2]); 393 394 /* 395 * The data should have been populated into the control cache 396 * so should be readable through the control. 397 */ 398 KUNIT_EXPECT_EQ(test, 399 cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes), 400 0); 401 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes); 402 403 KUNIT_EXPECT_EQ(test, 404 cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes), 405 0); 406 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes); 407 408 KUNIT_EXPECT_EQ(test, 409 cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback, def.length_bytes), 410 0); 411 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes); 412 } 413 414 /* 415 * Multiple different firmware with controls identical except for alg id. 416 * This is legal because the controls are qualified by algorithm id. 417 * The control cache should be initialized only with the data from 418 * the firmware containing it. 419 */ 420 static void cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls(struct kunit *test) 421 { 422 struct cs_dsp_test *priv = test->priv; 423 struct cs_dsp *dsp = priv->dsp; 424 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 425 struct cs_dsp_mock_wmfw_builder *builder[3]; 426 unsigned int reg, alg_base_words; 427 struct cs_dsp_coeff_ctl *walkctl, *ctl[3]; 428 struct firmware *wmfw; 429 u32 *reg_vals[3], *readback; 430 int i; 431 432 static_assert(ARRAY_SIZE(ctl) == ARRAY_SIZE(builder)); 433 static_assert(ARRAY_SIZE(reg_vals) == ARRAY_SIZE(builder)); 434 static_assert(ARRAY_SIZE(cs_dsp_ctl_cache_test_fw_names) >= ARRAY_SIZE(builder)); 435 436 /* Create an identical control in each firmware but with different alg id */ 437 for (i = 0; i < ARRAY_SIZE(builder); i++) { 438 builder[i] = _create_dummy_wmfw(test); 439 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, builder[i]); 440 441 cs_dsp_mock_wmfw_start_alg_info_block(builder[i], 442 cs_dsp_ctl_cache_test_algs[i].id, 443 "dummyalg", NULL); 444 cs_dsp_mock_wmfw_add_coeff_desc(builder[i], &def); 445 cs_dsp_mock_wmfw_end_alg_info_block(builder[i]); 446 } 447 448 for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { 449 reg_vals[i] = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 450 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals[i]); 451 } 452 453 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 454 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 455 456 /* 457 * For each firmware create random content in the register backing 458 * the control. Then download, start, stop and power-down. 459 */ 460 for (i = 0; i < ARRAY_SIZE(builder); i++) { 461 alg_base_words = _get_alg_mem_base_words(test, i, def.mem_type); 462 reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type); 463 reg += (alg_base_words + def.offset_dsp_words) * 464 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 465 466 get_random_bytes(reg_vals[i], def.length_bytes); 467 regmap_raw_write(dsp->regmap, reg, reg_vals[i], def.length_bytes); 468 wmfw = cs_dsp_mock_wmfw_get_firmware(builder[i]); 469 KUNIT_ASSERT_EQ(test, 470 cs_dsp_power_up(dsp, wmfw, 471 cs_dsp_ctl_cache_test_fw_names[i], 472 NULL, NULL, 473 cs_dsp_ctl_cache_test_fw_names[i]), 474 0); 475 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 476 cs_dsp_stop(dsp); 477 cs_dsp_power_down(dsp); 478 } 479 480 /* There should now be 3 controls */ 481 KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3); 482 483 /* 484 * There's no requirement for the control list to be in any 485 * particular order, so don't assume the order. 486 */ 487 for (i = 0; i < ARRAY_SIZE(ctl); i++) 488 ctl[i] = NULL; 489 490 list_for_each_entry(walkctl, &dsp->ctl_list, list) { 491 if (cs_dsp_ctl_cache_test_algs[0].id == walkctl->alg_region.alg) 492 ctl[0] = walkctl; 493 else if (cs_dsp_ctl_cache_test_algs[1].id == walkctl->alg_region.alg) 494 ctl[1] = walkctl; 495 else if (cs_dsp_ctl_cache_test_algs[2].id == walkctl->alg_region.alg) 496 ctl[2] = walkctl; 497 } 498 499 KUNIT_ASSERT_NOT_NULL(test, ctl[0]); 500 KUNIT_ASSERT_NOT_NULL(test, ctl[1]); 501 KUNIT_ASSERT_NOT_NULL(test, ctl[2]); 502 503 /* 504 * The data should have been populated into the control cache 505 * so should be readable through the control. 506 */ 507 KUNIT_EXPECT_EQ(test, 508 cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes), 509 0); 510 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes); 511 512 KUNIT_EXPECT_EQ(test, 513 cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes), 514 0); 515 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes); 516 517 KUNIT_EXPECT_EQ(test, 518 cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback, def.length_bytes), 519 0); 520 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes); 521 } 522 523 /* 524 * Firmware with controls at the same position in different memories. 525 * The control cache should be initialized with content from the 526 * correct memory region. 527 */ 528 static void cs_dsp_ctl_cache_init_multiple_mems(struct kunit *test) 529 { 530 struct cs_dsp_test *priv = test->priv; 531 struct cs_dsp *dsp = priv->dsp; 532 struct cs_dsp_test_local *local = priv->local; 533 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 534 unsigned int reg, alg_base_words; 535 struct cs_dsp_coeff_ctl *walkctl, *ctl[3]; 536 struct firmware *wmfw; 537 u32 *reg_vals[3], *readback; 538 int i; 539 540 static_assert(ARRAY_SIZE(ctl) == ARRAY_SIZE(reg_vals)); 541 542 for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { 543 reg_vals[i] = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 544 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals[i]); 545 get_random_bytes(reg_vals[i], def.length_bytes); 546 } 547 548 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 549 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 550 551 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 552 cs_dsp_ctl_cache_test_algs[0].id, 553 "dummyalg", NULL); 554 555 /* Create controls identical except for memory region */ 556 def.mem_type = WMFW_ADSP2_YM; 557 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 558 559 def.mem_type = WMFW_ADSP2_XM; 560 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 561 562 if (cs_dsp_mock_has_zm(priv)) { 563 def.mem_type = WMFW_ADSP2_ZM; 564 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 565 } 566 567 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 568 569 /* Create random content in the registers backing each control */ 570 alg_base_words = _get_alg_mem_base_words(test, 0, WMFW_ADSP2_YM); 571 reg = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_YM); 572 reg += (alg_base_words + def.offset_dsp_words) * 573 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 574 regmap_raw_write(dsp->regmap, reg, reg_vals[0], def.length_bytes); 575 576 alg_base_words = _get_alg_mem_base_words(test, 0, WMFW_ADSP2_XM); 577 reg = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_XM); 578 reg += (alg_base_words + def.offset_dsp_words) * 579 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 580 regmap_raw_write(dsp->regmap, reg, reg_vals[1], def.length_bytes); 581 582 if (cs_dsp_mock_has_zm(priv)) { 583 alg_base_words = _get_alg_mem_base_words(test, 0, WMFW_ADSP2_ZM); 584 reg = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_ZM); 585 reg += (alg_base_words + def.offset_dsp_words) * 586 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 587 regmap_raw_write(dsp->regmap, reg, reg_vals[2], def.length_bytes); 588 } 589 590 /* Download, run, stop and power-down the firmware */ 591 wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder); 592 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 593 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 594 cs_dsp_stop(dsp); 595 cs_dsp_power_down(dsp); 596 597 /* There should now be 2 or 3 controls */ 598 KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 599 cs_dsp_mock_has_zm(priv) ? 3 : 2); 600 601 /* 602 * There's no requirement for the control list to be in any 603 * particular order, so don't assume the order. 604 */ 605 for (i = 0; i < ARRAY_SIZE(ctl); i++) 606 ctl[i] = NULL; 607 608 list_for_each_entry(walkctl, &dsp->ctl_list, list) { 609 if (walkctl->alg_region.type == WMFW_ADSP2_YM) 610 ctl[0] = walkctl; 611 if (walkctl->alg_region.type == WMFW_ADSP2_XM) 612 ctl[1] = walkctl; 613 if (walkctl->alg_region.type == WMFW_ADSP2_ZM) 614 ctl[2] = walkctl; 615 } 616 617 618 /* 619 * The data should have been populated into the control cache 620 * so should be readable through the control. 621 */ 622 KUNIT_ASSERT_NOT_NULL(test, ctl[0]); 623 KUNIT_EXPECT_EQ(test, 624 cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes), 625 0); 626 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes); 627 628 KUNIT_ASSERT_NOT_NULL(test, ctl[1]); 629 KUNIT_EXPECT_EQ(test, 630 cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes), 631 0); 632 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes); 633 634 if (cs_dsp_mock_has_zm(priv)) { 635 KUNIT_ASSERT_NOT_NULL(test, ctl[2]); 636 KUNIT_EXPECT_EQ(test, 637 cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback, 638 def.length_bytes), 639 0); 640 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes); 641 } 642 } 643 644 /* 645 * Firmware with controls at the same position in different algorithms 646 * The control cache should be initialized with content from the 647 * memory of the algorithm it points to. 648 */ 649 static void cs_dsp_ctl_cache_init_multiple_algs(struct kunit *test) 650 { 651 struct cs_dsp_test *priv = test->priv; 652 struct cs_dsp *dsp = priv->dsp; 653 struct cs_dsp_test_local *local = priv->local; 654 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 655 unsigned int reg, alg_base_words; 656 struct cs_dsp_coeff_ctl *walkctl, *ctl[3]; 657 struct firmware *wmfw; 658 u32 *reg_vals[3], *readback; 659 int i; 660 661 static_assert(ARRAY_SIZE(ctl) == ARRAY_SIZE(reg_vals)); 662 static_assert(ARRAY_SIZE(reg_vals) <= ARRAY_SIZE(cs_dsp_ctl_cache_test_algs)); 663 664 for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { 665 reg_vals[i] = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 666 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals[i]); 667 get_random_bytes(reg_vals[i], def.length_bytes); 668 } 669 670 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 671 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 672 673 /* Create controls identical except for algorithm */ 674 for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { 675 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 676 cs_dsp_ctl_cache_test_algs[i].id, 677 "dummyalg", NULL); 678 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 679 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 680 } 681 682 /* Create random content in the registers backing each control */ 683 for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { 684 alg_base_words = _get_alg_mem_base_words(test, i, def.mem_type); 685 reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type); 686 reg += (alg_base_words + def.offset_dsp_words) * 687 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 688 regmap_raw_write(dsp->regmap, reg, reg_vals[i], def.length_bytes); 689 } 690 691 /* Download, run, stop and power-down the firmware */ 692 wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder); 693 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 694 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 695 cs_dsp_stop(dsp); 696 cs_dsp_power_down(dsp); 697 698 /* There should now be 3 controls */ 699 KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3); 700 701 /* 702 * There's no requirement for the control list to be in any 703 * particular order, so don't assume the order. 704 */ 705 for (i = 0; i < ARRAY_SIZE(ctl); i++) 706 ctl[i] = NULL; 707 708 list_for_each_entry(walkctl, &dsp->ctl_list, list) { 709 if (walkctl->alg_region.alg == cs_dsp_ctl_cache_test_algs[0].id) 710 ctl[0] = walkctl; 711 if (walkctl->alg_region.alg == cs_dsp_ctl_cache_test_algs[1].id) 712 ctl[1] = walkctl; 713 if (walkctl->alg_region.alg == cs_dsp_ctl_cache_test_algs[2].id) 714 ctl[2] = walkctl; 715 } 716 717 KUNIT_ASSERT_NOT_NULL(test, ctl[0]); 718 KUNIT_ASSERT_NOT_NULL(test, ctl[1]); 719 KUNIT_ASSERT_NOT_NULL(test, ctl[2]); 720 721 /* 722 * The data should have been populated into the control cache 723 * so should be readable through the control. 724 */ 725 KUNIT_EXPECT_EQ(test, 726 cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes), 727 0); 728 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes); 729 730 KUNIT_EXPECT_EQ(test, 731 cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes), 732 0); 733 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes); 734 735 KUNIT_EXPECT_EQ(test, 736 cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback, 737 def.length_bytes), 738 0); 739 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes); 740 } 741 742 /* 743 * Firmware with controls in the same algorithm and memory but at 744 * different offsets. 745 * The control cache should be initialized with content from the 746 * correct offset. 747 * Only for wmfw format V2 and later. V1 only supports one control per 748 * memory per algorithm. 749 */ 750 static void cs_dsp_ctl_cache_init_multiple_offsets(struct kunit *test) 751 { 752 struct cs_dsp_test *priv = test->priv; 753 struct cs_dsp *dsp = priv->dsp; 754 struct cs_dsp_test_local *local = priv->local; 755 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 756 unsigned int reg, alg_base_words, alg_base_reg; 757 struct cs_dsp_coeff_ctl *walkctl, *ctl[3]; 758 struct firmware *wmfw; 759 u32 *reg_vals[3], *readback; 760 int i; 761 762 static_assert(ARRAY_SIZE(ctl) == ARRAY_SIZE(reg_vals)); 763 static_assert(ARRAY_SIZE(reg_vals) <= ARRAY_SIZE(cs_dsp_ctl_cache_test_algs)); 764 765 for (i = 0; i < ARRAY_SIZE(reg_vals); i++) { 766 reg_vals[i] = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 767 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals[i]); 768 get_random_bytes(reg_vals[i], def.length_bytes); 769 } 770 771 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 772 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 773 774 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 775 cs_dsp_ctl_cache_test_algs[0].id, 776 "dummyalg", NULL); 777 778 /* Create controls identical except for offset */ 779 def.offset_dsp_words = 0; 780 def.shortname = "CtlA"; 781 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 782 783 def.offset_dsp_words = 5; 784 def.shortname = "CtlB"; 785 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 786 787 def.offset_dsp_words = 8; 788 def.shortname = "CtlC"; 789 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 790 791 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 792 793 /* Create random content in the registers backing each control */ 794 alg_base_words = _get_alg_mem_base_words(test, 0, def.mem_type); 795 alg_base_reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type); 796 alg_base_reg += alg_base_words * cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 797 798 reg = alg_base_reg; 799 regmap_raw_write(dsp->regmap, reg, reg_vals[0], def.length_bytes); 800 reg = alg_base_reg + (5 * cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv)); 801 regmap_raw_write(dsp->regmap, reg, reg_vals[1], def.length_bytes); 802 reg = alg_base_reg + (8 * cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv)); 803 regmap_raw_write(dsp->regmap, reg, reg_vals[2], def.length_bytes); 804 805 /* Download, run, stop and power-down the firmware */ 806 wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder); 807 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 808 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 809 cs_dsp_stop(dsp); 810 cs_dsp_power_down(dsp); 811 812 /* There should now be 3 controls */ 813 KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3); 814 815 /* 816 * There's no requirement for the control list to be in any 817 * particular order, so don't assume the order. 818 */ 819 for (i = 0; i < ARRAY_SIZE(ctl); i++) 820 ctl[i] = NULL; 821 822 list_for_each_entry(walkctl, &dsp->ctl_list, list) { 823 if (walkctl->offset == 0) 824 ctl[0] = walkctl; 825 if (walkctl->offset == 5) 826 ctl[1] = walkctl; 827 if (walkctl->offset == 8) 828 ctl[2] = walkctl; 829 } 830 831 KUNIT_ASSERT_NOT_NULL(test, ctl[0]); 832 KUNIT_ASSERT_NOT_NULL(test, ctl[1]); 833 KUNIT_ASSERT_NOT_NULL(test, ctl[2]); 834 835 /* 836 * The data should have been populated into the control cache 837 * so should be readable through the control. 838 */ 839 KUNIT_EXPECT_EQ(test, 840 cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes), 841 0); 842 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes); 843 844 KUNIT_EXPECT_EQ(test, 845 cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes), 846 0); 847 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes); 848 849 KUNIT_EXPECT_EQ(test, 850 cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback, 851 def.length_bytes), 852 0); 853 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes); 854 } 855 856 /* 857 * Read from a cached control before the firmware is started. 858 * Should return the data in the cache. 859 */ 860 static void cs_dsp_ctl_cache_read_not_started(struct kunit *test) 861 { 862 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 863 struct cs_dsp_test *priv = test->priv; 864 struct cs_dsp_test_local *local = priv->local; 865 struct cs_dsp *dsp = priv->dsp; 866 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 867 int alg_idx = _find_alg_entry(test, param->alg_id); 868 unsigned int reg, alg_base_words; 869 struct cs_dsp_coeff_ctl *ctl; 870 struct firmware *wmfw; 871 u32 *reg_vals, *readback; 872 873 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 874 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 875 876 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 877 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 878 879 /* Create some DSP data to be read into the control cache */ 880 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 881 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 882 reg += (alg_base_words + param->offs_words) * 883 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 884 get_random_bytes(reg_vals, param->len_bytes); 885 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 886 887 /* Create control pointing to this data */ 888 def.flags = param->flags; 889 def.mem_type = param->mem_type; 890 def.offset_dsp_words = param->offs_words; 891 def.length_bytes = param->len_bytes; 892 893 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 894 cs_dsp_ctl_cache_test_algs[alg_idx].id, 895 "dummyalg", NULL); 896 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 897 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 898 899 /* Power-up DSP but don't start firmware */ 900 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 901 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 902 903 /* Drop expected writes and the regmap cache should be clean */ 904 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 905 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 906 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 907 908 /* Control should readback the data from the control cache */ 909 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 910 KUNIT_ASSERT_NOT_NULL(test, ctl); 911 KUNIT_EXPECT_EQ(test, 912 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 913 0); 914 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 915 } 916 917 /* 918 * Read from a cached control after the firmware has been stopped. 919 * Should return the data in the cache. 920 */ 921 static void cs_dsp_ctl_cache_read_stopped(struct kunit *test) 922 { 923 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 924 struct cs_dsp_test *priv = test->priv; 925 struct cs_dsp_test_local *local = priv->local; 926 struct cs_dsp *dsp = priv->dsp; 927 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 928 int alg_idx = _find_alg_entry(test, param->alg_id); 929 unsigned int reg, alg_base_words; 930 struct cs_dsp_coeff_ctl *ctl; 931 struct firmware *wmfw; 932 u32 *reg_vals, *readback; 933 934 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 935 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 936 937 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 938 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 939 940 /* Create some DSP data to be read into the control cache */ 941 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 942 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 943 reg += (alg_base_words + param->offs_words) * 944 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 945 get_random_bytes(reg_vals, param->len_bytes); 946 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 947 948 /* Create control pointing to this data */ 949 def.flags = param->flags; 950 def.mem_type = param->mem_type; 951 def.offset_dsp_words = param->offs_words; 952 def.length_bytes = param->len_bytes; 953 954 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 955 cs_dsp_ctl_cache_test_algs[alg_idx].id, 956 "dummyalg", NULL); 957 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 958 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 959 960 /* Power-up DSP */ 961 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 962 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 963 964 /* Start and stop the firmware */ 965 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 966 cs_dsp_stop(dsp); 967 968 /* Drop expected writes and the regmap cache should be clean */ 969 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 970 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 971 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 972 973 /* Control should readback the data from the control cache */ 974 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 975 KUNIT_ASSERT_NOT_NULL(test, ctl); 976 KUNIT_EXPECT_EQ(test, 977 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 978 0); 979 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 980 } 981 982 /* 983 * Read from a cached control after the DSP has been powered-up and 984 * then powered-down without running. 985 * Should return the data in the cache. 986 */ 987 static void cs_dsp_ctl_cache_read_powered_down(struct kunit *test) 988 { 989 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 990 struct cs_dsp_test *priv = test->priv; 991 struct cs_dsp_test_local *local = priv->local; 992 struct cs_dsp *dsp = priv->dsp; 993 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 994 int alg_idx = _find_alg_entry(test, param->alg_id); 995 unsigned int reg, alg_base_words; 996 struct cs_dsp_coeff_ctl *ctl; 997 struct firmware *wmfw; 998 u32 *reg_vals, *readback; 999 1000 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 1001 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1002 1003 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1004 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1005 1006 /* Create some DSP data to be read into the control cache */ 1007 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1008 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1009 reg += (alg_base_words + param->offs_words) * 1010 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1011 get_random_bytes(reg_vals, param->len_bytes); 1012 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 1013 1014 /* Create control pointing to this data */ 1015 def.flags = param->flags; 1016 def.mem_type = param->mem_type; 1017 def.offset_dsp_words = param->offs_words; 1018 def.length_bytes = param->len_bytes; 1019 1020 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1021 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1022 "dummyalg", NULL); 1023 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1024 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1025 1026 /* Power-up DSP then power-down */ 1027 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1028 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1029 cs_dsp_power_down(dsp); 1030 1031 /* Drop expected writes and the regmap cache should be clean */ 1032 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 1033 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1034 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1035 1036 /* Control should readback the data from the control cache */ 1037 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1038 KUNIT_ASSERT_NOT_NULL(test, ctl); 1039 KUNIT_EXPECT_EQ(test, 1040 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 1041 0); 1042 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 1043 } 1044 1045 /* 1046 * Read from a cached control after the firmware has been run and 1047 * stopped, then the DSP has been powered-down. 1048 * Should return the data in the cache. 1049 */ 1050 static void cs_dsp_ctl_cache_read_stopped_powered_down(struct kunit *test) 1051 { 1052 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1053 struct cs_dsp_test *priv = test->priv; 1054 struct cs_dsp_test_local *local = priv->local; 1055 struct cs_dsp *dsp = priv->dsp; 1056 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1057 int alg_idx = _find_alg_entry(test, param->alg_id); 1058 unsigned int reg, alg_base_words; 1059 struct cs_dsp_coeff_ctl *ctl; 1060 struct firmware *wmfw; 1061 u32 *reg_vals, *readback; 1062 1063 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 1064 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1065 1066 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1067 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1068 1069 /* Create some DSP data to be read into the control cache */ 1070 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1071 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1072 reg += (alg_base_words + param->offs_words) * 1073 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1074 get_random_bytes(reg_vals, param->len_bytes); 1075 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 1076 1077 /* Create control pointing to this data */ 1078 def.flags = param->flags; 1079 def.mem_type = param->mem_type; 1080 def.offset_dsp_words = param->offs_words; 1081 def.length_bytes = param->len_bytes; 1082 1083 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1084 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1085 "dummyalg", NULL); 1086 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1087 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1088 1089 /* Power-up DSP */ 1090 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1091 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1092 1093 /* Start and stop the firmware then power-down */ 1094 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1095 cs_dsp_stop(dsp); 1096 cs_dsp_power_down(dsp); 1097 1098 /* Drop expected writes and the regmap cache should be clean */ 1099 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 1100 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1101 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1102 1103 /* Control should readback the data from the control cache */ 1104 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1105 KUNIT_ASSERT_NOT_NULL(test, ctl); 1106 KUNIT_EXPECT_EQ(test, 1107 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 1108 0); 1109 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 1110 } 1111 1112 /* 1113 * Read from a cached control when a different firmware is currently 1114 * loaded into the DSP. 1115 * Should return the data in the cache. 1116 */ 1117 static void cs_dsp_ctl_cache_read_not_current_loaded_fw(struct kunit *test) 1118 { 1119 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1120 struct cs_dsp_test *priv = test->priv; 1121 struct cs_dsp_test_local *local = priv->local; 1122 struct cs_dsp *dsp = priv->dsp; 1123 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1124 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); 1125 int alg_idx = _find_alg_entry(test, param->alg_id); 1126 unsigned int reg, alg_base_words; 1127 struct cs_dsp_coeff_ctl *ctl; 1128 struct firmware *wmfw; 1129 u32 *reg_vals, *readback; 1130 1131 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 1132 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1133 1134 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1135 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1136 1137 /* Create some DSP data to be read into the control cache */ 1138 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1139 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1140 reg += (alg_base_words + param->offs_words) * 1141 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1142 get_random_bytes(reg_vals, param->len_bytes); 1143 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 1144 1145 /* Create control pointing to this data */ 1146 def.flags = param->flags; 1147 def.mem_type = param->mem_type; 1148 def.offset_dsp_words = param->offs_words; 1149 def.length_bytes = param->len_bytes; 1150 1151 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1152 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1153 "dummyalg", NULL); 1154 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1155 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1156 1157 /* Power-up DSP */ 1158 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1159 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1160 1161 /* Power-down DSP then power-up with a different firmware */ 1162 cs_dsp_power_down(dsp); 1163 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2); 1164 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0); 1165 1166 /* Drop expected writes and the regmap cache should be clean */ 1167 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 1168 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1169 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1170 1171 /* Control should readback the data from the control cache */ 1172 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1173 KUNIT_ASSERT_NOT_NULL(test, ctl); 1174 KUNIT_EXPECT_EQ(test, 1175 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 1176 0); 1177 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 1178 } 1179 1180 /* 1181 * Read from a cached control when a different firmware is currently 1182 * running. 1183 * Should return the data in the cache. 1184 */ 1185 static void cs_dsp_ctl_cache_read_not_current_running_fw(struct kunit *test) 1186 { 1187 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1188 struct cs_dsp_test *priv = test->priv; 1189 struct cs_dsp_test_local *local = priv->local; 1190 struct cs_dsp *dsp = priv->dsp; 1191 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1192 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); 1193 int alg_idx = _find_alg_entry(test, param->alg_id); 1194 unsigned int reg, alg_base_words; 1195 struct cs_dsp_coeff_ctl *ctl; 1196 struct firmware *wmfw; 1197 u32 *reg_vals, *readback; 1198 1199 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 1200 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1201 1202 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1203 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1204 1205 /* Create some DSP data to be read into the control cache */ 1206 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1207 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1208 reg += (alg_base_words + param->offs_words) * 1209 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1210 get_random_bytes(reg_vals, param->len_bytes); 1211 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 1212 1213 /* Create control pointing to this data */ 1214 def.flags = param->flags; 1215 def.mem_type = param->mem_type; 1216 def.offset_dsp_words = param->offs_words; 1217 def.length_bytes = param->len_bytes; 1218 1219 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1220 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1221 "dummyalg", NULL); 1222 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1223 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1224 1225 /* Power-up DSP then power-down */ 1226 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1227 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1228 cs_dsp_power_down(dsp); 1229 1230 /* Power-up with a different firmware and run it */ 1231 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2); 1232 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0); 1233 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1234 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1235 1236 /* Drop expected writes and the regmap cache should be clean */ 1237 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 1238 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1239 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1240 1241 /* Control should readback the data from the control cache */ 1242 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1243 KUNIT_ASSERT_NOT_NULL(test, ctl); 1244 KUNIT_EXPECT_EQ(test, 1245 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 1246 0); 1247 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 1248 } 1249 1250 /* 1251 * Read from a cached control with non-zero flags while the firmware is 1252 * running. 1253 * Should return the data in the cache, not from the registers. 1254 */ 1255 static void cs_dsp_ctl_cache_read_running(struct kunit *test) 1256 { 1257 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1258 struct cs_dsp_test *priv = test->priv; 1259 struct cs_dsp_test_local *local = priv->local; 1260 struct cs_dsp *dsp = priv->dsp; 1261 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1262 int alg_idx = _find_alg_entry(test, param->alg_id); 1263 unsigned int reg, alg_base_words; 1264 struct cs_dsp_coeff_ctl *ctl; 1265 struct firmware *wmfw; 1266 u32 *init_reg_vals, *new_reg_vals, *readback; 1267 1268 init_reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 1269 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_reg_vals); 1270 1271 new_reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1272 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_reg_vals); 1273 1274 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1275 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1276 1277 /* Create data in the registers backing the control */ 1278 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1279 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1280 reg += (alg_base_words + param->offs_words) * 1281 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1282 get_random_bytes(init_reg_vals, param->len_bytes); 1283 regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes); 1284 1285 /* Create control pointing to this data */ 1286 def.flags = param->flags; 1287 def.mem_type = param->mem_type; 1288 def.offset_dsp_words = param->offs_words; 1289 def.length_bytes = param->len_bytes; 1290 1291 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1292 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1293 "dummyalg", NULL); 1294 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1295 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1296 1297 /* Power-up DSP */ 1298 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1299 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1300 1301 /* Start the firmware running */ 1302 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1303 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1304 1305 /* 1306 * Change the values in the registers backing the control then drop 1307 * them from the regmap cache. This allows checking that the control 1308 * read is returning values from the control cache and not accessing 1309 * the registers. 1310 */ 1311 KUNIT_ASSERT_EQ(test, 1312 regmap_raw_write(dsp->regmap, reg, new_reg_vals, param->len_bytes), 1313 0); 1314 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1315 1316 /* Control should readback the origin data from its cache */ 1317 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1318 KUNIT_ASSERT_NOT_NULL(test, ctl); 1319 KUNIT_EXPECT_EQ(test, 1320 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 1321 0); 1322 KUNIT_EXPECT_MEMEQ(test, readback, init_reg_vals, param->len_bytes); 1323 1324 /* Stop and power-down the DSP */ 1325 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 1326 cs_dsp_power_down(dsp); 1327 1328 /* Control should readback from the cache */ 1329 KUNIT_EXPECT_EQ(test, 1330 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 1331 0); 1332 KUNIT_EXPECT_MEMEQ(test, readback, init_reg_vals, param->len_bytes); 1333 } 1334 1335 /* 1336 * Read from a cached control with flags == 0 while the firmware is 1337 * running. 1338 * Should behave as volatile and read from the registers. 1339 * (This is for backwards compatibility with old firmware versions) 1340 */ 1341 static void cs_dsp_ctl_cache_read_running_zero_flags(struct kunit *test) 1342 { 1343 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1344 struct cs_dsp_test *priv = test->priv; 1345 struct cs_dsp_test_local *local = priv->local; 1346 struct cs_dsp *dsp = priv->dsp; 1347 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1348 int alg_idx = _find_alg_entry(test, param->alg_id); 1349 unsigned int reg, alg_base_words; 1350 struct cs_dsp_coeff_ctl *ctl; 1351 struct firmware *wmfw; 1352 u32 *init_reg_vals, *new_reg_vals, *readback; 1353 1354 init_reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1355 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_reg_vals); 1356 1357 new_reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 1358 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_reg_vals); 1359 1360 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1361 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1362 1363 /* Zero-fill the registers backing the control */ 1364 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1365 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1366 reg += (alg_base_words + param->offs_words) * 1367 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1368 regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes); 1369 1370 /* Create control pointing to this data */ 1371 def.flags = 0; 1372 def.mem_type = param->mem_type; 1373 def.offset_dsp_words = param->offs_words; 1374 def.length_bytes = param->len_bytes; 1375 1376 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1377 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1378 "dummyalg", NULL); 1379 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1380 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1381 1382 /* Power-up DSP */ 1383 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1384 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1385 1386 /* Start the firmware running */ 1387 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1388 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1389 1390 /* Change the values in the registers backing the control */ 1391 get_random_bytes(new_reg_vals, param->len_bytes); 1392 regmap_raw_write(dsp->regmap, reg, new_reg_vals, param->len_bytes); 1393 1394 /* Control should readback the new data from the registers */ 1395 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1396 KUNIT_ASSERT_NOT_NULL(test, ctl); 1397 KUNIT_EXPECT_EQ(test, 1398 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 1399 0); 1400 KUNIT_EXPECT_MEMEQ(test, readback, new_reg_vals, param->len_bytes); 1401 1402 /* Stop and power-down the DSP */ 1403 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 1404 cs_dsp_power_down(dsp); 1405 1406 /* Change the values in the registers backing the control */ 1407 regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes); 1408 1409 /* Control should readback from the cache */ 1410 KUNIT_EXPECT_EQ(test, 1411 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 1412 0); 1413 KUNIT_EXPECT_MEMEQ(test, readback, new_reg_vals, param->len_bytes); 1414 } 1415 1416 /* 1417 * Write to a cached control while the firmware is running. 1418 * This should be a writethrough operation, writing to the cache and 1419 * the registers. 1420 */ 1421 static void cs_dsp_ctl_cache_writethrough(struct kunit *test) 1422 { 1423 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1424 struct cs_dsp_test *priv = test->priv; 1425 struct cs_dsp_test_local *local = priv->local; 1426 struct cs_dsp *dsp = priv->dsp; 1427 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1428 int alg_idx = _find_alg_entry(test, param->alg_id); 1429 unsigned int reg, alg_base_words; 1430 struct cs_dsp_coeff_ctl *ctl; 1431 struct firmware *wmfw; 1432 u32 *reg_vals, *readback; 1433 1434 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 1435 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1436 1437 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1438 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1439 1440 /* Create some DSP data to be read into the control cache */ 1441 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1442 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1443 reg += (alg_base_words + param->offs_words) * 1444 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1445 memset(reg_vals, 0, param->len_bytes); 1446 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 1447 1448 /* Create control pointing to this data */ 1449 def.flags = param->flags; 1450 def.mem_type = param->mem_type; 1451 def.offset_dsp_words = param->offs_words; 1452 def.length_bytes = param->len_bytes; 1453 1454 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1455 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1456 "dummyalg", NULL); 1457 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1458 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1459 1460 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1461 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1462 1463 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1464 KUNIT_ASSERT_NOT_NULL(test, ctl); 1465 1466 /* Start the firmware and add an action to stop it during cleanup */ 1467 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1468 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1469 1470 /* Write new data to the control, it should be written to the registers */ 1471 get_random_bytes(reg_vals, param->len_bytes); 1472 KUNIT_EXPECT_EQ(test, 1473 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 1474 1); 1475 KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 1476 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 1477 } 1478 1479 /* 1480 * Write unchanged data to a cached control while the firmware is running. 1481 * The control write should return 0 to indicate that the content 1482 * didn't change. 1483 */ 1484 static void cs_dsp_ctl_cache_writethrough_unchanged(struct kunit *test) 1485 { 1486 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1487 struct cs_dsp_test *priv = test->priv; 1488 struct cs_dsp_test_local *local = priv->local; 1489 struct cs_dsp *dsp = priv->dsp; 1490 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1491 int alg_idx = _find_alg_entry(test, param->alg_id); 1492 unsigned int reg, alg_base_words; 1493 struct cs_dsp_coeff_ctl *ctl; 1494 struct firmware *wmfw; 1495 u32 *reg_vals, *readback; 1496 1497 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 1498 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1499 1500 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1501 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1502 1503 /* Create some DSP data to be read into the control cache */ 1504 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1505 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1506 reg += (alg_base_words + param->offs_words) * 1507 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1508 get_random_bytes(reg_vals, param->len_bytes); 1509 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 1510 1511 /* Create control pointing to this data */ 1512 def.flags = param->flags; 1513 def.mem_type = param->mem_type; 1514 def.offset_dsp_words = param->offs_words; 1515 def.length_bytes = param->len_bytes; 1516 1517 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1518 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1519 "dummyalg", NULL); 1520 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1521 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1522 1523 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1524 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1525 1526 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1527 KUNIT_ASSERT_NOT_NULL(test, ctl); 1528 1529 /* Start the firmware and add an action to stop it during cleanup */ 1530 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1531 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1532 1533 /* 1534 * If the control is write-only the cache will have been zero-initialized 1535 * so the first write will always indicate a change. 1536 */ 1537 if (def.flags && !(def.flags & WMFW_CTL_FLAG_READABLE)) { 1538 KUNIT_EXPECT_EQ(test, 1539 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, 1540 param->len_bytes), 1541 1); 1542 } 1543 1544 /* 1545 * Write the same data to the control, cs_dsp_coeff_lock_and_write_ctrl() 1546 * should return 0 to indicate the content didn't change. 1547 */ 1548 KUNIT_EXPECT_EQ(test, 1549 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 1550 0); 1551 KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 1552 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 1553 } 1554 1555 /* 1556 * Write unchanged data to a cached control while the firmware is not started. 1557 * The control write should return 0 to indicate that the cache content 1558 * didn't change. 1559 */ 1560 static void cs_dsp_ctl_cache_write_unchanged_not_started(struct kunit *test) 1561 { 1562 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1563 struct cs_dsp_test *priv = test->priv; 1564 struct cs_dsp_test_local *local = priv->local; 1565 struct cs_dsp *dsp = priv->dsp; 1566 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1567 int alg_idx = _find_alg_entry(test, param->alg_id); 1568 unsigned int reg, alg_base_words; 1569 struct cs_dsp_coeff_ctl *ctl; 1570 struct firmware *wmfw; 1571 u32 *reg_vals, *readback; 1572 1573 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 1574 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1575 1576 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1577 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1578 1579 /* Create some DSP data to be read into the control cache */ 1580 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1581 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1582 reg += (alg_base_words + param->offs_words) * 1583 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1584 get_random_bytes(reg_vals, param->len_bytes); 1585 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 1586 1587 /* Create control pointing to this data */ 1588 def.flags = param->flags; 1589 def.mem_type = param->mem_type; 1590 def.offset_dsp_words = param->offs_words; 1591 def.length_bytes = param->len_bytes; 1592 1593 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1594 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1595 "dummyalg", NULL); 1596 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1597 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1598 1599 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1600 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1601 1602 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1603 KUNIT_ASSERT_NOT_NULL(test, ctl); 1604 1605 /* 1606 * If the control is write-only the cache will have been zero-initialized 1607 * so the first write will always indicate a change. 1608 */ 1609 if (def.flags && !(def.flags & WMFW_CTL_FLAG_READABLE)) { 1610 KUNIT_EXPECT_EQ(test, 1611 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, 1612 param->len_bytes), 1613 1); 1614 } 1615 1616 /* 1617 * Write the same data to the control, cs_dsp_coeff_lock_and_write_ctrl() 1618 * should return 0 to indicate the content didn't change. 1619 */ 1620 KUNIT_EXPECT_EQ(test, 1621 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 1622 0); 1623 KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 1624 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 1625 } 1626 1627 /* 1628 * Write to a cached control while the firmware is loaded but not 1629 * started. 1630 * This should write to the cache only. 1631 */ 1632 static void cs_dsp_ctl_cache_write_not_started(struct kunit *test) 1633 { 1634 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1635 struct cs_dsp_test *priv = test->priv; 1636 struct cs_dsp_test_local *local = priv->local; 1637 struct cs_dsp *dsp = priv->dsp; 1638 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1639 int alg_idx = _find_alg_entry(test, param->alg_id); 1640 unsigned int reg, alg_base_words; 1641 struct cs_dsp_coeff_ctl *ctl; 1642 struct firmware *wmfw; 1643 u32 *reg_vals, *readback; 1644 1645 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1646 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1647 1648 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1649 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1650 1651 /* Create some DSP data to be read into the control cache */ 1652 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1653 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1654 reg += (alg_base_words + param->offs_words) * 1655 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1656 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 1657 1658 /* Create control pointing to this data */ 1659 def.flags = param->flags; 1660 def.mem_type = param->mem_type; 1661 def.offset_dsp_words = param->offs_words; 1662 def.length_bytes = param->len_bytes; 1663 1664 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1665 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1666 "dummyalg", NULL); 1667 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1668 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1669 1670 /* Power-up DSP but don't start firmware */ 1671 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1672 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1673 1674 /* Drop expected writes and the regmap cache should be clean */ 1675 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 1676 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1677 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1678 1679 /* Write new data to the control, it should not be written to the registers */ 1680 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1681 KUNIT_ASSERT_NOT_NULL(test, ctl); 1682 1683 get_random_bytes(reg_vals, param->len_bytes); 1684 KUNIT_EXPECT_EQ(test, 1685 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 1686 1); 1687 1688 /* Registers should not have been written so regmap cache should still be clean */ 1689 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1690 1691 /* Control should readback the new data from the control cache */ 1692 KUNIT_EXPECT_EQ(test, 1693 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 1694 0); 1695 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 1696 } 1697 1698 /* 1699 * Write to a cached control after the firmware has been loaded, 1700 * started and stopped. 1701 * This should write to the cache only. 1702 */ 1703 static void cs_dsp_ctl_cache_write_stopped(struct kunit *test) 1704 { 1705 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1706 struct cs_dsp_test *priv = test->priv; 1707 struct cs_dsp_test_local *local = priv->local; 1708 struct cs_dsp *dsp = priv->dsp; 1709 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1710 int alg_idx = _find_alg_entry(test, param->alg_id); 1711 unsigned int reg, alg_base_words; 1712 struct cs_dsp_coeff_ctl *ctl; 1713 struct firmware *wmfw; 1714 u32 *reg_vals, *readback; 1715 1716 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1717 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1718 1719 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1720 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1721 1722 /* Create some DSP data to be read into the control cache */ 1723 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1724 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1725 reg += (alg_base_words + param->offs_words) * 1726 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1727 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 1728 1729 /* Create control pointing to this data */ 1730 def.flags = param->flags; 1731 def.mem_type = param->mem_type; 1732 def.offset_dsp_words = param->offs_words; 1733 def.length_bytes = param->len_bytes; 1734 1735 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1736 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1737 "dummyalg", NULL); 1738 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1739 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1740 1741 /* Power-up DSP */ 1742 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1743 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1744 1745 /* Start and stop the firmware */ 1746 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1747 cs_dsp_stop(dsp); 1748 1749 /* Drop expected writes and the regmap cache should be clean */ 1750 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 1751 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1752 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1753 1754 /* Write new data to the control, it should not be written to the registers */ 1755 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1756 KUNIT_ASSERT_NOT_NULL(test, ctl); 1757 1758 get_random_bytes(reg_vals, param->len_bytes); 1759 KUNIT_EXPECT_EQ(test, 1760 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 1761 1); 1762 1763 /* Registers should not have been written so regmap cache should still be clean */ 1764 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1765 1766 /* Control should readback the new data from the control cache */ 1767 KUNIT_EXPECT_EQ(test, 1768 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 1769 0); 1770 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 1771 } 1772 1773 /* 1774 * Write to a cached control after the firmware has been loaded, 1775 * then the DSP powered-down. 1776 * This should write to the cache only. 1777 */ 1778 static void cs_dsp_ctl_cache_write_powered_down(struct kunit *test) 1779 { 1780 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1781 struct cs_dsp_test *priv = test->priv; 1782 struct cs_dsp_test_local *local = priv->local; 1783 struct cs_dsp *dsp = priv->dsp; 1784 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1785 int alg_idx = _find_alg_entry(test, param->alg_id); 1786 unsigned int reg, alg_base_words; 1787 struct cs_dsp_coeff_ctl *ctl; 1788 struct firmware *wmfw; 1789 u32 *reg_vals, *readback; 1790 1791 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1792 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1793 1794 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1795 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1796 1797 /* Create some DSP data to be read into the control cache */ 1798 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1799 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1800 reg += (alg_base_words + param->offs_words) * 1801 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1802 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 1803 1804 /* Create control pointing to this data */ 1805 def.flags = param->flags; 1806 def.mem_type = param->mem_type; 1807 def.offset_dsp_words = param->offs_words; 1808 def.length_bytes = param->len_bytes; 1809 1810 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1811 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1812 "dummyalg", NULL); 1813 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1814 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1815 1816 /* Power-up DSP then power-down */ 1817 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1818 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1819 cs_dsp_power_down(dsp); 1820 1821 /* Drop expected writes and the regmap cache should be clean */ 1822 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 1823 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1824 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1825 1826 /* Write new data to the control, it should not be written to the registers */ 1827 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1828 KUNIT_ASSERT_NOT_NULL(test, ctl); 1829 1830 get_random_bytes(reg_vals, param->len_bytes); 1831 KUNIT_EXPECT_EQ(test, 1832 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 1833 1); 1834 1835 /* Registers should not have been written so regmap cache should still be clean */ 1836 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1837 1838 /* Control should readback the new data from the control cache */ 1839 KUNIT_EXPECT_EQ(test, 1840 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 1841 0); 1842 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 1843 } 1844 1845 /* 1846 * Write to a cached control after the firmware has been loaded, 1847 * started, stopped, and then the DSP powered-down. 1848 * This should write to the cache only. 1849 */ 1850 static void cs_dsp_ctl_cache_write_stopped_powered_down(struct kunit *test) 1851 { 1852 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1853 struct cs_dsp_test *priv = test->priv; 1854 struct cs_dsp_test_local *local = priv->local; 1855 struct cs_dsp *dsp = priv->dsp; 1856 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1857 int alg_idx = _find_alg_entry(test, param->alg_id); 1858 unsigned int reg, alg_base_words; 1859 struct cs_dsp_coeff_ctl *ctl; 1860 struct firmware *wmfw; 1861 u32 *reg_vals, *readback; 1862 1863 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1864 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1865 1866 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1867 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1868 1869 /* Create some DSP data to be read into the control cache */ 1870 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1871 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1872 reg += (alg_base_words + param->offs_words) * 1873 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1874 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 1875 1876 /* Create control pointing to this data */ 1877 def.flags = param->flags; 1878 def.mem_type = param->mem_type; 1879 def.offset_dsp_words = param->offs_words; 1880 def.length_bytes = param->len_bytes; 1881 1882 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1883 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1884 "dummyalg", NULL); 1885 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1886 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1887 1888 /* Power-up DSP */ 1889 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1890 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1891 1892 /* Start and stop the firmware then power-down */ 1893 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1894 cs_dsp_stop(dsp); 1895 cs_dsp_power_down(dsp); 1896 1897 /* Drop expected writes and the regmap cache should be clean */ 1898 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 1899 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1900 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1901 1902 /* Write new data to the control, it should not be written to the registers */ 1903 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1904 KUNIT_ASSERT_NOT_NULL(test, ctl); 1905 1906 get_random_bytes(reg_vals, param->len_bytes); 1907 KUNIT_EXPECT_EQ(test, 1908 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 1909 1); 1910 1911 /* Registers should not have been written so regmap cache should still be clean */ 1912 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1913 1914 /* Control should readback the new data from the control cache */ 1915 KUNIT_EXPECT_EQ(test, 1916 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 1917 0); 1918 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 1919 } 1920 1921 /* 1922 * Write to a cached control that is not in the currently loaded firmware. 1923 * This should write to the cache only. 1924 */ 1925 static void cs_dsp_ctl_cache_write_not_current_loaded_fw(struct kunit *test) 1926 { 1927 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 1928 struct cs_dsp_test *priv = test->priv; 1929 struct cs_dsp_test_local *local = priv->local; 1930 struct cs_dsp *dsp = priv->dsp; 1931 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1932 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); 1933 int alg_idx = _find_alg_entry(test, param->alg_id); 1934 unsigned int reg, alg_base_words; 1935 struct cs_dsp_coeff_ctl *ctl; 1936 struct firmware *wmfw; 1937 u32 *reg_vals, *readback; 1938 1939 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1940 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1941 1942 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 1943 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1944 1945 /* Create some DSP data to be read into the control cache */ 1946 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1947 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1948 reg += (alg_base_words + param->offs_words) * 1949 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1950 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 1951 1952 /* Create control pointing to this data */ 1953 def.flags = param->flags; 1954 def.mem_type = param->mem_type; 1955 def.offset_dsp_words = param->offs_words; 1956 def.length_bytes = param->len_bytes; 1957 1958 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1959 cs_dsp_ctl_cache_test_algs[alg_idx].id, 1960 "dummyalg", NULL); 1961 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1962 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1963 1964 /* Power-up DSP */ 1965 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1966 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1967 1968 /* Get the control */ 1969 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1970 KUNIT_ASSERT_NOT_NULL(test, ctl); 1971 1972 /* Power-down DSP then power-up with a different firmware */ 1973 cs_dsp_power_down(dsp); 1974 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2); 1975 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0); 1976 1977 /* Control from unloaded firmware should be disabled */ 1978 KUNIT_EXPECT_FALSE(test, ctl->enabled); 1979 1980 /* Drop expected writes and the regmap cache should be clean */ 1981 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 1982 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1983 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1984 1985 /* 1986 * It should be possible to write new data to the control from 1987 * the first firmware. But this should not be written to the 1988 * registers. 1989 */ 1990 get_random_bytes(reg_vals, param->len_bytes); 1991 KUNIT_EXPECT_EQ(test, 1992 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 1993 1); 1994 1995 /* Registers should not have been written so regmap cache should still be clean */ 1996 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1997 1998 /* Control should readback the new data from the control cache */ 1999 KUNIT_EXPECT_EQ(test, 2000 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 2001 0); 2002 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 2003 } 2004 2005 /* 2006 * Write to a cached control that is not in the currently running firmware. 2007 * This should write to the cache only. 2008 */ 2009 static void cs_dsp_ctl_cache_write_not_current_running_fw(struct kunit *test) 2010 { 2011 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 2012 struct cs_dsp_test *priv = test->priv; 2013 struct cs_dsp_test_local *local = priv->local; 2014 struct cs_dsp *dsp = priv->dsp; 2015 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 2016 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); 2017 int alg_idx = _find_alg_entry(test, param->alg_id); 2018 unsigned int reg, alg_base_words; 2019 struct cs_dsp_coeff_ctl *ctl; 2020 struct firmware *wmfw; 2021 u32 *reg_vals, *readback; 2022 2023 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2024 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 2025 2026 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2027 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 2028 2029 /* Create some DSP data to be read into the control cache */ 2030 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 2031 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 2032 reg += (alg_base_words + param->offs_words) * 2033 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 2034 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 2035 2036 /* Create control pointing to this data */ 2037 def.flags = param->flags; 2038 def.mem_type = param->mem_type; 2039 def.offset_dsp_words = param->offs_words; 2040 def.length_bytes = param->len_bytes; 2041 2042 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 2043 cs_dsp_ctl_cache_test_algs[alg_idx].id, 2044 "dummyalg", NULL); 2045 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 2046 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 2047 2048 /* Power-up DSP then power-down */ 2049 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 2050 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 2051 cs_dsp_power_down(dsp); 2052 2053 /* Get the control */ 2054 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 2055 KUNIT_ASSERT_NOT_NULL(test, ctl); 2056 2057 /* Power-up with a different firmware and run it */ 2058 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2); 2059 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0); 2060 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2061 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2062 2063 /* Control from unloaded firmware should be disabled */ 2064 KUNIT_EXPECT_FALSE(test, ctl->enabled); 2065 2066 /* Drop expected writes and the regmap cache should be clean */ 2067 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 2068 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 2069 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 2070 2071 /* 2072 * It should be possible to write new data to the control from 2073 * the first firmware. But this should not be written to the 2074 * registers. 2075 */ 2076 get_random_bytes(reg_vals, param->len_bytes); 2077 KUNIT_EXPECT_EQ(test, 2078 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 2079 1); 2080 2081 /* Registers should not have been written so regmap cache should still be clean */ 2082 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 2083 2084 /* Control should readback the new data from the control cache */ 2085 KUNIT_EXPECT_EQ(test, 2086 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 2087 0); 2088 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 2089 } 2090 2091 /* 2092 * Write to a cached control before running the firmware. 2093 * The value written to the cache should be synced out to the registers 2094 * backing the control when the firmware is run. 2095 */ 2096 static void cs_dsp_ctl_cache_sync_write_before_run(struct kunit *test) 2097 { 2098 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 2099 struct cs_dsp_test *priv = test->priv; 2100 struct cs_dsp_test_local *local = priv->local; 2101 struct cs_dsp *dsp = priv->dsp; 2102 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 2103 int alg_idx = _find_alg_entry(test, param->alg_id); 2104 unsigned int reg, alg_base_words; 2105 struct cs_dsp_coeff_ctl *ctl; 2106 struct firmware *wmfw; 2107 u32 *reg_vals, *readback; 2108 2109 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2110 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 2111 2112 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2113 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 2114 2115 /* Create some DSP data to be read into the control cache */ 2116 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 2117 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 2118 reg += (alg_base_words + param->offs_words) * 2119 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 2120 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 2121 2122 /* Create control pointing to this data */ 2123 def.flags = param->flags; 2124 def.mem_type = param->mem_type; 2125 def.offset_dsp_words = param->offs_words; 2126 def.length_bytes = param->len_bytes; 2127 2128 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 2129 cs_dsp_ctl_cache_test_algs[alg_idx].id, 2130 "dummyalg", NULL); 2131 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 2132 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 2133 2134 /* Power-up DSP but don't start firmware */ 2135 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 2136 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 2137 2138 /* Write new data to the control, it should not be written to the registers */ 2139 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 2140 KUNIT_ASSERT_NOT_NULL(test, ctl); 2141 2142 get_random_bytes(reg_vals, param->len_bytes); 2143 KUNIT_EXPECT_EQ(test, 2144 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 2145 1); 2146 2147 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2148 KUNIT_EXPECT_MEMNEQ(test, readback, reg_vals, param->len_bytes); 2149 2150 /* Start the firmware and the cached data should be written to registers */ 2151 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2152 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2153 2154 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2155 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 2156 2157 /* Control should readback the new data from the control cache */ 2158 KUNIT_EXPECT_EQ(test, 2159 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 2160 0); 2161 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 2162 } 2163 2164 /* 2165 * Write to a cached control while the firmware is running. 2166 * The value written should be synced out to the registers 2167 * backing the control when the firmware is next run. 2168 */ 2169 static void cs_dsp_ctl_cache_sync_write_while_running(struct kunit *test) 2170 { 2171 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 2172 struct cs_dsp_test *priv = test->priv; 2173 struct cs_dsp_test_local *local = priv->local; 2174 struct cs_dsp *dsp = priv->dsp; 2175 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 2176 int alg_idx = _find_alg_entry(test, param->alg_id); 2177 unsigned int reg, alg_base_words; 2178 struct cs_dsp_coeff_ctl *ctl; 2179 struct firmware *wmfw; 2180 u32 *init_vals, *ctl_vals, *readback; 2181 2182 init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2183 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals); 2184 2185 ctl_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2186 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals); 2187 2188 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2189 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 2190 2191 /* Zero-fill the registers backing the control */ 2192 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 2193 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 2194 reg += (alg_base_words + param->offs_words) * 2195 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 2196 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes); 2197 2198 /* Create control pointing to this data */ 2199 def.flags = param->flags; 2200 def.mem_type = param->mem_type; 2201 def.offset_dsp_words = param->offs_words; 2202 def.length_bytes = param->len_bytes; 2203 2204 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 2205 cs_dsp_ctl_cache_test_algs[alg_idx].id, 2206 "dummyalg", NULL); 2207 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 2208 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 2209 2210 /* Power-up DSP and start firmware */ 2211 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 2212 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 2213 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2214 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2215 2216 /* Write new data to the control */ 2217 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 2218 KUNIT_ASSERT_NOT_NULL(test, ctl); 2219 2220 get_random_bytes(ctl_vals, param->len_bytes); 2221 KUNIT_EXPECT_EQ(test, 2222 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, param->len_bytes), 2223 1); 2224 2225 /* Stop firmware and zero the registers backing the control */ 2226 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 2227 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes); 2228 KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2229 KUNIT_EXPECT_MEMEQ(test, readback, init_vals, param->len_bytes); 2230 2231 /* Start the firmware and the cached data should be written to registers */ 2232 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2233 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2234 2235 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2236 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes); 2237 2238 /* Control should readback the new data from the control cache */ 2239 KUNIT_EXPECT_EQ(test, 2240 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 2241 0); 2242 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes); 2243 } 2244 2245 /* 2246 * Write to a cached control after stopping the firmware. 2247 * The value written to the cache should be synced out to the registers 2248 * backing the control when the firmware is next run. 2249 */ 2250 static void cs_dsp_ctl_cache_sync_write_after_stop(struct kunit *test) 2251 { 2252 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 2253 struct cs_dsp_test *priv = test->priv; 2254 struct cs_dsp_test_local *local = priv->local; 2255 struct cs_dsp *dsp = priv->dsp; 2256 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 2257 int alg_idx = _find_alg_entry(test, param->alg_id); 2258 unsigned int reg, alg_base_words; 2259 struct cs_dsp_coeff_ctl *ctl; 2260 struct firmware *wmfw; 2261 u32 *reg_vals, *readback; 2262 2263 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2264 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 2265 2266 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2267 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 2268 2269 /* Create some DSP data to be read into the control cache */ 2270 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 2271 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 2272 reg += (alg_base_words + param->offs_words) * 2273 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 2274 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 2275 2276 /* Create control pointing to this data */ 2277 def.flags = param->flags; 2278 def.mem_type = param->mem_type; 2279 def.offset_dsp_words = param->offs_words; 2280 def.length_bytes = param->len_bytes; 2281 2282 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 2283 cs_dsp_ctl_cache_test_algs[alg_idx].id, 2284 "dummyalg", NULL); 2285 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 2286 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 2287 2288 /* Power-up DSP but don't start firmware */ 2289 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 2290 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 2291 2292 /* Start and stop the firmware */ 2293 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2294 cs_dsp_stop(dsp); 2295 2296 /* Write new data to the control, it should not be written to the registers */ 2297 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 2298 KUNIT_ASSERT_NOT_NULL(test, ctl); 2299 2300 get_random_bytes(reg_vals, param->len_bytes); 2301 KUNIT_EXPECT_EQ(test, 2302 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 2303 1); 2304 2305 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2306 KUNIT_EXPECT_MEMNEQ(test, readback, reg_vals, param->len_bytes); 2307 2308 /* Start the firmware and the cached data should be written to registers */ 2309 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2310 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2311 2312 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2313 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 2314 2315 /* Control should readback the new data from the control cache */ 2316 KUNIT_EXPECT_EQ(test, 2317 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 2318 0); 2319 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 2320 } 2321 2322 /* 2323 * Write to a cached control that is not in the currently loaded firmware. 2324 * The value written to the cache should be synced out to the registers 2325 * backing the control the next time the firmware containing the 2326 * control is run. 2327 */ 2328 static void cs_dsp_ctl_cache_sync_write_not_current_fw(struct kunit *test) 2329 { 2330 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 2331 struct cs_dsp_test *priv = test->priv; 2332 struct cs_dsp_test_local *local = priv->local; 2333 struct cs_dsp *dsp = priv->dsp; 2334 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 2335 int alg_idx = _find_alg_entry(test, param->alg_id); 2336 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); 2337 unsigned int reg, alg_base_words; 2338 struct cs_dsp_coeff_ctl *ctl; 2339 struct firmware *wmfw; 2340 u32 *reg_vals, *readback; 2341 2342 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2343 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 2344 2345 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2346 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 2347 2348 /* Create some DSP data to be read into the control cache */ 2349 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 2350 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 2351 reg += (alg_base_words + param->offs_words) * 2352 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 2353 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 2354 2355 /* Create control pointing to this data */ 2356 def.flags = param->flags; 2357 def.mem_type = param->mem_type; 2358 def.offset_dsp_words = param->offs_words; 2359 def.length_bytes = param->len_bytes; 2360 2361 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 2362 cs_dsp_ctl_cache_test_algs[alg_idx].id, 2363 "dummyalg", NULL); 2364 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 2365 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 2366 2367 /* Power-up DSP but don't start firmware */ 2368 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 2369 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 2370 2371 /* Get the control */ 2372 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 2373 KUNIT_ASSERT_NOT_NULL(test, ctl); 2374 2375 /* Power-down DSP then power-up with a different firmware */ 2376 cs_dsp_power_down(dsp); 2377 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2); 2378 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0); 2379 2380 /* Write new data to the control, it should not be written to the registers */ 2381 get_random_bytes(reg_vals, param->len_bytes); 2382 KUNIT_EXPECT_EQ(test, 2383 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 2384 1); 2385 2386 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2387 KUNIT_EXPECT_MEMNEQ(test, readback, reg_vals, param->len_bytes); 2388 2389 /* Power-down DSP then power-up with the original firmware */ 2390 cs_dsp_power_down(dsp); 2391 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 2392 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 2393 2394 /* Start the firmware and the cached data should be written to registers */ 2395 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2396 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2397 2398 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2399 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 2400 2401 /* Control should readback the new data from the control cache */ 2402 KUNIT_EXPECT_EQ(test, 2403 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 2404 0); 2405 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 2406 } 2407 2408 /* 2409 * The value in the control cache should be synced out to the registers 2410 * backing the control every time the firmware containing the control 2411 * is run. 2412 */ 2413 static void cs_dsp_ctl_cache_sync_reapply_every_run(struct kunit *test) 2414 { 2415 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 2416 struct cs_dsp_test *priv = test->priv; 2417 struct cs_dsp_test_local *local = priv->local; 2418 struct cs_dsp *dsp = priv->dsp; 2419 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 2420 int alg_idx = _find_alg_entry(test, param->alg_id); 2421 unsigned int reg, alg_base_words; 2422 struct cs_dsp_coeff_ctl *ctl; 2423 struct firmware *wmfw; 2424 u32 *init_vals, *readback, *ctl_vals; 2425 2426 init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2427 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals); 2428 2429 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2430 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 2431 2432 ctl_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 2433 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals); 2434 2435 /* Zero-fill the registers backing the control */ 2436 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 2437 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 2438 reg += (alg_base_words + param->offs_words) * 2439 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 2440 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes); 2441 2442 /* Create control pointing to this data */ 2443 def.flags = param->flags; 2444 def.mem_type = param->mem_type; 2445 def.offset_dsp_words = param->offs_words; 2446 def.length_bytes = param->len_bytes; 2447 2448 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 2449 cs_dsp_ctl_cache_test_algs[alg_idx].id, 2450 "dummyalg", NULL); 2451 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 2452 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 2453 2454 /* Power-up DSP but don't start firmware */ 2455 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 2456 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 2457 2458 /* Write new data to the control */ 2459 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 2460 KUNIT_ASSERT_NOT_NULL(test, ctl); 2461 2462 get_random_bytes(ctl_vals, param->len_bytes); 2463 KUNIT_EXPECT_EQ(test, 2464 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, param->len_bytes), 2465 1); 2466 2467 /* Start the firmware and the cached data should be written to registers */ 2468 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2469 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2470 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2471 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes); 2472 2473 /* Stop the firmware and reset the registers */ 2474 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 2475 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes); 2476 2477 /* Start the firmware again and the cached data should be written to registers */ 2478 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2479 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2480 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2481 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes); 2482 2483 /* Control should readback the new data from the control cache */ 2484 KUNIT_EXPECT_EQ(test, 2485 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 2486 0); 2487 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes); 2488 } 2489 2490 /* 2491 * The value in the control cache should be retained if the same 2492 * firmware is downloaded again. It should be synced out to the 2493 * registers backing the control after the firmware containing the 2494 * control is downloaded again and run. 2495 */ 2496 static void cs_dsp_ctl_cache_sync_reapply_after_fw_reload(struct kunit *test) 2497 { 2498 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 2499 struct cs_dsp_test *priv = test->priv; 2500 struct cs_dsp_test_local *local = priv->local; 2501 struct cs_dsp *dsp = priv->dsp; 2502 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 2503 int alg_idx = _find_alg_entry(test, param->alg_id); 2504 unsigned int reg, alg_base_words; 2505 struct cs_dsp_coeff_ctl *ctl; 2506 struct firmware *wmfw; 2507 u32 *init_vals, *readback, *ctl_vals; 2508 2509 init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2510 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals); 2511 2512 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2513 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 2514 2515 ctl_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 2516 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals); 2517 2518 /* Zero-fill the registers backing the control */ 2519 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 2520 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 2521 reg += (alg_base_words + param->offs_words) * 2522 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 2523 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes); 2524 2525 /* Create control pointing to this data */ 2526 def.flags = param->flags; 2527 def.mem_type = param->mem_type; 2528 def.offset_dsp_words = param->offs_words; 2529 def.length_bytes = param->len_bytes; 2530 2531 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 2532 cs_dsp_ctl_cache_test_algs[alg_idx].id, 2533 "dummyalg", NULL); 2534 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 2535 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 2536 2537 /* Power-up DSP but don't start firmware */ 2538 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 2539 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 2540 2541 /* Write new data to the control */ 2542 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 2543 KUNIT_ASSERT_NOT_NULL(test, ctl); 2544 2545 get_random_bytes(ctl_vals, param->len_bytes); 2546 KUNIT_EXPECT_EQ(test, 2547 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, param->len_bytes), 2548 1); 2549 2550 /* Start the firmware and the cached data should be written to registers */ 2551 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2552 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2553 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2554 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes); 2555 2556 /* Stop the firmware and power-down the DSP */ 2557 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 2558 cs_dsp_power_down(dsp); 2559 2560 /* Reset the registers */ 2561 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes); 2562 2563 /* Download the firmware again, the cache content should not change */ 2564 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 2565 2566 /* Start the firmware and the cached data should be written to registers */ 2567 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2568 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2569 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2570 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes); 2571 2572 /* Control should readback the new data from the control cache */ 2573 KUNIT_EXPECT_EQ(test, 2574 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 2575 0); 2576 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes); 2577 } 2578 2579 /* 2580 * The value in the control cache should be retained after a different 2581 * firmware is downloaded. 2582 * When the firmware containing the control is downloaded and run 2583 * the value in the control cache should be synced out to the registers 2584 * backing the control. 2585 */ 2586 static void cs_dsp_ctl_cache_sync_reapply_after_fw_swap(struct kunit *test) 2587 { 2588 const struct cs_dsp_ctl_cache_test_param *param = test->param_value; 2589 struct cs_dsp_test *priv = test->priv; 2590 struct cs_dsp_test_local *local = priv->local; 2591 struct cs_dsp *dsp = priv->dsp; 2592 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 2593 int alg_idx = _find_alg_entry(test, param->alg_id); 2594 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); 2595 unsigned int reg, alg_base_words; 2596 struct cs_dsp_coeff_ctl *ctl; 2597 struct firmware *wmfw; 2598 u32 *init_vals, *readback, *ctl_vals; 2599 2600 init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2601 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals); 2602 2603 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 2604 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 2605 2606 ctl_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 2607 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals); 2608 2609 /* Zero-fill the registers backing the control */ 2610 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 2611 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 2612 reg += (alg_base_words + param->offs_words) * 2613 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 2614 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes); 2615 2616 /* Create control pointing to this data */ 2617 def.flags = param->flags; 2618 def.mem_type = param->mem_type; 2619 def.offset_dsp_words = param->offs_words; 2620 def.length_bytes = param->len_bytes; 2621 2622 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 2623 cs_dsp_ctl_cache_test_algs[alg_idx].id, 2624 "dummyalg", NULL); 2625 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 2626 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 2627 2628 /* Power-up DSP but don't start firmware */ 2629 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 2630 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 2631 2632 /* Write new data to the control */ 2633 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 2634 KUNIT_ASSERT_NOT_NULL(test, ctl); 2635 2636 get_random_bytes(ctl_vals, param->len_bytes); 2637 KUNIT_EXPECT_EQ(test, 2638 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, param->len_bytes), 2639 1); 2640 2641 /* Start the firmware and the cached data should be written to registers */ 2642 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2643 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2644 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2645 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes); 2646 2647 /* Stop the firmware and power-down the DSP */ 2648 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 2649 cs_dsp_power_down(dsp); 2650 2651 /* Reset the registers */ 2652 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes); 2653 2654 /* Download and run a different firmware */ 2655 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2); 2656 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0); 2657 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2658 cs_dsp_power_down(dsp); 2659 2660 /* Reset the registers */ 2661 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes); 2662 2663 /* Download the original firmware again */ 2664 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 2665 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 2666 KUNIT_EXPECT_TRUE(test, ctl->set); 2667 2668 /* Start the firmware and the cached data should be written to registers */ 2669 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2670 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2671 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 2672 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes); 2673 2674 /* Control should readback the new data from the control cache */ 2675 KUNIT_EXPECT_EQ(test, 2676 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 2677 0); 2678 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes); 2679 } 2680 2681 static int cs_dsp_ctl_cache_test_common_init(struct kunit *test, struct cs_dsp *dsp, 2682 int wmfw_version) 2683 { 2684 struct cs_dsp_test *priv; 2685 struct cs_dsp_test_local *local; 2686 struct device *test_dev; 2687 int ret; 2688 2689 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); 2690 if (!priv) 2691 return -ENOMEM; 2692 2693 local = kunit_kzalloc(test, sizeof(struct cs_dsp_test_local), GFP_KERNEL); 2694 if (!local) 2695 return -ENOMEM; 2696 2697 priv->test = test; 2698 priv->dsp = dsp; 2699 test->priv = priv; 2700 priv->local = local; 2701 priv->local->wmfw_version = wmfw_version; 2702 2703 /* Create dummy struct device */ 2704 test_dev = kunit_device_register(test, "cs_dsp_test_drv"); 2705 if (IS_ERR(test_dev)) 2706 return PTR_ERR(test_dev); 2707 2708 dsp->dev = get_device(test_dev); 2709 if (!dsp->dev) 2710 return -ENODEV; 2711 2712 ret = kunit_add_action_or_reset(test, _put_device_wrapper, dsp->dev); 2713 if (ret) 2714 return ret; 2715 2716 dev_set_drvdata(dsp->dev, priv); 2717 2718 /* Allocate regmap */ 2719 ret = cs_dsp_mock_regmap_init(priv); 2720 if (ret) 2721 return ret; 2722 2723 /* 2724 * There must always be a XM header with at least 1 algorithm, so create 2725 * a dummy one that tests can use and extract it to a data blob. 2726 */ 2727 local->xm_header = cs_dsp_create_mock_xm_header(priv, 2728 cs_dsp_ctl_cache_test_algs, 2729 ARRAY_SIZE(cs_dsp_ctl_cache_test_algs)); 2730 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->xm_header); 2731 2732 /* Create wmfw builder */ 2733 local->wmfw_builder = _create_dummy_wmfw(test); 2734 2735 /* Init cs_dsp */ 2736 dsp->client_ops = kunit_kzalloc(test, sizeof(*dsp->client_ops), GFP_KERNEL); 2737 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dsp->client_ops); 2738 2739 switch (dsp->type) { 2740 case WMFW_ADSP2: 2741 ret = cs_dsp_adsp2_init(dsp); 2742 break; 2743 case WMFW_HALO: 2744 ret = cs_dsp_halo_init(dsp); 2745 break; 2746 default: 2747 KUNIT_FAIL(test, "Untested DSP type %d\n", dsp->type); 2748 return -EINVAL; 2749 } 2750 2751 if (ret) 2752 return ret; 2753 2754 /* Automatically call cs_dsp_remove() when test case ends */ 2755 return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); 2756 } 2757 2758 static int cs_dsp_ctl_cache_test_halo_init(struct kunit *test) 2759 { 2760 struct cs_dsp *dsp; 2761 2762 /* Fill in cs_dsp and initialize */ 2763 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL); 2764 if (!dsp) 2765 return -ENOMEM; 2766 2767 dsp->num = 1; 2768 dsp->type = WMFW_HALO; 2769 dsp->mem = cs_dsp_mock_halo_dsp1_regions; 2770 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_halo_dsp1_region_sizes); 2771 dsp->base = cs_dsp_mock_halo_core_base; 2772 dsp->base_sysinfo = cs_dsp_mock_halo_sysinfo_base; 2773 2774 return cs_dsp_ctl_cache_test_common_init(test, dsp, 3); 2775 } 2776 2777 static int cs_dsp_ctl_cache_test_adsp2_32bit_init(struct kunit *test, int wmfw_ver) 2778 { 2779 struct cs_dsp *dsp; 2780 2781 /* Fill in cs_dsp and initialize */ 2782 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL); 2783 if (!dsp) 2784 return -ENOMEM; 2785 2786 dsp->num = 1; 2787 dsp->type = WMFW_ADSP2; 2788 dsp->rev = 1; 2789 dsp->mem = cs_dsp_mock_adsp2_32bit_dsp1_regions; 2790 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_32bit_dsp1_region_sizes); 2791 dsp->base = cs_dsp_mock_adsp2_32bit_sysbase; 2792 2793 return cs_dsp_ctl_cache_test_common_init(test, dsp, wmfw_ver); 2794 } 2795 2796 static int cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1_init(struct kunit *test) 2797 { 2798 return cs_dsp_ctl_cache_test_adsp2_32bit_init(test, 1); 2799 } 2800 2801 static int cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2_init(struct kunit *test) 2802 { 2803 return cs_dsp_ctl_cache_test_adsp2_32bit_init(test, 2); 2804 } 2805 2806 static int cs_dsp_ctl_cache_test_adsp2_16bit_init(struct kunit *test, int wmfw_ver) 2807 { 2808 struct cs_dsp *dsp; 2809 2810 /* Fill in cs_dsp and initialize */ 2811 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL); 2812 if (!dsp) 2813 return -ENOMEM; 2814 2815 dsp->num = 1; 2816 dsp->type = WMFW_ADSP2; 2817 dsp->rev = 0; 2818 dsp->mem = cs_dsp_mock_adsp2_16bit_dsp1_regions; 2819 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_16bit_dsp1_region_sizes); 2820 dsp->base = cs_dsp_mock_adsp2_16bit_sysbase; 2821 2822 return cs_dsp_ctl_cache_test_common_init(test, dsp, wmfw_ver); 2823 } 2824 2825 static int cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1_init(struct kunit *test) 2826 { 2827 return cs_dsp_ctl_cache_test_adsp2_16bit_init(test, 1); 2828 } 2829 2830 static int cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2_init(struct kunit *test) 2831 { 2832 return cs_dsp_ctl_cache_test_adsp2_16bit_init(test, 2); 2833 } 2834 2835 static void cs_dsp_ctl_all_param_desc(const struct cs_dsp_ctl_cache_test_param *param, 2836 char *desc) 2837 { 2838 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "alg:%#x %s@%u len:%u flags:%#x", 2839 param->alg_id, cs_dsp_mem_region_name(param->mem_type), 2840 param->offs_words, param->len_bytes, param->flags); 2841 } 2842 2843 /* All parameters populated, with various lengths */ 2844 static const struct cs_dsp_ctl_cache_test_param all_pop_varying_len_cases[] = { 2845 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2846 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 8 }, 2847 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 12 }, 2848 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 16 }, 2849 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 48 }, 2850 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 100 }, 2851 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 512 }, 2852 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 1000 }, 2853 }; 2854 KUNIT_ARRAY_PARAM(all_pop_varying_len, all_pop_varying_len_cases, 2855 cs_dsp_ctl_all_param_desc); 2856 2857 /* All parameters populated, with various offsets */ 2858 static const struct cs_dsp_ctl_cache_test_param all_pop_varying_offset_cases[] = { 2859 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 0, .len_bytes = 4 }, 2860 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2861 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 2, .len_bytes = 4 }, 2862 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 3, .len_bytes = 4 }, 2863 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 8, .len_bytes = 4 }, 2864 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 10, .len_bytes = 4 }, 2865 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 128, .len_bytes = 4 }, 2866 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 180, .len_bytes = 4 }, 2867 }; 2868 KUNIT_ARRAY_PARAM(all_pop_varying_offset, all_pop_varying_offset_cases, 2869 cs_dsp_ctl_all_param_desc); 2870 2871 /* All parameters populated, with various X and Y memory regions */ 2872 static const struct cs_dsp_ctl_cache_test_param all_pop_varying_xy_cases[] = { 2873 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_XM, .offs_words = 1, .len_bytes = 4 }, 2874 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2875 }; 2876 KUNIT_ARRAY_PARAM(all_pop_varying_xy, all_pop_varying_xy_cases, 2877 cs_dsp_ctl_all_param_desc); 2878 2879 /* All parameters populated, using ZM */ 2880 static const struct cs_dsp_ctl_cache_test_param all_pop_z_cases[] = { 2881 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_ZM, .offs_words = 1, .len_bytes = 4 }, 2882 }; 2883 KUNIT_ARRAY_PARAM(all_pop_z, all_pop_z_cases, cs_dsp_ctl_all_param_desc); 2884 2885 /* All parameters populated, with various algorithm ids */ 2886 static const struct cs_dsp_ctl_cache_test_param all_pop_varying_alg_cases[] = { 2887 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2888 { .alg_id = 0xb, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2889 { .alg_id = 0x9f1234, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2890 { .alg_id = 0xff00ff, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2891 }; 2892 KUNIT_ARRAY_PARAM(all_pop_varying_alg, all_pop_varying_alg_cases, 2893 cs_dsp_ctl_all_param_desc); 2894 2895 /* 2896 * All parameters populated, with all combinations of flags for a 2897 * non-volatile readable control 2898 */ 2899 static const struct cs_dsp_ctl_cache_test_param all_pop_nonvol_readable_flags_cases[] = { 2900 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2901 .flags = 0 2902 }, 2903 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2904 .flags = WMFW_CTL_FLAG_READABLE, 2905 }, 2906 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2907 .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2908 }, 2909 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2910 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE, 2911 }, 2912 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2913 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2914 }, 2915 }; 2916 KUNIT_ARRAY_PARAM(all_pop_nonvol_readable_flags, 2917 all_pop_nonvol_readable_flags_cases, 2918 cs_dsp_ctl_all_param_desc); 2919 2920 /* 2921 * All parameters populated, with all combinations of flags for a 2922 * non-volatile readable control, except flags==0 2923 */ 2924 static const struct cs_dsp_ctl_cache_test_param all_pop_nonvol_readable_nonzero_flags_cases[] = { 2925 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2926 .flags = WMFW_CTL_FLAG_READABLE, 2927 }, 2928 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2929 .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2930 }, 2931 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2932 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE, 2933 }, 2934 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2935 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2936 }, 2937 }; 2938 KUNIT_ARRAY_PARAM(all_pop_nonvol_readable_nonzero_flags, 2939 all_pop_nonvol_readable_nonzero_flags_cases, 2940 cs_dsp_ctl_all_param_desc); 2941 2942 /* 2943 * All parameters populated, with all combinations of flags for a 2944 * non-volatile writeable control 2945 */ 2946 static const struct cs_dsp_ctl_cache_test_param all_pop_nonvol_writeable_flags_cases[] = { 2947 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2948 .flags = 0 2949 }, 2950 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2951 .flags = WMFW_CTL_FLAG_WRITEABLE, 2952 }, 2953 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2954 .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2955 }, 2956 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2957 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE, 2958 }, 2959 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2960 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2961 }, 2962 }; 2963 KUNIT_ARRAY_PARAM(all_pop_nonvol_writeable_flags, 2964 all_pop_nonvol_writeable_flags_cases, 2965 cs_dsp_ctl_all_param_desc); 2966 2967 /* 2968 * All parameters populated, with all combinations of flags for a 2969 * non-volatile write-only control of varying lengths 2970 */ 2971 static const struct cs_dsp_ctl_cache_test_param all_pop_nonvol_write_only_length_cases[] = { 2972 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2973 .flags = WMFW_CTL_FLAG_WRITEABLE, 2974 }, 2975 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 512, 2976 .flags = WMFW_CTL_FLAG_WRITEABLE, 2977 }, 2978 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2979 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE, 2980 }, 2981 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 512, 2982 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE, 2983 }, 2984 }; 2985 KUNIT_ARRAY_PARAM(all_pop_nonvol_write_only_length, 2986 all_pop_nonvol_write_only_length_cases, 2987 cs_dsp_ctl_all_param_desc); 2988 2989 static struct kunit_case cs_dsp_ctl_cache_test_cases_v1[] = { 2990 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_len_gen_params), 2991 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_offset_gen_params), 2992 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_xy_gen_params), 2993 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_z_gen_params), 2994 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_alg_gen_params), 2995 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_nonvol_readable_flags_gen_params), 2996 2997 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init_write_only, 2998 all_pop_nonvol_write_only_length_gen_params), 2999 3000 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fw_same_controls), 3001 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls), 3002 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_mems), 3003 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_algs), 3004 3005 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_started, 3006 all_pop_nonvol_readable_flags_gen_params), 3007 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped, 3008 all_pop_nonvol_readable_flags_gen_params), 3009 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_powered_down, 3010 all_pop_nonvol_readable_flags_gen_params), 3011 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped_powered_down, 3012 all_pop_nonvol_readable_flags_gen_params), 3013 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_loaded_fw, 3014 all_pop_nonvol_readable_flags_gen_params), 3015 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_running_fw, 3016 all_pop_nonvol_readable_flags_gen_params), 3017 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running, 3018 all_pop_nonvol_readable_nonzero_flags_gen_params), 3019 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running_zero_flags, 3020 all_pop_varying_len_gen_params), 3021 3022 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_len_gen_params), 3023 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_offset_gen_params), 3024 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_xy_gen_params), 3025 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_z_gen_params), 3026 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_alg_gen_params), 3027 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_nonvol_writeable_flags_gen_params), 3028 3029 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3030 all_pop_varying_len_gen_params), 3031 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3032 all_pop_varying_offset_gen_params), 3033 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3034 all_pop_varying_xy_gen_params), 3035 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3036 all_pop_z_gen_params), 3037 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3038 all_pop_varying_alg_gen_params), 3039 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3040 all_pop_nonvol_writeable_flags_gen_params), 3041 3042 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_unchanged_not_started, 3043 all_pop_nonvol_writeable_flags_gen_params), 3044 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_started, 3045 all_pop_nonvol_writeable_flags_gen_params), 3046 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped, 3047 all_pop_nonvol_writeable_flags_gen_params), 3048 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_powered_down, 3049 all_pop_nonvol_writeable_flags_gen_params), 3050 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped_powered_down, 3051 all_pop_nonvol_writeable_flags_gen_params), 3052 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_loaded_fw, 3053 all_pop_nonvol_writeable_flags_gen_params), 3054 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_running_fw, 3055 all_pop_nonvol_writeable_flags_gen_params), 3056 3057 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_before_run, 3058 all_pop_nonvol_writeable_flags_gen_params), 3059 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_while_running, 3060 all_pop_nonvol_writeable_flags_gen_params), 3061 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_after_stop, 3062 all_pop_nonvol_writeable_flags_gen_params), 3063 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_not_current_fw, 3064 all_pop_nonvol_writeable_flags_gen_params), 3065 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_every_run, 3066 all_pop_nonvol_writeable_flags_gen_params), 3067 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_reload, 3068 all_pop_nonvol_writeable_flags_gen_params), 3069 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_swap, 3070 all_pop_nonvol_writeable_flags_gen_params), 3071 3072 { } /* terminator */ 3073 }; 3074 3075 static struct kunit_case cs_dsp_ctl_cache_test_cases_v2[] = { 3076 KUNIT_CASE(cs_dsp_ctl_v2_cache_alloc), 3077 3078 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_len_gen_params), 3079 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_offset_gen_params), 3080 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_xy_gen_params), 3081 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_z_gen_params), 3082 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_alg_gen_params), 3083 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_nonvol_readable_flags_gen_params), 3084 3085 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init_write_only, 3086 all_pop_nonvol_write_only_length_gen_params), 3087 3088 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fw_same_controls), 3089 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls), 3090 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_mems), 3091 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_algs), 3092 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_offsets), 3093 3094 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_started, 3095 all_pop_nonvol_readable_flags_gen_params), 3096 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped, 3097 all_pop_nonvol_readable_flags_gen_params), 3098 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_powered_down, 3099 all_pop_nonvol_readable_flags_gen_params), 3100 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped_powered_down, 3101 all_pop_nonvol_readable_flags_gen_params), 3102 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_loaded_fw, 3103 all_pop_nonvol_readable_flags_gen_params), 3104 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_running_fw, 3105 all_pop_nonvol_readable_flags_gen_params), 3106 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running, 3107 all_pop_nonvol_readable_nonzero_flags_gen_params), 3108 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running_zero_flags, 3109 all_pop_varying_len_gen_params), 3110 3111 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_len_gen_params), 3112 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_offset_gen_params), 3113 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_xy_gen_params), 3114 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_z_gen_params), 3115 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_alg_gen_params), 3116 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_nonvol_writeable_flags_gen_params), 3117 3118 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3119 all_pop_varying_len_gen_params), 3120 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3121 all_pop_varying_offset_gen_params), 3122 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3123 all_pop_varying_xy_gen_params), 3124 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3125 all_pop_z_gen_params), 3126 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3127 all_pop_varying_alg_gen_params), 3128 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3129 all_pop_nonvol_writeable_flags_gen_params), 3130 3131 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_unchanged_not_started, 3132 all_pop_nonvol_writeable_flags_gen_params), 3133 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_started, 3134 all_pop_nonvol_writeable_flags_gen_params), 3135 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped, 3136 all_pop_nonvol_writeable_flags_gen_params), 3137 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_powered_down, 3138 all_pop_nonvol_writeable_flags_gen_params), 3139 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped_powered_down, 3140 all_pop_nonvol_writeable_flags_gen_params), 3141 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_loaded_fw, 3142 all_pop_nonvol_writeable_flags_gen_params), 3143 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_running_fw, 3144 all_pop_nonvol_writeable_flags_gen_params), 3145 3146 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_before_run, 3147 all_pop_nonvol_writeable_flags_gen_params), 3148 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_while_running, 3149 all_pop_nonvol_writeable_flags_gen_params), 3150 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_after_stop, 3151 all_pop_nonvol_writeable_flags_gen_params), 3152 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_not_current_fw, 3153 all_pop_nonvol_writeable_flags_gen_params), 3154 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_every_run, 3155 all_pop_nonvol_writeable_flags_gen_params), 3156 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_reload, 3157 all_pop_nonvol_writeable_flags_gen_params), 3158 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_swap, 3159 all_pop_nonvol_writeable_flags_gen_params), 3160 3161 { } /* terminator */ 3162 }; 3163 3164 static struct kunit_case cs_dsp_ctl_cache_test_cases_v3[] = { 3165 KUNIT_CASE(cs_dsp_ctl_v2_cache_alloc), 3166 3167 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_len_gen_params), 3168 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_offset_gen_params), 3169 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_xy_gen_params), 3170 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_alg_gen_params), 3171 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_nonvol_readable_flags_gen_params), 3172 3173 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init_write_only, 3174 all_pop_nonvol_write_only_length_gen_params), 3175 3176 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fw_same_controls), 3177 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls), 3178 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_mems), 3179 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_algs), 3180 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_offsets), 3181 3182 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_started, 3183 all_pop_nonvol_readable_flags_gen_params), 3184 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped, 3185 all_pop_nonvol_readable_flags_gen_params), 3186 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_powered_down, 3187 all_pop_nonvol_readable_flags_gen_params), 3188 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped_powered_down, 3189 all_pop_nonvol_readable_flags_gen_params), 3190 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_loaded_fw, 3191 all_pop_nonvol_readable_flags_gen_params), 3192 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_running_fw, 3193 all_pop_nonvol_readable_flags_gen_params), 3194 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running, 3195 all_pop_nonvol_readable_nonzero_flags_gen_params), 3196 3197 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_len_gen_params), 3198 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_offset_gen_params), 3199 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_xy_gen_params), 3200 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_alg_gen_params), 3201 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_nonvol_writeable_flags_gen_params), 3202 3203 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3204 all_pop_varying_len_gen_params), 3205 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3206 all_pop_varying_offset_gen_params), 3207 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3208 all_pop_varying_xy_gen_params), 3209 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3210 all_pop_varying_alg_gen_params), 3211 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged, 3212 all_pop_nonvol_writeable_flags_gen_params), 3213 3214 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_unchanged_not_started, 3215 all_pop_nonvol_writeable_flags_gen_params), 3216 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_started, 3217 all_pop_nonvol_writeable_flags_gen_params), 3218 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped, 3219 all_pop_nonvol_writeable_flags_gen_params), 3220 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_powered_down, 3221 all_pop_nonvol_writeable_flags_gen_params), 3222 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped_powered_down, 3223 all_pop_nonvol_writeable_flags_gen_params), 3224 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_loaded_fw, 3225 all_pop_nonvol_writeable_flags_gen_params), 3226 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_running_fw, 3227 all_pop_nonvol_writeable_flags_gen_params), 3228 3229 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_before_run, 3230 all_pop_nonvol_writeable_flags_gen_params), 3231 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_while_running, 3232 all_pop_nonvol_writeable_flags_gen_params), 3233 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_after_stop, 3234 all_pop_nonvol_writeable_flags_gen_params), 3235 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_not_current_fw, 3236 all_pop_nonvol_writeable_flags_gen_params), 3237 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_every_run, 3238 all_pop_nonvol_writeable_flags_gen_params), 3239 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_reload, 3240 all_pop_nonvol_writeable_flags_gen_params), 3241 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_swap, 3242 all_pop_nonvol_writeable_flags_gen_params), 3243 3244 { } /* terminator */ 3245 }; 3246 3247 static struct kunit_suite cs_dsp_ctl_cache_test_halo = { 3248 .name = "cs_dsp_ctl_cache_wmfwV3_halo", 3249 .init = cs_dsp_ctl_cache_test_halo_init, 3250 .test_cases = cs_dsp_ctl_cache_test_cases_v3, 3251 }; 3252 3253 static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1 = { 3254 .name = "cs_dsp_ctl_cache_wmfwV1_adsp2_32bit", 3255 .init = cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1_init, 3256 .test_cases = cs_dsp_ctl_cache_test_cases_v1, 3257 }; 3258 3259 static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2 = { 3260 .name = "cs_dsp_ctl_cache_wmfwV2_adsp2_32bit", 3261 .init = cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2_init, 3262 .test_cases = cs_dsp_ctl_cache_test_cases_v2, 3263 }; 3264 3265 static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1 = { 3266 .name = "cs_dsp_ctl_cache_wmfwV1_adsp2_16bit", 3267 .init = cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1_init, 3268 .test_cases = cs_dsp_ctl_cache_test_cases_v1, 3269 }; 3270 3271 static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2 = { 3272 .name = "cs_dsp_ctl_cache_wmfwV2_adsp2_16bit", 3273 .init = cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2_init, 3274 .test_cases = cs_dsp_ctl_cache_test_cases_v2, 3275 }; 3276 3277 kunit_test_suites(&cs_dsp_ctl_cache_test_halo, 3278 &cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1, 3279 &cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2, 3280 &cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1, 3281 &cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2); 3282