xref: /linux/drivers/firmware/cirrus/test/cs_dsp_test_control_cache.c (revision af477f4d5a6c183e2dd44f49dd9a7950bfa7bd50)
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.offset_dsp_words = 0;
780 	def.shortname = "CtlA";
781 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
782 
783 	def.offset_dsp_words = 5;
784 	def.shortname = "CtlB";
785 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
786 
787 	def.offset_dsp_words = 8;
788 	def.shortname = "CtlC";
789 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
790 
791 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
792 
793 	/* Create random content in the registers backing each control */
794 	alg_base_words = _get_alg_mem_base_words(test, 0, def.mem_type);
795 	alg_base_reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type);
796 	alg_base_reg += alg_base_words * cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
797 
798 	reg = alg_base_reg;
799 	regmap_raw_write(dsp->regmap, reg, reg_vals[0], def.length_bytes);
800 	reg = alg_base_reg + (5 * cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv));
801 	regmap_raw_write(dsp->regmap, reg, reg_vals[1], def.length_bytes);
802 	reg = alg_base_reg + (8 * cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv));
803 	regmap_raw_write(dsp->regmap, reg, reg_vals[2], def.length_bytes);
804 
805 	/* Download, run, stop and power-down the firmware */
806 	wmfw = cs_dsp_mock_wmfw_get_firmware(local->wmfw_builder);
807 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
808 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
809 	cs_dsp_stop(dsp);
810 	cs_dsp_power_down(dsp);
811 
812 	/* There should now be 3 controls */
813 	KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
814 
815 	/*
816 	 * There's no requirement for the control list to be in any
817 	 * particular order, so don't assume the order.
818 	 */
819 	for (i = 0; i < ARRAY_SIZE(ctl); i++)
820 		ctl[i] = NULL;
821 
822 	list_for_each_entry(walkctl, &dsp->ctl_list, list) {
823 		if (walkctl->offset == 0)
824 			ctl[0] = walkctl;
825 		if (walkctl->offset == 5)
826 			ctl[1] = walkctl;
827 		if (walkctl->offset == 8)
828 			ctl[2] = walkctl;
829 	}
830 
831 	KUNIT_ASSERT_NOT_NULL(test, ctl[0]);
832 	KUNIT_ASSERT_NOT_NULL(test, ctl[1]);
833 	KUNIT_ASSERT_NOT_NULL(test, ctl[2]);
834 
835 	/*
836 	 * The data should have been populated into the control cache
837 	 * so should be readable through the control.
838 	 */
839 	KUNIT_EXPECT_EQ(test,
840 			cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
841 			0);
842 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
843 
844 	KUNIT_EXPECT_EQ(test,
845 			cs_dsp_coeff_lock_and_read_ctrl(ctl[1], 0, readback, def.length_bytes),
846 			0);
847 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[1], def.length_bytes);
848 
849 	KUNIT_EXPECT_EQ(test,
850 			cs_dsp_coeff_lock_and_read_ctrl(ctl[2], 0, readback,
851 							def.length_bytes),
852 			0);
853 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[2], def.length_bytes);
854 }
855 
856 /*
857  * Read from a cached control before the firmware is started.
858  * Should return the data in the cache.
859  */
cs_dsp_ctl_cache_read_not_started(struct kunit * test)860 static void cs_dsp_ctl_cache_read_not_started(struct kunit *test)
861 {
862 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
863 	struct cs_dsp_test *priv = test->priv;
864 	struct cs_dsp_test_local *local = priv->local;
865 	struct cs_dsp *dsp = priv->dsp;
866 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
867 	int alg_idx = _find_alg_entry(test, param->alg_id);
868 	unsigned int reg, alg_base_words;
869 	struct cs_dsp_coeff_ctl *ctl;
870 	struct firmware *wmfw;
871 	u32 *reg_vals, *readback;
872 
873 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
874 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
875 
876 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
877 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
878 
879 	/* Create some DSP data to be read into the control cache */
880 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
881 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
882 	reg += (alg_base_words + param->offs_words) *
883 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
884 	get_random_bytes(reg_vals, param->len_bytes);
885 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
886 
887 	/* Create control pointing to this data */
888 	def.flags = param->flags;
889 	def.mem_type = param->mem_type;
890 	def.offset_dsp_words = param->offs_words;
891 	def.length_bytes = param->len_bytes;
892 
893 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
894 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
895 					      "dummyalg", NULL);
896 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
897 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
898 
899 	/* Power-up DSP but don't start firmware */
900 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
901 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
902 
903 	/* Drop expected writes and the regmap cache should be clean */
904 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
905 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
906 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
907 
908 	/* Control should readback the data from the control cache */
909 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
910 	KUNIT_ASSERT_NOT_NULL(test, ctl);
911 	KUNIT_EXPECT_EQ(test,
912 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
913 			0);
914 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
915 }
916 
917 /*
918  * Read from a cached control after the firmware has been stopped.
919  * Should return the data in the cache.
920  */
cs_dsp_ctl_cache_read_stopped(struct kunit * test)921 static void cs_dsp_ctl_cache_read_stopped(struct kunit *test)
922 {
923 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
924 	struct cs_dsp_test *priv = test->priv;
925 	struct cs_dsp_test_local *local = priv->local;
926 	struct cs_dsp *dsp = priv->dsp;
927 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
928 	int alg_idx = _find_alg_entry(test, param->alg_id);
929 	unsigned int reg, alg_base_words;
930 	struct cs_dsp_coeff_ctl *ctl;
931 	struct firmware *wmfw;
932 	u32 *reg_vals, *readback;
933 
934 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
935 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
936 
937 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
938 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
939 
940 	/* Create some DSP data to be read into the control cache */
941 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
942 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
943 	reg += (alg_base_words + param->offs_words) *
944 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
945 	get_random_bytes(reg_vals, param->len_bytes);
946 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
947 
948 	/* Create control pointing to this data */
949 	def.flags = param->flags;
950 	def.mem_type = param->mem_type;
951 	def.offset_dsp_words = param->offs_words;
952 	def.length_bytes = param->len_bytes;
953 
954 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
955 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
956 					      "dummyalg", NULL);
957 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
958 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
959 
960 	/* Power-up DSP */
961 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
962 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
963 
964 	/* Start and stop the firmware */
965 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
966 	cs_dsp_stop(dsp);
967 
968 	/* Drop expected writes and the regmap cache should be clean */
969 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
970 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
971 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
972 
973 	/* Control should readback the data from the control cache */
974 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
975 	KUNIT_ASSERT_NOT_NULL(test, ctl);
976 	KUNIT_EXPECT_EQ(test,
977 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
978 			0);
979 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
980 }
981 
982 /*
983  * Read from a cached control after the DSP has been powered-up and
984  * then powered-down without running.
985  * Should return the data in the cache.
986  */
cs_dsp_ctl_cache_read_powered_down(struct kunit * test)987 static void cs_dsp_ctl_cache_read_powered_down(struct kunit *test)
988 {
989 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
990 	struct cs_dsp_test *priv = test->priv;
991 	struct cs_dsp_test_local *local = priv->local;
992 	struct cs_dsp *dsp = priv->dsp;
993 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
994 	int alg_idx = _find_alg_entry(test, param->alg_id);
995 	unsigned int reg, alg_base_words;
996 	struct cs_dsp_coeff_ctl *ctl;
997 	struct firmware *wmfw;
998 	u32 *reg_vals, *readback;
999 
1000 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1001 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1002 
1003 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1004 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1005 
1006 	/* Create some DSP data to be read into the control cache */
1007 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1008 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1009 	reg += (alg_base_words + param->offs_words) *
1010 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1011 	get_random_bytes(reg_vals, param->len_bytes);
1012 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1013 
1014 	/* Create control pointing to this data */
1015 	def.flags = param->flags;
1016 	def.mem_type = param->mem_type;
1017 	def.offset_dsp_words = param->offs_words;
1018 	def.length_bytes = param->len_bytes;
1019 
1020 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1021 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1022 					      "dummyalg", NULL);
1023 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1024 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1025 
1026 	/* Power-up DSP then power-down */
1027 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1028 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1029 	cs_dsp_power_down(dsp);
1030 
1031 	/* Drop expected writes and the regmap cache should be clean */
1032 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1033 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1034 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1035 
1036 	/* Control should readback the data from the control cache */
1037 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1038 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1039 	KUNIT_EXPECT_EQ(test,
1040 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1041 			0);
1042 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1043 }
1044 
1045 /*
1046  * Read from a cached control after the firmware has been run and
1047  * stopped, then the DSP has been powered-down.
1048  * Should return the data in the cache.
1049  */
cs_dsp_ctl_cache_read_stopped_powered_down(struct kunit * test)1050 static void cs_dsp_ctl_cache_read_stopped_powered_down(struct kunit *test)
1051 {
1052 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1053 	struct cs_dsp_test *priv = test->priv;
1054 	struct cs_dsp_test_local *local = priv->local;
1055 	struct cs_dsp *dsp = priv->dsp;
1056 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1057 	int alg_idx = _find_alg_entry(test, param->alg_id);
1058 	unsigned int reg, alg_base_words;
1059 	struct cs_dsp_coeff_ctl *ctl;
1060 	struct firmware *wmfw;
1061 	u32 *reg_vals, *readback;
1062 
1063 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1064 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1065 
1066 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1067 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1068 
1069 	/* Create some DSP data to be read into the control cache */
1070 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1071 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1072 	reg += (alg_base_words + param->offs_words) *
1073 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1074 	get_random_bytes(reg_vals, param->len_bytes);
1075 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1076 
1077 	/* Create control pointing to this data */
1078 	def.flags = param->flags;
1079 	def.mem_type = param->mem_type;
1080 	def.offset_dsp_words = param->offs_words;
1081 	def.length_bytes = param->len_bytes;
1082 
1083 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1084 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1085 					      "dummyalg", NULL);
1086 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1087 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1088 
1089 	/* Power-up DSP */
1090 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1091 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1092 
1093 	/* Start and stop the firmware then power-down */
1094 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1095 	cs_dsp_stop(dsp);
1096 	cs_dsp_power_down(dsp);
1097 
1098 	/* Drop expected writes and the regmap cache should be clean */
1099 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1100 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1101 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1102 
1103 	/* Control should readback the data from the control cache */
1104 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1105 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1106 	KUNIT_EXPECT_EQ(test,
1107 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1108 			0);
1109 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1110 }
1111 
1112 /*
1113  * Read from a cached control when a different firmware is currently
1114  * loaded into the DSP.
1115  * Should return the data in the cache.
1116  */
cs_dsp_ctl_cache_read_not_current_loaded_fw(struct kunit * test)1117 static void cs_dsp_ctl_cache_read_not_current_loaded_fw(struct kunit *test)
1118 {
1119 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1120 	struct cs_dsp_test *priv = test->priv;
1121 	struct cs_dsp_test_local *local = priv->local;
1122 	struct cs_dsp *dsp = priv->dsp;
1123 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1124 	struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test);
1125 	int alg_idx = _find_alg_entry(test, param->alg_id);
1126 	unsigned int reg, alg_base_words;
1127 	struct cs_dsp_coeff_ctl *ctl;
1128 	struct firmware *wmfw;
1129 	u32 *reg_vals, *readback;
1130 
1131 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1132 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1133 
1134 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1135 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1136 
1137 	/* Create some DSP data to be read into the control cache */
1138 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1139 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1140 	reg += (alg_base_words + param->offs_words) *
1141 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1142 	get_random_bytes(reg_vals, param->len_bytes);
1143 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1144 
1145 	/* Create control pointing to this data */
1146 	def.flags = param->flags;
1147 	def.mem_type = param->mem_type;
1148 	def.offset_dsp_words = param->offs_words;
1149 	def.length_bytes = param->len_bytes;
1150 
1151 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1152 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1153 					      "dummyalg", NULL);
1154 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1155 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1156 
1157 	/* Power-up DSP */
1158 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1159 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1160 
1161 	/* Power-down DSP then power-up with a different firmware */
1162 	cs_dsp_power_down(dsp);
1163 	wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
1164 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
1165 
1166 	/* Drop expected writes and the regmap cache should be clean */
1167 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1168 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1169 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1170 
1171 	/* Control should readback the data from the control cache */
1172 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1173 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1174 	KUNIT_EXPECT_EQ(test,
1175 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1176 			0);
1177 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1178 }
1179 
1180 /*
1181  * Read from a cached control when a different firmware is currently
1182  * running.
1183  * Should return the data in the cache.
1184  */
cs_dsp_ctl_cache_read_not_current_running_fw(struct kunit * test)1185 static void cs_dsp_ctl_cache_read_not_current_running_fw(struct kunit *test)
1186 {
1187 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1188 	struct cs_dsp_test *priv = test->priv;
1189 	struct cs_dsp_test_local *local = priv->local;
1190 	struct cs_dsp *dsp = priv->dsp;
1191 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1192 	struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test);
1193 	int alg_idx = _find_alg_entry(test, param->alg_id);
1194 	unsigned int reg, alg_base_words;
1195 	struct cs_dsp_coeff_ctl *ctl;
1196 	struct firmware *wmfw;
1197 	u32 *reg_vals, *readback;
1198 
1199 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1200 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1201 
1202 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1203 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1204 
1205 	/* Create some DSP data to be read into the control cache */
1206 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1207 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1208 	reg += (alg_base_words + param->offs_words) *
1209 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1210 	get_random_bytes(reg_vals, param->len_bytes);
1211 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1212 
1213 	/* Create control pointing to this data */
1214 	def.flags = param->flags;
1215 	def.mem_type = param->mem_type;
1216 	def.offset_dsp_words = param->offs_words;
1217 	def.length_bytes = param->len_bytes;
1218 
1219 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1220 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1221 					      "dummyalg", NULL);
1222 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1223 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1224 
1225 	/* Power-up DSP then power-down */
1226 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1227 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1228 	cs_dsp_power_down(dsp);
1229 
1230 	/* Power-up with a different firmware and run it */
1231 	wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
1232 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
1233 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1234 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
1235 
1236 	/* Drop expected writes and the regmap cache should be clean */
1237 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1238 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1239 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1240 
1241 	/* Control should readback the data from the control cache */
1242 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1243 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1244 	KUNIT_EXPECT_EQ(test,
1245 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1246 			0);
1247 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1248 }
1249 
1250 /*
1251  * Read from a cached control with non-zero flags while the firmware is
1252  * running.
1253  * Should return the data in the cache, not from the registers.
1254  */
cs_dsp_ctl_cache_read_running(struct kunit * test)1255 static void cs_dsp_ctl_cache_read_running(struct kunit *test)
1256 {
1257 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1258 	struct cs_dsp_test *priv = test->priv;
1259 	struct cs_dsp_test_local *local = priv->local;
1260 	struct cs_dsp *dsp = priv->dsp;
1261 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1262 	int alg_idx = _find_alg_entry(test, param->alg_id);
1263 	unsigned int reg, alg_base_words;
1264 	struct cs_dsp_coeff_ctl *ctl;
1265 	struct firmware *wmfw;
1266 	u32 *init_reg_vals, *new_reg_vals, *readback;
1267 
1268 	init_reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1269 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_reg_vals);
1270 
1271 	new_reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1272 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_reg_vals);
1273 
1274 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1275 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1276 
1277 	/* Create data in the registers backing the control */
1278 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1279 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1280 	reg += (alg_base_words + param->offs_words) *
1281 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1282 	get_random_bytes(init_reg_vals, param->len_bytes);
1283 	regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes);
1284 
1285 	/* Create control pointing to this data */
1286 	def.flags = param->flags;
1287 	def.mem_type = param->mem_type;
1288 	def.offset_dsp_words = param->offs_words;
1289 	def.length_bytes = param->len_bytes;
1290 
1291 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1292 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1293 					      "dummyalg", NULL);
1294 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1295 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1296 
1297 	/* Power-up DSP */
1298 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1299 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1300 
1301 	/* Start the firmware running */
1302 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1303 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
1304 
1305 	/*
1306 	 * Change the values in the registers backing the control then drop
1307 	 * them from the regmap cache. This allows checking that the control
1308 	 * read is returning values from the control cache and not accessing
1309 	 * the registers.
1310 	 */
1311 	KUNIT_ASSERT_EQ(test,
1312 			regmap_raw_write(dsp->regmap, reg, new_reg_vals, param->len_bytes),
1313 			0);
1314 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1315 
1316 	/* Control should readback the origin data from its cache */
1317 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1318 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1319 	KUNIT_EXPECT_EQ(test,
1320 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1321 			0);
1322 	KUNIT_EXPECT_MEMEQ(test, readback, init_reg_vals, param->len_bytes);
1323 
1324 	/* Stop and power-down the DSP */
1325 	kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
1326 	cs_dsp_power_down(dsp);
1327 
1328 	/* Control should readback from the cache */
1329 	KUNIT_EXPECT_EQ(test,
1330 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1331 			0);
1332 	KUNIT_EXPECT_MEMEQ(test, readback, init_reg_vals, param->len_bytes);
1333 }
1334 
1335 /*
1336  * Read from a cached control with flags == 0 while the firmware is
1337  * running.
1338  * Should behave as volatile and read from the registers.
1339  * (This is for backwards compatibility with old firmware versions)
1340  */
cs_dsp_ctl_cache_read_running_zero_flags(struct kunit * test)1341 static void cs_dsp_ctl_cache_read_running_zero_flags(struct kunit *test)
1342 {
1343 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1344 	struct cs_dsp_test *priv = test->priv;
1345 	struct cs_dsp_test_local *local = priv->local;
1346 	struct cs_dsp *dsp = priv->dsp;
1347 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1348 	int alg_idx = _find_alg_entry(test, param->alg_id);
1349 	unsigned int reg, alg_base_words;
1350 	struct cs_dsp_coeff_ctl *ctl;
1351 	struct firmware *wmfw;
1352 	u32 *init_reg_vals, *new_reg_vals, *readback;
1353 
1354 	init_reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1355 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_reg_vals);
1356 
1357 	new_reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1358 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_reg_vals);
1359 
1360 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1361 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1362 
1363 	/* Zero-fill the registers backing the control */
1364 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1365 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1366 	reg += (alg_base_words + param->offs_words) *
1367 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1368 	regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes);
1369 
1370 	/* Create control pointing to this data */
1371 	def.flags = 0;
1372 	def.mem_type = param->mem_type;
1373 	def.offset_dsp_words = param->offs_words;
1374 	def.length_bytes = param->len_bytes;
1375 
1376 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1377 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1378 					      "dummyalg", NULL);
1379 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1380 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1381 
1382 	/* Power-up DSP */
1383 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1384 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1385 
1386 	/* Start the firmware running */
1387 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1388 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
1389 
1390 	/* Change the values in the registers backing the control */
1391 	get_random_bytes(new_reg_vals, param->len_bytes);
1392 	regmap_raw_write(dsp->regmap, reg, new_reg_vals, param->len_bytes);
1393 
1394 	/* Control should readback the new data from the registers */
1395 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1396 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1397 	KUNIT_EXPECT_EQ(test,
1398 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1399 			0);
1400 	KUNIT_EXPECT_MEMEQ(test, readback, new_reg_vals, param->len_bytes);
1401 
1402 	/* Stop and power-down the DSP */
1403 	kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
1404 	cs_dsp_power_down(dsp);
1405 
1406 	/* Change the values in the registers backing the control */
1407 	regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes);
1408 
1409 	/* Control should readback from the cache */
1410 	KUNIT_EXPECT_EQ(test,
1411 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1412 			0);
1413 	KUNIT_EXPECT_MEMEQ(test, readback, new_reg_vals, param->len_bytes);
1414 }
1415 
1416 /*
1417  * Write to a cached control while the firmware is running.
1418  * This should be a writethrough operation, writing to the cache and
1419  * the registers.
1420  */
cs_dsp_ctl_cache_writethrough(struct kunit * test)1421 static void cs_dsp_ctl_cache_writethrough(struct kunit *test)
1422 {
1423 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1424 	struct cs_dsp_test *priv = test->priv;
1425 	struct cs_dsp_test_local *local = priv->local;
1426 	struct cs_dsp *dsp = priv->dsp;
1427 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1428 	int alg_idx = _find_alg_entry(test, param->alg_id);
1429 	unsigned int reg, alg_base_words;
1430 	struct cs_dsp_coeff_ctl *ctl;
1431 	struct firmware *wmfw;
1432 	u32 *reg_vals, *readback;
1433 
1434 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1435 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1436 
1437 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1438 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1439 
1440 	/* Create some DSP data to be read into the control cache */
1441 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1442 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1443 	reg += (alg_base_words + param->offs_words) *
1444 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1445 	memset(reg_vals, 0, param->len_bytes);
1446 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1447 
1448 	/* Create control pointing to this data */
1449 	def.flags = param->flags;
1450 	def.mem_type = param->mem_type;
1451 	def.offset_dsp_words = param->offs_words;
1452 	def.length_bytes = param->len_bytes;
1453 
1454 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1455 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1456 					      "dummyalg", NULL);
1457 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1458 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1459 
1460 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1461 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1462 
1463 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1464 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1465 
1466 	/* Start the firmware and add an action to stop it during cleanup */
1467 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1468 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
1469 
1470 	/* Write new data to the control, it should be written to the registers */
1471 	get_random_bytes(reg_vals, param->len_bytes);
1472 	KUNIT_EXPECT_EQ(test,
1473 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1474 			1);
1475 	KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
1476 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1477 }
1478 
1479 /*
1480  * Write unchanged data to a cached control while the firmware is running.
1481  * The control write should return 0 to indicate that the content
1482  * didn't change.
1483  */
cs_dsp_ctl_cache_writethrough_unchanged(struct kunit * test)1484 static void cs_dsp_ctl_cache_writethrough_unchanged(struct kunit *test)
1485 {
1486 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1487 	struct cs_dsp_test *priv = test->priv;
1488 	struct cs_dsp_test_local *local = priv->local;
1489 	struct cs_dsp *dsp = priv->dsp;
1490 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1491 	int alg_idx = _find_alg_entry(test, param->alg_id);
1492 	unsigned int reg, alg_base_words;
1493 	struct cs_dsp_coeff_ctl *ctl;
1494 	struct firmware *wmfw;
1495 	u32 *reg_vals, *readback;
1496 
1497 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1498 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1499 
1500 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1501 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1502 
1503 	/* Create some DSP data to be read into the control cache */
1504 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1505 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1506 	reg += (alg_base_words + param->offs_words) *
1507 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1508 	get_random_bytes(reg_vals, param->len_bytes);
1509 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1510 
1511 	/* Create control pointing to this data */
1512 	def.flags = param->flags;
1513 	def.mem_type = param->mem_type;
1514 	def.offset_dsp_words = param->offs_words;
1515 	def.length_bytes = param->len_bytes;
1516 
1517 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1518 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1519 					      "dummyalg", NULL);
1520 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1521 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1522 
1523 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1524 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1525 
1526 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1527 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1528 
1529 	/* Start the firmware and add an action to stop it during cleanup */
1530 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1531 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
1532 
1533 	/*
1534 	 * If the control is write-only the cache will have been zero-initialized
1535 	 * so the first write will always indicate a change.
1536 	 */
1537 	if (def.flags && !(def.flags & WMFW_CTL_FLAG_READABLE)) {
1538 		KUNIT_EXPECT_EQ(test,
1539 				cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals,
1540 								 param->len_bytes),
1541 				1);
1542 	}
1543 
1544 	/*
1545 	 * Write the same data to the control, cs_dsp_coeff_lock_and_write_ctrl()
1546 	 * should return 0 to indicate the content didn't change.
1547 	 */
1548 	KUNIT_EXPECT_EQ(test,
1549 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1550 			0);
1551 	KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
1552 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1553 }
1554 
1555 /*
1556  * Write unchanged data to a cached control while the firmware is not started.
1557  * The control write should return 0 to indicate that the cache content
1558  * didn't change.
1559  */
cs_dsp_ctl_cache_write_unchanged_not_started(struct kunit * test)1560 static void cs_dsp_ctl_cache_write_unchanged_not_started(struct kunit *test)
1561 {
1562 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1563 	struct cs_dsp_test *priv = test->priv;
1564 	struct cs_dsp_test_local *local = priv->local;
1565 	struct cs_dsp *dsp = priv->dsp;
1566 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1567 	int alg_idx = _find_alg_entry(test, param->alg_id);
1568 	unsigned int reg, alg_base_words;
1569 	struct cs_dsp_coeff_ctl *ctl;
1570 	struct firmware *wmfw;
1571 	u32 *reg_vals, *readback;
1572 
1573 	reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
1574 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1575 
1576 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1577 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1578 
1579 	/* Create some DSP data to be read into the control cache */
1580 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1581 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1582 	reg += (alg_base_words + param->offs_words) *
1583 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1584 	get_random_bytes(reg_vals, param->len_bytes);
1585 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1586 
1587 	/* Create control pointing to this data */
1588 	def.flags = param->flags;
1589 	def.mem_type = param->mem_type;
1590 	def.offset_dsp_words = param->offs_words;
1591 	def.length_bytes = param->len_bytes;
1592 
1593 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1594 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1595 					      "dummyalg", NULL);
1596 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1597 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1598 
1599 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1600 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1601 
1602 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1603 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1604 
1605 	/*
1606 	 * If the control is write-only the cache will have been zero-initialized
1607 	 * so the first write will always indicate a change.
1608 	 */
1609 	if (def.flags && !(def.flags & WMFW_CTL_FLAG_READABLE)) {
1610 		KUNIT_EXPECT_EQ(test,
1611 				cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals,
1612 								 param->len_bytes),
1613 				1);
1614 	}
1615 
1616 	/*
1617 	 * Write the same data to the control, cs_dsp_coeff_lock_and_write_ctrl()
1618 	 * should return 0 to indicate the content didn't change.
1619 	 */
1620 	KUNIT_EXPECT_EQ(test,
1621 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1622 			0);
1623 	KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
1624 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1625 }
1626 
1627 /*
1628  * Write to a cached control while the firmware is loaded but not
1629  * started.
1630  * This should write to the cache only.
1631  */
cs_dsp_ctl_cache_write_not_started(struct kunit * test)1632 static void cs_dsp_ctl_cache_write_not_started(struct kunit *test)
1633 {
1634 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1635 	struct cs_dsp_test *priv = test->priv;
1636 	struct cs_dsp_test_local *local = priv->local;
1637 	struct cs_dsp *dsp = priv->dsp;
1638 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1639 	int alg_idx = _find_alg_entry(test, param->alg_id);
1640 	unsigned int reg, alg_base_words;
1641 	struct cs_dsp_coeff_ctl *ctl;
1642 	struct firmware *wmfw;
1643 	u32 *reg_vals, *readback;
1644 
1645 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1646 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1647 
1648 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1649 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1650 
1651 	/* Create some DSP data to be read into the control cache */
1652 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1653 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1654 	reg += (alg_base_words + param->offs_words) *
1655 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1656 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1657 
1658 	/* Create control pointing to this data */
1659 	def.flags = param->flags;
1660 	def.mem_type = param->mem_type;
1661 	def.offset_dsp_words = param->offs_words;
1662 	def.length_bytes = param->len_bytes;
1663 
1664 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1665 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1666 					      "dummyalg", NULL);
1667 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1668 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1669 
1670 	/* Power-up DSP but don't start firmware */
1671 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1672 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1673 
1674 	/* Drop expected writes and the regmap cache should be clean */
1675 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1676 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1677 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1678 
1679 	/* Write new data to the control, it should not be written to the registers */
1680 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1681 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1682 
1683 	get_random_bytes(reg_vals, param->len_bytes);
1684 	KUNIT_EXPECT_EQ(test,
1685 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1686 			1);
1687 
1688 	/* Registers should not have been written so regmap cache should still be clean */
1689 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1690 
1691 	/* Control should readback the new data from the control cache */
1692 	KUNIT_EXPECT_EQ(test,
1693 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1694 			0);
1695 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1696 }
1697 
1698 /*
1699  * Write to a cached control after the firmware has been loaded,
1700  * started and stopped.
1701  * This should write to the cache only.
1702  */
cs_dsp_ctl_cache_write_stopped(struct kunit * test)1703 static void cs_dsp_ctl_cache_write_stopped(struct kunit *test)
1704 {
1705 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1706 	struct cs_dsp_test *priv = test->priv;
1707 	struct cs_dsp_test_local *local = priv->local;
1708 	struct cs_dsp *dsp = priv->dsp;
1709 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1710 	int alg_idx = _find_alg_entry(test, param->alg_id);
1711 	unsigned int reg, alg_base_words;
1712 	struct cs_dsp_coeff_ctl *ctl;
1713 	struct firmware *wmfw;
1714 	u32 *reg_vals, *readback;
1715 
1716 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1717 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1718 
1719 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1720 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1721 
1722 	/* Create some DSP data to be read into the control cache */
1723 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1724 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1725 	reg += (alg_base_words + param->offs_words) *
1726 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1727 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1728 
1729 	/* Create control pointing to this data */
1730 	def.flags = param->flags;
1731 	def.mem_type = param->mem_type;
1732 	def.offset_dsp_words = param->offs_words;
1733 	def.length_bytes = param->len_bytes;
1734 
1735 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1736 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1737 					      "dummyalg", NULL);
1738 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1739 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1740 
1741 	/* Power-up DSP */
1742 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1743 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1744 
1745 	/* Start and stop the firmware */
1746 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1747 	cs_dsp_stop(dsp);
1748 
1749 	/* Drop expected writes and the regmap cache should be clean */
1750 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1751 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1752 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1753 
1754 	/* Write new data to the control, it should not be written to the registers */
1755 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1756 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1757 
1758 	get_random_bytes(reg_vals, param->len_bytes);
1759 	KUNIT_EXPECT_EQ(test,
1760 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1761 			1);
1762 
1763 	/* Registers should not have been written so regmap cache should still be clean */
1764 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1765 
1766 	/* Control should readback the new data from the control cache */
1767 	KUNIT_EXPECT_EQ(test,
1768 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1769 			0);
1770 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1771 }
1772 
1773 /*
1774  * Write to a cached control after the firmware has been loaded,
1775  * then the DSP powered-down.
1776  * This should write to the cache only.
1777  */
cs_dsp_ctl_cache_write_powered_down(struct kunit * test)1778 static void cs_dsp_ctl_cache_write_powered_down(struct kunit *test)
1779 {
1780 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1781 	struct cs_dsp_test *priv = test->priv;
1782 	struct cs_dsp_test_local *local = priv->local;
1783 	struct cs_dsp *dsp = priv->dsp;
1784 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1785 	int alg_idx = _find_alg_entry(test, param->alg_id);
1786 	unsigned int reg, alg_base_words;
1787 	struct cs_dsp_coeff_ctl *ctl;
1788 	struct firmware *wmfw;
1789 	u32 *reg_vals, *readback;
1790 
1791 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1792 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1793 
1794 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1795 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1796 
1797 	/* Create some DSP data to be read into the control cache */
1798 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1799 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1800 	reg += (alg_base_words + param->offs_words) *
1801 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1802 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1803 
1804 	/* Create control pointing to this data */
1805 	def.flags = param->flags;
1806 	def.mem_type = param->mem_type;
1807 	def.offset_dsp_words = param->offs_words;
1808 	def.length_bytes = param->len_bytes;
1809 
1810 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1811 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1812 					      "dummyalg", NULL);
1813 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1814 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1815 
1816 	/* Power-up DSP then power-down */
1817 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1818 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1819 	cs_dsp_power_down(dsp);
1820 
1821 	/* Drop expected writes and the regmap cache should be clean */
1822 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1823 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1824 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1825 
1826 	/* Write new data to the control, it should not be written to the registers */
1827 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1828 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1829 
1830 	get_random_bytes(reg_vals, param->len_bytes);
1831 	KUNIT_EXPECT_EQ(test,
1832 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1833 			1);
1834 
1835 	/* Registers should not have been written so regmap cache should still be clean */
1836 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1837 
1838 	/* Control should readback the new data from the control cache */
1839 	KUNIT_EXPECT_EQ(test,
1840 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1841 			0);
1842 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1843 }
1844 
1845 /*
1846  * Write to a cached control after the firmware has been loaded,
1847  * started, stopped, and then the DSP powered-down.
1848  * This should write to the cache only.
1849  */
cs_dsp_ctl_cache_write_stopped_powered_down(struct kunit * test)1850 static void cs_dsp_ctl_cache_write_stopped_powered_down(struct kunit *test)
1851 {
1852 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1853 	struct cs_dsp_test *priv = test->priv;
1854 	struct cs_dsp_test_local *local = priv->local;
1855 	struct cs_dsp *dsp = priv->dsp;
1856 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1857 	int alg_idx = _find_alg_entry(test, param->alg_id);
1858 	unsigned int reg, alg_base_words;
1859 	struct cs_dsp_coeff_ctl *ctl;
1860 	struct firmware *wmfw;
1861 	u32 *reg_vals, *readback;
1862 
1863 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1864 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1865 
1866 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1867 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1868 
1869 	/* Create some DSP data to be read into the control cache */
1870 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1871 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1872 	reg += (alg_base_words + param->offs_words) *
1873 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1874 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1875 
1876 	/* Create control pointing to this data */
1877 	def.flags = param->flags;
1878 	def.mem_type = param->mem_type;
1879 	def.offset_dsp_words = param->offs_words;
1880 	def.length_bytes = param->len_bytes;
1881 
1882 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1883 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1884 					      "dummyalg", NULL);
1885 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1886 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1887 
1888 	/* Power-up DSP */
1889 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1890 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1891 
1892 	/* Start and stop the firmware then power-down */
1893 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
1894 	cs_dsp_stop(dsp);
1895 	cs_dsp_power_down(dsp);
1896 
1897 	/* Drop expected writes and the regmap cache should be clean */
1898 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1899 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1900 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1901 
1902 	/* Write new data to the control, it should not be written to the registers */
1903 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1904 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1905 
1906 	get_random_bytes(reg_vals, param->len_bytes);
1907 	KUNIT_EXPECT_EQ(test,
1908 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1909 			1);
1910 
1911 	/* Registers should not have been written so regmap cache should still be clean */
1912 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1913 
1914 	/* Control should readback the new data from the control cache */
1915 	KUNIT_EXPECT_EQ(test,
1916 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
1917 			0);
1918 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
1919 }
1920 
1921 /*
1922  * Write to a cached control that is not in the currently loaded firmware.
1923  * This should write to the cache only.
1924  */
cs_dsp_ctl_cache_write_not_current_loaded_fw(struct kunit * test)1925 static void cs_dsp_ctl_cache_write_not_current_loaded_fw(struct kunit *test)
1926 {
1927 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
1928 	struct cs_dsp_test *priv = test->priv;
1929 	struct cs_dsp_test_local *local = priv->local;
1930 	struct cs_dsp *dsp = priv->dsp;
1931 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
1932 	struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test);
1933 	int alg_idx = _find_alg_entry(test, param->alg_id);
1934 	unsigned int reg, alg_base_words;
1935 	struct cs_dsp_coeff_ctl *ctl;
1936 	struct firmware *wmfw;
1937 	u32 *reg_vals, *readback;
1938 
1939 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1940 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
1941 
1942 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
1943 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1944 
1945 	/* Create some DSP data to be read into the control cache */
1946 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
1947 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
1948 	reg += (alg_base_words + param->offs_words) *
1949 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
1950 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
1951 
1952 	/* Create control pointing to this data */
1953 	def.flags = param->flags;
1954 	def.mem_type = param->mem_type;
1955 	def.offset_dsp_words = param->offs_words;
1956 	def.length_bytes = param->len_bytes;
1957 
1958 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
1959 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
1960 					      "dummyalg", NULL);
1961 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
1962 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
1963 
1964 	/* Power-up DSP */
1965 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1966 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
1967 
1968 	/* Get the control */
1969 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
1970 	KUNIT_ASSERT_NOT_NULL(test, ctl);
1971 
1972 	/* Power-down DSP then power-up with a different firmware */
1973 	cs_dsp_power_down(dsp);
1974 	wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
1975 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
1976 
1977 	/* Control from unloaded firmware should be disabled */
1978 	KUNIT_EXPECT_FALSE(test, ctl->enabled);
1979 
1980 	/* Drop expected writes and the regmap cache should be clean */
1981 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1982 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
1983 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1984 
1985 	/*
1986 	 * It should be possible to write new data to the control from
1987 	 * the first firmware. But this should not be written to the
1988 	 * registers.
1989 	 */
1990 	get_random_bytes(reg_vals, param->len_bytes);
1991 	KUNIT_EXPECT_EQ(test,
1992 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1993 			1);
1994 
1995 	/* Registers should not have been written so regmap cache should still be clean */
1996 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1997 
1998 	/* Control should readback the new data from the control cache */
1999 	KUNIT_EXPECT_EQ(test,
2000 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2001 			0);
2002 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2003 }
2004 
2005 /*
2006  * Write to a cached control that is not in the currently running firmware.
2007  * This should write to the cache only.
2008  */
cs_dsp_ctl_cache_write_not_current_running_fw(struct kunit * test)2009 static void cs_dsp_ctl_cache_write_not_current_running_fw(struct kunit *test)
2010 {
2011 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2012 	struct cs_dsp_test *priv = test->priv;
2013 	struct cs_dsp_test_local *local = priv->local;
2014 	struct cs_dsp *dsp = priv->dsp;
2015 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2016 	struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test);
2017 	int alg_idx = _find_alg_entry(test, param->alg_id);
2018 	unsigned int reg, alg_base_words;
2019 	struct cs_dsp_coeff_ctl *ctl;
2020 	struct firmware *wmfw;
2021 	u32 *reg_vals, *readback;
2022 
2023 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2024 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
2025 
2026 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2027 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2028 
2029 	/* Create some DSP data to be read into the control cache */
2030 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2031 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2032 	reg += (alg_base_words + param->offs_words) *
2033 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2034 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
2035 
2036 	/* Create control pointing to this data */
2037 	def.flags = param->flags;
2038 	def.mem_type = param->mem_type;
2039 	def.offset_dsp_words = param->offs_words;
2040 	def.length_bytes = param->len_bytes;
2041 
2042 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2043 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2044 					      "dummyalg", NULL);
2045 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2046 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2047 
2048 	/* Power-up DSP then power-down */
2049 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2050 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2051 	cs_dsp_power_down(dsp);
2052 
2053 	/* Get the control */
2054 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2055 	KUNIT_ASSERT_NOT_NULL(test, ctl);
2056 
2057 	/* Power-up with a different firmware and run it */
2058 	wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
2059 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
2060 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2061 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2062 
2063 	/* Control from unloaded firmware should be disabled */
2064 	KUNIT_EXPECT_FALSE(test, ctl->enabled);
2065 
2066 	/* Drop expected writes and the regmap cache should be clean */
2067 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
2068 	cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
2069 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
2070 
2071 	/*
2072 	 * It should be possible to write new data to the control from
2073 	 * the first firmware. But this should not be written to the
2074 	 * registers.
2075 	 */
2076 	get_random_bytes(reg_vals, param->len_bytes);
2077 	KUNIT_EXPECT_EQ(test,
2078 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
2079 			1);
2080 
2081 	/* Registers should not have been written so regmap cache should still be clean */
2082 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
2083 
2084 	/* Control should readback the new data from the control cache */
2085 	KUNIT_EXPECT_EQ(test,
2086 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2087 			0);
2088 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2089 }
2090 
2091 /*
2092  * Write to a cached control before running the firmware.
2093  * The value written to the cache should be synced out to the registers
2094  * backing the control when the firmware is run.
2095  */
cs_dsp_ctl_cache_sync_write_before_run(struct kunit * test)2096 static void cs_dsp_ctl_cache_sync_write_before_run(struct kunit *test)
2097 {
2098 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2099 	struct cs_dsp_test *priv = test->priv;
2100 	struct cs_dsp_test_local *local = priv->local;
2101 	struct cs_dsp *dsp = priv->dsp;
2102 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2103 	int alg_idx = _find_alg_entry(test, param->alg_id);
2104 	unsigned int reg, alg_base_words;
2105 	struct cs_dsp_coeff_ctl *ctl;
2106 	struct firmware *wmfw;
2107 	u32 *reg_vals, *readback;
2108 
2109 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2110 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
2111 
2112 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2113 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2114 
2115 	/* Create some DSP data to be read into the control cache */
2116 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2117 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2118 	reg += (alg_base_words + param->offs_words) *
2119 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2120 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
2121 
2122 	/* Create control pointing to this data */
2123 	def.flags = param->flags;
2124 	def.mem_type = param->mem_type;
2125 	def.offset_dsp_words = param->offs_words;
2126 	def.length_bytes = param->len_bytes;
2127 
2128 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2129 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2130 					      "dummyalg", NULL);
2131 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2132 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2133 
2134 	/* Power-up DSP but don't start firmware */
2135 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2136 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2137 
2138 	/* Write new data to the control, it should not be written to the registers */
2139 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2140 	KUNIT_ASSERT_NOT_NULL(test, ctl);
2141 
2142 	get_random_bytes(reg_vals, param->len_bytes);
2143 	KUNIT_EXPECT_EQ(test,
2144 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
2145 			1);
2146 
2147 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2148 	KUNIT_EXPECT_MEMNEQ(test, readback, reg_vals, param->len_bytes);
2149 
2150 	/* Start the firmware and the cached data should be written to registers */
2151 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2152 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2153 
2154 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2155 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2156 
2157 	/* Control should readback the new data from the control cache */
2158 	KUNIT_EXPECT_EQ(test,
2159 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2160 			0);
2161 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2162 }
2163 
2164 /*
2165  * Write to a cached control while the firmware is running.
2166  * The value written should be synced out to the registers
2167  * backing the control when the firmware is next run.
2168  */
cs_dsp_ctl_cache_sync_write_while_running(struct kunit * test)2169 static void cs_dsp_ctl_cache_sync_write_while_running(struct kunit *test)
2170 {
2171 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2172 	struct cs_dsp_test *priv = test->priv;
2173 	struct cs_dsp_test_local *local = priv->local;
2174 	struct cs_dsp *dsp = priv->dsp;
2175 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2176 	int alg_idx = _find_alg_entry(test, param->alg_id);
2177 	unsigned int reg, alg_base_words;
2178 	struct cs_dsp_coeff_ctl *ctl;
2179 	struct firmware *wmfw;
2180 	u32 *init_vals, *ctl_vals, *readback;
2181 
2182 	init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2183 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals);
2184 
2185 	ctl_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2186 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals);
2187 
2188 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2189 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2190 
2191 	/* Zero-fill the registers backing the control */
2192 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2193 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2194 	reg += (alg_base_words + param->offs_words) *
2195 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2196 	regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2197 
2198 	/* Create control pointing to this data */
2199 	def.flags = param->flags;
2200 	def.mem_type = param->mem_type;
2201 	def.offset_dsp_words = param->offs_words;
2202 	def.length_bytes = param->len_bytes;
2203 
2204 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2205 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2206 					      "dummyalg", NULL);
2207 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2208 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2209 
2210 	/* Power-up DSP and start firmware */
2211 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2212 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2213 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2214 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2215 
2216 	/* Write new data to the control */
2217 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2218 	KUNIT_ASSERT_NOT_NULL(test, ctl);
2219 
2220 	get_random_bytes(ctl_vals, param->len_bytes);
2221 	KUNIT_EXPECT_EQ(test,
2222 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, param->len_bytes),
2223 			1);
2224 
2225 	/* Stop firmware and zero the registers backing the control */
2226 	kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
2227 	regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2228 	KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2229 	KUNIT_EXPECT_MEMEQ(test, readback, init_vals, param->len_bytes);
2230 
2231 	/* Start the firmware and the cached data should be written to registers */
2232 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2233 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2234 
2235 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2236 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2237 
2238 	/* Control should readback the new data from the control cache */
2239 	KUNIT_EXPECT_EQ(test,
2240 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2241 			0);
2242 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2243 }
2244 
2245 /*
2246  * Write to a cached control after stopping the firmware.
2247  * The value written to the cache should be synced out to the registers
2248  * backing the control when the firmware is next run.
2249  */
cs_dsp_ctl_cache_sync_write_after_stop(struct kunit * test)2250 static void cs_dsp_ctl_cache_sync_write_after_stop(struct kunit *test)
2251 {
2252 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2253 	struct cs_dsp_test *priv = test->priv;
2254 	struct cs_dsp_test_local *local = priv->local;
2255 	struct cs_dsp *dsp = priv->dsp;
2256 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2257 	int alg_idx = _find_alg_entry(test, param->alg_id);
2258 	unsigned int reg, alg_base_words;
2259 	struct cs_dsp_coeff_ctl *ctl;
2260 	struct firmware *wmfw;
2261 	u32 *reg_vals, *readback;
2262 
2263 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2264 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
2265 
2266 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2267 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2268 
2269 	/* Create some DSP data to be read into the control cache */
2270 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2271 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2272 	reg += (alg_base_words + param->offs_words) *
2273 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2274 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
2275 
2276 	/* Create control pointing to this data */
2277 	def.flags = param->flags;
2278 	def.mem_type = param->mem_type;
2279 	def.offset_dsp_words = param->offs_words;
2280 	def.length_bytes = param->len_bytes;
2281 
2282 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2283 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2284 					      "dummyalg", NULL);
2285 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2286 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2287 
2288 	/* Power-up DSP but don't start firmware */
2289 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2290 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2291 
2292 	/* Start and stop the firmware */
2293 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2294 	cs_dsp_stop(dsp);
2295 
2296 	/* Write new data to the control, it should not be written to the registers */
2297 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2298 	KUNIT_ASSERT_NOT_NULL(test, ctl);
2299 
2300 	get_random_bytes(reg_vals, param->len_bytes);
2301 	KUNIT_EXPECT_EQ(test,
2302 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
2303 			1);
2304 
2305 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2306 	KUNIT_EXPECT_MEMNEQ(test, readback, reg_vals, param->len_bytes);
2307 
2308 	/* Start the firmware and the cached data should be written to registers */
2309 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2310 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2311 
2312 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2313 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2314 
2315 	/* Control should readback the new data from the control cache */
2316 	KUNIT_EXPECT_EQ(test,
2317 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2318 			0);
2319 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2320 }
2321 
2322 /*
2323  * Write to a cached control that is not in the currently loaded firmware.
2324  * The value written to the cache should be synced out to the registers
2325  * backing the control the next time the firmware containing the
2326  * control is run.
2327  */
cs_dsp_ctl_cache_sync_write_not_current_fw(struct kunit * test)2328 static void cs_dsp_ctl_cache_sync_write_not_current_fw(struct kunit *test)
2329 {
2330 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2331 	struct cs_dsp_test *priv = test->priv;
2332 	struct cs_dsp_test_local *local = priv->local;
2333 	struct cs_dsp *dsp = priv->dsp;
2334 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2335 	int alg_idx = _find_alg_entry(test, param->alg_id);
2336 	struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test);
2337 	unsigned int reg, alg_base_words;
2338 	struct cs_dsp_coeff_ctl *ctl;
2339 	struct firmware *wmfw;
2340 	u32 *reg_vals, *readback;
2341 
2342 	reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2343 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
2344 
2345 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2346 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2347 
2348 	/* Create some DSP data to be read into the control cache */
2349 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2350 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2351 	reg += (alg_base_words + param->offs_words) *
2352 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2353 	regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
2354 
2355 	/* Create control pointing to this data */
2356 	def.flags = param->flags;
2357 	def.mem_type = param->mem_type;
2358 	def.offset_dsp_words = param->offs_words;
2359 	def.length_bytes = param->len_bytes;
2360 
2361 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2362 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2363 					      "dummyalg", NULL);
2364 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2365 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2366 
2367 	/* Power-up DSP but don't start firmware */
2368 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2369 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2370 
2371 	/* Get the control */
2372 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2373 	KUNIT_ASSERT_NOT_NULL(test, ctl);
2374 
2375 	/* Power-down DSP then power-up with a different firmware */
2376 	cs_dsp_power_down(dsp);
2377 	wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
2378 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
2379 
2380 	/* Write new data to the control, it should not be written to the registers */
2381 	get_random_bytes(reg_vals, param->len_bytes);
2382 	KUNIT_EXPECT_EQ(test,
2383 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
2384 			1);
2385 
2386 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2387 	KUNIT_EXPECT_MEMNEQ(test, readback, reg_vals, param->len_bytes);
2388 
2389 	/* Power-down DSP then power-up with the original firmware */
2390 	cs_dsp_power_down(dsp);
2391 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2392 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2393 
2394 	/* Start the firmware and the cached data should be written to registers */
2395 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2396 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2397 
2398 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2399 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2400 
2401 	/* Control should readback the new data from the control cache */
2402 	KUNIT_EXPECT_EQ(test,
2403 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2404 			0);
2405 	KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
2406 }
2407 
2408 /*
2409  * The value in the control cache should be synced out to the registers
2410  * backing the control every time the firmware containing the control
2411  * is run.
2412  */
cs_dsp_ctl_cache_sync_reapply_every_run(struct kunit * test)2413 static void cs_dsp_ctl_cache_sync_reapply_every_run(struct kunit *test)
2414 {
2415 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2416 	struct cs_dsp_test *priv = test->priv;
2417 	struct cs_dsp_test_local *local = priv->local;
2418 	struct cs_dsp *dsp = priv->dsp;
2419 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2420 	int alg_idx = _find_alg_entry(test, param->alg_id);
2421 	unsigned int reg, alg_base_words;
2422 	struct cs_dsp_coeff_ctl *ctl;
2423 	struct firmware *wmfw;
2424 	u32 *init_vals, *readback, *ctl_vals;
2425 
2426 	init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2427 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals);
2428 
2429 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2430 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2431 
2432 	ctl_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
2433 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals);
2434 
2435 	/* Zero-fill the registers backing the control */
2436 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2437 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2438 	reg += (alg_base_words + param->offs_words) *
2439 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2440 	regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2441 
2442 	/* Create control pointing to this data */
2443 	def.flags = param->flags;
2444 	def.mem_type = param->mem_type;
2445 	def.offset_dsp_words = param->offs_words;
2446 	def.length_bytes = param->len_bytes;
2447 
2448 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2449 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2450 					      "dummyalg", NULL);
2451 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2452 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2453 
2454 	/* Power-up DSP but don't start firmware */
2455 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2456 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2457 
2458 	/* Write new data to the control */
2459 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2460 	KUNIT_ASSERT_NOT_NULL(test, ctl);
2461 
2462 	get_random_bytes(ctl_vals, param->len_bytes);
2463 	KUNIT_EXPECT_EQ(test,
2464 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, param->len_bytes),
2465 			1);
2466 
2467 	/* Start the firmware and the cached data should be written to registers */
2468 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2469 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2470 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2471 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2472 
2473 	/* Stop the firmware and reset the registers */
2474 	kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
2475 	regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2476 
2477 	/* Start the firmware again and the cached data should be written to registers */
2478 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2479 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2480 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2481 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2482 
2483 	/* Control should readback the new data from the control cache */
2484 	KUNIT_EXPECT_EQ(test,
2485 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2486 			0);
2487 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2488 }
2489 
2490 /*
2491  * The value in the control cache should be retained if the same
2492  * firmware is downloaded again. It should be synced out to the
2493  * registers backing the control after the firmware containing the
2494  * control is downloaded again and run.
2495  */
cs_dsp_ctl_cache_sync_reapply_after_fw_reload(struct kunit * test)2496 static void cs_dsp_ctl_cache_sync_reapply_after_fw_reload(struct kunit *test)
2497 {
2498 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2499 	struct cs_dsp_test *priv = test->priv;
2500 	struct cs_dsp_test_local *local = priv->local;
2501 	struct cs_dsp *dsp = priv->dsp;
2502 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2503 	int alg_idx = _find_alg_entry(test, param->alg_id);
2504 	unsigned int reg, alg_base_words;
2505 	struct cs_dsp_coeff_ctl *ctl;
2506 	struct firmware *wmfw;
2507 	u32 *init_vals, *readback, *ctl_vals;
2508 
2509 	init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2510 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals);
2511 
2512 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2513 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2514 
2515 	ctl_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
2516 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals);
2517 
2518 	/* Zero-fill the registers backing the control */
2519 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2520 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2521 	reg += (alg_base_words + param->offs_words) *
2522 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2523 	regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2524 
2525 	/* Create control pointing to this data */
2526 	def.flags = param->flags;
2527 	def.mem_type = param->mem_type;
2528 	def.offset_dsp_words = param->offs_words;
2529 	def.length_bytes = param->len_bytes;
2530 
2531 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2532 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2533 					      "dummyalg", NULL);
2534 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2535 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2536 
2537 	/* Power-up DSP but don't start firmware */
2538 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2539 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2540 
2541 	/* Write new data to the control */
2542 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2543 	KUNIT_ASSERT_NOT_NULL(test, ctl);
2544 
2545 	get_random_bytes(ctl_vals, param->len_bytes);
2546 	KUNIT_EXPECT_EQ(test,
2547 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, param->len_bytes),
2548 			1);
2549 
2550 	/* Start the firmware and the cached data should be written to registers */
2551 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2552 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2553 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2554 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2555 
2556 	/* Stop the firmware and power-down the DSP */
2557 	kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
2558 	cs_dsp_power_down(dsp);
2559 
2560 	/* Reset the registers */
2561 	regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2562 
2563 	/* Download the firmware again, the cache content should not change */
2564 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2565 
2566 	/* Start the firmware and the cached data should be written to registers */
2567 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2568 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2569 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2570 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2571 
2572 	/* Control should readback the new data from the control cache */
2573 	KUNIT_EXPECT_EQ(test,
2574 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2575 			0);
2576 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2577 }
2578 
2579 /*
2580  * The value in the control cache should be retained after a different
2581  * firmware is downloaded.
2582  * When the firmware containing the control is downloaded and run
2583  * the value in the control cache should be synced out to the registers
2584  * backing the control.
2585  */
cs_dsp_ctl_cache_sync_reapply_after_fw_swap(struct kunit * test)2586 static void cs_dsp_ctl_cache_sync_reapply_after_fw_swap(struct kunit *test)
2587 {
2588 	const struct cs_dsp_ctl_cache_test_param *param = test->param_value;
2589 	struct cs_dsp_test *priv = test->priv;
2590 	struct cs_dsp_test_local *local = priv->local;
2591 	struct cs_dsp *dsp = priv->dsp;
2592 	struct cs_dsp_mock_coeff_def def = mock_coeff_template;
2593 	int alg_idx = _find_alg_entry(test, param->alg_id);
2594 	struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test);
2595 	unsigned int reg, alg_base_words;
2596 	struct cs_dsp_coeff_ctl *ctl;
2597 	struct firmware *wmfw;
2598 	u32 *init_vals, *readback, *ctl_vals;
2599 
2600 	init_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2601 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, init_vals);
2602 
2603 	readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL);
2604 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
2605 
2606 	ctl_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL);
2607 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals);
2608 
2609 	/* Zero-fill the registers backing the control */
2610 	alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
2611 	reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
2612 	reg += (alg_base_words + param->offs_words) *
2613 		cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2614 	regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2615 
2616 	/* Create control pointing to this data */
2617 	def.flags = param->flags;
2618 	def.mem_type = param->mem_type;
2619 	def.offset_dsp_words = param->offs_words;
2620 	def.length_bytes = param->len_bytes;
2621 
2622 	cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
2623 					      cs_dsp_ctl_cache_test_algs[alg_idx].id,
2624 					      "dummyalg", NULL);
2625 	cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
2626 	cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
2627 
2628 	/* Power-up DSP but don't start firmware */
2629 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2630 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2631 
2632 	/* Write new data to the control */
2633 	ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
2634 	KUNIT_ASSERT_NOT_NULL(test, ctl);
2635 
2636 	get_random_bytes(ctl_vals, param->len_bytes);
2637 	KUNIT_EXPECT_EQ(test,
2638 			cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, param->len_bytes),
2639 			1);
2640 
2641 	/* Start the firmware and the cached data should be written to registers */
2642 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2643 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2644 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2645 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2646 
2647 	/* Stop the firmware and power-down the DSP */
2648 	kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
2649 	cs_dsp_power_down(dsp);
2650 
2651 	/* Reset the registers */
2652 	regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2653 
2654 	/* Download and run a different firmware */
2655 	wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
2656 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
2657 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2658 	cs_dsp_power_down(dsp);
2659 
2660 	/* Reset the registers */
2661 	regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
2662 
2663 	/* Download the original firmware again */
2664 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2665 	KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
2666 	KUNIT_EXPECT_TRUE(test, ctl->set);
2667 
2668 	/* Start the firmware and the cached data should be written to registers */
2669 	KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
2670 	KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
2671 	KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
2672 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2673 
2674 	/* Control should readback the new data from the control cache */
2675 	KUNIT_EXPECT_EQ(test,
2676 			cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
2677 			0);
2678 	KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
2679 }
2680 
cs_dsp_ctl_cache_test_common_init(struct kunit * test,struct cs_dsp * dsp,int wmfw_version)2681 static int cs_dsp_ctl_cache_test_common_init(struct kunit *test, struct cs_dsp *dsp,
2682 					     int wmfw_version)
2683 {
2684 	struct cs_dsp_test *priv;
2685 	struct cs_dsp_test_local *local;
2686 	struct device *test_dev;
2687 	int ret;
2688 
2689 	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
2690 	if (!priv)
2691 		return -ENOMEM;
2692 
2693 	local = kunit_kzalloc(test, sizeof(struct cs_dsp_test_local), GFP_KERNEL);
2694 	if (!local)
2695 		return -ENOMEM;
2696 
2697 	priv->test = test;
2698 	priv->dsp = dsp;
2699 	test->priv = priv;
2700 	priv->local = local;
2701 	priv->local->wmfw_version = wmfw_version;
2702 
2703 	/* Create dummy struct device */
2704 	test_dev = kunit_device_register(test, "cs_dsp_test_drv");
2705 	if (IS_ERR(test_dev))
2706 		return PTR_ERR(test_dev);
2707 
2708 	dsp->dev = get_device(test_dev);
2709 	if (!dsp->dev)
2710 		return -ENODEV;
2711 
2712 	ret = kunit_add_action_or_reset(test, _put_device_wrapper, dsp->dev);
2713 	if (ret)
2714 		return ret;
2715 
2716 	dev_set_drvdata(dsp->dev, priv);
2717 
2718 	/* Allocate regmap */
2719 	ret = cs_dsp_mock_regmap_init(priv);
2720 	if (ret)
2721 		return ret;
2722 
2723 	/*
2724 	 * There must always be a XM header with at least 1 algorithm, so create
2725 	 * a dummy one that tests can use and extract it to a data blob.
2726 	 */
2727 	local->xm_header = cs_dsp_create_mock_xm_header(priv,
2728 							cs_dsp_ctl_cache_test_algs,
2729 							ARRAY_SIZE(cs_dsp_ctl_cache_test_algs));
2730 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->xm_header);
2731 
2732 	/* Create wmfw builder */
2733 	local->wmfw_builder = _create_dummy_wmfw(test);
2734 
2735 	/* Init cs_dsp */
2736 	dsp->client_ops = kunit_kzalloc(test, sizeof(*dsp->client_ops), GFP_KERNEL);
2737 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dsp->client_ops);
2738 
2739 	switch (dsp->type) {
2740 	case WMFW_ADSP2:
2741 		ret = cs_dsp_adsp2_init(dsp);
2742 		break;
2743 	case WMFW_HALO:
2744 		ret = cs_dsp_halo_init(dsp);
2745 		break;
2746 	default:
2747 		KUNIT_FAIL(test, "Untested DSP type %d\n", dsp->type);
2748 		return -EINVAL;
2749 	}
2750 
2751 	if (ret)
2752 		return ret;
2753 
2754 	/* Automatically call cs_dsp_remove() when test case ends */
2755 	return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
2756 }
2757 
cs_dsp_ctl_cache_test_halo_init(struct kunit * test)2758 static int cs_dsp_ctl_cache_test_halo_init(struct kunit *test)
2759 {
2760 	struct cs_dsp *dsp;
2761 
2762 	/* Fill in cs_dsp and initialize */
2763 	dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
2764 	if (!dsp)
2765 		return -ENOMEM;
2766 
2767 	dsp->num = 1;
2768 	dsp->type = WMFW_HALO;
2769 	dsp->mem = cs_dsp_mock_halo_dsp1_regions;
2770 	dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_halo_dsp1_region_sizes);
2771 	dsp->base = cs_dsp_mock_halo_core_base;
2772 	dsp->base_sysinfo = cs_dsp_mock_halo_sysinfo_base;
2773 
2774 	return cs_dsp_ctl_cache_test_common_init(test, dsp, 3);
2775 }
2776 
cs_dsp_ctl_cache_test_adsp2_32bit_init(struct kunit * test,int wmfw_ver)2777 static int cs_dsp_ctl_cache_test_adsp2_32bit_init(struct kunit *test, int wmfw_ver)
2778 {
2779 	struct cs_dsp *dsp;
2780 
2781 	/* Fill in cs_dsp and initialize */
2782 	dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
2783 	if (!dsp)
2784 		return -ENOMEM;
2785 
2786 	dsp->num = 1;
2787 	dsp->type = WMFW_ADSP2;
2788 	dsp->rev = 1;
2789 	dsp->mem = cs_dsp_mock_adsp2_32bit_dsp1_regions;
2790 	dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_32bit_dsp1_region_sizes);
2791 	dsp->base = cs_dsp_mock_adsp2_32bit_sysbase;
2792 
2793 	return cs_dsp_ctl_cache_test_common_init(test, dsp, wmfw_ver);
2794 }
2795 
cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1_init(struct kunit * test)2796 static int cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1_init(struct kunit *test)
2797 {
2798 	return cs_dsp_ctl_cache_test_adsp2_32bit_init(test, 1);
2799 }
2800 
cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2_init(struct kunit * test)2801 static int cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2_init(struct kunit *test)
2802 {
2803 	return cs_dsp_ctl_cache_test_adsp2_32bit_init(test, 2);
2804 }
2805 
cs_dsp_ctl_cache_test_adsp2_16bit_init(struct kunit * test,int wmfw_ver)2806 static int cs_dsp_ctl_cache_test_adsp2_16bit_init(struct kunit *test, int wmfw_ver)
2807 {
2808 	struct cs_dsp *dsp;
2809 
2810 	/* Fill in cs_dsp and initialize */
2811 	dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
2812 	if (!dsp)
2813 		return -ENOMEM;
2814 
2815 	dsp->num = 1;
2816 	dsp->type = WMFW_ADSP2;
2817 	dsp->rev = 0;
2818 	dsp->mem = cs_dsp_mock_adsp2_16bit_dsp1_regions;
2819 	dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_16bit_dsp1_region_sizes);
2820 	dsp->base = cs_dsp_mock_adsp2_16bit_sysbase;
2821 
2822 	return cs_dsp_ctl_cache_test_common_init(test, dsp, wmfw_ver);
2823 }
2824 
cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1_init(struct kunit * test)2825 static int cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1_init(struct kunit *test)
2826 {
2827 	return cs_dsp_ctl_cache_test_adsp2_16bit_init(test, 1);
2828 }
2829 
cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2_init(struct kunit * test)2830 static int cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2_init(struct kunit *test)
2831 {
2832 	return cs_dsp_ctl_cache_test_adsp2_16bit_init(test, 2);
2833 }
2834 
cs_dsp_ctl_all_param_desc(const struct cs_dsp_ctl_cache_test_param * param,char * desc)2835 static void cs_dsp_ctl_all_param_desc(const struct cs_dsp_ctl_cache_test_param *param,
2836 				      char *desc)
2837 {
2838 	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "alg:%#x %s@%u len:%u flags:%#x",
2839 		 param->alg_id, cs_dsp_mem_region_name(param->mem_type),
2840 		 param->offs_words, param->len_bytes, param->flags);
2841 }
2842 
2843 /* All parameters populated, with various lengths */
2844 static const struct cs_dsp_ctl_cache_test_param all_pop_varying_len_cases[] = {
2845 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2846 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 8 },
2847 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 12 },
2848 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 16 },
2849 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 48 },
2850 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 100 },
2851 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 512 },
2852 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 1000 },
2853 };
2854 KUNIT_ARRAY_PARAM(all_pop_varying_len, all_pop_varying_len_cases,
2855 		  cs_dsp_ctl_all_param_desc);
2856 
2857 /* All parameters populated, with various offsets */
2858 static const struct cs_dsp_ctl_cache_test_param all_pop_varying_offset_cases[] = {
2859 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 0,   .len_bytes = 4 },
2860 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1,   .len_bytes = 4 },
2861 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 2,   .len_bytes = 4 },
2862 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 3,   .len_bytes = 4 },
2863 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 8,   .len_bytes = 4 },
2864 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 10,  .len_bytes = 4 },
2865 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 128, .len_bytes = 4 },
2866 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 180, .len_bytes = 4 },
2867 };
2868 KUNIT_ARRAY_PARAM(all_pop_varying_offset, all_pop_varying_offset_cases,
2869 		  cs_dsp_ctl_all_param_desc);
2870 
2871 /* All parameters populated, with various X and Y memory regions */
2872 static const struct cs_dsp_ctl_cache_test_param all_pop_varying_xy_cases[] = {
2873 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_XM, .offs_words = 1, .len_bytes = 4 },
2874 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2875 };
2876 KUNIT_ARRAY_PARAM(all_pop_varying_xy, all_pop_varying_xy_cases,
2877 		  cs_dsp_ctl_all_param_desc);
2878 
2879 /* All parameters populated, using ZM */
2880 static const struct cs_dsp_ctl_cache_test_param all_pop_z_cases[] = {
2881 	{ .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_ZM, .offs_words = 1, .len_bytes = 4 },
2882 };
2883 KUNIT_ARRAY_PARAM(all_pop_z, all_pop_z_cases, cs_dsp_ctl_all_param_desc);
2884 
2885 /* All parameters populated, with various algorithm ids */
2886 static const struct cs_dsp_ctl_cache_test_param all_pop_varying_alg_cases[] = {
2887 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2888 	{ .alg_id = 0xb,      .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2889 	{ .alg_id = 0x9f1234, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2890 	{ .alg_id = 0xff00ff, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 },
2891 };
2892 KUNIT_ARRAY_PARAM(all_pop_varying_alg, all_pop_varying_alg_cases,
2893 		  cs_dsp_ctl_all_param_desc);
2894 
2895 /*
2896  * All parameters populated, with all combinations of flags for a
2897  * non-volatile readable control
2898  */
2899 static const struct cs_dsp_ctl_cache_test_param all_pop_nonvol_readable_flags_cases[] = {
2900 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2901 	  .flags = 0
2902 	},
2903 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2904 	  .flags = WMFW_CTL_FLAG_READABLE,
2905 	},
2906 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2907 	  .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
2908 	},
2909 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2910 	  .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE,
2911 	},
2912 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2913 	  .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
2914 	},
2915 };
2916 KUNIT_ARRAY_PARAM(all_pop_nonvol_readable_flags,
2917 		  all_pop_nonvol_readable_flags_cases,
2918 		  cs_dsp_ctl_all_param_desc);
2919 
2920 /*
2921  * All parameters populated, with all combinations of flags for a
2922  * non-volatile readable control, except flags==0
2923  */
2924 static const struct cs_dsp_ctl_cache_test_param all_pop_nonvol_readable_nonzero_flags_cases[] = {
2925 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2926 	  .flags = WMFW_CTL_FLAG_READABLE,
2927 	},
2928 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2929 	  .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
2930 	},
2931 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2932 	  .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE,
2933 	},
2934 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2935 	  .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
2936 	},
2937 };
2938 KUNIT_ARRAY_PARAM(all_pop_nonvol_readable_nonzero_flags,
2939 		  all_pop_nonvol_readable_nonzero_flags_cases,
2940 		  cs_dsp_ctl_all_param_desc);
2941 
2942 /*
2943  * All parameters populated, with all combinations of flags for a
2944  * non-volatile writeable control
2945  */
2946 static const struct cs_dsp_ctl_cache_test_param all_pop_nonvol_writeable_flags_cases[] = {
2947 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2948 	  .flags = 0
2949 	},
2950 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2951 	  .flags = WMFW_CTL_FLAG_WRITEABLE,
2952 	},
2953 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2954 	  .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
2955 	},
2956 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2957 	  .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE,
2958 	},
2959 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2960 	  .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE,
2961 	},
2962 };
2963 KUNIT_ARRAY_PARAM(all_pop_nonvol_writeable_flags,
2964 		  all_pop_nonvol_writeable_flags_cases,
2965 		  cs_dsp_ctl_all_param_desc);
2966 
2967 /*
2968  * All parameters populated, with all combinations of flags for a
2969  * non-volatile write-only control of varying lengths
2970  */
2971 static const struct cs_dsp_ctl_cache_test_param all_pop_nonvol_write_only_length_cases[] = {
2972 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2973 	  .flags = WMFW_CTL_FLAG_WRITEABLE,
2974 	},
2975 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 512,
2976 	  .flags = WMFW_CTL_FLAG_WRITEABLE,
2977 	},
2978 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4,
2979 	  .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE,
2980 	},
2981 	{ .alg_id = 0xfafa,   .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 512,
2982 	  .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE,
2983 	},
2984 };
2985 KUNIT_ARRAY_PARAM(all_pop_nonvol_write_only_length,
2986 		  all_pop_nonvol_write_only_length_cases,
2987 		  cs_dsp_ctl_all_param_desc);
2988 
2989 static struct kunit_case cs_dsp_ctl_cache_test_cases_v1[] = {
2990 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_len_gen_params),
2991 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_offset_gen_params),
2992 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_xy_gen_params),
2993 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_z_gen_params),
2994 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_alg_gen_params),
2995 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_nonvol_readable_flags_gen_params),
2996 
2997 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init_write_only,
2998 			 all_pop_nonvol_write_only_length_gen_params),
2999 
3000 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fw_same_controls),
3001 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls),
3002 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_mems),
3003 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_algs),
3004 
3005 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_started,
3006 			 all_pop_nonvol_readable_flags_gen_params),
3007 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped,
3008 			 all_pop_nonvol_readable_flags_gen_params),
3009 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_powered_down,
3010 			 all_pop_nonvol_readable_flags_gen_params),
3011 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped_powered_down,
3012 			 all_pop_nonvol_readable_flags_gen_params),
3013 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_loaded_fw,
3014 			 all_pop_nonvol_readable_flags_gen_params),
3015 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_running_fw,
3016 			 all_pop_nonvol_readable_flags_gen_params),
3017 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running,
3018 			 all_pop_nonvol_readable_nonzero_flags_gen_params),
3019 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running_zero_flags,
3020 			 all_pop_varying_len_gen_params),
3021 
3022 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_len_gen_params),
3023 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_offset_gen_params),
3024 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_xy_gen_params),
3025 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_z_gen_params),
3026 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_alg_gen_params),
3027 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_nonvol_writeable_flags_gen_params),
3028 
3029 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3030 			 all_pop_varying_len_gen_params),
3031 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3032 			 all_pop_varying_offset_gen_params),
3033 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3034 			 all_pop_varying_xy_gen_params),
3035 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3036 			 all_pop_z_gen_params),
3037 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3038 			 all_pop_varying_alg_gen_params),
3039 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3040 			 all_pop_nonvol_writeable_flags_gen_params),
3041 
3042 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_unchanged_not_started,
3043 			 all_pop_nonvol_writeable_flags_gen_params),
3044 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_started,
3045 			 all_pop_nonvol_writeable_flags_gen_params),
3046 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped,
3047 			 all_pop_nonvol_writeable_flags_gen_params),
3048 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_powered_down,
3049 			 all_pop_nonvol_writeable_flags_gen_params),
3050 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped_powered_down,
3051 			 all_pop_nonvol_writeable_flags_gen_params),
3052 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_loaded_fw,
3053 			 all_pop_nonvol_writeable_flags_gen_params),
3054 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_running_fw,
3055 			 all_pop_nonvol_writeable_flags_gen_params),
3056 
3057 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_before_run,
3058 			 all_pop_nonvol_writeable_flags_gen_params),
3059 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_while_running,
3060 			 all_pop_nonvol_writeable_flags_gen_params),
3061 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_after_stop,
3062 			 all_pop_nonvol_writeable_flags_gen_params),
3063 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_not_current_fw,
3064 			 all_pop_nonvol_writeable_flags_gen_params),
3065 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_every_run,
3066 			 all_pop_nonvol_writeable_flags_gen_params),
3067 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_reload,
3068 			 all_pop_nonvol_writeable_flags_gen_params),
3069 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_swap,
3070 			 all_pop_nonvol_writeable_flags_gen_params),
3071 
3072 	{ } /* terminator */
3073 };
3074 
3075 static struct kunit_case cs_dsp_ctl_cache_test_cases_v2[] = {
3076 	KUNIT_CASE(cs_dsp_ctl_v2_cache_alloc),
3077 
3078 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_len_gen_params),
3079 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_offset_gen_params),
3080 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_xy_gen_params),
3081 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_z_gen_params),
3082 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_alg_gen_params),
3083 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_nonvol_readable_flags_gen_params),
3084 
3085 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init_write_only,
3086 			 all_pop_nonvol_write_only_length_gen_params),
3087 
3088 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fw_same_controls),
3089 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls),
3090 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_mems),
3091 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_algs),
3092 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_offsets),
3093 
3094 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_started,
3095 			 all_pop_nonvol_readable_flags_gen_params),
3096 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped,
3097 			 all_pop_nonvol_readable_flags_gen_params),
3098 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_powered_down,
3099 			 all_pop_nonvol_readable_flags_gen_params),
3100 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped_powered_down,
3101 			 all_pop_nonvol_readable_flags_gen_params),
3102 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_loaded_fw,
3103 			 all_pop_nonvol_readable_flags_gen_params),
3104 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_running_fw,
3105 			 all_pop_nonvol_readable_flags_gen_params),
3106 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running,
3107 			 all_pop_nonvol_readable_nonzero_flags_gen_params),
3108 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running_zero_flags,
3109 			 all_pop_varying_len_gen_params),
3110 
3111 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_len_gen_params),
3112 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_offset_gen_params),
3113 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_xy_gen_params),
3114 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_z_gen_params),
3115 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_alg_gen_params),
3116 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_nonvol_writeable_flags_gen_params),
3117 
3118 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3119 			 all_pop_varying_len_gen_params),
3120 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3121 			 all_pop_varying_offset_gen_params),
3122 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3123 			 all_pop_varying_xy_gen_params),
3124 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3125 			 all_pop_z_gen_params),
3126 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3127 			 all_pop_varying_alg_gen_params),
3128 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3129 			 all_pop_nonvol_writeable_flags_gen_params),
3130 
3131 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_unchanged_not_started,
3132 			 all_pop_nonvol_writeable_flags_gen_params),
3133 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_started,
3134 			 all_pop_nonvol_writeable_flags_gen_params),
3135 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped,
3136 			 all_pop_nonvol_writeable_flags_gen_params),
3137 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_powered_down,
3138 			 all_pop_nonvol_writeable_flags_gen_params),
3139 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped_powered_down,
3140 			 all_pop_nonvol_writeable_flags_gen_params),
3141 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_loaded_fw,
3142 			 all_pop_nonvol_writeable_flags_gen_params),
3143 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_running_fw,
3144 			 all_pop_nonvol_writeable_flags_gen_params),
3145 
3146 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_before_run,
3147 			 all_pop_nonvol_writeable_flags_gen_params),
3148 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_while_running,
3149 			 all_pop_nonvol_writeable_flags_gen_params),
3150 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_after_stop,
3151 			 all_pop_nonvol_writeable_flags_gen_params),
3152 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_not_current_fw,
3153 			 all_pop_nonvol_writeable_flags_gen_params),
3154 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_every_run,
3155 			 all_pop_nonvol_writeable_flags_gen_params),
3156 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_reload,
3157 			 all_pop_nonvol_writeable_flags_gen_params),
3158 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_swap,
3159 			 all_pop_nonvol_writeable_flags_gen_params),
3160 
3161 	{ } /* terminator */
3162 };
3163 
3164 static struct kunit_case cs_dsp_ctl_cache_test_cases_v3[] = {
3165 	KUNIT_CASE(cs_dsp_ctl_v2_cache_alloc),
3166 
3167 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_len_gen_params),
3168 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_offset_gen_params),
3169 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_xy_gen_params),
3170 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_varying_alg_gen_params),
3171 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init, all_pop_nonvol_readable_flags_gen_params),
3172 
3173 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_init_write_only,
3174 			 all_pop_nonvol_write_only_length_gen_params),
3175 
3176 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fw_same_controls),
3177 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls),
3178 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_mems),
3179 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_algs),
3180 	KUNIT_CASE(cs_dsp_ctl_cache_init_multiple_offsets),
3181 
3182 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_started,
3183 			 all_pop_nonvol_readable_flags_gen_params),
3184 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped,
3185 			 all_pop_nonvol_readable_flags_gen_params),
3186 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_powered_down,
3187 			 all_pop_nonvol_readable_flags_gen_params),
3188 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_stopped_powered_down,
3189 			 all_pop_nonvol_readable_flags_gen_params),
3190 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_loaded_fw,
3191 			 all_pop_nonvol_readable_flags_gen_params),
3192 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_not_current_running_fw,
3193 			 all_pop_nonvol_readable_flags_gen_params),
3194 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_read_running,
3195 			 all_pop_nonvol_readable_nonzero_flags_gen_params),
3196 
3197 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_len_gen_params),
3198 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_offset_gen_params),
3199 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_xy_gen_params),
3200 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_varying_alg_gen_params),
3201 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough, all_pop_nonvol_writeable_flags_gen_params),
3202 
3203 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3204 			 all_pop_varying_len_gen_params),
3205 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3206 			 all_pop_varying_offset_gen_params),
3207 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3208 			 all_pop_varying_xy_gen_params),
3209 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3210 			 all_pop_varying_alg_gen_params),
3211 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_writethrough_unchanged,
3212 			 all_pop_nonvol_writeable_flags_gen_params),
3213 
3214 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_unchanged_not_started,
3215 			 all_pop_nonvol_writeable_flags_gen_params),
3216 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_started,
3217 			 all_pop_nonvol_writeable_flags_gen_params),
3218 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped,
3219 			 all_pop_nonvol_writeable_flags_gen_params),
3220 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_powered_down,
3221 			 all_pop_nonvol_writeable_flags_gen_params),
3222 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_stopped_powered_down,
3223 			 all_pop_nonvol_writeable_flags_gen_params),
3224 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_loaded_fw,
3225 			 all_pop_nonvol_writeable_flags_gen_params),
3226 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_write_not_current_running_fw,
3227 			 all_pop_nonvol_writeable_flags_gen_params),
3228 
3229 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_before_run,
3230 			 all_pop_nonvol_writeable_flags_gen_params),
3231 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_while_running,
3232 			 all_pop_nonvol_writeable_flags_gen_params),
3233 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_after_stop,
3234 			 all_pop_nonvol_writeable_flags_gen_params),
3235 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_write_not_current_fw,
3236 			 all_pop_nonvol_writeable_flags_gen_params),
3237 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_every_run,
3238 			 all_pop_nonvol_writeable_flags_gen_params),
3239 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_reload,
3240 			 all_pop_nonvol_writeable_flags_gen_params),
3241 	KUNIT_CASE_PARAM(cs_dsp_ctl_cache_sync_reapply_after_fw_swap,
3242 			 all_pop_nonvol_writeable_flags_gen_params),
3243 
3244 	{ } /* terminator */
3245 };
3246 
3247 static struct kunit_suite cs_dsp_ctl_cache_test_halo = {
3248 	.name = "cs_dsp_ctl_cache_wmfwV3_halo",
3249 	.init = cs_dsp_ctl_cache_test_halo_init,
3250 	.test_cases = cs_dsp_ctl_cache_test_cases_v3,
3251 };
3252 
3253 static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1 = {
3254 	.name = "cs_dsp_ctl_cache_wmfwV1_adsp2_32bit",
3255 	.init = cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1_init,
3256 	.test_cases = cs_dsp_ctl_cache_test_cases_v1,
3257 };
3258 
3259 static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2 = {
3260 	.name = "cs_dsp_ctl_cache_wmfwV2_adsp2_32bit",
3261 	.init = cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2_init,
3262 	.test_cases = cs_dsp_ctl_cache_test_cases_v2,
3263 };
3264 
3265 static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1 = {
3266 	.name = "cs_dsp_ctl_cache_wmfwV1_adsp2_16bit",
3267 	.init = cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1_init,
3268 	.test_cases = cs_dsp_ctl_cache_test_cases_v1,
3269 };
3270 
3271 static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2 = {
3272 	.name = "cs_dsp_ctl_cache_wmfwV2_adsp2_16bit",
3273 	.init = cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2_init,
3274 	.test_cases = cs_dsp_ctl_cache_test_cases_v2,
3275 };
3276 
3277 kunit_test_suites(&cs_dsp_ctl_cache_test_halo,
3278 		  &cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1,
3279 		  &cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2,
3280 		  &cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1,
3281 		  &cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2);
3282