1 // SPDX-License-Identifier: GPL-2.0-only
3 // KUnit tests for cs_dsp.
5 // Copyright (C) 2024 Cirrus Logic, Inc. and
6 // Cirrus Logic International Semiconductor Ltd.
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>
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 *);
23 struct cs_dsp_test_local {
24 struct cs_dsp_mock_xm_header *xm_header;
25 struct cs_dsp_mock_wmfw_builder *wmfw_builder;
29 struct cs_dsp_ctl_cache_test_param {
32 unsigned int offs_words;
33 unsigned int len_bytes;
38 static const struct cs_dsp_mock_alg_def cs_dsp_ctl_cache_test_algs[] = {
43 .xm_size_words = 1000,
45 .ym_size_words = 1000,
47 .zm_size_words = 1000,
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,
62 .xm_base_words = 2060,
64 .ym_base_words = 2000,
66 .zm_base_words = 2000,
72 .xm_base_words = 2100,
74 .ym_base_words = 2032,
76 .zm_base_words = 2032,
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,
89 static const char * const cs_dsp_ctl_cache_test_fw_names[] = {
90 "misc", "mbc/vss", "haps",
93 static int _find_alg_entry(struct kunit *test, unsigned int alg_id)
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)
102 KUNIT_ASSERT_LT(test, i, ARRAY_SIZE(cs_dsp_ctl_cache_test_algs));
107 static int _get_alg_mem_base_words(struct kunit *test, int alg_index, int mem_type)
111 return cs_dsp_ctl_cache_test_algs[alg_index].xm_base_words;
113 return cs_dsp_ctl_cache_test_algs[alg_index].ym_base_words;
115 return cs_dsp_ctl_cache_test_algs[alg_index].zm_base_words;
117 KUNIT_FAIL(test, "Bug in test: illegal memory type %d\n", mem_type);
122 static struct cs_dsp_mock_wmfw_builder *_create_dummy_wmfw(struct kunit *test)
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;
128 builder = cs_dsp_mock_wmfw_init(priv, local->wmfw_version);
129 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, builder);
131 /* Init an XM header */
132 cs_dsp_mock_wmfw_add_data_block(builder,
134 local->xm_header->blob_data,
135 local->xm_header->blob_size_bytes);
141 * Memory allocated for control cache must be large enough.
142 * This creates multiple controls of different sizes so only works on
145 static void cs_dsp_ctl_v2_cache_alloc(struct kunit *test)
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;
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);
168 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
169 cs_dsp_ctl_cache_test_algs[0].id,
172 /* Create controls of different sizes */
173 def.mem_type = WMFW_ADSP2_YM;
174 def.shortname = ctl_name;
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);
180 def.offset_dsp_words += def.length_bytes / sizeof(u32);
182 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
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);
187 KUNIT_EXPECT_EQ(test, list_count_nodes(&dsp->ctl_list), num_ctls);
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);
195 * Content of registers backing a control should be read into the
196 * control cache when the firmware is downloaded.
198 static void cs_dsp_ctl_cache_init(struct kunit *test)
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;
211 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
212 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
214 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
215 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
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);
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;
231 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
232 cs_dsp_ctl_cache_test_algs[alg_idx].id,
234 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
235 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
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);
240 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
241 KUNIT_ASSERT_NOT_NULL(test, ctl);
244 * The data should have been populated into the control cache
245 * so should be readable through the control.
247 KUNIT_EXPECT_EQ(test,
248 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
250 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
254 * For a non-volatile write-only control the cache should be zero-filled
255 * when the firmware is downloaded.
257 static void cs_dsp_ctl_cache_init_write_only(struct kunit *test)
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;
269 zeros = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
270 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, zeros);
272 readback = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
273 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
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;
281 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
282 cs_dsp_ctl_cache_test_algs[alg_idx].id,
284 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
285 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
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);
290 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
291 KUNIT_ASSERT_NOT_NULL(test, ctl);
294 * The control cache should have been zero-filled so should be
295 * readable through the control.
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),
301 KUNIT_EXPECT_MEMEQ(test, readback, zeros, param->len_bytes);
305 * Multiple different firmware with identical controls.
306 * This is legal because different firmwares could contain the same
308 * The control cache should be initialized only with the data from
309 * the firmware containing it.
311 static void cs_dsp_ctl_cache_init_multiple_fw_same_controls(struct kunit *test)
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;
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));
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]);
332 cs_dsp_mock_wmfw_start_alg_info_block(builder[i],
333 cs_dsp_ctl_cache_test_algs[0].id,
335 cs_dsp_mock_wmfw_add_coeff_desc(builder[i], &def);
336 cs_dsp_mock_wmfw_end_alg_info_block(builder[i]);
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]);
344 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL);
345 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
348 * For each firmware create random content in the register backing
349 * the control. Then download, start, stop and power-down.
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);
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],
364 cs_dsp_ctl_cache_test_fw_names[i]),
366 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
368 cs_dsp_power_down(dsp);
371 /* There should now be 3 controls */
372 KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
375 * There's no requirement for the control list to be in any
376 * particular order, so don't assume the order.
378 for (i = 0; i < ARRAY_SIZE(ctl); i++)
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)
384 else if (strcmp(walkctl->fw_name, cs_dsp_ctl_cache_test_fw_names[1]) == 0)
386 else if (strcmp(walkctl->fw_name, cs_dsp_ctl_cache_test_fw_names[2]) == 0)
390 KUNIT_ASSERT_NOT_NULL(test, ctl[0]);
391 KUNIT_ASSERT_NOT_NULL(test, ctl[1]);
392 KUNIT_ASSERT_NOT_NULL(test, ctl[2]);
395 * The data should have been populated into the control cache
396 * so should be readable through the control.
398 KUNIT_EXPECT_EQ(test,
399 cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
401 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
403 KUNIT_EXPECT_EQ(test,
404 cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes),
406 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes);
408 KUNIT_EXPECT_EQ(test,
409 cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback, def.length_bytes),
411 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes);
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.
420 static void cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls(struct kunit *test)
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;
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));
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]);
441 cs_dsp_mock_wmfw_start_alg_info_block(builder[i],
442 cs_dsp_ctl_cache_test_algs[i].id,
444 cs_dsp_mock_wmfw_add_coeff_desc(builder[i], &def);
445 cs_dsp_mock_wmfw_end_alg_info_block(builder[i]);
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]);
453 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL);
454 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
457 * For each firmware create random content in the register backing
458 * the control. Then download, start, stop and power-down.
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);
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],
473 cs_dsp_ctl_cache_test_fw_names[i]),
475 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
477 cs_dsp_power_down(dsp);
480 /* There should now be 3 controls */
481 KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
484 * There's no requirement for the control list to be in any
485 * particular order, so don't assume the order.
487 for (i = 0; i < ARRAY_SIZE(ctl); i++)
490 list_for_each_entry(walkctl, &dsp->ctl_list, list) {
491 if (cs_dsp_ctl_cache_test_algs[0].id == walkctl->alg_region.alg)
493 else if (cs_dsp_ctl_cache_test_algs[1].id == walkctl->alg_region.alg)
495 else if (cs_dsp_ctl_cache_test_algs[2].id == walkctl->alg_region.alg)
499 KUNIT_ASSERT_NOT_NULL(test, ctl[0]);
500 KUNIT_ASSERT_NOT_NULL(test, ctl[1]);
501 KUNIT_ASSERT_NOT_NULL(test, ctl[2]);
504 * The data should have been populated into the control cache
505 * so should be readable through the control.
507 KUNIT_EXPECT_EQ(test,
508 cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
510 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
512 KUNIT_EXPECT_EQ(test,
513 cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes),
515 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes);
517 KUNIT_EXPECT_EQ(test,
518 cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback, def.length_bytes),
520 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes);
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.
528 static void cs_dsp_ctl_cache_init_multiple_mems(struct kunit *test)
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;
540 static_assert(ARRAY_SIZE(ctl) == ARRAY_SIZE(reg_vals));
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);
548 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL);
549 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
551 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
552 cs_dsp_ctl_cache_test_algs[0].id,
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);
559 def.mem_type = WMFW_ADSP2_XM;
560 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
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);
567 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
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);
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);
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);
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);
595 cs_dsp_power_down(dsp);
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);
602 * There's no requirement for the control list to be in any
603 * particular order, so don't assume the order.
605 for (i = 0; i < ARRAY_SIZE(ctl); i++)
608 list_for_each_entry(walkctl, &dsp->ctl_list, list) {
609 if (walkctl->alg_region.type == WMFW_ADSP2_YM)
611 if (walkctl->alg_region.type == WMFW_ADSP2_XM)
613 if (walkctl->alg_region.type == WMFW_ADSP2_ZM)
619 * The data should have been populated into the control cache
620 * so should be readable through the control.
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),
626 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
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),
632 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes);
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,
640 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes);
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.
649 static void cs_dsp_ctl_cache_init_multiple_algs(struct kunit *test)
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;
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));
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);
670 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL);
671 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
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,
678 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
679 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
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);
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);
696 cs_dsp_power_down(dsp);
698 /* There should now be 3 controls */
699 KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
702 * There's no requirement for the control list to be in any
703 * particular order, so don't assume the order.
705 for (i = 0; i < ARRAY_SIZE(ctl); i++)
708 list_for_each_entry(walkctl, &dsp->ctl_list, list) {
709 if (walkctl->alg_region.alg == cs_dsp_ctl_cache_test_algs[0].id)
711 if (walkctl->alg_region.alg == cs_dsp_ctl_cache_test_algs[1].id)
713 if (walkctl->alg_region.alg == cs_dsp_ctl_cache_test_algs[2].id)
717 KUNIT_ASSERT_NOT_NULL(test, ctl[0]);
718 KUNIT_ASSERT_NOT_NULL(test, ctl[1]);
719 KUNIT_ASSERT_NOT_NULL(test, ctl[2]);
722 * The data should have been populated into the control cache
723 * so should be readable through the control.
725 KUNIT_EXPECT_EQ(test,
726 cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
728 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
730 KUNIT_EXPECT_EQ(test,
731 cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes),
733 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes);
735 KUNIT_EXPECT_EQ(test,
736 cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback,
739 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes);
743 * Firmware with controls in the same algorithm and memory but at
745 * The control cache should be initialized with content from the
747 * Only for wmfw format V2 and later. V1 only supports one control per
748 * memory per algorithm.
750 static void cs_dsp_ctl_cache_init_multiple_offsets(struct kunit *test)
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;
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));
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);
771 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL);
772 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
774 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
775 cs_dsp_ctl_cache_test_algs[0].id,
778 /* Create controls identical except for offset */
779 def.length_bytes = 8;
780 def.offset_dsp_words = 0;
781 def.shortname = "CtlA";
782 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
784 def.offset_dsp_words = 5;
785 def.shortname = "CtlB";
786 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
788 def.offset_dsp_words = 8;
789 def.shortname = "CtlC";
790 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
792 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
794 /* Create random content in the registers backing each control */
795 alg_base_words = _get_alg_mem_base_words(test, 0, def.mem_type);
796 alg_base_reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type);
797 alg_base_reg += alg_base_words * cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
800 regmap_raw_write(dsp->regmap, reg, reg_vals[0], def.length_bytes);
801 reg = alg_base_reg + (5 * cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv));
802 regmap_raw_write(dsp->regmap, reg, reg_vals[1], def.length_bytes);
803 reg = alg_base_reg + (8 * cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv));
804 regmap_raw_write(dsp->regmap, reg, reg_vals[2], def.length_bytes);
806 /* Download, run, stop and power-down the firmware */
807 wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder);
808 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
809 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
811 cs_dsp_power_down(dsp);
813 /* There should now be 3 controls */
814 KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
817 * There's no requirement for the control list to be in any
818 * particular order, so don't assume the order.
820 for (i = 0; i < ARRAY_SIZE(ctl); i++)
823 list_for_each_entry(walkctl, &dsp->ctl_list, list) {
824 if (walkctl->offset == 0)
826 if (walkctl->offset == 5)
828 if (walkctl->offset == 8)
832 KUNIT_ASSERT_NOT_NULL(test, ctl[0]);
833 KUNIT_ASSERT_NOT_NULL(test, ctl[1]);
834 KUNIT_ASSERT_NOT_NULL(test, ctl[2]);
837 * The data should have been populated into the control cache
838 * so should be readable through the control.
840 KUNIT_EXPECT_EQ(test,
841 cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
843 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
845 KUNIT_EXPECT_EQ(test,
846 cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes),
848 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes);
850 KUNIT_EXPECT_EQ(test,
851 cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback,
854 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes);
858 * Read from a cached control before the firmware is started.
859 * Should return the data in the cache.
861 static void cs_dsp_ctl_cache_read_not_started(struct kunit *test)
863 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
864 struct cs_dsp_test *priv = test->priv;
865 struct cs_dsp_test_local *local = priv->local;
866 struct cs_dsp *dsp = priv->dsp;
867 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
868 int alg_idx = _find_alg_entry(test, param->alg_id);
869 unsigned int reg, alg_base_words;
870 struct cs_dsp_coeff_ctl *ctl;
871 struct firmware *wmfw;
872 u32 *reg_vals, *readback;
874 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
875 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
877 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
878 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
880 /* Create some DSP data to be read into the control cache */
881 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
882 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
883 reg += (alg_base_words + param->offs_words) *
884 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
885 get_random_bytes(reg_vals, param->len_bytes);
886 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
888 /* Create control pointing to this data */
889 def.flags = param->flags;
890 def.mem_type = param->mem_type;
891 def.offset_dsp_words = param->offs_words;
892 def.length_bytes = param->len_bytes;
894 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
895 cs_dsp_ctl_cache_test_algs[alg_idx].id,
897 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
898 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
900 /* Power-up DSP but don't start firmware */
901 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
902 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
904 /* Drop expected writes and the regmap cache should be clean */
905 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
906 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
907 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
909 /* Control should readback the data from the control cache */
910 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
911 KUNIT_ASSERT_NOT_NULL(test, ctl);
912 KUNIT_EXPECT_EQ(test,
913 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
915 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
919 * Read from a cached control after the firmware has been stopped.
920 * Should return the data in the cache.
922 static void cs_dsp_ctl_cache_read_stopped(struct kunit *test)
924 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
925 struct cs_dsp_test *priv = test->priv;
926 struct cs_dsp_test_local *local = priv->local;
927 struct cs_dsp *dsp = priv->dsp;
928 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
929 int alg_idx = _find_alg_entry(test, param->alg_id);
930 unsigned int reg, alg_base_words;
931 struct cs_dsp_coeff_ctl *ctl;
932 struct firmware *wmfw;
933 u32 *reg_vals, *readback;
935 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
936 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
938 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
939 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
941 /* Create some DSP data to be read into the control cache */
942 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
943 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
944 reg += (alg_base_words + param->offs_words) *
945 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
946 get_random_bytes(reg_vals, param->len_bytes);
947 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
949 /* Create control pointing to this data */
950 def.flags = param->flags;
951 def.mem_type = param->mem_type;
952 def.offset_dsp_words = param->offs_words;
953 def.length_bytes = param->len_bytes;
955 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
956 cs_dsp_ctl_cache_test_algs[alg_idx].id,
958 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
959 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
962 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
963 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
965 /* Start and stop the firmware */
966 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
969 /* Drop expected writes and the regmap cache should be clean */
970 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
971 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
972 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
974 /* Control should readback the data from the control cache */
975 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
976 KUNIT_ASSERT_NOT_NULL(test, ctl);
977 KUNIT_EXPECT_EQ(test,
978 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
980 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
984 * Read from a cached control after the DSP has been powered-up and
985 * then powered-down without running.
986 * Should return the data in the cache.
988 static void cs_dsp_ctl_cache_read_powered_down(struct kunit *test)
990 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
991 struct cs_dsp_test *priv = test->priv;
992 struct cs_dsp_test_local *local = priv->local;
993 struct cs_dsp *dsp = priv->dsp;
994 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
995 int alg_idx = _find_alg_entry(test, param->alg_id);
996 unsigned int reg, alg_base_words;
997 struct cs_dsp_coeff_ctl *ctl;
998 struct firmware *wmfw;
999 u32 *reg_vals, *readback;
1001 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1002 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1004 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1005 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1007 /* Create some DSP data to be read into the control cache */
1008 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1009 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1010 reg += (alg_base_words + param->offs_words) *
1011 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1012 get_random_bytes(reg_vals, param->len_bytes);
1013 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1015 /* Create control pointing to this data */
1016 def.flags = param->flags;
1017 def.mem_type = param->mem_type;
1018 def.offset_dsp_words = param->offs_words;
1019 def.length_bytes = param->len_bytes;
1021 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1022 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1024 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1025 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1027 /* Power-up DSP then power-down */
1028 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1029 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1030 cs_dsp_power_down(dsp);
1032 /* Drop expected writes and the regmap cache should be clean */
1033 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1034 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1035 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1037 /* Control should readback the data from the control cache */
1038 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1039 KUNIT_ASSERT_NOT_NULL(test, ctl);
1040 KUNIT_EXPECT_EQ(test,
1041 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1043 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1047 * Read from a cached control after the firmware has been run and
1048 * stopped, then the DSP has been powered-down.
1049 * Should return the data in the cache.
1051 static void cs_dsp_ctl_cache_read_stopped_powered_down(struct kunit *test)
1053 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1054 struct cs_dsp_test *priv = test->priv;
1055 struct cs_dsp_test_local *local = priv->local;
1056 struct cs_dsp *dsp = priv->dsp;
1057 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1058 int alg_idx = _find_alg_entry(test, param->alg_id);
1059 unsigned int reg, alg_base_words;
1060 struct cs_dsp_coeff_ctl *ctl;
1061 struct firmware *wmfw;
1062 u32 *reg_vals, *readback;
1064 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1065 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1067 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1068 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1070 /* Create some DSP data to be read into the control cache */
1071 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1072 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1073 reg += (alg_base_words + param->offs_words) *
1074 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1075 get_random_bytes(reg_vals, param->len_bytes);
1076 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1078 /* Create control pointing to this data */
1079 def.flags = param->flags;
1080 def.mem_type = param->mem_type;
1081 def.offset_dsp_words = param->offs_words;
1082 def.length_bytes = param->len_bytes;
1084 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1085 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1087 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1088 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1091 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1092 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1094 /* Start and stop the firmware then power-down */
1095 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1097 cs_dsp_power_down(dsp);
1099 /* Drop expected writes and the regmap cache should be clean */
1100 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1101 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1102 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1104 /* Control should readback the data from the control cache */
1105 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1106 KUNIT_ASSERT_NOT_NULL(test, ctl);
1107 KUNIT_EXPECT_EQ(test,
1108 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1110 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1114 * Read from a cached control when a different firmware is currently
1115 * loaded into the DSP.
1116 * Should return the data in the cache.
1118 static void cs_dsp_ctl_cache_read_not_current_loaded_fw(struct kunit *test)
1120 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1121 struct cs_dsp_test *priv = test->priv;
1122 struct cs_dsp_test_local *local = priv->local;
1123 struct cs_dsp *dsp = priv->dsp;
1124 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1125 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test);
1126 int alg_idx = _find_alg_entry(test, param->alg_id);
1127 unsigned int reg, alg_base_words;
1128 struct cs_dsp_coeff_ctl *ctl;
1129 struct firmware *wmfw;
1130 u32 *reg_vals, *readback;
1132 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1133 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1135 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1136 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1138 /* Create some DSP data to be read into the control cache */
1139 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1140 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1141 reg += (alg_base_words + param->offs_words) *
1142 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1143 get_random_bytes(reg_vals, param->len_bytes);
1144 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1146 /* Create control pointing to this data */
1147 def.flags = param->flags;
1148 def.mem_type = param->mem_type;
1149 def.offset_dsp_words = param->offs_words;
1150 def.length_bytes = param->len_bytes;
1152 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1153 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1155 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1156 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1159 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1160 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1162 /* Power-down DSP then power-up with a different firmware */
1163 cs_dsp_power_down(dsp);
1164 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
1165 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
1167 /* Drop expected writes and the regmap cache should be clean */
1168 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1169 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1170 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1172 /* Control should readback the data from the control cache */
1173 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1174 KUNIT_ASSERT_NOT_NULL(test, ctl);
1175 KUNIT_EXPECT_EQ(test,
1176 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1178 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1182 * Read from a cached control when a different firmware is currently
1184 * Should return the data in the cache.
1186 static void cs_dsp_ctl_cache_read_not_current_running_fw(struct kunit *test)
1188 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1189 struct cs_dsp_test *priv = test->priv;
1190 struct cs_dsp_test_local *local = priv->local;
1191 struct cs_dsp *dsp = priv->dsp;
1192 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1193 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test);
1194 int alg_idx = _find_alg_entry(test, param->alg_id);
1195 unsigned int reg, alg_base_words;
1196 struct cs_dsp_coeff_ctl *ctl;
1197 struct firmware *wmfw;
1198 u32 *reg_vals, *readback;
1200 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1201 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1203 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1204 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1206 /* Create some DSP data to be read into the control cache */
1207 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1208 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1209 reg += (alg_base_words + param->offs_words) *
1210 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1211 get_random_bytes(reg_vals, param->len_bytes);
1212 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1214 /* Create control pointing to this data */
1215 def.flags = param->flags;
1216 def.mem_type = param->mem_type;
1217 def.offset_dsp_words = param->offs_words;
1218 def.length_bytes = param->len_bytes;
1220 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1221 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1223 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1224 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1226 /* Power-up DSP then power-down */
1227 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1228 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1229 cs_dsp_power_down(dsp);
1231 /* Power-up with a different firmware and run it */
1232 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
1233 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
1234 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1235 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
1237 /* Drop expected writes and the regmap cache should be clean */
1238 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1239 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1240 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1242 /* Control should readback the data from the control cache */
1243 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1244 KUNIT_ASSERT_NOT_NULL(test, ctl);
1245 KUNIT_EXPECT_EQ(test,
1246 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1248 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1252 * Read from a cached control with non-zero flags while the firmware is
1254 * Should return the data in the cache, not from the registers.
1256 static void cs_dsp_ctl_cache_read_running(struct kunit *test)
1258 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1259 struct cs_dsp_test *priv = test->priv;
1260 struct cs_dsp_test_local *local = priv->local;
1261 struct cs_dsp *dsp = priv->dsp;
1262 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1263 int alg_idx = _find_alg_entry(test, param->alg_id);
1264 unsigned int reg, alg_base_words;
1265 struct cs_dsp_coeff_ctl *ctl;
1266 struct firmware *wmfw;
1267 u32 *init_reg_vals, *new_reg_vals, *readback;
1269 init_reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1270 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_reg_vals);
1272 new_reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1273 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_reg_vals);
1275 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1276 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1278 /* Create data in the registers backing the control */
1279 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1280 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1281 reg += (alg_base_words + param->offs_words) *
1282 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1283 get_random_bytes(init_reg_vals, param->len_bytes);
1284 regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes);
1286 /* Create control pointing to this data */
1287 def.flags = param->flags;
1288 def.mem_type = param->mem_type;
1289 def.offset_dsp_words = param->offs_words;
1290 def.length_bytes = param->len_bytes;
1292 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1293 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1295 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1296 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1299 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1300 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1302 /* Start the firmware running */
1303 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1304 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
1307 * Change the values in the registers backing the control then drop
1308 * them from the regmap cache. This allows checking that the control
1309 * read is returning values from the control cache and not accessing
1312 KUNIT_ASSERT_EQ(test,
1313 regmap_raw_write(dsp->regmap, reg, new_reg_vals, param->len_bytes),
1315 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1317 /* Control should readback the origin data from its cache */
1318 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1319 KUNIT_ASSERT_NOT_NULL(test, ctl);
1320 KUNIT_EXPECT_EQ(test,
1321 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1323 KUNIT_EXPECT_MEMEQ(test, readback, init_reg_vals, param->len_bytes);
1325 /* Stop and power-down the DSP */
1326 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
1327 cs_dsp_power_down(dsp);
1329 /* Control should readback from the cache */
1330 KUNIT_EXPECT_EQ(test,
1331 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1333 KUNIT_EXPECT_MEMEQ(test, readback, init_reg_vals, param->len_bytes);
1337 * Read from a cached control with flags == 0 while the firmware is
1339 * Should behave as volatile and read from the registers.
1340 * (This is for backwards compatibility with old firmware versions)
1342 static void cs_dsp_ctl_cache_read_running_zero_flags(struct kunit *test)
1344 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1345 struct cs_dsp_test *priv = test->priv;
1346 struct cs_dsp_test_local *local = priv->local;
1347 struct cs_dsp *dsp = priv->dsp;
1348 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1349 int alg_idx = _find_alg_entry(test, param->alg_id);
1350 unsigned int reg, alg_base_words;
1351 struct cs_dsp_coeff_ctl *ctl;
1352 struct firmware *wmfw;
1353 u32 *init_reg_vals, *new_reg_vals, *readback;
1355 init_reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1356 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_reg_vals);
1358 new_reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1359 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_reg_vals);
1361 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1362 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1364 /* Zero-fill the registers backing the control */
1365 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1366 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1367 reg += (alg_base_words + param->offs_words) *
1368 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1369 regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes);
1371 /* Create control pointing to this data */
1373 def.mem_type = param->mem_type;
1374 def.offset_dsp_words = param->offs_words;
1375 def.length_bytes = param->len_bytes;
1377 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1378 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1380 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1381 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1384 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1385 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1387 /* Start the firmware running */
1388 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1389 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
1391 /* Change the values in the registers backing the control */
1392 get_random_bytes(new_reg_vals, param->len_bytes);
1393 regmap_raw_write(dsp->regmap, reg, new_reg_vals, param->len_bytes);
1395 /* Control should readback the new data from the registers */
1396 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1397 KUNIT_ASSERT_NOT_NULL(test, ctl);
1398 KUNIT_EXPECT_EQ(test,
1399 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1401 KUNIT_EXPECT_MEMEQ(test, readback, new_reg_vals, param->len_bytes);
1403 /* Stop and power-down the DSP */
1404 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
1405 cs_dsp_power_down(dsp);
1407 /* Change the values in the registers backing the control */
1408 regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes);
1410 /* Control should readback from the cache */
1411 KUNIT_EXPECT_EQ(test,
1412 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1414 KUNIT_EXPECT_MEMEQ(test, readback, new_reg_vals, param->len_bytes);
1418 * Write to a cached control while the firmware is running.
1419 * This should be a writethrough operation, writing to the cache and
1422 static void cs_dsp_ctl_cache_writethrough(struct kunit *test)
1424 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1425 struct cs_dsp_test *priv = test->priv;
1426 struct cs_dsp_test_local *local = priv->local;
1427 struct cs_dsp *dsp = priv->dsp;
1428 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1429 int alg_idx = _find_alg_entry(test, param->alg_id);
1430 unsigned int reg, alg_base_words;
1431 struct cs_dsp_coeff_ctl *ctl;
1432 struct firmware *wmfw;
1433 u32 *reg_vals, *readback;
1435 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1436 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1438 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1439 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1441 /* Create some DSP data to be read into the control cache */
1442 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1443 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1444 reg += (alg_base_words + param->offs_words) *
1445 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1446 memset(reg_vals, 0, param->len_bytes);
1447 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1449 /* Create control pointing to this data */
1450 def.flags = param->flags;
1451 def.mem_type = param->mem_type;
1452 def.offset_dsp_words = param->offs_words;
1453 def.length_bytes = param->len_bytes;
1455 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1456 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1458 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1459 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1461 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1462 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1464 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1465 KUNIT_ASSERT_NOT_NULL(test, ctl);
1467 /* Start the firmware and add an action to stop it during cleanup */
1468 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1469 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
1471 /* Write new data to the control, it should be written to the registers */
1472 get_random_bytes(reg_vals, param->len_bytes);
1473 KUNIT_EXPECT_EQ(test,
1474 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1476 KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
1477 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1481 * Write unchanged data to a cached control while the firmware is running.
1482 * The control write should return 0 to indicate that the content
1485 static void cs_dsp_ctl_cache_writethrough_unchanged(struct kunit *test)
1487 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1488 struct cs_dsp_test *priv = test->priv;
1489 struct cs_dsp_test_local *local = priv->local;
1490 struct cs_dsp *dsp = priv->dsp;
1491 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1492 int alg_idx = _find_alg_entry(test, param->alg_id);
1493 unsigned int reg, alg_base_words;
1494 struct cs_dsp_coeff_ctl *ctl;
1495 struct firmware *wmfw;
1496 u32 *reg_vals, *readback;
1498 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1499 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1501 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1502 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1504 /* Create some DSP data to be read into the control cache */
1505 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1506 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1507 reg += (alg_base_words + param->offs_words) *
1508 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1509 get_random_bytes(reg_vals, param->len_bytes);
1510 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1512 /* Create control pointing to this data */
1513 def.flags = param->flags;
1514 def.mem_type = param->mem_type;
1515 def.offset_dsp_words = param->offs_words;
1516 def.length_bytes = param->len_bytes;
1518 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1519 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1521 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1522 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1524 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1525 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1527 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1528 KUNIT_ASSERT_NOT_NULL(test, ctl);
1530 /* Start the firmware and add an action to stop it during cleanup */
1531 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1532 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
1535 * If the control is write-only the cache will have been zero-initialized
1536 * so the first write will always indicate a change.
1538 if (def.flags && !(def.flags & WMFW_CTL_FLAG_READABLE)) {
1539 KUNIT_EXPECT_EQ(test,
1540 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals,
1546 * Write the same data to the control, cs_dsp_coeff_lock_and_write_ctrl()
1547 * should return 0 to indicate the content didn't change.
1549 KUNIT_EXPECT_EQ(test,
1550 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1552 KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
1553 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1557 * Write unchanged data to a cached control while the firmware is not started.
1558 * The control write should return 0 to indicate that the cache content
1561 static void cs_dsp_ctl_cache_write_unchanged_not_started(struct kunit *test)
1563 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1564 struct cs_dsp_test *priv = test->priv;
1565 struct cs_dsp_test_local *local = priv->local;
1566 struct cs_dsp *dsp = priv->dsp;
1567 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1568 int alg_idx = _find_alg_entry(test, param->alg_id);
1569 unsigned int reg, alg_base_words;
1570 struct cs_dsp_coeff_ctl *ctl;
1571 struct firmware *wmfw;
1572 u32 *reg_vals, *readback;
1574 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1575 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1577 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1578 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1580 /* Create some DSP data to be read into the control cache */
1581 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1582 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1583 reg += (alg_base_words + param->offs_words) *
1584 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1585 get_random_bytes(reg_vals, param->len_bytes);
1586 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1588 /* Create control pointing to this data */
1589 def.flags = param->flags;
1590 def.mem_type = param->mem_type;
1591 def.offset_dsp_words = param->offs_words;
1592 def.length_bytes = param->len_bytes;
1594 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1595 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1597 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1598 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1600 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1601 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1603 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1604 KUNIT_ASSERT_NOT_NULL(test, ctl);
1607 * If the control is write-only the cache will have been zero-initialized
1608 * so the first write will always indicate a change.
1610 if (def.flags && !(def.flags & WMFW_CTL_FLAG_READABLE)) {
1611 KUNIT_EXPECT_EQ(test,
1612 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals,
1618 * Write the same data to the control, cs_dsp_coeff_lock_and_write_ctrl()
1619 * should return 0 to indicate the content didn't change.
1621 KUNIT_EXPECT_EQ(test,
1622 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1624 KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
1625 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1629 * Write to a cached control while the firmware is loaded but not
1631 * This should write to the cache only.
1633 static void cs_dsp_ctl_cache_write_not_started(struct kunit *test)
1635 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1636 struct cs_dsp_test *priv = test->priv;
1637 struct cs_dsp_test_local *local = priv->local;
1638 struct cs_dsp *dsp = priv->dsp;
1639 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1640 int alg_idx = _find_alg_entry(test, param->alg_id);
1641 unsigned int reg, alg_base_words;
1642 struct cs_dsp_coeff_ctl *ctl;
1643 struct firmware *wmfw;
1644 u32 *reg_vals, *readback;
1646 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1647 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1649 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1650 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1652 /* Create some DSP data to be read into the control cache */
1653 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1654 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1655 reg += (alg_base_words + param->offs_words) *
1656 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1657 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1659 /* Create control pointing to this data */
1660 def.flags = param->flags;
1661 def.mem_type = param->mem_type;
1662 def.offset_dsp_words = param->offs_words;
1663 def.length_bytes = param->len_bytes;
1665 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1666 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1668 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1669 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1671 /* Power-up DSP but don't start firmware */
1672 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1673 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1675 /* Drop expected writes and the regmap cache should be clean */
1676 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1677 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1678 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1680 /* Write new data to the control, it should not be written to the registers */
1681 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1682 KUNIT_ASSERT_NOT_NULL(test, ctl);
1684 get_random_bytes(reg_vals, param->len_bytes);
1685 KUNIT_EXPECT_EQ(test,
1686 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1689 /* Registers should not have been written so regmap cache should still be clean */
1690 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1692 /* Control should readback the new data from the control cache */
1693 KUNIT_EXPECT_EQ(test,
1694 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1696 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1700 * Write to a cached control after the firmware has been loaded,
1701 * started and stopped.
1702 * This should write to the cache only.
1704 static void cs_dsp_ctl_cache_write_stopped(struct kunit *test)
1706 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1707 struct cs_dsp_test *priv = test->priv;
1708 struct cs_dsp_test_local *local = priv->local;
1709 struct cs_dsp *dsp = priv->dsp;
1710 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1711 int alg_idx = _find_alg_entry(test, param->alg_id);
1712 unsigned int reg, alg_base_words;
1713 struct cs_dsp_coeff_ctl *ctl;
1714 struct firmware *wmfw;
1715 u32 *reg_vals, *readback;
1717 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1718 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1720 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1721 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1723 /* Create some DSP data to be read into the control cache */
1724 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1725 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1726 reg += (alg_base_words + param->offs_words) *
1727 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1728 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1730 /* Create control pointing to this data */
1731 def.flags = param->flags;
1732 def.mem_type = param->mem_type;
1733 def.offset_dsp_words = param->offs_words;
1734 def.length_bytes = param->len_bytes;
1736 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1737 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1739 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1740 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1743 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1744 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1746 /* Start and stop the firmware */
1747 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1750 /* Drop expected writes and the regmap cache should be clean */
1751 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1752 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1753 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1755 /* Write new data to the control, it should not be written to the registers */
1756 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1757 KUNIT_ASSERT_NOT_NULL(test, ctl);
1759 get_random_bytes(reg_vals, param->len_bytes);
1760 KUNIT_EXPECT_EQ(test,
1761 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1764 /* Registers should not have been written so regmap cache should still be clean */
1765 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1767 /* Control should readback the new data from the control cache */
1768 KUNIT_EXPECT_EQ(test,
1769 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1771 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1775 * Write to a cached control after the firmware has been loaded,
1776 * then the DSP powered-down.
1777 * This should write to the cache only.
1779 static void cs_dsp_ctl_cache_write_powered_down(struct kunit *test)
1781 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1782 struct cs_dsp_test *priv = test->priv;
1783 struct cs_dsp_test_local *local = priv->local;
1784 struct cs_dsp *dsp = priv->dsp;
1785 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1786 int alg_idx = _find_alg_entry(test, param->alg_id);
1787 unsigned int reg, alg_base_words;
1788 struct cs_dsp_coeff_ctl *ctl;
1789 struct firmware *wmfw;
1790 u32 *reg_vals, *readback;
1792 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1793 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1795 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1796 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1798 /* Create some DSP data to be read into the control cache */
1799 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1800 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1801 reg += (alg_base_words + param->offs_words) *
1802 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1803 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1805 /* Create control pointing to this data */
1806 def.flags = param->flags;
1807 def.mem_type = param->mem_type;
1808 def.offset_dsp_words = param->offs_words;
1809 def.length_bytes = param->len_bytes;
1811 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1812 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1814 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1815 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1817 /* Power-up DSP then power-down */
1818 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1819 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1820 cs_dsp_power_down(dsp);
1822 /* Drop expected writes and the regmap cache should be clean */
1823 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1824 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1825 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1827 /* Write new data to the control, it should not be written to the registers */
1828 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1829 KUNIT_ASSERT_NOT_NULL(test, ctl);
1831 get_random_bytes(reg_vals, param->len_bytes);
1832 KUNIT_EXPECT_EQ(test,
1833 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1836 /* Registers should not have been written so regmap cache should still be clean */
1837 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1839 /* Control should readback the new data from the control cache */
1840 KUNIT_EXPECT_EQ(test,
1841 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1843 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1847 * Write to a cached control after the firmware has been loaded,
1848 * started, stopped, and then the DSP powered-down.
1849 * This should write to the cache only.
1851 static void cs_dsp_ctl_cache_write_stopped_powered_down(struct kunit *test)
1853 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1854 struct cs_dsp_test *priv = test->priv;
1855 struct cs_dsp_test_local *local = priv->local;
1856 struct cs_dsp *dsp = priv->dsp;
1857 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1858 int alg_idx = _find_alg_entry(test, param->alg_id);
1859 unsigned int reg, alg_base_words;
1860 struct cs_dsp_coeff_ctl *ctl;
1861 struct firmware *wmfw;
1862 u32 *reg_vals, *readback;
1864 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1865 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1867 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1868 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1870 /* Create some DSP data to be read into the control cache */
1871 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1872 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1873 reg += (alg_base_words + param->offs_words) *
1874 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1875 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1877 /* Create control pointing to this data */
1878 def.flags = param->flags;
1879 def.mem_type = param->mem_type;
1880 def.offset_dsp_words = param->offs_words;
1881 def.length_bytes = param->len_bytes;
1883 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1884 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1886 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1887 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1890 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1891 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1893 /* Start and stop the firmware then power-down */
1894 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1896 cs_dsp_power_down(dsp);
1898 /* Drop expected writes and the regmap cache should be clean */
1899 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1900 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1901 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1903 /* Write new data to the control, it should not be written to the registers */
1904 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1905 KUNIT_ASSERT_NOT_NULL(test, ctl);
1907 get_random_bytes(reg_vals, param->len_bytes);
1908 KUNIT_EXPECT_EQ(test,
1909 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1912 /* Registers should not have been written so regmap cache should still be clean */
1913 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1915 /* Control should readback the new data from the control cache */
1916 KUNIT_EXPECT_EQ(test,
1917 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1919 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1923 * Write to a cached control that is not in the currently loaded firmware.
1924 * This should write to the cache only.
1926 static void cs_dsp_ctl_cache_write_not_current_loaded_fw(struct kunit *test)
1928 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1929 struct cs_dsp_test *priv = test->priv;
1930 struct cs_dsp_test_local *local = priv->local;
1931 struct cs_dsp *dsp = priv->dsp;
1932 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1933 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test);
1934 int alg_idx = _find_alg_entry(test, param->alg_id);
1935 unsigned int reg, alg_base_words;
1936 struct cs_dsp_coeff_ctl *ctl;
1937 struct firmware *wmfw;
1938 u32 *reg_vals, *readback;
1940 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1941 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1943 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1944 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1946 /* Create some DSP data to be read into the control cache */
1947 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1948 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1949 reg += (alg_base_words + param->offs_words) *
1950 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1951 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1953 /* Create control pointing to this data */
1954 def.flags = param->flags;
1955 def.mem_type = param->mem_type;
1956 def.offset_dsp_words = param->offs_words;
1957 def.length_bytes = param->len_bytes;
1959 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1960 cs_dsp_ctl_cache_test_algs[alg_idx].id,
1962 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1963 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1966 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1967 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1969 /* Get the control */
1970 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1971 KUNIT_ASSERT_NOT_NULL(test, ctl);
1973 /* Power-down DSP then power-up with a different firmware */
1974 cs_dsp_power_down(dsp);
1975 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
1976 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
1978 /* Control from unloaded firmware should be disabled */
1979 KUNIT_EXPECT_FALSE(test, ctl->enabled);
1981 /* Drop expected writes and the regmap cache should be clean */
1982 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1983 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1984 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1987 * It should be possible to write new data to the control from
1988 * the first firmware. But this should not be written to the
1991 get_random_bytes(reg_vals, param->len_bytes);
1992 KUNIT_EXPECT_EQ(test,
1993 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1996 /* Registers should not have been written so regmap cache should still be clean */
1997 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1999 /* Control should readback the new data from the control cache */
2000 KUNIT_EXPECT_EQ(test,
2001 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2003 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2007 * Write to a cached control that is not in the currently running firmware.
2008 * This should write to the cache only.
2010 static void cs_dsp_ctl_cache_write_not_current_running_fw(struct kunit *test)
2012 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2013 struct cs_dsp_test *priv = test->priv;
2014 struct cs_dsp_test_local *local = priv->local;
2015 struct cs_dsp *dsp = priv->dsp;
2016 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2017 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test);
2018 int alg_idx = _find_alg_entry(test, param->alg_id);
2019 unsigned int reg, alg_base_words;
2020 struct cs_dsp_coeff_ctl *ctl;
2021 struct firmware *wmfw;
2022 u32 *reg_vals, *readback;
2024 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2025 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
2027 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2028 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2030 /* Create some DSP data to be read into the control cache */
2031 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2032 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2033 reg += (alg_base_words + param->offs_words) *
2034 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2035 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
2037 /* Create control pointing to this data */
2038 def.flags = param->flags;
2039 def.mem_type = param->mem_type;
2040 def.offset_dsp_words = param->offs_words;
2041 def.length_bytes = param->len_bytes;
2043 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2044 cs_dsp_ctl_cache_test_algs[alg_idx].id,
2046 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2047 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2049 /* Power-up DSP then power-down */
2050 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2051 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2052 cs_dsp_power_down(dsp);
2054 /* Get the control */
2055 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2056 KUNIT_ASSERT_NOT_NULL(test, ctl);
2058 /* Power-up with a different firmware and run it */
2059 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
2060 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
2061 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2062 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2064 /* Control from unloaded firmware should be disabled */
2065 KUNIT_EXPECT_FALSE(test, ctl->enabled);
2067 /* Drop expected writes and the regmap cache should be clean */
2068 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
2069 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
2070 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
2073 * It should be possible to write new data to the control from
2074 * the first firmware. But this should not be written to the
2077 get_random_bytes(reg_vals, param->len_bytes);
2078 KUNIT_EXPECT_EQ(test,
2079 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
2082 /* Registers should not have been written so regmap cache should still be clean */
2083 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
2085 /* Control should readback the new data from the control cache */
2086 KUNIT_EXPECT_EQ(test,
2087 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2089 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2093 * Write to a cached control before running the firmware.
2094 * The value written to the cache should be synced out to the registers
2095 * backing the control when the firmware is run.
2097 static void cs_dsp_ctl_cache_sync_write_before_run(struct kunit *test)
2099 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2100 struct cs_dsp_test *priv = test->priv;
2101 struct cs_dsp_test_local *local = priv->local;
2102 struct cs_dsp *dsp = priv->dsp;
2103 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2104 int alg_idx = _find_alg_entry(test, param->alg_id);
2105 unsigned int reg, alg_base_words;
2106 struct cs_dsp_coeff_ctl *ctl;
2107 struct firmware *wmfw;
2108 u32 *reg_vals, *readback;
2110 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2111 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
2113 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2114 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2116 /* Create some DSP data to be read into the control cache */
2117 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2118 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2119 reg += (alg_base_words + param->offs_words) *
2120 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2121 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
2123 /* Create control pointing to this data */
2124 def.flags = param->flags;
2125 def.mem_type = param->mem_type;
2126 def.offset_dsp_words = param->offs_words;
2127 def.length_bytes = param->len_bytes;
2129 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2130 cs_dsp_ctl_cache_test_algs[alg_idx].id,
2132 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2133 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2135 /* Power-up DSP but don't start firmware */
2136 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2137 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2139 /* Write new data to the control, it should not be written to the registers */
2140 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2141 KUNIT_ASSERT_NOT_NULL(test, ctl);
2143 get_random_bytes(reg_vals, param->len_bytes);
2144 KUNIT_EXPECT_EQ(test,
2145 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
2148 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2149 KUNIT_EXPECT_MEMNEQ(test, readback, reg_vals, param->len_bytes);
2151 /* Start the firmware and the cached data should be written to registers */
2152 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2153 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2155 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2156 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2158 /* Control should readback the new data from the control cache */
2159 KUNIT_EXPECT_EQ(test,
2160 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2162 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2166 * Write to a cached control while the firmware is running.
2167 * The value written should be synced out to the registers
2168 * backing the control when the firmware is next run.
2170 static void cs_dsp_ctl_cache_sync_write_while_running(struct kunit *test)
2172 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2173 struct cs_dsp_test *priv = test->priv;
2174 struct cs_dsp_test_local *local = priv->local;
2175 struct cs_dsp *dsp = priv->dsp;
2176 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2177 int alg_idx = _find_alg_entry(test, param->alg_id);
2178 unsigned int reg, alg_base_words;
2179 struct cs_dsp_coeff_ctl *ctl;
2180 struct firmware *wmfw;
2181 u32 *init_vals, *ctl_vals, *readback;
2183 init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2184 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals);
2186 ctl_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2187 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals);
2189 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2190 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2192 /* Zero-fill the registers backing the control */
2193 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2194 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2195 reg += (alg_base_words + param->offs_words) *
2196 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2197 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2199 /* Create control pointing to this data */
2200 def.flags = param->flags;
2201 def.mem_type = param->mem_type;
2202 def.offset_dsp_words = param->offs_words;
2203 def.length_bytes = param->len_bytes;
2205 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2206 cs_dsp_ctl_cache_test_algs[alg_idx].id,
2208 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2209 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2211 /* Power-up DSP and start firmware */
2212 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2213 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2214 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2215 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2217 /* Write new data to the control */
2218 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2219 KUNIT_ASSERT_NOT_NULL(test, ctl);
2221 get_random_bytes(ctl_vals, param->len_bytes);
2222 KUNIT_EXPECT_EQ(test,
2223 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, param->len_bytes),
2226 /* Stop firmware and zero the registers backing the control */
2227 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
2228 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2229 KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2230 KUNIT_EXPECT_MEMEQ(test, readback, init_vals, param->len_bytes);
2232 /* Start the firmware and the cached data should be written to registers */
2233 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2234 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2236 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2237 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2239 /* Control should readback the new data from the control cache */
2240 KUNIT_EXPECT_EQ(test,
2241 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2243 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2247 * Write to a cached control after stopping the firmware.
2248 * The value written to the cache should be synced out to the registers
2249 * backing the control when the firmware is next run.
2251 static void cs_dsp_ctl_cache_sync_write_after_stop(struct kunit *test)
2253 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2254 struct cs_dsp_test *priv = test->priv;
2255 struct cs_dsp_test_local *local = priv->local;
2256 struct cs_dsp *dsp = priv->dsp;
2257 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2258 int alg_idx = _find_alg_entry(test, param->alg_id);
2259 unsigned int reg, alg_base_words;
2260 struct cs_dsp_coeff_ctl *ctl;
2261 struct firmware *wmfw;
2262 u32 *reg_vals, *readback;
2264 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2265 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
2267 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2268 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2270 /* Create some DSP data to be read into the control cache */
2271 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2272 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2273 reg += (alg_base_words + param->offs_words) *
2274 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2275 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
2277 /* Create control pointing to this data */
2278 def.flags = param->flags;
2279 def.mem_type = param->mem_type;
2280 def.offset_dsp_words = param->offs_words;
2281 def.length_bytes = param->len_bytes;
2283 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2284 cs_dsp_ctl_cache_test_algs[alg_idx].id,
2286 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2287 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2289 /* Power-up DSP but don't start firmware */
2290 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2291 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2293 /* Start and stop the firmware */
2294 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2297 /* Write new data to the control, it should not be written to the registers */
2298 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2299 KUNIT_ASSERT_NOT_NULL(test, ctl);
2301 get_random_bytes(reg_vals, param->len_bytes);
2302 KUNIT_EXPECT_EQ(test,
2303 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
2306 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2307 KUNIT_EXPECT_MEMNEQ(test, readback, reg_vals, param->len_bytes);
2309 /* Start the firmware and the cached data should be written to registers */
2310 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2311 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2313 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2314 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2316 /* Control should readback the new data from the control cache */
2317 KUNIT_EXPECT_EQ(test,
2318 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2320 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2324 * Write to a cached control that is not in the currently loaded firmware.
2325 * The value written to the cache should be synced out to the registers
2326 * backing the control the next time the firmware containing the
2329 static void cs_dsp_ctl_cache_sync_write_not_current_fw(struct kunit *test)
2331 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2332 struct cs_dsp_test *priv = test->priv;
2333 struct cs_dsp_test_local *local = priv->local;
2334 struct cs_dsp *dsp = priv->dsp;
2335 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2336 int alg_idx = _find_alg_entry(test, param->alg_id);
2337 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test);
2338 unsigned int reg, alg_base_words;
2339 struct cs_dsp_coeff_ctl *ctl;
2340 struct firmware *wmfw;
2341 u32 *reg_vals, *readback;
2343 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2344 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
2346 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2347 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2349 /* Create some DSP data to be read into the control cache */
2350 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2351 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2352 reg += (alg_base_words + param->offs_words) *
2353 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2354 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
2356 /* Create control pointing to this data */
2357 def.flags = param->flags;
2358 def.mem_type = param->mem_type;
2359 def.offset_dsp_words = param->offs_words;
2360 def.length_bytes = param->len_bytes;
2362 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2363 cs_dsp_ctl_cache_test_algs[alg_idx].id,
2365 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2366 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2368 /* Power-up DSP but don't start firmware */
2369 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2370 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2372 /* Get the control */
2373 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2374 KUNIT_ASSERT_NOT_NULL(test, ctl);
2376 /* Power-down DSP then power-up with a different firmware */
2377 cs_dsp_power_down(dsp);
2378 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
2379 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
2381 /* Write new data to the control, it should not be written to the registers */
2382 get_random_bytes(reg_vals, param->len_bytes);
2383 KUNIT_EXPECT_EQ(test,
2384 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
2387 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2388 KUNIT_EXPECT_MEMNEQ(test, readback, reg_vals, param->len_bytes);
2390 /* Power-down DSP then power-up with the original firmware */
2391 cs_dsp_power_down(dsp);
2392 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2393 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2395 /* Start the firmware and the cached data should be written to registers */
2396 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2397 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2399 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2400 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2402 /* Control should readback the new data from the control cache */
2403 KUNIT_EXPECT_EQ(test,
2404 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2406 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2410 * The value in the control cache should be synced out to the registers
2411 * backing the control every time the firmware containing the control
2414 static void cs_dsp_ctl_cache_sync_reapply_every_run(struct kunit *test)
2416 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2417 struct cs_dsp_test *priv = test->priv;
2418 struct cs_dsp_test_local *local = priv->local;
2419 struct cs_dsp *dsp = priv->dsp;
2420 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2421 int alg_idx = _find_alg_entry(test, param->alg_id);
2422 unsigned int reg, alg_base_words;
2423 struct cs_dsp_coeff_ctl *ctl;
2424 struct firmware *wmfw;
2425 u32 *init_vals, *readback, *ctl_vals;
2427 init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2428 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals);
2430 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2431 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2433 ctl_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
2434 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals);
2436 /* Zero-fill the registers backing the control */
2437 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2438 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2439 reg += (alg_base_words + param->offs_words) *
2440 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2441 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2443 /* Create control pointing to this data */
2444 def.flags = param->flags;
2445 def.mem_type = param->mem_type;
2446 def.offset_dsp_words = param->offs_words;
2447 def.length_bytes = param->len_bytes;
2449 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2450 cs_dsp_ctl_cache_test_algs[alg_idx].id,
2452 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2453 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2455 /* Power-up DSP but don't start firmware */
2456 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2457 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2459 /* Write new data to the control */
2460 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2461 KUNIT_ASSERT_NOT_NULL(test, ctl);
2463 get_random_bytes(ctl_vals, param->len_bytes);
2464 KUNIT_EXPECT_EQ(test,
2465 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, param->len_bytes),
2468 /* Start the firmware and the cached data should be written to registers */
2469 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2470 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2471 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2472 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2474 /* Stop the firmware and reset the registers */
2475 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
2476 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2478 /* Start the firmware again and the cached data should be written to registers */
2479 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2480 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2481 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2482 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2484 /* Control should readback the new data from the control cache */
2485 KUNIT_EXPECT_EQ(test,
2486 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2488 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2492 * The value in the control cache should be retained if the same
2493 * firmware is downloaded again. It should be synced out to the
2494 * registers backing the control after the firmware containing the
2495 * control is downloaded again and run.
2497 static void cs_dsp_ctl_cache_sync_reapply_after_fw_reload(struct kunit *test)
2499 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2500 struct cs_dsp_test *priv = test->priv;
2501 struct cs_dsp_test_local *local = priv->local;
2502 struct cs_dsp *dsp = priv->dsp;
2503 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2504 int alg_idx = _find_alg_entry(test, param->alg_id);
2505 unsigned int reg, alg_base_words;
2506 struct cs_dsp_coeff_ctl *ctl;
2507 struct firmware *wmfw;
2508 u32 *init_vals, *readback, *ctl_vals;
2510 init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2511 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals);
2513 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2514 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2516 ctl_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
2517 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals);
2519 /* Zero-fill the registers backing the control */
2520 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2521 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2522 reg += (alg_base_words + param->offs_words) *
2523 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2524 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2526 /* Create control pointing to this data */
2527 def.flags = param->flags;
2528 def.mem_type = param->mem_type;
2529 def.offset_dsp_words = param->offs_words;
2530 def.length_bytes = param->len_bytes;
2532 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2533 cs_dsp_ctl_cache_test_algs[alg_idx].id,
2535 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2536 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2538 /* Power-up DSP but don't start firmware */
2539 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2540 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2542 /* Write new data to the control */
2543 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2544 KUNIT_ASSERT_NOT_NULL(test, ctl);
2546 get_random_bytes(ctl_vals, param->len_bytes);
2547 KUNIT_EXPECT_EQ(test,
2548 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, param->len_bytes),
2551 /* Start the firmware and the cached data should be written to registers */
2552 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2553 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2554 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2555 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2557 /* Stop the firmware and power-down the DSP */
2558 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
2559 cs_dsp_power_down(dsp);
2561 /* Reset the registers */
2562 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2564 /* Download the firmware again, the cache content should not change */
2565 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2567 /* Start the firmware and the cached data should be written to registers */
2568 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2569 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2570 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2571 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2573 /* Control should readback the new data from the control cache */
2574 KUNIT_EXPECT_EQ(test,
2575 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2577 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2581 * The value in the control cache should be retained after a different
2582 * firmware is downloaded.
2583 * When the firmware containing the control is downloaded and run
2584 * the value in the control cache should be synced out to the registers
2585 * backing the control.
2587 static void cs_dsp_ctl_cache_sync_reapply_after_fw_swap(struct kunit *test)
2589 const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2590 struct cs_dsp_test *priv = test->priv;
2591 struct cs_dsp_test_local *local = priv->local;
2592 struct cs_dsp *dsp = priv->dsp;
2593 struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2594 int alg_idx = _find_alg_entry(test, param->alg_id);
2595 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test);
2596 unsigned int reg, alg_base_words;
2597 struct cs_dsp_coeff_ctl *ctl;
2598 struct firmware *wmfw;
2599 u32 *init_vals, *readback, *ctl_vals;
2601 init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2602 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals);
2604 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2605 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2607 ctl_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
2608 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals);
2610 /* Zero-fill the registers backing the control */
2611 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2612 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2613 reg += (alg_base_words + param->offs_words) *
2614 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2615 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2617 /* Create control pointing to this data */
2618 def.flags = param->flags;
2619 def.mem_type = param->mem_type;
2620 def.offset_dsp_words = param->offs_words;
2621 def.length_bytes = param->len_bytes;
2623 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2624 cs_dsp_ctl_cache_test_algs[alg_idx].id,
2626 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2627 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2629 /* Power-up DSP but don't start firmware */
2630 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2631 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2633 /* Write new data to the control */
2634 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2635 KUNIT_ASSERT_NOT_NULL(test, ctl);
2637 get_random_bytes(ctl_vals, param->len_bytes);
2638 KUNIT_EXPECT_EQ(test,
2639 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, param->len_bytes),
2642 /* Start the firmware and the cached data should be written to registers */
2643 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2644 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2645 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2646 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2648 /* Stop the firmware and power-down the DSP */
2649 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
2650 cs_dsp_power_down(dsp);
2652 /* Reset the registers */
2653 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2655 /* Download and run a different firmware */
2656 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
2657 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
2658 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2659 cs_dsp_power_down(dsp);
2661 /* Reset the registers */
2662 regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2664 /* Download the original firmware again */
2665 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2666 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2667 KUNIT_EXPECT_TRUE(test, ctl->set);
2669 /* Start the firmware and the cached data should be written to registers */
2670 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2671 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2672 KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2673 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2675 /* Control should readback the new data from the control cache */
2676 KUNIT_EXPECT_EQ(test,
2677 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2679 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2682 static int cs_dsp_ctl_cache_test_common_init(struct kunit *test, struct cs_dsp *dsp,
2685 struct cs_dsp_test *priv;
2686 struct cs_dsp_test_local *local;
2687 struct device *test_dev;
2690 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
2694 local = kunit_kzalloc(test, sizeof(struct cs_dsp_test_local), GFP_KERNEL);
2701 priv->local = local;
2702 priv->local->wmfw_version = wmfw_version;
2704 /* Create dummy struct device */
2705 test_dev = kunit_device_register(test, "cs_dsp_test_drv");
2706 if (IS_ERR(test_dev))
2707 return PTR_ERR(test_dev);
2709 dsp->dev = get_device(test_dev);
2713 ret = kunit_add_action_or_reset(test, _put_device_wrapper, dsp->dev);
2717 dev_set_drvdata(dsp->dev, priv);
2719 /* Allocate regmap */
2720 ret = cs_dsp_mock_regmap_init(priv);
2725 * There must always be a XM header with at least 1 algorithm, so create
2726 * a dummy one that tests can use and extract it to a data blob.
2728 local->xm_header = cs_dsp_create_mock_xm_header(priv,
2729 cs_dsp_ctl_cache_test_algs,
2730 ARRAY_SIZE(cs_dsp_ctl_cache_test_algs));
2731 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->xm_header);
2733 /* Create wmfw builder */
2734 local->wmfw_builder = _create_dummy_wmfw(test);
2737 dsp->client_ops = kunit_kzalloc(test, sizeof(*dsp->client_ops), GFP_KERNEL);
2738 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dsp->client_ops);
2740 switch (dsp->type) {
2742 ret = cs_dsp_adsp2_init(dsp);
2745 ret = cs_dsp_halo_init(dsp);
2748 KUNIT_FAIL(test, "Untested DSP type %d\n", dsp->type);
2755 /* Automatically call cs_dsp_remove() when test case ends */
2756 return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
2759 static int cs_dsp_ctl_cache_test_halo_init(struct kunit *test)
2763 /* Fill in cs_dsp and initialize */
2764 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
2769 dsp->type = WMFW_HALO;
2770 dsp->mem = cs_dsp_mock_halo_dsp1_regions;
2771 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_halo_dsp1_region_sizes);
2772 dsp->base = cs_dsp_mock_halo_core_base;
2773 dsp->base_sysinfo = cs_dsp_mock_halo_sysinfo_base;
2775 return cs_dsp_ctl_cache_test_common_init(test, dsp, 3);
2778 static int cs_dsp_ctl_cache_test_adsp2_32bit_init(struct kunit *test, int wmfw_ver)
2782 /* Fill in cs_dsp and initialize */
2783 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
2788 dsp->type = WMFW_ADSP2;
2790 dsp->mem = cs_dsp_mock_adsp2_32bit_dsp1_regions;
2791 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_32bit_dsp1_region_sizes);
2792 dsp->base = cs_dsp_mock_adsp2_32bit_sysbase;
2794 return cs_dsp_ctl_cache_test_common_init(test, dsp, wmfw_ver);
2797 static int cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1_init(struct kunit *test)
2799 return cs_dsp_ctl_cache_test_adsp2_32bit_init(test, 1);
2802 static int cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2_init(struct kunit *test)
2804 return cs_dsp_ctl_cache_test_adsp2_32bit_init(test, 2);
2807 static int cs_dsp_ctl_cache_test_adsp2_16bit_init(struct kunit *test, int wmfw_ver)
2811 /* Fill in cs_dsp and initialize */
2812 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
2817 dsp->type = WMFW_ADSP2;
2819 dsp->mem = cs_dsp_mock_adsp2_16bit_dsp1_regions;
2820 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_16bit_dsp1_region_sizes);
2821 dsp->base = cs_dsp_mock_adsp2_16bit_sysbase;
2823 return cs_dsp_ctl_cache_test_common_init(test, dsp, wmfw_ver);
2826 static int cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1_init(struct kunit *test)
2828 return cs_dsp_ctl_cache_test_adsp2_16bit_init(test, 1);
2831 static int cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2_init(struct kunit *test)
2833 return cs_dsp_ctl_cache_test_adsp2_16bit_init(test, 2);
2836 static void cs_dsp_ctl_all_param_desc(const struct cs_dsp_ctl_cache_test_param *param,
2839 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "alg:%#x %s@%u len:%u flags:%#x",
2840 param->alg_id, cs_dsp_mem_region_name(param->mem_type),
2841 param->offs_words, param->len_bytes, param->flags);
2844 /* All parameters populated, with various lengths */
2845 static const struct cs_dsp_ctl_cache_test_param all_pop_varying_len_cases[] = {
2846 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2847 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 8 },
2848 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 12 },
2849 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 16 },
2850 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 48 },
2851 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 100 },
2852 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 512 },
2853 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 1000 },
2855 KUNIT_ARRAY_PARAM(all_pop_varying_len, all_pop_varying_len_cases,
2856 cs_dsp_ctl_all_param_desc);
2858 /* All parameters populated, with various offsets */
2859 static const struct cs_dsp_ctl_cache_test_param all_pop_varying_offset_cases[] = {
2860 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 0, .len_bytes = 4 },
2861 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2862 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 2, .len_bytes = 4 },
2863 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 3, .len_bytes = 4 },
2864 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 8, .len_bytes = 4 },
2865 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 10, .len_bytes = 4 },
2866 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 128, .len_bytes = 4 },
2867 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 180, .len_bytes = 4 },
2869 KUNIT_ARRAY_PARAM(all_pop_varying_offset, all_pop_varying_offset_cases,
2870 cs_dsp_ctl_all_param_desc);
2872 /* All parameters populated, with various X and Y memory regions */
2873 static const struct cs_dsp_ctl_cache_test_param all_pop_varying_xy_cases[] = {
2874 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_XM, .offs_words = 1, .len_bytes = 4 },
2875 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2877 KUNIT_ARRAY_PARAM(all_pop_varying_xy, all_pop_varying_xy_cases,
2878 cs_dsp_ctl_all_param_desc);
2880 /* All parameters populated, using ZM */
2881 static const struct cs_dsp_ctl_cache_test_param all_pop_z_cases[] = {
2882 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_ZM, .offs_words = 1, .len_bytes = 4 },
2884 KUNIT_ARRAY_PARAM(all_pop_z, all_pop_z_cases, cs_dsp_ctl_all_param_desc);
2886 /* All parameters populated, with various algorithm ids */
2887 static const struct cs_dsp_ctl_cache_test_param all_pop_varying_alg_cases[] = {
2888 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2889 { .alg_id = 0xb, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2890 { .alg_id = 0x9f1234, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2891 { .alg_id = 0xff00ff, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2893 KUNIT_ARRAY_PARAM(all_pop_varying_alg, all_pop_varying_alg_cases,
2894 cs_dsp_ctl_all_param_desc);
2897 * All parameters populated, with all combinations of flags for a
2898 * non-volatile readable control
2900 static const struct cs_dsp_ctl_cache_test_param all_pop_nonvol_readable_flags_cases[] = {
2901 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2904 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2905 .flags = WMFW_CTL_FLAG_READABLE,
2907 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2908 .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
2910 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2911 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE,
2913 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2914 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
2917 KUNIT_ARRAY_PARAM(all_pop_nonvol_readable_flags,
2918 all_pop_nonvol_readable_flags_cases,
2919 cs_dsp_ctl_all_param_desc);
2922 * All parameters populated, with all combinations of flags for a
2923 * non-volatile readable control, except flags==0
2925 static const struct cs_dsp_ctl_cache_test_param all_pop_nonvol_readable_nonzero_flags_cases[] = {
2926 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2927 .flags = WMFW_CTL_FLAG_READABLE,
2929 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2930 .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
2932 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2933 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE,
2935 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2936 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
2939 KUNIT_ARRAY_PARAM(all_pop_nonvol_readable_nonzero_flags,
2940 all_pop_nonvol_readable_nonzero_flags_cases,
2941 cs_dsp_ctl_all_param_desc);
2944 * All parameters populated, with all combinations of flags for a
2945 * non-volatile writeable control
2947 static const struct cs_dsp_ctl_cache_test_param all_pop_nonvol_writeable_flags_cases[] = {
2948 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2951 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2952 .flags = WMFW_CTL_FLAG_WRITEABLE,
2954 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2955 .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
2957 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2958 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE,
2960 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2961 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
2964 KUNIT_ARRAY_PARAM(all_pop_nonvol_writeable_flags,
2965 all_pop_nonvol_writeable_flags_cases,
2966 cs_dsp_ctl_all_param_desc);
2969 * All parameters populated, with all combinations of flags for a
2970 * non-volatile write-only control of varying lengths
2972 static const struct cs_dsp_ctl_cache_test_param all_pop_nonvol_write_only_length_cases[] = {
2973 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2974 .flags = WMFW_CTL_FLAG_WRITEABLE,
2976 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 512,
2977 .flags = WMFW_CTL_FLAG_WRITEABLE,
2979 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2980 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE,
2982 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 512,
2983 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE,
2986 KUNIT_ARRAY_PARAM(all_pop_nonvol_write_only_length,
2987 all_pop_nonvol_write_only_length_cases,
2988 cs_dsp_ctl_all_param_desc);
2990 static struct kunit_case cs_dsp_ctl_cache_test_cases_v1[] = {
2991 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_len_gen_params),
2992 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_offset_gen_params),
2993 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_xy_gen_params),
2994 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_z_gen_params),
2995 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_alg_gen_params),
2996 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_nonvol_readable_flags_gen_params),
2998 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init_write_only,
2999 all_pop_nonvol_write_only_length_gen_params),
3001 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fw_same_controls),
3002 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls),
3003 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_mems),
3004 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_algs),
3006 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_started,
3007 all_pop_nonvol_readable_flags_gen_params),
3008 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped,
3009 all_pop_nonvol_readable_flags_gen_params),
3010 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_powered_down,
3011 all_pop_nonvol_readable_flags_gen_params),
3012 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped_powered_down,
3013 all_pop_nonvol_readable_flags_gen_params),
3014 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_loaded_fw,
3015 all_pop_nonvol_readable_flags_gen_params),
3016 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_running_fw,
3017 all_pop_nonvol_readable_flags_gen_params),
3018 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running,
3019 all_pop_nonvol_readable_nonzero_flags_gen_params),
3020 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running_zero_flags,
3021 all_pop_varying_len_gen_params),
3023 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_len_gen_params),
3024 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_offset_gen_params),
3025 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_xy_gen_params),
3026 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_z_gen_params),
3027 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_alg_gen_params),
3028 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_nonvol_writeable_flags_gen_params),
3030 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3031 all_pop_varying_len_gen_params),
3032 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3033 all_pop_varying_offset_gen_params),
3034 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3035 all_pop_varying_xy_gen_params),
3036 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3037 all_pop_z_gen_params),
3038 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3039 all_pop_varying_alg_gen_params),
3040 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3041 all_pop_nonvol_writeable_flags_gen_params),
3043 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_unchanged_not_started,
3044 all_pop_nonvol_writeable_flags_gen_params),
3045 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_started,
3046 all_pop_nonvol_writeable_flags_gen_params),
3047 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped,
3048 all_pop_nonvol_writeable_flags_gen_params),
3049 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_powered_down,
3050 all_pop_nonvol_writeable_flags_gen_params),
3051 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped_powered_down,
3052 all_pop_nonvol_writeable_flags_gen_params),
3053 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_loaded_fw,
3054 all_pop_nonvol_writeable_flags_gen_params),
3055 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_running_fw,
3056 all_pop_nonvol_writeable_flags_gen_params),
3058 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_before_run,
3059 all_pop_nonvol_writeable_flags_gen_params),
3060 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_while_running,
3061 all_pop_nonvol_writeable_flags_gen_params),
3062 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_after_stop,
3063 all_pop_nonvol_writeable_flags_gen_params),
3064 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_not_current_fw,
3065 all_pop_nonvol_writeable_flags_gen_params),
3066 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_every_run,
3067 all_pop_nonvol_writeable_flags_gen_params),
3068 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_reload,
3069 all_pop_nonvol_writeable_flags_gen_params),
3070 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_swap,
3071 all_pop_nonvol_writeable_flags_gen_params),
3073 { } /* terminator */
3076 static struct kunit_case cs_dsp_ctl_cache_test_cases_v2[] = {
3077 KUNIT_CASE(cs_dsp_ctl_v2_cache_alloc),
3079 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_len_gen_params),
3080 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_offset_gen_params),
3081 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_xy_gen_params),
3082 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_z_gen_params),
3083 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_alg_gen_params),
3084 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_nonvol_readable_flags_gen_params),
3086 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init_write_only,
3087 all_pop_nonvol_write_only_length_gen_params),
3089 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fw_same_controls),
3090 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls),
3091 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_mems),
3092 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_algs),
3093 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_offsets),
3095 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_started,
3096 all_pop_nonvol_readable_flags_gen_params),
3097 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped,
3098 all_pop_nonvol_readable_flags_gen_params),
3099 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_powered_down,
3100 all_pop_nonvol_readable_flags_gen_params),
3101 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped_powered_down,
3102 all_pop_nonvol_readable_flags_gen_params),
3103 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_loaded_fw,
3104 all_pop_nonvol_readable_flags_gen_params),
3105 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_running_fw,
3106 all_pop_nonvol_readable_flags_gen_params),
3107 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running,
3108 all_pop_nonvol_readable_nonzero_flags_gen_params),
3109 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running_zero_flags,
3110 all_pop_varying_len_gen_params),
3112 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_len_gen_params),
3113 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_offset_gen_params),
3114 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_xy_gen_params),
3115 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_z_gen_params),
3116 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_alg_gen_params),
3117 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_nonvol_writeable_flags_gen_params),
3119 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3120 all_pop_varying_len_gen_params),
3121 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3122 all_pop_varying_offset_gen_params),
3123 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3124 all_pop_varying_xy_gen_params),
3125 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3126 all_pop_z_gen_params),
3127 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3128 all_pop_varying_alg_gen_params),
3129 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3130 all_pop_nonvol_writeable_flags_gen_params),
3132 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_unchanged_not_started,
3133 all_pop_nonvol_writeable_flags_gen_params),
3134 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_started,
3135 all_pop_nonvol_writeable_flags_gen_params),
3136 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped,
3137 all_pop_nonvol_writeable_flags_gen_params),
3138 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_powered_down,
3139 all_pop_nonvol_writeable_flags_gen_params),
3140 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped_powered_down,
3141 all_pop_nonvol_writeable_flags_gen_params),
3142 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_loaded_fw,
3143 all_pop_nonvol_writeable_flags_gen_params),
3144 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_running_fw,
3145 all_pop_nonvol_writeable_flags_gen_params),
3147 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_before_run,
3148 all_pop_nonvol_writeable_flags_gen_params),
3149 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_while_running,
3150 all_pop_nonvol_writeable_flags_gen_params),
3151 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_after_stop,
3152 all_pop_nonvol_writeable_flags_gen_params),
3153 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_not_current_fw,
3154 all_pop_nonvol_writeable_flags_gen_params),
3155 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_every_run,
3156 all_pop_nonvol_writeable_flags_gen_params),
3157 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_reload,
3158 all_pop_nonvol_writeable_flags_gen_params),
3159 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_swap,
3160 all_pop_nonvol_writeable_flags_gen_params),
3162 { } /* terminator */
3165 static struct kunit_case cs_dsp_ctl_cache_test_cases_v3[] = {
3166 KUNIT_CASE(cs_dsp_ctl_v2_cache_alloc),
3168 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_len_gen_params),
3169 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_offset_gen_params),
3170 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_xy_gen_params),
3171 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_alg_gen_params),
3172 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_nonvol_readable_flags_gen_params),
3174 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init_write_only,
3175 all_pop_nonvol_write_only_length_gen_params),
3177 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fw_same_controls),
3178 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls),
3179 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_mems),
3180 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_algs),
3181 KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_offsets),
3183 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_started,
3184 all_pop_nonvol_readable_flags_gen_params),
3185 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped,
3186 all_pop_nonvol_readable_flags_gen_params),
3187 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_powered_down,
3188 all_pop_nonvol_readable_flags_gen_params),
3189 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped_powered_down,
3190 all_pop_nonvol_readable_flags_gen_params),
3191 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_loaded_fw,
3192 all_pop_nonvol_readable_flags_gen_params),
3193 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_running_fw,
3194 all_pop_nonvol_readable_flags_gen_params),
3195 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running,
3196 all_pop_nonvol_readable_nonzero_flags_gen_params),
3198 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_len_gen_params),
3199 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_offset_gen_params),
3200 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_xy_gen_params),
3201 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_alg_gen_params),
3202 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_nonvol_writeable_flags_gen_params),
3204 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3205 all_pop_varying_len_gen_params),
3206 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3207 all_pop_varying_offset_gen_params),
3208 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3209 all_pop_varying_xy_gen_params),
3210 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3211 all_pop_varying_alg_gen_params),
3212 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3213 all_pop_nonvol_writeable_flags_gen_params),
3215 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_unchanged_not_started,
3216 all_pop_nonvol_writeable_flags_gen_params),
3217 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_started,
3218 all_pop_nonvol_writeable_flags_gen_params),
3219 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped,
3220 all_pop_nonvol_writeable_flags_gen_params),
3221 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_powered_down,
3222 all_pop_nonvol_writeable_flags_gen_params),
3223 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped_powered_down,
3224 all_pop_nonvol_writeable_flags_gen_params),
3225 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_loaded_fw,
3226 all_pop_nonvol_writeable_flags_gen_params),
3227 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_running_fw,
3228 all_pop_nonvol_writeable_flags_gen_params),
3230 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_before_run,
3231 all_pop_nonvol_writeable_flags_gen_params),
3232 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_while_running,
3233 all_pop_nonvol_writeable_flags_gen_params),
3234 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_after_stop,
3235 all_pop_nonvol_writeable_flags_gen_params),
3236 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_not_current_fw,
3237 all_pop_nonvol_writeable_flags_gen_params),
3238 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_every_run,
3239 all_pop_nonvol_writeable_flags_gen_params),
3240 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_reload,
3241 all_pop_nonvol_writeable_flags_gen_params),
3242 KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_swap,
3243 all_pop_nonvol_writeable_flags_gen_params),
3245 { } /* terminator */
3248 static struct kunit_suite cs_dsp_ctl_cache_test_halo = {
3249 .name = "cs_dsp_ctl_cache_wmfwV3_halo",
3250 .init = cs_dsp_ctl_cache_test_halo_init,
3251 .test_cases = cs_dsp_ctl_cache_test_cases_v3,
3254 static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1 = {
3255 .name = "cs_dsp_ctl_cache_wmfwV1_adsp2_32bit",
3256 .init = cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1_init,
3257 .test_cases = cs_dsp_ctl_cache_test_cases_v1,
3260 static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2 = {
3261 .name = "cs_dsp_ctl_cache_wmfwV2_adsp2_32bit",
3262 .init = cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2_init,
3263 .test_cases = cs_dsp_ctl_cache_test_cases_v2,
3266 static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1 = {
3267 .name = "cs_dsp_ctl_cache_wmfwV1_adsp2_16bit",
3268 .init = cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1_init,
3269 .test_cases = cs_dsp_ctl_cache_test_cases_v1,
3272 static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2 = {
3273 .name = "cs_dsp_ctl_cache_wmfwV2_adsp2_16bit",
3274 .init = cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2_init,
3275 .test_cases = cs_dsp_ctl_cache_test_cases_v2,
3278 kunit_test_suites(&cs_dsp_ctl_cache_test_halo,
3279 &cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1,
3280 &cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2,
3281 &cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1,
3282 &cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2);