1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // KUnit tests for cs_dsp.
4 //
5 // Copyright (C) 2024 Cirrus Logic, Inc. and
6 //                    Cirrus Logic International Semiconductor Ltd.
7 
8 #include <kunit/device.h>
9 #include <kunit/resource.h>
10 #include <kunit/test.h>
11 #include <linux/build_bug.h>
12 #include <linux/firmware/cirrus/cs_dsp.h>
13 #include <linux/firmware/cirrus/cs_dsp_test_utils.h>
14 #include <linux/firmware/cirrus/wmfw.h>
15 #include <linux/list.h>
16 #include <linux/random.h>
17 #include <linux/regmap.h>
18 
19 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *);
20 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_stop_wrapper, cs_dsp_stop, struct cs_dsp *);
21 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *);
22 
23 struct cs_dsp_test_local {
24 	struct cs_dsp_mock_xm_header *xm_header;
25 	struct cs_dsp_mock_wmfw_builder *wmfw_builder;
26 	int wmfw_version;
27 };
28 
29 struct cs_dsp_ctl_cache_test_param {
30 	int mem_type;
31 	int alg_id;
32 	unsigned int offs_words;
33 	unsigned int len_bytes;
34 	u16 ctl_type;
35 	u16 flags;
36 };
37 
38 static const struct cs_dsp_mock_alg_def cs_dsp_ctl_cache_test_algs[] = {
39 	{
40 		.id = 0xfafa,
41 		.ver = 0x100000,
42 		.xm_base_words = 60,
43 		.xm_size_words = 1000,
44 		.ym_base_words = 0,
45 		.ym_size_words = 1000,
46 		.zm_base_words = 0,
47 		.zm_size_words = 1000,
48 	},
49 	{
50 		.id = 0xb,
51 		.ver = 0x100001,
52 		.xm_base_words = 1060,
53 		.xm_size_words = 1000,
54 		.ym_base_words = 1000,
55 		.ym_size_words = 1000,
56 		.zm_base_words = 1000,
57 		.zm_size_words = 1000,
58 	},
59 	{
60 		.id = 0x9f1234,
61 		.ver = 0x100500,
62 		.xm_base_words = 2060,
63 		.xm_size_words = 32,
64 		.ym_base_words = 2000,
65 		.ym_size_words = 32,
66 		.zm_base_words = 2000,
67 		.zm_size_words = 32,
68 	},
69 	{
70 		.id = 0xff00ff,
71 		.ver = 0x300113,
72 		.xm_base_words = 2100,
73 		.xm_size_words = 32,
74 		.ym_base_words = 2032,
75 		.ym_size_words = 32,
76 		.zm_base_words = 2032,
77 		.zm_size_words = 32,
78 	},
79 };
80 
81 static const struct cs_dsp_mock_coeff_def mock_coeff_template = {
82 	.shortname = "Dummy Coeff",
83 	.type = WMFW_CTL_TYPE_BYTES,
84 	.mem_type = WMFW_ADSP2_YM,
85 	.flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
86 	.length_bytes = 4,
87 };
88 
89 static const char * const cs_dsp_ctl_cache_test_fw_names[] = {
90 	"misc", "mbc/vss", "haps",
91 };
92 
_find_alg_entry(struct kunit * test,unsigned int alg_id)93 static int _find_alg_entry(struct kunit *test, unsigned int alg_id)
94 {
95 	int i;
96 
97 	for (i = 0; i < ARRAY_SIZE(cs_dsp_ctl_cache_test_algs); ++i) {
98 		if (cs_dsp_ctl_cache_test_algs[i].id == alg_id)
99 			break;
100 	}
101 
102 	KUNIT_ASSERT_LT(test, i, ARRAY_SIZE(cs_dsp_ctl_cache_test_algs));
103 
104 	return i;
105 }
106 
_get_alg_mem_base_words(struct kunit * test,int alg_index,int mem_type)107 static int _get_alg_mem_base_words(struct kunit *test, int alg_index, int mem_type)
108 {
109 	switch (mem_type) {
110 	case WMFW_ADSP2_XM:
111 		return cs_dsp_ctl_cache_test_algs[alg_index].xm_base_words;
112 	case WMFW_ADSP2_YM:
113 		return cs_dsp_ctl_cache_test_algs[alg_index].ym_base_words;
114 	case WMFW_ADSP2_ZM:
115 		return cs_dsp_ctl_cache_test_algs[alg_index].zm_base_words;
116 	default:
117 		KUNIT_FAIL(test, "Bug in test: illegal memory type %d\n", mem_type);
118 		return 0;
119 	}
120 }
121 
_create_dummy_wmfw(struct kunit * test)122 static struct cs_dsp_mock_wmfw_builder *_create_dummy_wmfw(struct kunit *test)
123 {
124 	struct cs_dsp_test *priv = test->priv;
125 	struct cs_dsp_test_local *local = priv->local;
126 	struct cs_dsp_mock_wmfw_builder *builder;
127 
128 	builder = cs_dsp_mock_wmfw_init(priv, local->wmfw_version);
129 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, builder);
130 
131 	/* Init an XM header */
132 	cs_dsp_mock_wmfw_add_data_block(builder,
133 					WMFW_ADSP2_XM, 0,
134 					local->xm_header->blob_data,
135 					local->xm_header->blob_size_bytes);
136 
137 	return builder;
138 }
139 
140 /*
141  * Memory allocated for control cache must be large enough.
142  * This creates multiple controls of different sizes so only works on
143  * wmfw V2 and later.
144  */
cs_dsp_ctl_v2_cache_alloc(struct kunit * test)145 static void cs_dsp_ctl_v2_cache_alloc(struct kunit *test)
146 {
147 	struct cs_dsp_test *priv = test->priv;
148 	struct cs_dsp_test_local *local = priv->local;
149 	struct cs_dsp *dsp = priv->dsp;
150 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
151 	unsigned int reg, alg_base_words, alg_size_bytes;
152 	struct cs_dsp_coeff_ctl *ctl;
153 	struct firmware *wmfw;
154 	char ctl_name[4];
155 	u32 *reg_vals;
156 	int num_ctls;
157 
158 	/* Create some DSP data to initialize the control cache */
159 	alg_base_words = _get_alg_mem_base_words(test, 0, WMFW_ADSP2_YM);
160 	alg_size_bytes = cs_dsp_ctl_cache_test_algs[0].ym_size_words *
161 			 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
162 	reg_vals = kunit_kzalloc(test, alg_size_bytes, GFP_KERNEL);
163 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
164 	reg = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_YM);
165 	reg += alg_base_words *	cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
166 	regmap_raw_write(dsp->regmap, reg, reg_vals, alg_size_bytes);
167 
168 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
169 					      cs_dsp_ctl_cache_test_algs[0].id,
170 					      "dummyalg", NULL);
171 
172 	/* Create controls of different sizes */
173 	def.mem_type = WMFW_ADSP2_YM;
174 	def.shortname = ctl_name;
175 	num_ctls = 0;
176 	for (def.length_bytes = 4; def.length_bytes <= 64; def.length_bytes += 4) {
177 		snprintf(ctl_name, ARRAY_SIZE(ctl_name), "%x", def.length_bytes);
178 		cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
179 		num_ctls++;
180 		def.offset_dsp_words += def.length_bytes / sizeof(u32);
181 	}
182 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
183 
184 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
185 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
186 
187 	KUNIT_EXPECT_EQ(test, list_count_nodes(&dsp->ctl_list), num_ctls);
188 
189 	/* Check that the block allocated for the cache is large enough */
190 	list_for_each_entry(ctl, &dsp->ctl_list, list)
191 		KUNIT_EXPECT_GE(test, ksize(ctl->cache), ctl->len);
192 }
193 
194 /*
195  * Content of registers backing a control should be read into the
196  * control cache when the firmware is downloaded.
197  */
cs_dsp_ctl_cache_init(struct kunit * test)198 static void cs_dsp_ctl_cache_init(struct kunit *test)
199 {
200 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
201 	struct cs_dsp_test *priv = test->priv;
202 	struct cs_dsp_test_local *local = priv->local;
203 	struct cs_dsp *dsp = priv->dsp;
204 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
205 	int alg_idx = _find_alg_entry(test, param->alg_id);
206 	unsigned int reg, alg_base_words;
207 	struct cs_dsp_coeff_ctl *ctl;
208 	struct firmware *wmfw;
209 	u32 *reg_vals, *readback;
210 
211 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
212 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
213 
214 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
215 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
216 
217 	/* Create some DSP data to be read into the control cache */
218 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
219 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
220 	reg += (alg_base_words + param->offs_words) *
221 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
222 	get_random_bytes(reg_vals, param->len_bytes);
223 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
224 
225 	/* Create control pointing to this data */
226 	def.flags = param->flags;
227 	def.mem_type = param->mem_type;
228 	def.offset_dsp_words = param->offs_words;
229 	def.length_bytes = param->len_bytes;
230 
231 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
232 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
233 					      "dummyalg", NULL);
234 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
235 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
236 
237 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
238 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
239 
240 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
241 	KUNIT_ASSERT_NOT_NULL(test, ctl);
242 
243 	/*
244 	 * The data should have been populated into the control cache
245 	 * so should be readable through the control.
246 	 */
247 	KUNIT_EXPECT_EQ(test,
248 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
249 			0);
250 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
251 }
252 
253 /*
254  * For a non-volatile write-only control the cache should be zero-filled
255  * when the firmware is downloaded.
256  */
cs_dsp_ctl_cache_init_write_only(struct kunit * test)257 static void cs_dsp_ctl_cache_init_write_only(struct kunit *test)
258 {
259 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
260 	struct cs_dsp_test *priv = test->priv;
261 	struct cs_dsp_test_local *local = priv->local;
262 	struct cs_dsp *dsp = priv->dsp;
263 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
264 	int alg_idx = _find_alg_entry(test, param->alg_id);
265 	struct cs_dsp_coeff_ctl *ctl;
266 	struct firmware *wmfw;
267 	u32 *readback, *zeros;
268 
269 	zeros = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
270 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, zeros);
271 
272 	readback = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
273 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
274 
275 	/* Create a non-volatile write-only control */
276 	def.flags = param->flags & ~WMFW_CTL_FLAG_VOLATILE;
277 	def.mem_type = param->mem_type;
278 	def.offset_dsp_words = param->offs_words;
279 	def.length_bytes = param->len_bytes;
280 
281 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
282 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
283 					      "dummyalg", NULL);
284 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
285 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
286 
287 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
288 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
289 
290 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
291 	KUNIT_ASSERT_NOT_NULL(test, ctl);
292 
293 	/*
294 	 * The control cache should have been zero-filled so should be
295 	 * readable through the control.
296 	 */
297 	get_random_bytes(readback, param->len_bytes);
298 	KUNIT_EXPECT_EQ(test,
299 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
300 			0);
301 	KUNIT_EXPECT_MEMEQ(test, readback, zeros, param->len_bytes);
302 }
303 
304 /*
305  * Multiple different firmware with identical controls.
306  * This is legal because different firmwares could contain the same
307  * algorithm.
308  * The control cache should be initialized only with the data from
309  * the firmware containing it.
310  */
cs_dsp_ctl_cache_init_multiple_fw_same_controls(struct kunit * test)311 static void cs_dsp_ctl_cache_init_multiple_fw_same_controls(struct kunit *test)
312 {
313 	struct cs_dsp_test *priv = test->priv;
314 	struct cs_dsp *dsp = priv->dsp;
315 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
316 	struct cs_dsp_mock_wmfw_builder *builder[3];
317 	unsigned int reg, alg_base_words;
318 	struct cs_dsp_coeff_ctl *walkctl, *ctl[3];
319 	struct firmware *wmfw;
320 	u32 *reg_vals[3], *readback;
321 	int i;
322 
323 	static_assert(ARRAY_SIZE(ctl) == ARRAY_SIZE(builder));
324 	static_assert(ARRAY_SIZE(reg_vals) == ARRAY_SIZE(builder));
325 	static_assert(ARRAY_SIZE(cs_dsp_ctl_cache_test_fw_names) >= ARRAY_SIZE(builder));
326 
327 	/* Create an identical control in each firmware but with different alg id */
328 	for (i = 0; i < ARRAY_SIZE(builder); i++) {
329 		builder[i] = _create_dummy_wmfw(test);
330 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, builder[i]);
331 
332 		cs_dsp_mock_wmfw_start_alg_info_block(builder[i],
333 						      cs_dsp_ctl_cache_test_algs[0].id,
334 						      "dummyalg", NULL);
335 		cs_dsp_mock_wmfw_add_coeff_desc(builder[i], &def);
336 		cs_dsp_mock_wmfw_end_alg_info_block(builder[i]);
337 	}
338 
339 	for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
340 		reg_vals[i] = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL);
341 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals[i]);
342 	}
343 
344 	readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL);
345 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
346 
347 	/*
348 	 * For each firmware create random content in the register backing
349 	 * the control. Then download, start, stop and power-down.
350 	 */
351 	for (i = 0; i < ARRAY_SIZE(builder); i++) {
352 		alg_base_words = _get_alg_mem_base_words(test, 0, def.mem_type);
353 		reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type);
354 		reg += (alg_base_words + def.offset_dsp_words) *
355 			cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
356 
357 		get_random_bytes(reg_vals[i], def.length_bytes);
358 		regmap_raw_write(dsp->regmap, reg, reg_vals[i], def.length_bytes);
359 		wmfw = cs_dsp_mock_wmfw_get_firmware(builder[i]);
360 		KUNIT_ASSERT_EQ(test,
361 				cs_dsp_power_up(dsp, wmfw,
362 						cs_dsp_ctl_cache_test_fw_names[i],
363 						NULL, NULL,
364 						cs_dsp_ctl_cache_test_fw_names[i]),
365 				0);
366 		KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
367 		cs_dsp_stop(dsp);
368 		cs_dsp_power_down(dsp);
369 	}
370 
371 	/* There should now be 3 controls */
372 	KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
373 
374 	/*
375 	 * There's no requirement for the control list to be in any
376 	 * particular order, so don't assume the order.
377 	 */
378 	for (i = 0; i < ARRAY_SIZE(ctl); i++)
379 		ctl[i] = NULL;
380 
381 	list_for_each_entry(walkctl, &dsp->ctl_list, list) {
382 		if (strcmp(walkctl->fw_name, cs_dsp_ctl_cache_test_fw_names[0]) == 0)
383 			ctl[0] = walkctl;
384 		else if (strcmp(walkctl->fw_name, cs_dsp_ctl_cache_test_fw_names[1]) == 0)
385 			ctl[1] = walkctl;
386 		else if (strcmp(walkctl->fw_name, cs_dsp_ctl_cache_test_fw_names[2]) == 0)
387 			ctl[2] = walkctl;
388 	}
389 
390 	KUNIT_ASSERT_NOT_NULL(test, ctl[0]);
391 	KUNIT_ASSERT_NOT_NULL(test, ctl[1]);
392 	KUNIT_ASSERT_NOT_NULL(test, ctl[2]);
393 
394 	/*
395 	 * The data should have been populated into the control cache
396 	 * so should be readable through the control.
397 	 */
398 	KUNIT_EXPECT_EQ(test,
399 			cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
400 			0);
401 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
402 
403 	KUNIT_EXPECT_EQ(test,
404 			cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes),
405 			0);
406 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes);
407 
408 	KUNIT_EXPECT_EQ(test,
409 			cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback, def.length_bytes),
410 			0);
411 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes);
412 }
413 
414 /*
415  * Multiple different firmware with controls identical except for alg id.
416  * This is legal because the controls are qualified by algorithm id.
417  * The control cache should be initialized only with the data from
418  * the firmware containing it.
419  */
cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls(struct kunit * test)420 static void cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls(struct kunit *test)
421 {
422 	struct cs_dsp_test *priv = test->priv;
423 	struct cs_dsp *dsp = priv->dsp;
424 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
425 	struct cs_dsp_mock_wmfw_builder *builder[3];
426 	unsigned int reg, alg_base_words;
427 	struct cs_dsp_coeff_ctl *walkctl, *ctl[3];
428 	struct firmware *wmfw;
429 	u32 *reg_vals[3], *readback;
430 	int i;
431 
432 	static_assert(ARRAY_SIZE(ctl) == ARRAY_SIZE(builder));
433 	static_assert(ARRAY_SIZE(reg_vals) == ARRAY_SIZE(builder));
434 	static_assert(ARRAY_SIZE(cs_dsp_ctl_cache_test_fw_names) >= ARRAY_SIZE(builder));
435 
436 	/* Create an identical control in each firmware but with different alg id */
437 	for (i = 0; i < ARRAY_SIZE(builder); i++) {
438 		builder[i] = _create_dummy_wmfw(test);
439 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, builder[i]);
440 
441 		cs_dsp_mock_wmfw_start_alg_info_block(builder[i],
442 						      cs_dsp_ctl_cache_test_algs[i].id,
443 						      "dummyalg", NULL);
444 		cs_dsp_mock_wmfw_add_coeff_desc(builder[i], &def);
445 		cs_dsp_mock_wmfw_end_alg_info_block(builder[i]);
446 	}
447 
448 	for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
449 		reg_vals[i] = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL);
450 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals[i]);
451 	}
452 
453 	readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL);
454 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
455 
456 	/*
457 	 * For each firmware create random content in the register backing
458 	 * the control. Then download, start, stop and power-down.
459 	 */
460 	for (i = 0; i < ARRAY_SIZE(builder); i++) {
461 		alg_base_words = _get_alg_mem_base_words(test, i, def.mem_type);
462 		reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type);
463 		reg += (alg_base_words + def.offset_dsp_words) *
464 			cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
465 
466 		get_random_bytes(reg_vals[i], def.length_bytes);
467 		regmap_raw_write(dsp->regmap, reg, reg_vals[i], def.length_bytes);
468 		wmfw = cs_dsp_mock_wmfw_get_firmware(builder[i]);
469 		KUNIT_ASSERT_EQ(test,
470 				cs_dsp_power_up(dsp, wmfw,
471 						cs_dsp_ctl_cache_test_fw_names[i],
472 						NULL, NULL,
473 						cs_dsp_ctl_cache_test_fw_names[i]),
474 				0);
475 		KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
476 		cs_dsp_stop(dsp);
477 		cs_dsp_power_down(dsp);
478 	}
479 
480 	/* There should now be 3 controls */
481 	KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
482 
483 	/*
484 	 * There's no requirement for the control list to be in any
485 	 * particular order, so don't assume the order.
486 	 */
487 	for (i = 0; i < ARRAY_SIZE(ctl); i++)
488 		ctl[i] = NULL;
489 
490 	list_for_each_entry(walkctl, &dsp->ctl_list, list) {
491 		if (cs_dsp_ctl_cache_test_algs[0].id == walkctl->alg_region.alg)
492 			ctl[0] = walkctl;
493 		else if (cs_dsp_ctl_cache_test_algs[1].id == walkctl->alg_region.alg)
494 			ctl[1] = walkctl;
495 		else if (cs_dsp_ctl_cache_test_algs[2].id == walkctl->alg_region.alg)
496 			ctl[2] = walkctl;
497 	}
498 
499 	KUNIT_ASSERT_NOT_NULL(test, ctl[0]);
500 	KUNIT_ASSERT_NOT_NULL(test, ctl[1]);
501 	KUNIT_ASSERT_NOT_NULL(test, ctl[2]);
502 
503 	/*
504 	 * The data should have been populated into the control cache
505 	 * so should be readable through the control.
506 	 */
507 	KUNIT_EXPECT_EQ(test,
508 			cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
509 			0);
510 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
511 
512 	KUNIT_EXPECT_EQ(test,
513 			cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes),
514 			0);
515 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes);
516 
517 	KUNIT_EXPECT_EQ(test,
518 			cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback, def.length_bytes),
519 			0);
520 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes);
521 }
522 
523 /*
524  * Firmware with controls at the same position in different memories.
525  * The control cache should be initialized with content from the
526  * correct memory region.
527  */
cs_dsp_ctl_cache_init_multiple_mems(struct kunit * test)528 static void cs_dsp_ctl_cache_init_multiple_mems(struct kunit *test)
529 {
530 	struct cs_dsp_test *priv = test->priv;
531 	struct cs_dsp *dsp = priv->dsp;
532 	struct cs_dsp_test_local *local = priv->local;
533 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
534 	unsigned int reg, alg_base_words;
535 	struct cs_dsp_coeff_ctl *walkctl, *ctl[3];
536 	struct firmware *wmfw;
537 	u32 *reg_vals[3], *readback;
538 	int i;
539 
540 	static_assert(ARRAY_SIZE(ctl) ==  ARRAY_SIZE(reg_vals));
541 
542 	for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
543 		reg_vals[i] = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL);
544 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals[i]);
545 		get_random_bytes(reg_vals[i], def.length_bytes);
546 	}
547 
548 	readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL);
549 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
550 
551 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
552 					      cs_dsp_ctl_cache_test_algs[0].id,
553 					      "dummyalg", NULL);
554 
555 	/* Create controls identical except for memory region */
556 	def.mem_type = WMFW_ADSP2_YM;
557 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
558 
559 	def.mem_type = WMFW_ADSP2_XM;
560 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
561 
562 	if (cs_dsp_mock_has_zm(priv)) {
563 		def.mem_type = WMFW_ADSP2_ZM;
564 		cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
565 	}
566 
567 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
568 
569 	/* Create random content in the registers backing each control */
570 	alg_base_words = _get_alg_mem_base_words(test, 0, WMFW_ADSP2_YM);
571 	reg = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_YM);
572 	reg += (alg_base_words + def.offset_dsp_words) *
573 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
574 	regmap_raw_write(dsp->regmap, reg, reg_vals[0], def.length_bytes);
575 
576 	alg_base_words = _get_alg_mem_base_words(test, 0, WMFW_ADSP2_XM);
577 	reg = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_XM);
578 	reg += (alg_base_words + def.offset_dsp_words) *
579 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
580 	regmap_raw_write(dsp->regmap, reg, reg_vals[1], def.length_bytes);
581 
582 	if (cs_dsp_mock_has_zm(priv)) {
583 		alg_base_words = _get_alg_mem_base_words(test, 0, WMFW_ADSP2_ZM);
584 		reg = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_ZM);
585 		reg += (alg_base_words + def.offset_dsp_words) *
586 			cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
587 		regmap_raw_write(dsp->regmap, reg, reg_vals[2], def.length_bytes);
588 	}
589 
590 	/* Download, run, stop and power-down the firmware */
591 	wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder);
592 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
593 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
594 	cs_dsp_stop(dsp);
595 	cs_dsp_power_down(dsp);
596 
597 	/* There should now be 2 or 3 controls */
598 	KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list),
599 			cs_dsp_mock_has_zm(priv) ? 3 : 2);
600 
601 	/*
602 	 * There's no requirement for the control list to be in any
603 	 * particular order, so don't assume the order.
604 	 */
605 	for (i = 0; i < ARRAY_SIZE(ctl); i++)
606 		ctl[i] = NULL;
607 
608 	list_for_each_entry(walkctl, &dsp->ctl_list, list) {
609 		if (walkctl->alg_region.type == WMFW_ADSP2_YM)
610 			ctl[0] = walkctl;
611 		if (walkctl->alg_region.type == WMFW_ADSP2_XM)
612 			ctl[1] = walkctl;
613 		if (walkctl->alg_region.type == WMFW_ADSP2_ZM)
614 			ctl[2] = walkctl;
615 	}
616 
617 
618 	/*
619 	 * The data should have been populated into the control cache
620 	 * so should be readable through the control.
621 	 */
622 	KUNIT_ASSERT_NOT_NULL(test, ctl[0]);
623 	KUNIT_EXPECT_EQ(test,
624 			cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
625 			0);
626 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
627 
628 	KUNIT_ASSERT_NOT_NULL(test, ctl[1]);
629 	KUNIT_EXPECT_EQ(test,
630 			cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes),
631 			0);
632 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes);
633 
634 	if (cs_dsp_mock_has_zm(priv)) {
635 		KUNIT_ASSERT_NOT_NULL(test, ctl[2]);
636 		KUNIT_EXPECT_EQ(test,
637 				cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback,
638 								def.length_bytes),
639 				0);
640 		KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes);
641 	}
642 }
643 
644 /*
645  * Firmware with controls at the same position in different algorithms
646  * The control cache should be initialized with content from the
647  * memory of the algorithm it points to.
648  */
cs_dsp_ctl_cache_init_multiple_algs(struct kunit * test)649 static void cs_dsp_ctl_cache_init_multiple_algs(struct kunit *test)
650 {
651 	struct cs_dsp_test *priv = test->priv;
652 	struct cs_dsp *dsp = priv->dsp;
653 	struct cs_dsp_test_local *local = priv->local;
654 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
655 	unsigned int reg, alg_base_words;
656 	struct cs_dsp_coeff_ctl *walkctl, *ctl[3];
657 	struct firmware *wmfw;
658 	u32 *reg_vals[3], *readback;
659 	int i;
660 
661 	static_assert(ARRAY_SIZE(ctl) ==  ARRAY_SIZE(reg_vals));
662 	static_assert(ARRAY_SIZE(reg_vals) <= ARRAY_SIZE(cs_dsp_ctl_cache_test_algs));
663 
664 	for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
665 		reg_vals[i] = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL);
666 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals[i]);
667 		get_random_bytes(reg_vals[i], def.length_bytes);
668 	}
669 
670 	readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL);
671 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
672 
673 	/* Create controls identical except for algorithm */
674 	for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
675 		cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
676 						      cs_dsp_ctl_cache_test_algs[i].id,
677 						      "dummyalg", NULL);
678 		cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
679 		cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
680 	}
681 
682 	/* Create random content in the registers backing each control */
683 	for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
684 		alg_base_words = _get_alg_mem_base_words(test, i, def.mem_type);
685 		reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type);
686 		reg += (alg_base_words + def.offset_dsp_words) *
687 			cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
688 		regmap_raw_write(dsp->regmap, reg, reg_vals[i], def.length_bytes);
689 	}
690 
691 	/* Download, run, stop and power-down the firmware */
692 	wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder);
693 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
694 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
695 	cs_dsp_stop(dsp);
696 	cs_dsp_power_down(dsp);
697 
698 	/* There should now be 3 controls */
699 	KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
700 
701 	/*
702 	 * There's no requirement for the control list to be in any
703 	 * particular order, so don't assume the order.
704 	 */
705 	for (i = 0; i < ARRAY_SIZE(ctl); i++)
706 		ctl[i] = NULL;
707 
708 	list_for_each_entry(walkctl, &dsp->ctl_list, list) {
709 		if (walkctl->alg_region.alg == cs_dsp_ctl_cache_test_algs[0].id)
710 			ctl[0] = walkctl;
711 		if (walkctl->alg_region.alg == cs_dsp_ctl_cache_test_algs[1].id)
712 			ctl[1] = walkctl;
713 		if (walkctl->alg_region.alg == cs_dsp_ctl_cache_test_algs[2].id)
714 			ctl[2] = walkctl;
715 	}
716 
717 	KUNIT_ASSERT_NOT_NULL(test, ctl[0]);
718 	KUNIT_ASSERT_NOT_NULL(test, ctl[1]);
719 	KUNIT_ASSERT_NOT_NULL(test, ctl[2]);
720 
721 	/*
722 	 * The data should have been populated into the control cache
723 	 * so should be readable through the control.
724 	 */
725 	KUNIT_EXPECT_EQ(test,
726 			cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
727 			0);
728 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
729 
730 	KUNIT_EXPECT_EQ(test,
731 			cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes),
732 			0);
733 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes);
734 
735 	KUNIT_EXPECT_EQ(test,
736 			cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback,
737 							def.length_bytes),
738 			0);
739 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes);
740 }
741 
742 /*
743  * Firmware with controls in the same algorithm and memory but at
744  * different offsets.
745  * The control cache should be initialized with content from the
746  * correct offset.
747  * Only for wmfw format V2 and later. V1 only supports one control per
748  * memory per algorithm.
749  */
cs_dsp_ctl_cache_init_multiple_offsets(struct kunit * test)750 static void cs_dsp_ctl_cache_init_multiple_offsets(struct kunit *test)
751 {
752 	struct cs_dsp_test *priv = test->priv;
753 	struct cs_dsp *dsp = priv->dsp;
754 	struct cs_dsp_test_local *local = priv->local;
755 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
756 	unsigned int reg, alg_base_words, alg_base_reg;
757 	struct cs_dsp_coeff_ctl *walkctl, *ctl[3];
758 	struct firmware *wmfw;
759 	u32 *reg_vals[3], *readback;
760 	int i;
761 
762 	static_assert(ARRAY_SIZE(ctl) ==  ARRAY_SIZE(reg_vals));
763 	static_assert(ARRAY_SIZE(reg_vals) <= ARRAY_SIZE(cs_dsp_ctl_cache_test_algs));
764 
765 	for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
766 		reg_vals[i] = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL);
767 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals[i]);
768 		get_random_bytes(reg_vals[i], def.length_bytes);
769 	}
770 
771 	readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL);
772 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
773 
774 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
775 					      cs_dsp_ctl_cache_test_algs[0].id,
776 					      "dummyalg", NULL);
777 
778 	/* Create controls identical except for offset */
779 	def.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);
783 
784 	def.offset_dsp_words = 5;
785 	def.shortname = "CtlB";
786 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
787 
788 	def.offset_dsp_words = 8;
789 	def.shortname = "CtlC";
790 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
791 
792 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
793 
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);
798 
799 	reg = alg_base_reg;
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);
805 
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);
810 	cs_dsp_stop(dsp);
811 	cs_dsp_power_down(dsp);
812 
813 	/* There should now be 3 controls */
814 	KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
815 
816 	/*
817 	 * There's no requirement for the control list to be in any
818 	 * particular order, so don't assume the order.
819 	 */
820 	for (i = 0; i < ARRAY_SIZE(ctl); i++)
821 		ctl[i] = NULL;
822 
823 	list_for_each_entry(walkctl, &dsp->ctl_list, list) {
824 		if (walkctl->offset == 0)
825 			ctl[0] = walkctl;
826 		if (walkctl->offset == 5)
827 			ctl[1] = walkctl;
828 		if (walkctl->offset == 8)
829 			ctl[2] = walkctl;
830 	}
831 
832 	KUNIT_ASSERT_NOT_NULL(test, ctl[0]);
833 	KUNIT_ASSERT_NOT_NULL(test, ctl[1]);
834 	KUNIT_ASSERT_NOT_NULL(test, ctl[2]);
835 
836 	/*
837 	 * The data should have been populated into the control cache
838 	 * so should be readable through the control.
839 	 */
840 	KUNIT_EXPECT_EQ(test,
841 			cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
842 			0);
843 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
844 
845 	KUNIT_EXPECT_EQ(test,
846 			cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes),
847 			0);
848 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes);
849 
850 	KUNIT_EXPECT_EQ(test,
851 			cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback,
852 							def.length_bytes),
853 			0);
854 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes);
855 }
856 
857 /*
858  * Read from a cached control before the firmware is started.
859  * Should return the data in the cache.
860  */
cs_dsp_ctl_cache_read_not_started(struct kunit * test)861 static void cs_dsp_ctl_cache_read_not_started(struct kunit *test)
862 {
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;
873 
874 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
875 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
876 
877 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
878 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
879 
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);
887 
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;
893 
894 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
895 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
896 					      "dummyalg", NULL);
897 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
898 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
899 
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);
903 
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));
908 
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),
914 			0);
915 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
916 }
917 
918 /*
919  * Read from a cached control after the firmware has been stopped.
920  * Should return the data in the cache.
921  */
cs_dsp_ctl_cache_read_stopped(struct kunit * test)922 static void cs_dsp_ctl_cache_read_stopped(struct kunit *test)
923 {
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;
934 
935 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
936 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
937 
938 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
939 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
940 
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);
948 
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;
954 
955 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
956 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
957 					      "dummyalg", NULL);
958 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
959 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
960 
961 	/* Power-up DSP */
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);
964 
965 	/* Start and stop the firmware */
966 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
967 	cs_dsp_stop(dsp);
968 
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));
973 
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),
979 			0);
980 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
981 }
982 
983 /*
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.
987  */
cs_dsp_ctl_cache_read_powered_down(struct kunit * test)988 static void cs_dsp_ctl_cache_read_powered_down(struct kunit *test)
989 {
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;
1000 
1001 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1002 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1003 
1004 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1005 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1006 
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);
1014 
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;
1020 
1021 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1022 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1023 					      "dummyalg", NULL);
1024 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1025 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1026 
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);
1031 
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));
1036 
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),
1042 			0);
1043 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1044 }
1045 
1046 /*
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.
1050  */
cs_dsp_ctl_cache_read_stopped_powered_down(struct kunit * test)1051 static void cs_dsp_ctl_cache_read_stopped_powered_down(struct kunit *test)
1052 {
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;
1063 
1064 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1065 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1066 
1067 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1068 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1069 
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);
1077 
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;
1083 
1084 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1085 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1086 					      "dummyalg", NULL);
1087 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1088 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1089 
1090 	/* Power-up DSP */
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);
1093 
1094 	/* Start and stop the firmware then power-down */
1095 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1096 	cs_dsp_stop(dsp);
1097 	cs_dsp_power_down(dsp);
1098 
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));
1103 
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),
1109 			0);
1110 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1111 }
1112 
1113 /*
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.
1117  */
cs_dsp_ctl_cache_read_not_current_loaded_fw(struct kunit * test)1118 static void cs_dsp_ctl_cache_read_not_current_loaded_fw(struct kunit *test)
1119 {
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;
1131 
1132 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1133 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1134 
1135 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1136 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1137 
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);
1145 
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;
1151 
1152 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1153 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1154 					      "dummyalg", NULL);
1155 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1156 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1157 
1158 	/* Power-up DSP */
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);
1161 
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);
1166 
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));
1171 
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),
1177 			0);
1178 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1179 }
1180 
1181 /*
1182  * Read from a cached control when a different firmware is currently
1183  * running.
1184  * Should return the data in the cache.
1185  */
cs_dsp_ctl_cache_read_not_current_running_fw(struct kunit * test)1186 static void cs_dsp_ctl_cache_read_not_current_running_fw(struct kunit *test)
1187 {
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;
1199 
1200 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1201 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1202 
1203 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1204 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1205 
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);
1213 
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;
1219 
1220 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1221 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1222 					      "dummyalg", NULL);
1223 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1224 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1225 
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);
1230 
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);
1236 
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));
1241 
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),
1247 			0);
1248 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1249 }
1250 
1251 /*
1252  * Read from a cached control with non-zero flags while the firmware is
1253  * running.
1254  * Should return the data in the cache, not from the registers.
1255  */
cs_dsp_ctl_cache_read_running(struct kunit * test)1256 static void cs_dsp_ctl_cache_read_running(struct kunit *test)
1257 {
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;
1268 
1269 	init_reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1270 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_reg_vals);
1271 
1272 	new_reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1273 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_reg_vals);
1274 
1275 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1276 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1277 
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);
1285 
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;
1291 
1292 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1293 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1294 					      "dummyalg", NULL);
1295 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1296 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1297 
1298 	/* Power-up DSP */
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);
1301 
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);
1305 
1306 	/*
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
1310 	 * the registers.
1311 	 */
1312 	KUNIT_ASSERT_EQ(test,
1313 			regmap_raw_write(dsp->regmap, reg, new_reg_vals, param->len_bytes),
1314 			0);
1315 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1316 
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),
1322 			0);
1323 	KUNIT_EXPECT_MEMEQ(test, readback, init_reg_vals, param->len_bytes);
1324 
1325 	/* Stop and power-down the DSP */
1326 	kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
1327 	cs_dsp_power_down(dsp);
1328 
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),
1332 			0);
1333 	KUNIT_EXPECT_MEMEQ(test, readback, init_reg_vals, param->len_bytes);
1334 }
1335 
1336 /*
1337  * Read from a cached control with flags == 0 while the firmware is
1338  * running.
1339  * Should behave as volatile and read from the registers.
1340  * (This is for backwards compatibility with old firmware versions)
1341  */
cs_dsp_ctl_cache_read_running_zero_flags(struct kunit * test)1342 static void cs_dsp_ctl_cache_read_running_zero_flags(struct kunit *test)
1343 {
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;
1354 
1355 	init_reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1356 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_reg_vals);
1357 
1358 	new_reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1359 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_reg_vals);
1360 
1361 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1362 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1363 
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);
1370 
1371 	/* Create control pointing to this data */
1372 	def.flags = 0;
1373 	def.mem_type = param->mem_type;
1374 	def.offset_dsp_words = param->offs_words;
1375 	def.length_bytes = param->len_bytes;
1376 
1377 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1378 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1379 					      "dummyalg", NULL);
1380 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1381 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1382 
1383 	/* Power-up DSP */
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);
1386 
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);
1390 
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);
1394 
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),
1400 			0);
1401 	KUNIT_EXPECT_MEMEQ(test, readback, new_reg_vals, param->len_bytes);
1402 
1403 	/* Stop and power-down the DSP */
1404 	kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
1405 	cs_dsp_power_down(dsp);
1406 
1407 	/* Change the values in the registers backing the control */
1408 	regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes);
1409 
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),
1413 			0);
1414 	KUNIT_EXPECT_MEMEQ(test, readback, new_reg_vals, param->len_bytes);
1415 }
1416 
1417 /*
1418  * Write to a cached control while the firmware is running.
1419  * This should be a writethrough operation, writing to the cache and
1420  * the registers.
1421  */
cs_dsp_ctl_cache_writethrough(struct kunit * test)1422 static void cs_dsp_ctl_cache_writethrough(struct kunit *test)
1423 {
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;
1434 
1435 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1436 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1437 
1438 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1439 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1440 
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);
1448 
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;
1454 
1455 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1456 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1457 					      "dummyalg", NULL);
1458 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1459 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1460 
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);
1463 
1464 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1465 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1466 
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);
1470 
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),
1475 			1);
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);
1478 }
1479 
1480 /*
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
1483  * didn't change.
1484  */
cs_dsp_ctl_cache_writethrough_unchanged(struct kunit * test)1485 static void cs_dsp_ctl_cache_writethrough_unchanged(struct kunit *test)
1486 {
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;
1497 
1498 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1499 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1500 
1501 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1502 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1503 
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);
1511 
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;
1517 
1518 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1519 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1520 					      "dummyalg", NULL);
1521 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1522 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1523 
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);
1526 
1527 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1528 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1529 
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);
1533 
1534 	/*
1535 	 * If the control is write-only the cache will have been zero-initialized
1536 	 * so the first write will always indicate a change.
1537 	 */
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,
1541 								 param->len_bytes),
1542 				1);
1543 	}
1544 
1545 	/*
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.
1548 	 */
1549 	KUNIT_EXPECT_EQ(test,
1550 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1551 			0);
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);
1554 }
1555 
1556 /*
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
1559  * didn't change.
1560  */
cs_dsp_ctl_cache_write_unchanged_not_started(struct kunit * test)1561 static void cs_dsp_ctl_cache_write_unchanged_not_started(struct kunit *test)
1562 {
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;
1573 
1574 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1575 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1576 
1577 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1578 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1579 
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);
1587 
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;
1593 
1594 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1595 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1596 					      "dummyalg", NULL);
1597 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1598 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1599 
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);
1602 
1603 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1604 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1605 
1606 	/*
1607 	 * If the control is write-only the cache will have been zero-initialized
1608 	 * so the first write will always indicate a change.
1609 	 */
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,
1613 								 param->len_bytes),
1614 				1);
1615 	}
1616 
1617 	/*
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.
1620 	 */
1621 	KUNIT_EXPECT_EQ(test,
1622 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1623 			0);
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);
1626 }
1627 
1628 /*
1629  * Write to a cached control while the firmware is loaded but not
1630  * started.
1631  * This should write to the cache only.
1632  */
cs_dsp_ctl_cache_write_not_started(struct kunit * test)1633 static void cs_dsp_ctl_cache_write_not_started(struct kunit *test)
1634 {
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;
1645 
1646 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1647 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1648 
1649 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1650 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1651 
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);
1658 
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;
1664 
1665 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1666 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1667 					      "dummyalg", NULL);
1668 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1669 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1670 
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);
1674 
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));
1679 
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);
1683 
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),
1687 			1);
1688 
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));
1691 
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),
1695 			0);
1696 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1697 }
1698 
1699 /*
1700  * Write to a cached control after the firmware has been loaded,
1701  * started and stopped.
1702  * This should write to the cache only.
1703  */
cs_dsp_ctl_cache_write_stopped(struct kunit * test)1704 static void cs_dsp_ctl_cache_write_stopped(struct kunit *test)
1705 {
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;
1716 
1717 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1718 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1719 
1720 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1721 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1722 
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);
1729 
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;
1735 
1736 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1737 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1738 					      "dummyalg", NULL);
1739 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1740 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1741 
1742 	/* Power-up DSP */
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);
1745 
1746 	/* Start and stop the firmware */
1747 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1748 	cs_dsp_stop(dsp);
1749 
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));
1754 
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);
1758 
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),
1762 			1);
1763 
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));
1766 
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),
1770 			0);
1771 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1772 }
1773 
1774 /*
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.
1778  */
cs_dsp_ctl_cache_write_powered_down(struct kunit * test)1779 static void cs_dsp_ctl_cache_write_powered_down(struct kunit *test)
1780 {
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;
1791 
1792 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1793 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1794 
1795 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1796 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1797 
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);
1804 
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;
1810 
1811 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1812 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1813 					      "dummyalg", NULL);
1814 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1815 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1816 
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);
1821 
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));
1826 
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);
1830 
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),
1834 			1);
1835 
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));
1838 
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),
1842 			0);
1843 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1844 }
1845 
1846 /*
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.
1850  */
cs_dsp_ctl_cache_write_stopped_powered_down(struct kunit * test)1851 static void cs_dsp_ctl_cache_write_stopped_powered_down(struct kunit *test)
1852 {
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;
1863 
1864 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1865 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1866 
1867 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1868 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1869 
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);
1876 
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;
1882 
1883 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1884 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1885 					      "dummyalg", NULL);
1886 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1887 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1888 
1889 	/* Power-up DSP */
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);
1892 
1893 	/* Start and stop the firmware then power-down */
1894 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1895 	cs_dsp_stop(dsp);
1896 	cs_dsp_power_down(dsp);
1897 
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));
1902 
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);
1906 
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),
1910 			1);
1911 
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));
1914 
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),
1918 			0);
1919 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1920 }
1921 
1922 /*
1923  * Write to a cached control that is not in the currently loaded firmware.
1924  * This should write to the cache only.
1925  */
cs_dsp_ctl_cache_write_not_current_loaded_fw(struct kunit * test)1926 static void cs_dsp_ctl_cache_write_not_current_loaded_fw(struct kunit *test)
1927 {
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;
1939 
1940 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1941 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1942 
1943 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1944 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1945 
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);
1952 
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;
1958 
1959 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1960 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1961 					      "dummyalg", NULL);
1962 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1963 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1964 
1965 	/* Power-up DSP */
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);
1968 
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);
1972 
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);
1977 
1978 	/* Control from unloaded firmware should be disabled */
1979 	KUNIT_EXPECT_FALSE(test, ctl->enabled);
1980 
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));
1985 
1986 	/*
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
1989 	 * registers.
1990 	 */
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),
1994 			1);
1995 
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));
1998 
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),
2002 			0);
2003 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2004 }
2005 
2006 /*
2007  * Write to a cached control that is not in the currently running firmware.
2008  * This should write to the cache only.
2009  */
cs_dsp_ctl_cache_write_not_current_running_fw(struct kunit * test)2010 static void cs_dsp_ctl_cache_write_not_current_running_fw(struct kunit *test)
2011 {
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;
2023 
2024 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2025 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
2026 
2027 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2028 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2029 
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);
2036 
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;
2042 
2043 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2044 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2045 					      "dummyalg", NULL);
2046 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2047 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2048 
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);
2053 
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);
2057 
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);
2063 
2064 	/* Control from unloaded firmware should be disabled */
2065 	KUNIT_EXPECT_FALSE(test, ctl->enabled);
2066 
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));
2071 
2072 	/*
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
2075 	 * registers.
2076 	 */
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),
2080 			1);
2081 
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));
2084 
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),
2088 			0);
2089 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2090 }
2091 
2092 /*
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.
2096  */
cs_dsp_ctl_cache_sync_write_before_run(struct kunit * test)2097 static void cs_dsp_ctl_cache_sync_write_before_run(struct kunit *test)
2098 {
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;
2109 
2110 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2111 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
2112 
2113 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2114 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2115 
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);
2122 
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;
2128 
2129 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2130 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2131 					      "dummyalg", NULL);
2132 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2133 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2134 
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);
2138 
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);
2142 
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),
2146 			1);
2147 
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);
2150 
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);
2154 
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);
2157 
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),
2161 			0);
2162 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2163 }
2164 
2165 /*
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.
2169  */
cs_dsp_ctl_cache_sync_write_while_running(struct kunit * test)2170 static void cs_dsp_ctl_cache_sync_write_while_running(struct kunit *test)
2171 {
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;
2182 
2183 	init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2184 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals);
2185 
2186 	ctl_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2187 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals);
2188 
2189 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2190 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2191 
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);
2198 
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;
2204 
2205 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2206 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2207 					      "dummyalg", NULL);
2208 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2209 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2210 
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);
2216 
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);
2220 
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),
2224 			1);
2225 
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);
2231 
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);
2235 
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);
2238 
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),
2242 			0);
2243 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2244 }
2245 
2246 /*
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.
2250  */
cs_dsp_ctl_cache_sync_write_after_stop(struct kunit * test)2251 static void cs_dsp_ctl_cache_sync_write_after_stop(struct kunit *test)
2252 {
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;
2263 
2264 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2265 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
2266 
2267 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2268 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2269 
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);
2276 
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;
2282 
2283 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2284 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2285 					      "dummyalg", NULL);
2286 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2287 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2288 
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);
2292 
2293 	/* Start and stop the firmware */
2294 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2295 	cs_dsp_stop(dsp);
2296 
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);
2300 
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),
2304 			1);
2305 
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);
2308 
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);
2312 
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);
2315 
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),
2319 			0);
2320 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2321 }
2322 
2323 /*
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
2327  * control is run.
2328  */
cs_dsp_ctl_cache_sync_write_not_current_fw(struct kunit * test)2329 static void cs_dsp_ctl_cache_sync_write_not_current_fw(struct kunit *test)
2330 {
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;
2342 
2343 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2344 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
2345 
2346 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2347 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2348 
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);
2355 
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;
2361 
2362 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2363 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2364 					      "dummyalg", NULL);
2365 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2366 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2367 
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);
2371 
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);
2375 
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);
2380 
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),
2385 			1);
2386 
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);
2389 
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);
2394 
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);
2398 
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);
2401 
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),
2405 			0);
2406 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2407 }
2408 
2409 /*
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
2412  * is run.
2413  */
cs_dsp_ctl_cache_sync_reapply_every_run(struct kunit * test)2414 static void cs_dsp_ctl_cache_sync_reapply_every_run(struct kunit *test)
2415 {
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;
2426 
2427 	init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2428 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals);
2429 
2430 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2431 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2432 
2433 	ctl_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
2434 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals);
2435 
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);
2442 
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;
2448 
2449 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2450 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2451 					      "dummyalg", NULL);
2452 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2453 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2454 
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);
2458 
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);
2462 
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),
2466 			1);
2467 
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);
2473 
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);
2477 
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);
2483 
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),
2487 			0);
2488 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2489 }
2490 
2491 /*
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.
2496  */
cs_dsp_ctl_cache_sync_reapply_after_fw_reload(struct kunit * test)2497 static void cs_dsp_ctl_cache_sync_reapply_after_fw_reload(struct kunit *test)
2498 {
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;
2509 
2510 	init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2511 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals);
2512 
2513 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2514 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2515 
2516 	ctl_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
2517 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals);
2518 
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);
2525 
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;
2531 
2532 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2533 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2534 					      "dummyalg", NULL);
2535 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2536 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2537 
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);
2541 
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);
2545 
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),
2549 			1);
2550 
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);
2556 
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);
2560 
2561 	/* Reset the registers */
2562 	regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2563 
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);
2566 
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);
2572 
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),
2576 			0);
2577 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2578 }
2579 
2580 /*
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.
2586  */
cs_dsp_ctl_cache_sync_reapply_after_fw_swap(struct kunit * test)2587 static void cs_dsp_ctl_cache_sync_reapply_after_fw_swap(struct kunit *test)
2588 {
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;
2600 
2601 	init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2602 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals);
2603 
2604 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2605 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2606 
2607 	ctl_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
2608 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals);
2609 
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);
2616 
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;
2622 
2623 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2624 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2625 					      "dummyalg", NULL);
2626 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2627 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2628 
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);
2632 
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);
2636 
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),
2640 			1);
2641 
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);
2647 
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);
2651 
2652 	/* Reset the registers */
2653 	regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2654 
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);
2660 
2661 	/* Reset the registers */
2662 	regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2663 
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);
2668 
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);
2674 
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),
2678 			0);
2679 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2680 }
2681 
cs_dsp_ctl_cache_test_common_init(struct kunit * test,struct cs_dsp * dsp,int wmfw_version)2682 static int cs_dsp_ctl_cache_test_common_init(struct kunit *test, struct cs_dsp *dsp,
2683 					     int wmfw_version)
2684 {
2685 	struct cs_dsp_test *priv;
2686 	struct cs_dsp_test_local *local;
2687 	struct device *test_dev;
2688 	int ret;
2689 
2690 	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
2691 	if (!priv)
2692 		return -ENOMEM;
2693 
2694 	local = kunit_kzalloc(test, sizeof(struct cs_dsp_test_local), GFP_KERNEL);
2695 	if (!local)
2696 		return -ENOMEM;
2697 
2698 	priv->test = test;
2699 	priv->dsp = dsp;
2700 	test->priv = priv;
2701 	priv->local = local;
2702 	priv->local->wmfw_version = wmfw_version;
2703 
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);
2708 
2709 	dsp->dev = get_device(test_dev);
2710 	if (!dsp->dev)
2711 		return -ENODEV;
2712 
2713 	ret = kunit_add_action_or_reset(test, _put_device_wrapper, dsp->dev);
2714 	if (ret)
2715 		return ret;
2716 
2717 	dev_set_drvdata(dsp->dev, priv);
2718 
2719 	/* Allocate regmap */
2720 	ret = cs_dsp_mock_regmap_init(priv);
2721 	if (ret)
2722 		return ret;
2723 
2724 	/*
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.
2727 	 */
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);
2732 
2733 	/* Create wmfw builder */
2734 	local->wmfw_builder = _create_dummy_wmfw(test);
2735 
2736 	/* Init cs_dsp */
2737 	dsp->client_ops = kunit_kzalloc(test, sizeof(*dsp->client_ops), GFP_KERNEL);
2738 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dsp->client_ops);
2739 
2740 	switch (dsp->type) {
2741 	case WMFW_ADSP2:
2742 		ret = cs_dsp_adsp2_init(dsp);
2743 		break;
2744 	case WMFW_HALO:
2745 		ret = cs_dsp_halo_init(dsp);
2746 		break;
2747 	default:
2748 		KUNIT_FAIL(test, "Untested DSP type %d\n", dsp->type);
2749 		return -EINVAL;
2750 	}
2751 
2752 	if (ret)
2753 		return ret;
2754 
2755 	/* Automatically call cs_dsp_remove() when test case ends */
2756 	return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
2757 }
2758 
cs_dsp_ctl_cache_test_halo_init(struct kunit * test)2759 static int cs_dsp_ctl_cache_test_halo_init(struct kunit *test)
2760 {
2761 	struct cs_dsp *dsp;
2762 
2763 	/* Fill in cs_dsp and initialize */
2764 	dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
2765 	if (!dsp)
2766 		return -ENOMEM;
2767 
2768 	dsp->num = 1;
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;
2774 
2775 	return cs_dsp_ctl_cache_test_common_init(test, dsp, 3);
2776 }
2777 
cs_dsp_ctl_cache_test_adsp2_32bit_init(struct kunit * test,int wmfw_ver)2778 static int cs_dsp_ctl_cache_test_adsp2_32bit_init(struct kunit *test, int wmfw_ver)
2779 {
2780 	struct cs_dsp *dsp;
2781 
2782 	/* Fill in cs_dsp and initialize */
2783 	dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
2784 	if (!dsp)
2785 		return -ENOMEM;
2786 
2787 	dsp->num = 1;
2788 	dsp->type = WMFW_ADSP2;
2789 	dsp->rev = 1;
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;
2793 
2794 	return cs_dsp_ctl_cache_test_common_init(test, dsp, wmfw_ver);
2795 }
2796 
cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1_init(struct kunit * test)2797 static int cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1_init(struct kunit *test)
2798 {
2799 	return cs_dsp_ctl_cache_test_adsp2_32bit_init(test, 1);
2800 }
2801 
cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2_init(struct kunit * test)2802 static int cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2_init(struct kunit *test)
2803 {
2804 	return cs_dsp_ctl_cache_test_adsp2_32bit_init(test, 2);
2805 }
2806 
cs_dsp_ctl_cache_test_adsp2_16bit_init(struct kunit * test,int wmfw_ver)2807 static int cs_dsp_ctl_cache_test_adsp2_16bit_init(struct kunit *test, int wmfw_ver)
2808 {
2809 	struct cs_dsp *dsp;
2810 
2811 	/* Fill in cs_dsp and initialize */
2812 	dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
2813 	if (!dsp)
2814 		return -ENOMEM;
2815 
2816 	dsp->num = 1;
2817 	dsp->type = WMFW_ADSP2;
2818 	dsp->rev = 0;
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;
2822 
2823 	return cs_dsp_ctl_cache_test_common_init(test, dsp, wmfw_ver);
2824 }
2825 
cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1_init(struct kunit * test)2826 static int cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1_init(struct kunit *test)
2827 {
2828 	return cs_dsp_ctl_cache_test_adsp2_16bit_init(test, 1);
2829 }
2830 
cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2_init(struct kunit * test)2831 static int cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2_init(struct kunit *test)
2832 {
2833 	return cs_dsp_ctl_cache_test_adsp2_16bit_init(test, 2);
2834 }
2835 
cs_dsp_ctl_all_param_desc(const struct cs_dsp_ctl_cache_test_param * param,char * desc)2836 static void cs_dsp_ctl_all_param_desc(const struct cs_dsp_ctl_cache_test_param *param,
2837 				      char *desc)
2838 {
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);
2842 }
2843 
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 },
2854 };
2855 KUNIT_ARRAY_PARAM(all_pop_varying_len, all_pop_varying_len_cases,
2856 		  cs_dsp_ctl_all_param_desc);
2857 
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 },
2868 };
2869 KUNIT_ARRAY_PARAM(all_pop_varying_offset, all_pop_varying_offset_cases,
2870 		  cs_dsp_ctl_all_param_desc);
2871 
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 },
2876 };
2877 KUNIT_ARRAY_PARAM(all_pop_varying_xy, all_pop_varying_xy_cases,
2878 		  cs_dsp_ctl_all_param_desc);
2879 
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 },
2883 };
2884 KUNIT_ARRAY_PARAM(all_pop_z, all_pop_z_cases, cs_dsp_ctl_all_param_desc);
2885 
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 },
2892 };
2893 KUNIT_ARRAY_PARAM(all_pop_varying_alg, all_pop_varying_alg_cases,
2894 		  cs_dsp_ctl_all_param_desc);
2895 
2896 /*
2897  * All parameters populated, with all combinations of flags for a
2898  * non-volatile readable control
2899  */
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,
2902 	  .flags = 0
2903 	},
2904 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2905 	  .flags = WMFW_CTL_FLAG_READABLE,
2906 	},
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,
2909 	},
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,
2912 	},
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,
2915 	},
2916 };
2917 KUNIT_ARRAY_PARAM(all_pop_nonvol_readable_flags,
2918 		  all_pop_nonvol_readable_flags_cases,
2919 		  cs_dsp_ctl_all_param_desc);
2920 
2921 /*
2922  * All parameters populated, with all combinations of flags for a
2923  * non-volatile readable control, except flags==0
2924  */
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,
2928 	},
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,
2931 	},
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,
2934 	},
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,
2937 	},
2938 };
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);
2942 
2943 /*
2944  * All parameters populated, with all combinations of flags for a
2945  * non-volatile writeable control
2946  */
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,
2949 	  .flags = 0
2950 	},
2951 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2952 	  .flags = WMFW_CTL_FLAG_WRITEABLE,
2953 	},
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,
2956 	},
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,
2959 	},
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,
2962 	},
2963 };
2964 KUNIT_ARRAY_PARAM(all_pop_nonvol_writeable_flags,
2965 		  all_pop_nonvol_writeable_flags_cases,
2966 		  cs_dsp_ctl_all_param_desc);
2967 
2968 /*
2969  * All parameters populated, with all combinations of flags for a
2970  * non-volatile write-only control of varying lengths
2971  */
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,
2975 	},
2976 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 512,
2977 	  .flags = WMFW_CTL_FLAG_WRITEABLE,
2978 	},
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,
2981 	},
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,
2984 	},
2985 };
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);
2989 
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),
2997 
2998 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init_write_only,
2999 			 all_pop_nonvol_write_only_length_gen_params),
3000 
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),
3005 
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),
3022 
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),
3029 
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),
3042 
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),
3057 
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),
3072 
3073 	{ } /* terminator */
3074 };
3075 
3076 static struct kunit_case cs_dsp_ctl_cache_test_cases_v2[] = {
3077 	KUNIT_CASE(cs_dsp_ctl_v2_cache_alloc),
3078 
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),
3085 
3086 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init_write_only,
3087 			 all_pop_nonvol_write_only_length_gen_params),
3088 
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),
3094 
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),
3111 
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),
3118 
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),
3131 
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),
3146 
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),
3161 
3162 	{ } /* terminator */
3163 };
3164 
3165 static struct kunit_case cs_dsp_ctl_cache_test_cases_v3[] = {
3166 	KUNIT_CASE(cs_dsp_ctl_v2_cache_alloc),
3167 
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),
3173 
3174 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init_write_only,
3175 			 all_pop_nonvol_write_only_length_gen_params),
3176 
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),
3182 
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),
3197 
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),
3203 
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),
3214 
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),
3229 
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),
3244 
3245 	{ } /* terminator */
3246 };
3247 
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,
3252 };
3253 
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,
3258 };
3259 
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,
3264 };
3265 
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,
3270 };
3271 
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,
3276 };
3277 
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);
3283