xref: /linux/drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c (revision 6f7e6393d1ce636bb7ec77a7fe7b77458fddf701)
1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // KUnit tests for cs_dsp.
4 //
5 // Copyright (C) 2024 Cirrus Logic, Inc. and
6 //                    Cirrus Logic International Semiconductor Ltd.
7 //
8 
9 #include <kunit/device.h>
10 #include <kunit/resource.h>
11 #include <kunit/test.h>
12 #include <linux/build_bug.h>
13 #include <linux/firmware/cirrus/cs_dsp.h>
14 #include <linux/firmware/cirrus/cs_dsp_test_utils.h>
15 #include <linux/firmware/cirrus/wmfw.h>
16 #include <linux/random.h>
17 #include <linux/regmap.h>
18 #include <linux/string.h>
19 #include <linux/vmalloc.h>
20 
21 #include "../cs_dsp.h"
22 
23 /*
24  * Test method is:
25  *
26  * 1) Create a mock regmap in cache-only mode so that all writes will be cached.
27  * 2) Create dummy wmfw file.
28  * 3) Call cs_dsp_power_up() with the bin file.
29  * 4) Readback the cached value of registers that should have been written and
30  *    check they have the correct value.
31  * 5) All the registers that are expected to have been written are dropped from
32  *    the cache. This should leave the cache clean.
33  * 6) If the cache is still dirty there have been unexpected writes.
34  */
35 
36 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *)
37 KUNIT_DEFINE_ACTION_WRAPPER(_vfree_wrapper, vfree, void *)
38 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *)
39 
40 struct cs_dsp_test_local {
41 	struct cs_dsp_mock_xm_header *xm_header;
42 	struct cs_dsp_mock_wmfw_builder *wmfw_builder;
43 	int wmfw_version;
44 };
45 
46 struct cs_dsp_wmfw_test_param {
47 	unsigned int num_blocks;
48 	int mem_type;
49 };
50 
51 static const struct cs_dsp_mock_alg_def cs_dsp_wmfw_test_mock_algs[] = {
52 	{
53 		.id = 0xfafa,
54 		.ver = 0x100000,
55 		.xm_size_words = 164,
56 		.ym_size_words = 164,
57 		.zm_size_words = 164,
58 	},
59 };
60 
61 /*
62  * wmfw that writes the XM header.
63  * cs_dsp always reads this back from unpacked XM.
64  */
65 static void wmfw_write_xm_header_unpacked(struct kunit *test)
66 {
67 	struct cs_dsp_test *priv = test->priv;
68 	struct cs_dsp_test_local *local = priv->local;
69 	struct firmware *wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
70 	unsigned int reg_addr;
71 	u8 *readback;
72 
73 	/* XM header payload was added to wmfw by test case init function */
74 
75 	KUNIT_EXPECT_EQ(test,
76 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
77 			0);
78 
79 	/* Read raw so endianness and register width don't matter */
80 	readback = kunit_kzalloc(test, local->xm_header->blob_size_bytes, GFP_KERNEL);
81 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
82 
83 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_XM);
84 	KUNIT_EXPECT_EQ(test,
85 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
86 					local->xm_header->blob_size_bytes),
87 			0);
88 	KUNIT_EXPECT_MEMEQ(test, readback, local->xm_header->blob_data,
89 			   local->xm_header->blob_size_bytes);
90 
91 	/* Drop expected writes and the cache should then be clean */
92 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
93 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
94 }
95 
96 /* Write one payload of length param->num_blocks */
97 static void wmfw_write_one_payload(struct kunit *test)
98 {
99 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
100 	struct cs_dsp_test *priv = test->priv;
101 	struct cs_dsp_test_local *local = priv->local;
102 	struct firmware *wmfw;
103 	unsigned int reg_addr;
104 	u8 *payload_data, *readback;
105 	unsigned int mem_offset_dsp_words = 0;
106 	unsigned int payload_size_bytes;
107 
108 	payload_size_bytes = param->num_blocks *
109 			     cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);
110 
111 	/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */
112 	do {
113 		payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);
114 	} while (payload_size_bytes % 4);
115 
116 	payload_data = kunit_kmalloc(test, payload_size_bytes, GFP_KERNEL);
117 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);
118 	get_random_bytes(payload_data, payload_size_bytes);
119 
120 	readback = kunit_kzalloc(test, payload_size_bytes, GFP_KERNEL);
121 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
122 
123 	/* Tests on XM must be after the XM header */
124 	if (param->mem_type == WMFW_ADSP2_XM)
125 		mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);
126 
127 	/* Add a single payload */
128 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
129 					param->mem_type, mem_offset_dsp_words,
130 					payload_data, payload_size_bytes);
131 
132 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
133 
134 	KUNIT_EXPECT_EQ(test,
135 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
136 			0);
137 
138 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
139 	reg_addr += cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv) * mem_offset_dsp_words;
140 	KUNIT_EXPECT_EQ(test,
141 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes),
142 			0);
143 	KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);
144 
145 	/* Drop expected writes and the cache should then be clean */
146 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);
147 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
148 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
149 }
150 
151 /* Write several smallest possible payloads for the given memory type */
152 static void wmfw_write_multiple_oneblock_payloads(struct kunit *test)
153 {
154 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
155 	struct cs_dsp_test *priv = test->priv;
156 	struct cs_dsp_test_local *local = priv->local;
157 	struct firmware *wmfw;
158 	unsigned int reg_addr;
159 	u8 *payload_data, *readback;
160 	unsigned int mem_offset_dsp_words = 0;
161 	unsigned int payload_size_bytes, payload_size_dsp_words;
162 	const unsigned int num_payloads = param->num_blocks;
163 	int i;
164 
165 	/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */
166 	payload_size_dsp_words = 0;
167 	payload_size_bytes = 0;
168 	do {
169 		payload_size_dsp_words += cs_dsp_mock_reg_block_length_dsp_words(priv,
170 										 param->mem_type);
171 		payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);
172 	} while (payload_size_bytes % 4);
173 
174 	payload_data = kunit_kcalloc(test, num_payloads, payload_size_bytes, GFP_KERNEL);
175 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);
176 
177 	readback = kunit_kcalloc(test, num_payloads, payload_size_bytes, GFP_KERNEL);
178 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
179 
180 	get_random_bytes(payload_data, num_payloads * payload_size_bytes);
181 
182 	/* Tests on XM must be after the XM header */
183 	if (param->mem_type == WMFW_ADSP2_XM)
184 		mem_offset_dsp_words += local->xm_header->blob_size_bytes / payload_size_bytes;
185 
186 	/* Add multiple payloads of one block each */
187 	for (i = 0; i < num_payloads; ++i) {
188 		cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
189 						param->mem_type,
190 						mem_offset_dsp_words + (i * payload_size_dsp_words),
191 						&payload_data[i * payload_size_bytes],
192 						payload_size_bytes);
193 	}
194 
195 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
196 
197 	KUNIT_EXPECT_EQ(test,
198 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
199 			0);
200 
201 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
202 	reg_addr += cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv) * mem_offset_dsp_words;
203 	KUNIT_EXPECT_EQ(test,
204 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
205 					num_payloads * payload_size_bytes),
206 			0);
207 	KUNIT_EXPECT_MEMEQ(test, readback, payload_data, num_payloads * payload_size_bytes);
208 
209 	/* Drop expected writes and the cache should then be clean */
210 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, num_payloads * payload_size_bytes);
211 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
212 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
213 }
214 
215 /*
216  * Write several smallest possible payloads of the given memory type
217  * in reverse address order
218  */
219 static void wmfw_write_multiple_oneblock_payloads_reverse(struct kunit *test)
220 {
221 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
222 	struct cs_dsp_test *priv = test->priv;
223 	struct cs_dsp_test_local *local = priv->local;
224 	struct firmware *wmfw;
225 	unsigned int reg_addr;
226 	u8 *payload_data, *readback;
227 	unsigned int mem_offset_dsp_words = 0;
228 	unsigned int payload_size_bytes, payload_size_dsp_words;
229 	const unsigned int num_payloads = param->num_blocks;
230 	int i;
231 
232 	/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */
233 	payload_size_dsp_words = 0;
234 	payload_size_bytes = 0;
235 	do {
236 		payload_size_dsp_words += cs_dsp_mock_reg_block_length_dsp_words(priv,
237 										 param->mem_type);
238 		payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);
239 	} while (payload_size_bytes % 4);
240 
241 	payload_data = kunit_kcalloc(test, num_payloads, payload_size_bytes, GFP_KERNEL);
242 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);
243 
244 	readback = kunit_kcalloc(test, num_payloads, payload_size_bytes, GFP_KERNEL);
245 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
246 
247 	get_random_bytes(payload_data, num_payloads * payload_size_bytes);
248 
249 	/* Tests on XM must be after the XM header */
250 	if (param->mem_type == WMFW_ADSP2_XM)
251 		mem_offset_dsp_words += local->xm_header->blob_size_bytes / payload_size_bytes;
252 
253 	/* Add multiple payloads of one block each */
254 	for (i = num_payloads - 1; i >= 0; --i) {
255 		cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
256 						param->mem_type,
257 						mem_offset_dsp_words + (i * payload_size_dsp_words),
258 						&payload_data[i * payload_size_bytes],
259 						payload_size_bytes);
260 	}
261 
262 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
263 
264 	KUNIT_EXPECT_EQ(test,
265 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
266 			0);
267 
268 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
269 	reg_addr += cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv) * mem_offset_dsp_words;
270 	KUNIT_EXPECT_EQ(test,
271 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
272 					num_payloads * payload_size_bytes),
273 			0);
274 	KUNIT_EXPECT_MEMEQ(test, readback, payload_data, num_payloads * payload_size_bytes);
275 
276 	/* Drop expected writes and the cache should then be clean */
277 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, num_payloads * payload_size_bytes);
278 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
279 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
280 }
281 
282 /*
283  * Write multiple payloads of length param->num_blocks.
284  * The payloads are not in address order and collectively do not patch
285  * a contiguous block of memory.
286  */
287 static void wmfw_write_multiple_payloads_sparse_unordered(struct kunit *test)
288 {
289 	static const unsigned int random_offsets[] = {
290 		11, 69, 59, 61, 32, 75, 4, 38, 70, 13, 79, 47, 46, 53, 18, 44,
291 		54, 35, 51, 21, 26, 45, 27, 41, 66, 2, 17, 56, 40, 9, 8, 20,
292 		29, 19, 63, 42, 12, 16, 43, 3, 5, 55, 52, 22
293 	};
294 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
295 	struct cs_dsp_test *priv = test->priv;
296 	struct cs_dsp_test_local *local = priv->local;
297 	struct firmware *wmfw;
298 	unsigned int reg_addr;
299 	u8 *payload_data, *readback;
300 	unsigned int mem_offset_dsp_words = 0;
301 	unsigned int payload_size_bytes, payload_size_dsp_words;
302 	const int num_payloads = ARRAY_SIZE(random_offsets);
303 	int i;
304 
305 	payload_size_bytes = param->num_blocks *
306 			     cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);
307 	payload_size_dsp_words = param->num_blocks *
308 				 cs_dsp_mock_reg_block_length_dsp_words(priv, param->mem_type);
309 
310 	/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */
311 	do {
312 		payload_size_dsp_words += cs_dsp_mock_reg_block_length_dsp_words(priv,
313 										 param->mem_type);
314 		payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);
315 	} while (payload_size_bytes % 4);
316 
317 	payload_data = kunit_kcalloc(test, num_payloads, payload_size_bytes, GFP_KERNEL);
318 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);
319 	get_random_bytes(payload_data, payload_size_bytes);
320 
321 	readback = kunit_kcalloc(test, num_payloads, payload_size_bytes, GFP_KERNEL);
322 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
323 
324 	/* Tests on XM must be after the XM header */
325 	if (param->mem_type == WMFW_ADSP2_XM)
326 		mem_offset_dsp_words += local->xm_header->blob_size_bytes / payload_size_bytes;
327 
328 	/* Add multiple payloads of one block each at "random" locations */
329 	for (i = 0; i < num_payloads; ++i) {
330 		unsigned int offset = random_offsets[i] * payload_size_dsp_words;
331 
332 		cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
333 						param->mem_type,
334 						mem_offset_dsp_words + offset,
335 						&payload_data[i * payload_size_bytes],
336 						payload_size_bytes);
337 	}
338 
339 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
340 
341 	KUNIT_EXPECT_EQ(test,
342 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
343 			0);
344 
345 	for (i = 0; i < num_payloads; ++i) {
346 		unsigned int offset_num_regs = (random_offsets[i] * payload_size_bytes) /
347 						regmap_get_val_bytes(priv->dsp->regmap);
348 		reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
349 		reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
350 		reg_addr += cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv) * mem_offset_dsp_words;
351 		KUNIT_EXPECT_EQ(test,
352 				regmap_raw_read(priv->dsp->regmap, reg_addr,
353 						&readback[i * payload_size_bytes],
354 						payload_size_bytes),
355 				0);
356 
357 		cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);
358 	}
359 
360 	KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);
361 
362 	/* Drop expected writes and the cache should then be clean */
363 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
364 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
365 }
366 
367 /* Write the whole of PM in a single unpacked payload */
368 static void wmfw_write_all_unpacked_pm(struct kunit *test)
369 {
370 	struct cs_dsp_test *priv = test->priv;
371 	struct cs_dsp_test_local *local = priv->local;
372 	struct firmware *wmfw;
373 	unsigned int reg_addr;
374 	u8 *payload_data, *readback;
375 	unsigned int payload_size_bytes;
376 
377 	payload_size_bytes = cs_dsp_mock_size_of_region(priv->dsp, WMFW_ADSP2_PM);
378 	payload_data = vmalloc(payload_size_bytes);
379 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);
380 	kunit_add_action_or_reset(priv->test, _vfree_wrapper, payload_data);
381 
382 	readback = vmalloc(payload_size_bytes);
383 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
384 	kunit_add_action_or_reset(priv->test, _vfree_wrapper, readback);
385 	memset(readback, 0, payload_size_bytes);
386 
387 	/* Add a single PM payload */
388 	get_random_bytes(payload_data, payload_size_bytes);
389 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
390 					WMFW_ADSP2_PM, 0,
391 					payload_data, payload_size_bytes);
392 
393 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
394 
395 	KUNIT_EXPECT_EQ(test,
396 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
397 			0);
398 
399 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_PM);
400 	KUNIT_EXPECT_EQ(test,
401 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes),
402 			0);
403 	KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);
404 
405 	/* Drop expected writes and the cache should then be clean */
406 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);
407 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
408 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
409 }
410 
411 /* Write the whole of PM in a single packed payload */
412 static void wmfw_write_all_packed_pm(struct kunit *test)
413 {
414 	struct cs_dsp_test *priv = test->priv;
415 	struct cs_dsp_test_local *local = priv->local;
416 	struct firmware *wmfw;
417 	unsigned int reg_addr;
418 	u8 *payload_data, *readback;
419 	unsigned int payload_size_bytes;
420 
421 	payload_size_bytes = cs_dsp_mock_size_of_region(priv->dsp, WMFW_HALO_PM_PACKED);
422 	payload_data = vmalloc(payload_size_bytes);
423 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);
424 	kunit_add_action_or_reset(priv->test, _vfree_wrapper, payload_data);
425 
426 	readback = vmalloc(payload_size_bytes);
427 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
428 	kunit_add_action_or_reset(priv->test, _vfree_wrapper, readback);
429 	memset(readback, 0, payload_size_bytes);
430 
431 	/* Add a single PM payload */
432 	get_random_bytes(payload_data, payload_size_bytes);
433 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
434 					WMFW_HALO_PM_PACKED, 0,
435 					payload_data, payload_size_bytes);
436 
437 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
438 
439 	KUNIT_EXPECT_EQ(test,
440 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
441 			0);
442 
443 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_HALO_PM_PACKED);
444 	KUNIT_EXPECT_EQ(test,
445 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes),
446 			0);
447 	KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);
448 
449 	/* Drop expected writes and the cache should then be clean */
450 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);
451 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
452 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
453 }
454 
455 /*
456  * Write a series of payloads to various unpacked memory regions.
457  * The payloads are of various lengths and offsets, driven by the
458  * payload_defs table. The offset and length are both given as a
459  * number of minimum-sized register blocks to keep the maths simpler.
460  * (Where a minimum-sized register block is the smallest number of
461  * registers that contain a whole number of DSP words.)
462  */
463 static void wmfw_write_multiple_unpacked_mem(struct kunit *test)
464 {
465 	static const struct {
466 		int mem_type;
467 		unsigned int offset_num_blocks;
468 		unsigned int num_blocks;
469 	} payload_defs[] = {
470 		{ WMFW_ADSP2_PM, 11, 60 },
471 		{ WMFW_ADSP2_ZM, 69, 8 },
472 		{ WMFW_ADSP2_YM, 32, 74 },
473 		{ WMFW_ADSP2_XM, 70, 38 },
474 		{ WMFW_ADSP2_PM, 84, 48 },
475 		{ WMFW_ADSP2_XM, 46, 18 },
476 		{ WMFW_ADSP2_PM, 0,  8 },
477 		{ WMFW_ADSP2_YM, 0, 30 },
478 		{ WMFW_ADSP2_PM, 160, 50 },
479 		{ WMFW_ADSP2_ZM, 21, 26 },
480 	};
481 	struct cs_dsp_test *priv = test->priv;
482 	struct cs_dsp_test_local *local = priv->local;
483 	struct firmware *wmfw;
484 	unsigned int payload_size_bytes, offset_num_dsp_words;
485 	unsigned int reg_addr, offset_bytes, offset_num_regs;
486 	void **payload_data;
487 	void *readback;
488 	int i, ret;
489 
490 	payload_data = kunit_kcalloc(test, ARRAY_SIZE(payload_defs), sizeof(*payload_data),
491 				     GFP_KERNEL);
492 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);
493 
494 	for (i = 0; i < ARRAY_SIZE(payload_defs); ++i) {
495 		payload_size_bytes = payload_defs[i].num_blocks *
496 				     cs_dsp_mock_reg_block_length_bytes(priv,
497 									payload_defs[i].mem_type);
498 
499 		payload_data[i] = kunit_kmalloc(test, payload_size_bytes, GFP_KERNEL);
500 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data[i]);
501 		get_random_bytes(payload_data[i], payload_size_bytes);
502 
503 		offset_num_dsp_words = payload_defs[i].offset_num_blocks *
504 				       cs_dsp_mock_reg_block_length_dsp_words(priv,
505 									 payload_defs[i].mem_type);
506 		cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
507 						payload_defs[i].mem_type,
508 						offset_num_dsp_words,
509 						payload_data[i],
510 						payload_size_bytes);
511 	}
512 
513 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
514 
515 	KUNIT_EXPECT_EQ(test,
516 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
517 			0);
518 
519 	for (i = 0; i < ARRAY_SIZE(payload_defs); ++i) {
520 		payload_size_bytes = payload_defs[i].num_blocks *
521 				     cs_dsp_mock_reg_block_length_bytes(priv,
522 									payload_defs[i].mem_type);
523 
524 		readback = kunit_kzalloc(test, payload_size_bytes, GFP_KERNEL);
525 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
526 
527 		offset_bytes = payload_defs[i].offset_num_blocks *
528 			       cs_dsp_mock_reg_block_length_bytes(priv, payload_defs[i].mem_type);
529 		offset_num_regs = offset_bytes / regmap_get_val_bytes(priv->dsp->regmap);
530 		reg_addr = cs_dsp_mock_base_addr_for_mem(priv, payload_defs[i].mem_type);
531 		reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
532 		ret = regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes);
533 		KUNIT_EXPECT_EQ_MSG(test, ret, 0, "%s @%u num:%u\n",
534 				    cs_dsp_mem_region_name(payload_defs[i].mem_type),
535 				    payload_defs[i].offset_num_blocks, payload_defs[i].num_blocks);
536 		KUNIT_EXPECT_MEMEQ_MSG(test, readback, payload_data[i], payload_size_bytes,
537 				       "%s @%u num:%u\n",
538 				       cs_dsp_mem_region_name(payload_defs[i].mem_type),
539 				       payload_defs[i].offset_num_blocks,
540 				       payload_defs[i].num_blocks);
541 
542 		kunit_kfree(test, readback);
543 
544 		cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);
545 	}
546 
547 	/* Drop expected writes and the cache should then be clean */
548 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
549 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
550 }
551 
552 /*
553  * Write a series of payloads to various packed and unpacked memory regions.
554  * The payloads are of various lengths and offsets, driven by the
555  * payload_defs table. The offset and length are both given as a
556  * number of minimum-sized register blocks to keep the maths simpler.
557  * (Where a minimum-sized register block is the smallest number of
558  * registers that contain a whole number of DSP words.)
559  */
560 static void wmfw_write_multiple_packed_unpacked_mem(struct kunit *test)
561 {
562 	static const struct {
563 		int mem_type;
564 		unsigned int offset_num_blocks;
565 		unsigned int num_blocks;
566 	} payload_defs[] = {
567 		{ WMFW_HALO_PM_PACKED,	11, 60 },
568 		{ WMFW_ADSP2_YM,	69, 8 },
569 		{ WMFW_HALO_YM_PACKED,	32, 74 },
570 		{ WMFW_HALO_XM_PACKED,	70, 38 },
571 		{ WMFW_HALO_PM_PACKED,	84, 48 },
572 		{ WMFW_HALO_XM_PACKED,	46, 18 },
573 		{ WMFW_HALO_PM_PACKED,	0,  8 },
574 		{ WMFW_HALO_YM_PACKED,	0, 30 },
575 		{ WMFW_HALO_PM_PACKED,	160, 50 },
576 		{ WMFW_ADSP2_XM,	21, 26 },
577 	};
578 	struct cs_dsp_test *priv = test->priv;
579 	struct cs_dsp_test_local *local = priv->local;
580 	struct firmware *wmfw;
581 	unsigned int payload_size_bytes, offset_num_dsp_words;
582 	unsigned int reg_addr, offset_bytes, offset_num_regs;
583 	void **payload_data;
584 	void *readback;
585 	int i, ret;
586 
587 	payload_data = kunit_kcalloc(test, ARRAY_SIZE(payload_defs), sizeof(*payload_data),
588 				     GFP_KERNEL);
589 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);
590 
591 	for (i = 0; i < ARRAY_SIZE(payload_defs); ++i) {
592 		payload_size_bytes = payload_defs[i].num_blocks *
593 				     cs_dsp_mock_reg_block_length_bytes(priv,
594 									payload_defs[i].mem_type);
595 
596 		payload_data[i] = kunit_kmalloc(test, payload_size_bytes, GFP_KERNEL);
597 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data[i]);
598 		get_random_bytes(payload_data[i], payload_size_bytes);
599 
600 		offset_num_dsp_words = payload_defs[i].offset_num_blocks *
601 				       cs_dsp_mock_reg_block_length_dsp_words(priv,
602 									 payload_defs[i].mem_type);
603 		cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
604 						payload_defs[i].mem_type,
605 						offset_num_dsp_words,
606 						payload_data[i],
607 						payload_size_bytes);
608 	}
609 
610 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
611 
612 	KUNIT_EXPECT_EQ(test,
613 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
614 			0);
615 
616 	for (i = 0; i < ARRAY_SIZE(payload_defs); ++i) {
617 		payload_size_bytes = payload_defs[i].num_blocks *
618 				     cs_dsp_mock_reg_block_length_bytes(priv,
619 									payload_defs[i].mem_type);
620 
621 		readback = kunit_kzalloc(test, payload_size_bytes, GFP_KERNEL);
622 		KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
623 
624 		offset_bytes = payload_defs[i].offset_num_blocks *
625 			       cs_dsp_mock_reg_block_length_bytes(priv, payload_defs[i].mem_type);
626 		offset_num_regs = offset_bytes / regmap_get_val_bytes(priv->dsp->regmap);
627 		reg_addr = cs_dsp_mock_base_addr_for_mem(priv, payload_defs[i].mem_type);
628 		reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
629 		ret = regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes);
630 		KUNIT_EXPECT_EQ_MSG(test, ret, 0, "%s @%u num:%u\n",
631 				    cs_dsp_mem_region_name(payload_defs[i].mem_type),
632 				    payload_defs[i].offset_num_blocks,
633 				    payload_defs[i].num_blocks);
634 		KUNIT_EXPECT_MEMEQ_MSG(test, readback, payload_data[i], payload_size_bytes,
635 				       "%s @%u num:%u\n",
636 				       cs_dsp_mem_region_name(payload_defs[i].mem_type),
637 				       payload_defs[i].offset_num_blocks,
638 				       payload_defs[i].num_blocks);
639 
640 		kunit_kfree(test, readback);
641 
642 		cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);
643 	}
644 
645 	/* Drop expected writes and the cache should then be clean */
646 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
647 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
648 }
649 
650 /*
651  * Write XM/YM data that is one word longer than a packed block multiple,
652  * using one packed payload followed by one unpacked word.
653  */
654 static void wmfw_write_packed_1_unpacked_trailing(struct kunit *test)
655 {
656 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
657 	struct cs_dsp_test *priv = test->priv;
658 	struct cs_dsp_test_local *local = priv->local;
659 	int packed_mem_type = param->mem_type;
660 	int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
661 	unsigned int dsp_words_per_packed_block =
662 		cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);
663 	unsigned int dsp_words_per_unpacked_block =
664 		cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);
665 	unsigned int mem_offset_dsp_words = 0;
666 	struct firmware *wmfw;
667 	unsigned int reg_addr;
668 	void *packed_payload_data, *readback;
669 	u32 unpacked_payload_data[1];
670 	unsigned int packed_payload_size_bytes, packed_payload_size_dsp_words;
671 	unsigned int offset_num_regs;
672 
673 	packed_payload_size_bytes = param->num_blocks *
674 				    cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);
675 	packed_payload_size_dsp_words = param->num_blocks * dsp_words_per_packed_block;
676 
677 	packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);
678 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);
679 	get_random_bytes(packed_payload_data, packed_payload_size_bytes);
680 
681 	get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));
682 
683 	readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);
684 
685 	/* Tests on XM must be after the XM header */
686 	if (unpacked_mem_type == WMFW_ADSP2_XM) {
687 		mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);
688 
689 		/* Round up to multiple of packed block length */
690 		mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);
691 	}
692 
693 	/* Add a single packed payload */
694 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
695 					packed_mem_type, mem_offset_dsp_words,
696 					packed_payload_data, packed_payload_size_bytes);
697 	/*
698 	 * Add payload of one unpacked word to DSP memory right after
699 	 * the packed payload words.
700 	 */
701 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
702 					unpacked_mem_type,
703 					mem_offset_dsp_words + packed_payload_size_dsp_words,
704 					unpacked_payload_data, sizeof(unpacked_payload_data));
705 
706 	/* Download the wmfw */
707 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
708 	KUNIT_EXPECT_EQ(test,
709 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
710 			0);
711 
712 	/*
713 	 * Check that the packed payload was written correctly and drop
714 	 * it from the regmap cache.
715 	 */
716 	offset_num_regs = (mem_offset_dsp_words / dsp_words_per_packed_block) *
717 			  cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
718 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
719 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
720 	KUNIT_EXPECT_EQ(test,
721 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
722 					packed_payload_size_bytes),
723 			0);
724 	KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
725 
726 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);
727 
728 	/*
729 	 * Check that the unpacked word was written correctly and drop
730 	 * it from the regmap cache. The unpacked payload is offset within
731 	 * unpacked register space by the number of DSP words that were
732 	 * written in the packed payload.
733 	 */
734 	offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *
735 			  cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
736 	offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *
737 			   cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
738 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
739 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
740 	KUNIT_EXPECT_EQ(test,
741 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
742 					sizeof(unpacked_payload_data)),
743 			0);
744 	KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
745 
746 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));
747 
748 	/* Drop expected writes and the cache should then be clean */
749 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
750 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
751 }
752 
753 /*
754  * Write XM/YM data that is two words longer than a packed block multiple,
755  * using one packed payload followed by one payload of two unpacked words.
756  */
757 static void wmfw_write_packed_2_unpacked_trailing(struct kunit *test)
758 {
759 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
760 	struct cs_dsp_test *priv = test->priv;
761 	struct cs_dsp_test_local *local = priv->local;
762 	int packed_mem_type = param->mem_type;
763 	int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
764 	unsigned int dsp_words_per_packed_block =
765 		cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);
766 	unsigned int dsp_words_per_unpacked_block =
767 		cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);
768 	unsigned int mem_offset_dsp_words = 0;
769 	struct firmware *wmfw;
770 	unsigned int reg_addr;
771 	void *packed_payload_data, *readback;
772 	u32 unpacked_payload_data[2];
773 	unsigned int packed_payload_size_bytes, packed_payload_size_dsp_words;
774 	unsigned int offset_num_regs;
775 
776 	packed_payload_size_bytes = param->num_blocks *
777 				    cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);
778 	packed_payload_size_dsp_words = param->num_blocks * dsp_words_per_packed_block;
779 
780 	packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);
781 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);
782 	get_random_bytes(packed_payload_data, packed_payload_size_bytes);
783 
784 	get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));
785 
786 	readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);
787 
788 	/* Tests on XM must be after the XM header */
789 	if (unpacked_mem_type == WMFW_ADSP2_XM) {
790 		mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);
791 
792 		/* Round up to multiple of packed block length */
793 		mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);
794 	}
795 
796 	/* Add a single packed payload */
797 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
798 					packed_mem_type, mem_offset_dsp_words,
799 					packed_payload_data, packed_payload_size_bytes);
800 	/*
801 	 * Add payload of two unpacked words to DSP memory right after
802 	 * the packed payload words.
803 	 */
804 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
805 					unpacked_mem_type,
806 					mem_offset_dsp_words + packed_payload_size_dsp_words,
807 					unpacked_payload_data, sizeof(unpacked_payload_data));
808 
809 	/* Download the wmfw */
810 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
811 	KUNIT_EXPECT_EQ(test,
812 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
813 			0);
814 
815 	/*
816 	 * Check that the packed payload was written correctly and drop
817 	 * it from the regmap cache.
818 	 */
819 	offset_num_regs = (mem_offset_dsp_words / dsp_words_per_packed_block) *
820 			  cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
821 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
822 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
823 	KUNIT_EXPECT_EQ(test,
824 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
825 					packed_payload_size_bytes),
826 			0);
827 	KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
828 
829 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);
830 
831 	/*
832 	 * Check that the unpacked words were written correctly and drop
833 	 * them from the regmap cache. The unpacked payload is offset
834 	 * within unpacked register space by the number of DSP words
835 	 * that were written in the packed payload.
836 	 */
837 	offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *
838 			  cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
839 	offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *
840 			   cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
841 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
842 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
843 	KUNIT_EXPECT_EQ(test,
844 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
845 					sizeof(unpacked_payload_data)),
846 			0);
847 	KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
848 
849 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));
850 
851 	/* Drop expected writes and the cache should then be clean */
852 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
853 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
854 }
855 
856 /*
857  * Write XM/YM data that is three words longer than a packed block multiple,
858  * using one packed payload followed by one payload of three unpacked words.
859  */
860 static void wmfw_write_packed_3_unpacked_trailing(struct kunit *test)
861 {
862 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
863 	struct cs_dsp_test *priv = test->priv;
864 	struct cs_dsp_test_local *local = priv->local;
865 	int packed_mem_type = param->mem_type;
866 	int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
867 	unsigned int dsp_words_per_packed_block =
868 		cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);
869 	unsigned int dsp_words_per_unpacked_block =
870 		cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);
871 	unsigned int mem_offset_dsp_words = 0;
872 	struct firmware *wmfw;
873 	unsigned int reg_addr;
874 	void *packed_payload_data, *readback;
875 	u32 unpacked_payload_data[3];
876 	unsigned int packed_payload_size_bytes, packed_payload_size_dsp_words;
877 	unsigned int offset_num_regs;
878 
879 	packed_payload_size_bytes = param->num_blocks *
880 				    cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);
881 	packed_payload_size_dsp_words = param->num_blocks * dsp_words_per_packed_block;
882 
883 	packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);
884 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);
885 	get_random_bytes(packed_payload_data, packed_payload_size_bytes);
886 
887 	get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));
888 
889 	readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);
890 
891 	/* Tests on XM must be after the XM header */
892 	if (unpacked_mem_type == WMFW_ADSP2_XM) {
893 		mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);
894 
895 		/* Round up to multiple of packed block length */
896 		mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);
897 	}
898 
899 	/* Add a single packed payload */
900 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
901 					packed_mem_type, mem_offset_dsp_words,
902 					packed_payload_data, packed_payload_size_bytes);
903 	/*
904 	 * Add payload of three unpacked words to DSP memory right after
905 	 * the packed payload words.
906 	 */
907 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
908 					unpacked_mem_type,
909 					mem_offset_dsp_words + packed_payload_size_dsp_words,
910 					unpacked_payload_data, sizeof(unpacked_payload_data));
911 
912 	/* Download the wmfw */
913 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
914 	KUNIT_EXPECT_EQ(test,
915 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
916 			0);
917 
918 	/*
919 	 * Check that the packed payload was written correctly and drop
920 	 * it from the regmap cache.
921 	 */
922 	offset_num_regs = (mem_offset_dsp_words / dsp_words_per_packed_block) *
923 			  cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
924 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
925 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
926 	KUNIT_EXPECT_EQ(test,
927 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
928 					packed_payload_size_bytes),
929 			0);
930 	KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
931 
932 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);
933 
934 	/*
935 	 * Check that the unpacked words were written correctly and drop
936 	 * them from the regmap cache. The unpacked payload is offset
937 	 * within unpacked register space by the number of DSP words
938 	 * that were written in the packed payload.
939 	 */
940 	offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *
941 			  cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
942 	offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *
943 			   cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
944 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
945 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
946 	KUNIT_EXPECT_EQ(test,
947 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
948 					sizeof(unpacked_payload_data)),
949 			0);
950 	KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
951 
952 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));
953 
954 	/* Drop expected writes and the cache should then be clean */
955 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
956 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
957 }
958 
959 /*
960  * Write XM/YM data that is two words longer than a packed block multiple,
961  * using one packed payload followed by two payloads of one unpacked word each.
962  */
963 static void wmfw_write_packed_2_single_unpacked_trailing(struct kunit *test)
964 {
965 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
966 	struct cs_dsp_test *priv = test->priv;
967 	struct cs_dsp_test_local *local = priv->local;
968 	int packed_mem_type = param->mem_type;
969 	int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
970 	unsigned int dsp_words_per_packed_block =
971 		cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);
972 	unsigned int dsp_words_per_unpacked_block =
973 		cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);
974 	unsigned int mem_offset_dsp_words = 0;
975 	struct firmware *wmfw;
976 	unsigned int reg_addr;
977 	void *packed_payload_data, *readback;
978 	u32 unpacked_payload_data[2];
979 	unsigned int packed_payload_size_bytes, packed_payload_size_dsp_words;
980 	unsigned int offset_num_regs;
981 
982 	packed_payload_size_bytes = param->num_blocks *
983 				    cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);
984 	packed_payload_size_dsp_words = param->num_blocks * dsp_words_per_packed_block;
985 
986 	packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);
987 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);
988 	get_random_bytes(packed_payload_data, packed_payload_size_bytes);
989 
990 	get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));
991 
992 	readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);
993 
994 	/* Tests on XM must be after the XM header */
995 	if (unpacked_mem_type == WMFW_ADSP2_XM) {
996 		mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);
997 
998 		/* Round up to multiple of packed block length */
999 		mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);
1000 	}
1001 
1002 	/* Add a single packed payload */
1003 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1004 					packed_mem_type, mem_offset_dsp_words,
1005 					packed_payload_data, packed_payload_size_bytes);
1006 	/*
1007 	 * Add two unpacked words to DSP memory right after the packed
1008 	 * payload words. Each unpacked word in its own payload.
1009 	 */
1010 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1011 					unpacked_mem_type,
1012 					mem_offset_dsp_words + packed_payload_size_dsp_words,
1013 					&unpacked_payload_data[0],
1014 					sizeof(unpacked_payload_data[0]));
1015 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1016 					unpacked_mem_type,
1017 					mem_offset_dsp_words + packed_payload_size_dsp_words + 1,
1018 					&unpacked_payload_data[1],
1019 					sizeof(unpacked_payload_data[1]));
1020 
1021 	/* Download the wmfw */
1022 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1023 	KUNIT_EXPECT_EQ(test,
1024 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
1025 			0);
1026 
1027 	/*
1028 	 * Check that the packed payload was written correctly and drop
1029 	 * it from the regmap cache.
1030 	 */
1031 	offset_num_regs = (mem_offset_dsp_words / dsp_words_per_packed_block) *
1032 			  cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
1033 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
1034 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1035 	KUNIT_EXPECT_EQ(test,
1036 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1037 					packed_payload_size_bytes),
1038 			0);
1039 	KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
1040 
1041 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);
1042 
1043 	/*
1044 	 * Check that the unpacked words were written correctly and drop
1045 	 * them from the regmap cache. The unpacked words are offset
1046 	 * within unpacked register space by the number of DSP words
1047 	 * that were written in the packed payload.
1048 	 */
1049 	offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *
1050 			  cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
1051 	offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *
1052 			   cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
1053 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
1054 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1055 	KUNIT_EXPECT_EQ(test,
1056 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1057 					sizeof(unpacked_payload_data)),
1058 			0);
1059 	KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
1060 
1061 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));
1062 
1063 	/* Drop expected writes and the cache should then be clean */
1064 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1065 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1066 }
1067 
1068 /*
1069  * Write XM/YM data that is three words longer than a packed block multiple,
1070  * using one packed payload followed by three payloads of one unpacked word each.
1071  */
1072 static void wmfw_write_packed_3_single_unpacked_trailing(struct kunit *test)
1073 {
1074 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
1075 	struct cs_dsp_test *priv = test->priv;
1076 	struct cs_dsp_test_local *local = priv->local;
1077 	int packed_mem_type = param->mem_type;
1078 	int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1079 	unsigned int dsp_words_per_packed_block =
1080 		cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);
1081 	unsigned int dsp_words_per_unpacked_block =
1082 		cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);
1083 	unsigned int mem_offset_dsp_words = 0;
1084 	struct firmware *wmfw;
1085 	unsigned int reg_addr;
1086 	void *packed_payload_data, *readback;
1087 	u32 unpacked_payload_data[3];
1088 	unsigned int packed_payload_size_bytes, packed_payload_size_dsp_words;
1089 	unsigned int offset_num_regs;
1090 
1091 	packed_payload_size_bytes = param->num_blocks *
1092 				 cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);
1093 	packed_payload_size_dsp_words = param->num_blocks * dsp_words_per_packed_block;
1094 
1095 	packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);
1096 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);
1097 	get_random_bytes(packed_payload_data, packed_payload_size_bytes);
1098 
1099 	get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));
1100 
1101 	readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);
1102 
1103 	/* Tests on XM must be after the XM header */
1104 	if (unpacked_mem_type == WMFW_ADSP2_XM) {
1105 		mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);
1106 
1107 		/* Round up to multiple of packed block length */
1108 		mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);
1109 	}
1110 
1111 	/* Add a single packed payload */
1112 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1113 					packed_mem_type, mem_offset_dsp_words,
1114 					packed_payload_data, packed_payload_size_bytes);
1115 	/*
1116 	 * Add three unpacked words to DSP memory right after the packed
1117 	 * payload words. Each unpacked word in its own payload.
1118 	 */
1119 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1120 					unpacked_mem_type,
1121 					mem_offset_dsp_words + packed_payload_size_dsp_words,
1122 					&unpacked_payload_data[0],
1123 					sizeof(unpacked_payload_data[0]));
1124 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1125 					unpacked_mem_type,
1126 					mem_offset_dsp_words + packed_payload_size_dsp_words + 1,
1127 					&unpacked_payload_data[1],
1128 					sizeof(unpacked_payload_data[1]));
1129 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1130 					unpacked_mem_type,
1131 					mem_offset_dsp_words + packed_payload_size_dsp_words + 2,
1132 					&unpacked_payload_data[2],
1133 					sizeof(unpacked_payload_data[2]));
1134 
1135 	/* Download the wmfw */
1136 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1137 	KUNIT_EXPECT_EQ(test,
1138 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
1139 			0);
1140 	/*
1141 	 * Check that the packed payload was written correctly and drop
1142 	 * it from the regmap cache.
1143 	 */
1144 	offset_num_regs = (mem_offset_dsp_words / dsp_words_per_packed_block) *
1145 			  cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
1146 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
1147 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1148 	KUNIT_EXPECT_EQ(test,
1149 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1150 					packed_payload_size_bytes),
1151 			0);
1152 	KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
1153 
1154 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);
1155 
1156 	/*
1157 	 * Check that the unpacked words were written correctly and drop
1158 	 * them from the regmap cache. The unpacked words are offset
1159 	 * within unpacked register space by the number of DSP words
1160 	 * that were written in the packed payload.
1161 	 */
1162 	offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *
1163 			  cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
1164 	offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *
1165 			   cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
1166 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
1167 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1168 	KUNIT_EXPECT_EQ(test,
1169 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1170 					sizeof(unpacked_payload_data)),
1171 			0);
1172 	KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
1173 
1174 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));
1175 
1176 	/* Drop expected writes and the cache should then be clean */
1177 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1178 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1179 }
1180 
1181 /*
1182  * Write XM/YM data that is one word longer than a packed block multiple,
1183  * and does not start on a packed alignment. Use one unpacked word
1184  * followed by a packed payload.
1185  */
1186 static void wmfw_write_packed_1_unpacked_leading(struct kunit *test)
1187 {
1188 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
1189 	struct cs_dsp_test *priv = test->priv;
1190 	struct cs_dsp_test_local *local = priv->local;
1191 	int packed_mem_type = param->mem_type;
1192 	int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1193 	unsigned int dsp_words_per_packed_block =
1194 		cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);
1195 	unsigned int dsp_words_per_unpacked_block =
1196 		cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);
1197 	unsigned int packed_payload_offset_dsp_words = 0;
1198 	struct firmware *wmfw;
1199 	unsigned int reg_addr;
1200 	void *packed_payload_data, *readback;
1201 	u32 unpacked_payload_data[1];
1202 	unsigned int packed_payload_size_bytes;
1203 	unsigned int offset_num_regs;
1204 
1205 	packed_payload_size_bytes = param->num_blocks *
1206 				    cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);
1207 
1208 	packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);
1209 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);
1210 	get_random_bytes(packed_payload_data, packed_payload_size_bytes);
1211 
1212 	get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));
1213 
1214 	readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);
1215 
1216 	/* Tests on XM must be after the XM header */
1217 	if (unpacked_mem_type == WMFW_ADSP2_XM)
1218 		packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes /
1219 						   sizeof(u32);
1220 	/*
1221 	 * Leave space for an unaligned word before the packed block and
1222 	 * round the packed block start to multiple of packed block length.
1223 	 */
1224 	packed_payload_offset_dsp_words += 1;
1225 	packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,
1226 						  dsp_words_per_packed_block);
1227 
1228 	/* Add a single unpacked word right before the first word of packed data */
1229 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1230 					unpacked_mem_type,
1231 					packed_payload_offset_dsp_words - 1,
1232 					unpacked_payload_data, sizeof(unpacked_payload_data));
1233 
1234 	/* Add payload of packed data to the DSP memory after the unpacked word. */
1235 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1236 					packed_mem_type,
1237 					packed_payload_offset_dsp_words,
1238 					packed_payload_data, packed_payload_size_bytes);
1239 
1240 	/* Download the wmfw */
1241 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1242 	KUNIT_EXPECT_EQ(test,
1243 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
1244 			0);
1245 	/*
1246 	 * Check that the packed payload was written correctly and drop
1247 	 * it from the regmap cache.
1248 	 */
1249 	offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *
1250 			  cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
1251 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
1252 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1253 	KUNIT_EXPECT_EQ(test,
1254 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1255 					packed_payload_size_bytes),
1256 			0);
1257 	KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
1258 
1259 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);
1260 
1261 	/*
1262 	 * Check that the unpacked word was written correctly and drop
1263 	 * it from the regmap cache.
1264 	 */
1265 	offset_num_regs = ((packed_payload_offset_dsp_words - 1) / dsp_words_per_unpacked_block) *
1266 			  cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
1267 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
1268 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1269 	KUNIT_EXPECT_EQ(test,
1270 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1271 					sizeof(unpacked_payload_data)),
1272 			0);
1273 	KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
1274 
1275 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));
1276 
1277 	/* Drop expected writes and the cache should then be clean */
1278 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1279 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1280 }
1281 
1282 /*
1283  * Write XM/YM data that is two words longer than a packed block multiple,
1284  * and does not start on a packed alignment. Use one payload of two unpacked
1285  * words followed by a packed payload.
1286  */
1287 static void wmfw_write_packed_2_unpacked_leading(struct kunit *test)
1288 {
1289 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
1290 	struct cs_dsp_test *priv = test->priv;
1291 	struct cs_dsp_test_local *local = priv->local;
1292 	int packed_mem_type = param->mem_type;
1293 	int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1294 	unsigned int dsp_words_per_packed_block =
1295 		cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);
1296 	unsigned int dsp_words_per_unpacked_block =
1297 		cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);
1298 	unsigned int packed_payload_offset_dsp_words = 0;
1299 	struct firmware *wmfw;
1300 	unsigned int reg_addr;
1301 	void *packed_payload_data, *readback;
1302 	u32 unpacked_payload_data[2];
1303 	unsigned int packed_payload_size_bytes;
1304 	unsigned int offset_num_regs;
1305 
1306 	packed_payload_size_bytes = param->num_blocks *
1307 				    cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);
1308 
1309 	packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);
1310 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);
1311 	get_random_bytes(packed_payload_data, packed_payload_size_bytes);
1312 
1313 	get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));
1314 
1315 	readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);
1316 
1317 	/* Tests on XM must be after the XM header */
1318 	if (unpacked_mem_type == WMFW_ADSP2_XM)
1319 		packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes /
1320 						   sizeof(u32);
1321 	/*
1322 	 * Leave space for two unaligned words before the packed block and
1323 	 * round the packed block start to multiple of packed block length.
1324 	 */
1325 	packed_payload_offset_dsp_words += 2;
1326 	packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,
1327 						  dsp_words_per_packed_block);
1328 
1329 	/*
1330 	 * Add two unpacked words as a single payload right before the
1331 	 * first word of packed data
1332 	 */
1333 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1334 					unpacked_mem_type,
1335 					packed_payload_offset_dsp_words - 2,
1336 					unpacked_payload_data, sizeof(unpacked_payload_data));
1337 
1338 	/* Add payload of packed data to the DSP memory after the unpacked words. */
1339 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1340 					packed_mem_type,
1341 					packed_payload_offset_dsp_words,
1342 					packed_payload_data, packed_payload_size_bytes);
1343 
1344 	/* Download the wmfw */
1345 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1346 	KUNIT_EXPECT_EQ(test,
1347 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
1348 			0);
1349 	/*
1350 	 * Check that the packed payload was written correctly and drop
1351 	 * it from the regmap cache.
1352 	 */
1353 	offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *
1354 			  cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
1355 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
1356 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1357 	KUNIT_EXPECT_EQ(test,
1358 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1359 					packed_payload_size_bytes),
1360 			0);
1361 	KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
1362 
1363 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);
1364 
1365 	/*
1366 	 * Check that the unpacked words were written correctly and drop
1367 	 * them from the regmap cache.
1368 	 */
1369 	offset_num_regs = ((packed_payload_offset_dsp_words - 2) / dsp_words_per_unpacked_block) *
1370 			  cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
1371 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
1372 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1373 	KUNIT_EXPECT_EQ(test,
1374 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1375 					sizeof(unpacked_payload_data)),
1376 			0);
1377 	KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
1378 
1379 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));
1380 
1381 	/* Drop expected writes and the cache should then be clean */
1382 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1383 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1384 }
1385 
1386 /*
1387  * Write XM/YM data that is three words longer than a packed block multiple,
1388  * and does not start on a packed alignment. Use one payload of three unpacked
1389  * words followed by a packed payload.
1390  */
1391 static void wmfw_write_packed_3_unpacked_leading(struct kunit *test)
1392 {
1393 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
1394 	struct cs_dsp_test *priv = test->priv;
1395 	struct cs_dsp_test_local *local = priv->local;
1396 	int packed_mem_type = param->mem_type;
1397 	int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1398 	unsigned int dsp_words_per_packed_block =
1399 		cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);
1400 	unsigned int dsp_words_per_unpacked_block =
1401 		cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);
1402 	unsigned int packed_payload_offset_dsp_words = 0;
1403 	struct firmware *wmfw;
1404 	unsigned int reg_addr;
1405 	void *packed_payload_data, *readback;
1406 	u32 unpacked_payload_data[3];
1407 	unsigned int packed_payload_size_bytes;
1408 	unsigned int offset_num_regs;
1409 
1410 	packed_payload_size_bytes = param->num_blocks *
1411 				    cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);
1412 
1413 	packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);
1414 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);
1415 	get_random_bytes(packed_payload_data, packed_payload_size_bytes);
1416 
1417 	get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));
1418 
1419 	readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);
1420 
1421 	/* Tests on XM must be after the XM header */
1422 	if (unpacked_mem_type == WMFW_ADSP2_XM)
1423 		packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes /
1424 						   sizeof(u32);
1425 	/*
1426 	 * Leave space for three unaligned words before the packed block and
1427 	 * round the packed block start to multiple of packed block length.
1428 	 */
1429 	packed_payload_offset_dsp_words += 3;
1430 	packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,
1431 						  dsp_words_per_packed_block);
1432 
1433 	/*
1434 	 * Add three unpacked words as a single payload right before the
1435 	 * first word of packed data
1436 	 */
1437 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1438 					unpacked_mem_type,
1439 					packed_payload_offset_dsp_words - 3,
1440 					unpacked_payload_data, sizeof(unpacked_payload_data));
1441 
1442 	/* Add payload of packed data to the DSP memory after the unpacked words. */
1443 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1444 					packed_mem_type,
1445 					packed_payload_offset_dsp_words,
1446 					packed_payload_data, packed_payload_size_bytes);
1447 
1448 	/* Download the wmfw */
1449 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1450 	KUNIT_EXPECT_EQ(test,
1451 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
1452 			0);
1453 	/*
1454 	 * Check that the packed payload was written correctly and drop
1455 	 * it from the regmap cache.
1456 	 */
1457 	offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *
1458 			  cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
1459 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
1460 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1461 	KUNIT_EXPECT_EQ(test,
1462 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1463 					packed_payload_size_bytes),
1464 			0);
1465 	KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
1466 
1467 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);
1468 
1469 	/*
1470 	 * Check that the unpacked words were written correctly and drop
1471 	 * them from the regmap cache.
1472 	 */
1473 	offset_num_regs = ((packed_payload_offset_dsp_words - 3) / dsp_words_per_unpacked_block) *
1474 			  cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
1475 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
1476 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1477 	KUNIT_EXPECT_EQ(test,
1478 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1479 					sizeof(unpacked_payload_data)),
1480 			0);
1481 	KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
1482 
1483 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));
1484 
1485 	/* Drop expected writes and the cache should then be clean */
1486 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1487 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1488 }
1489 
1490 /*
1491  * Write XM/YM data that is two words longer than a packed block multiple,
1492  * and does not start on a packed alignment. Use two payloads of one unpacked
1493  * word each, followed by a packed payload.
1494  */
1495 static void wmfw_write_packed_2_single_unpacked_leading(struct kunit *test)
1496 {
1497 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
1498 	struct cs_dsp_test *priv = test->priv;
1499 	struct cs_dsp_test_local *local = priv->local;
1500 	int packed_mem_type = param->mem_type;
1501 	int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1502 	unsigned int dsp_words_per_packed_block =
1503 		cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);
1504 	unsigned int dsp_words_per_unpacked_block =
1505 		cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);
1506 	unsigned int packed_payload_offset_dsp_words = 0;
1507 	struct firmware *wmfw;
1508 	unsigned int reg_addr;
1509 	void *packed_payload_data, *readback;
1510 	u32 unpacked_payload_data[2];
1511 	unsigned int packed_payload_size_bytes;
1512 	unsigned int offset_num_regs;
1513 
1514 	packed_payload_size_bytes = param->num_blocks *
1515 				    cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);
1516 
1517 	packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);
1518 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);
1519 	get_random_bytes(packed_payload_data, packed_payload_size_bytes);
1520 
1521 	get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));
1522 
1523 	readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);
1524 
1525 	/* Tests on XM must be after the XM header */
1526 	if (unpacked_mem_type == WMFW_ADSP2_XM)
1527 		packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes /
1528 						   sizeof(u32);
1529 	/*
1530 	 * Leave space for two unaligned words before the packed block and
1531 	 * round the packed block start to multiple of packed block length.
1532 	 */
1533 	packed_payload_offset_dsp_words += 2;
1534 	packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,
1535 						  dsp_words_per_packed_block);
1536 
1537 	/*
1538 	 * Add two unpacked words as two payloads each containing a single
1539 	 * unpacked word.
1540 	 */
1541 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1542 					unpacked_mem_type,
1543 					packed_payload_offset_dsp_words - 2,
1544 					&unpacked_payload_data[0],
1545 					sizeof(unpacked_payload_data[0]));
1546 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1547 					unpacked_mem_type,
1548 					packed_payload_offset_dsp_words - 1,
1549 					&unpacked_payload_data[1],
1550 					sizeof(unpacked_payload_data[1]));
1551 
1552 	/* Add payload of packed data to the DSP memory after the unpacked words. */
1553 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1554 					packed_mem_type,
1555 					packed_payload_offset_dsp_words,
1556 					packed_payload_data, packed_payload_size_bytes);
1557 
1558 	/* Download the wmfw */
1559 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1560 	KUNIT_EXPECT_EQ(test,
1561 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
1562 			0);
1563 	/*
1564 	 * Check that the packed payload was written correctly and drop
1565 	 * it from the regmap cache.
1566 	 */
1567 	offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *
1568 			  cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
1569 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
1570 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1571 	KUNIT_EXPECT_EQ(test,
1572 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1573 					packed_payload_size_bytes),
1574 			0);
1575 	KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
1576 
1577 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);
1578 
1579 	/*
1580 	 * Check that the unpacked words were written correctly and drop
1581 	 * them from the regmap cache.
1582 	 */
1583 	offset_num_regs = ((packed_payload_offset_dsp_words - 2) / dsp_words_per_unpacked_block) *
1584 			  cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
1585 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
1586 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1587 	KUNIT_EXPECT_EQ(test,
1588 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1589 					sizeof(unpacked_payload_data)),
1590 			0);
1591 	KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
1592 
1593 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));
1594 
1595 	/* Drop expected writes and the cache should then be clean */
1596 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1597 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1598 }
1599 
1600 /*
1601  * Write XM/YM data that is three words longer than a packed block multiple,
1602  * and does not start on a packed alignment. Use three payloads of one unpacked
1603  * word each, followed by a packed payload.
1604  */
1605 static void wmfw_write_packed_3_single_unpacked_leading(struct kunit *test)
1606 {
1607 	const struct cs_dsp_wmfw_test_param *param = test->param_value;
1608 	struct cs_dsp_test *priv = test->priv;
1609 	struct cs_dsp_test_local *local = priv->local;
1610 	int packed_mem_type = param->mem_type;
1611 	int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1612 	unsigned int dsp_words_per_packed_block =
1613 		cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);
1614 	unsigned int dsp_words_per_unpacked_block =
1615 		cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);
1616 	unsigned int packed_payload_offset_dsp_words = 0;
1617 	struct firmware *wmfw;
1618 	unsigned int reg_addr;
1619 	void *packed_payload_data, *readback;
1620 	u32 unpacked_payload_data[3];
1621 	unsigned int packed_payload_size_bytes;
1622 	unsigned int offset_num_regs;
1623 
1624 	packed_payload_size_bytes = param->num_blocks *
1625 				    cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);
1626 
1627 	packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);
1628 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);
1629 	get_random_bytes(packed_payload_data, packed_payload_size_bytes);
1630 
1631 	get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));
1632 
1633 	readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);
1634 
1635 	/* Tests on XM must be after the XM header */
1636 	if (unpacked_mem_type == WMFW_ADSP2_XM)
1637 		packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes /
1638 						   sizeof(u32);
1639 	/*
1640 	 * Leave space for two unaligned words before the packed block and
1641 	 * round the packed block start to multiple of packed block length.
1642 	 */
1643 	packed_payload_offset_dsp_words += 3;
1644 	packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,
1645 						  dsp_words_per_packed_block);
1646 
1647 	/*
1648 	 * Add three unpacked words as three payloads each containing a single
1649 	 * unpacked word.
1650 	 */
1651 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1652 					unpacked_mem_type,
1653 					packed_payload_offset_dsp_words - 3,
1654 					&unpacked_payload_data[0],
1655 					sizeof(unpacked_payload_data[0]));
1656 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1657 					unpacked_mem_type,
1658 					packed_payload_offset_dsp_words - 2,
1659 					&unpacked_payload_data[1],
1660 					sizeof(unpacked_payload_data[1]));
1661 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1662 					unpacked_mem_type,
1663 					packed_payload_offset_dsp_words - 1,
1664 					&unpacked_payload_data[2],
1665 					sizeof(unpacked_payload_data[2]));
1666 
1667 	/* Add payload of packed data to the DSP memory after the unpacked words. */
1668 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1669 					packed_mem_type,
1670 					packed_payload_offset_dsp_words,
1671 					packed_payload_data, packed_payload_size_bytes);
1672 
1673 	/* Download the wmfw */
1674 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1675 	KUNIT_EXPECT_EQ(test,
1676 			cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
1677 			0);
1678 	/*
1679 	 * Check that the packed payload was written correctly and drop
1680 	 * it from the regmap cache.
1681 	 */
1682 	offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *
1683 			  cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
1684 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
1685 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1686 	KUNIT_EXPECT_EQ(test,
1687 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1688 					packed_payload_size_bytes),
1689 			0);
1690 	KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
1691 
1692 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);
1693 
1694 	/*
1695 	 * Check that the unpacked words were written correctly and drop
1696 	 * them from the regmap cache.
1697 	 */
1698 	offset_num_regs = ((packed_payload_offset_dsp_words - 3) / dsp_words_per_unpacked_block) *
1699 			  cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
1700 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
1701 	reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
1702 	KUNIT_EXPECT_EQ(test,
1703 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1704 					sizeof(unpacked_payload_data)),
1705 			0);
1706 	KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
1707 
1708 	cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));
1709 
1710 	/* Drop expected writes and the cache should then be clean */
1711 	cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1712 	KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1713 }
1714 
1715 /* Load a wmfw containing multiple info blocks */
1716 static void wmfw_load_with_info(struct kunit *test)
1717 {
1718 	struct cs_dsp_test *priv = test->priv;
1719 	struct cs_dsp_test_local *local = priv->local;
1720 	struct firmware *wmfw;
1721 	unsigned int reg_addr;
1722 	u8 *payload_data, *readback;
1723 	char *infobuf;
1724 	const unsigned int payload_size_bytes = 48;
1725 	int ret;
1726 
1727 	payload_data = kunit_kmalloc(test, payload_size_bytes, GFP_KERNEL);
1728 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);
1729 	get_random_bytes(payload_data, payload_size_bytes);
1730 
1731 	readback = kunit_kzalloc(test, payload_size_bytes, GFP_KERNEL);
1732 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);
1733 
1734 	/* Add a couple of info blocks at the start of the wmfw */
1735 	cs_dsp_mock_wmfw_add_info(local->wmfw_builder, "This is a timestamp");
1736 	cs_dsp_mock_wmfw_add_info(local->wmfw_builder, "This is some more info");
1737 
1738 	/* Add a single payload */
1739 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1740 					WMFW_ADSP2_YM, 0,
1741 					payload_data, payload_size_bytes);
1742 
1743 	/* Add a bigger info block then another small one*/
1744 	infobuf = kunit_kzalloc(test, 512, GFP_KERNEL);
1745 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, infobuf);
1746 
1747 	for (; strlcat(infobuf, "Waffle{Blah}\n", 512) < 512;)
1748 		;
1749 
1750 	cs_dsp_mock_wmfw_add_info(local->wmfw_builder, infobuf);
1751 	cs_dsp_mock_wmfw_add_info(local->wmfw_builder, "Another block of info");
1752 
1753 	/* Add another payload */
1754 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1755 					WMFW_ADSP2_YM, 64,
1756 					payload_data, payload_size_bytes);
1757 
1758 	wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
1759 
1760 	ret = cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc");
1761 	KUNIT_EXPECT_EQ_MSG(test, ret, 0, "cs_dsp_power_up failed: %d\n", ret);
1762 
1763 	/* Check first payload was written */
1764 	reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_YM);
1765 	KUNIT_EXPECT_EQ(test,
1766 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes),
1767 			0);
1768 	KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);
1769 
1770 	/* Check second payload was written */
1771 	reg_addr += cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv) * 64;
1772 	KUNIT_EXPECT_EQ(test,
1773 			regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes),
1774 			0);
1775 	KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);
1776 }
1777 
1778 static int cs_dsp_wmfw_test_common_init(struct kunit *test, struct cs_dsp *dsp,
1779 					int wmfw_version)
1780 {
1781 	struct cs_dsp_test *priv;
1782 	struct cs_dsp_test_local *local;
1783 	struct device *test_dev;
1784 	int ret;
1785 
1786 	priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
1787 	if (!priv)
1788 		return -ENOMEM;
1789 
1790 	local = kunit_kzalloc(test, sizeof(struct cs_dsp_test_local), GFP_KERNEL);
1791 	if (!local)
1792 		return -ENOMEM;
1793 
1794 	priv->test = test;
1795 	priv->dsp = dsp;
1796 	test->priv = priv;
1797 	priv->local = local;
1798 	priv->local->wmfw_version = wmfw_version;
1799 
1800 	/* Create dummy struct device */
1801 	test_dev = kunit_device_register(test, "cs_dsp_test_drv");
1802 	if (IS_ERR(test_dev))
1803 		return PTR_ERR(test_dev);
1804 
1805 	dsp->dev = get_device(test_dev);
1806 	if (!dsp->dev)
1807 		return -ENODEV;
1808 
1809 	ret = kunit_add_action_or_reset(test, _put_device_wrapper, dsp->dev);
1810 	if (ret)
1811 		return ret;
1812 
1813 	dev_set_drvdata(dsp->dev, priv);
1814 
1815 	/* Allocate regmap */
1816 	ret = cs_dsp_mock_regmap_init(priv);
1817 	if (ret)
1818 		return ret;
1819 
1820 	/*
1821 	 * There must always be a XM header with at least 1 algorithm, so create
1822 	 * a dummy one that tests can use and extract it to a data payload.
1823 	 */
1824 	local->xm_header = cs_dsp_create_mock_xm_header(priv,
1825 							cs_dsp_wmfw_test_mock_algs,
1826 							ARRAY_SIZE(cs_dsp_wmfw_test_mock_algs));
1827 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->xm_header);
1828 
1829 	local->wmfw_builder = cs_dsp_mock_wmfw_init(priv, priv->local->wmfw_version);
1830 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->wmfw_builder);
1831 
1832 	/* Add dummy XM header payload to wmfw */
1833 	cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
1834 					WMFW_ADSP2_XM, 0,
1835 					local->xm_header->blob_data,
1836 					local->xm_header->blob_size_bytes);
1837 
1838 	/* Init cs_dsp */
1839 	dsp->client_ops = kunit_kzalloc(test, sizeof(*dsp->client_ops), GFP_KERNEL);
1840 	KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dsp->client_ops);
1841 
1842 	switch (dsp->type) {
1843 	case WMFW_ADSP2:
1844 		ret = cs_dsp_adsp2_init(dsp);
1845 		break;
1846 	case WMFW_HALO:
1847 		ret = cs_dsp_halo_init(dsp);
1848 		break;
1849 	default:
1850 		KUNIT_FAIL(test, "Untested DSP type %d\n", dsp->type);
1851 		return -EINVAL;
1852 	}
1853 
1854 	if (ret)
1855 		return ret;
1856 
1857 	/* Automatically call cs_dsp_remove() when test case ends */
1858 	ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
1859 	if (ret)
1860 		return ret;
1861 
1862 	/*
1863 	 * The large number of test cases will cause an unusually large amount
1864 	 * of dev_info() messages from cs_dsp, so suppress these.
1865 	 */
1866 	cs_dsp_suppress_info_messages = true;
1867 
1868 	return 0;
1869 }
1870 
1871 static void cs_dsp_wmfw_test_exit(struct kunit *test)
1872 {
1873 	cs_dsp_suppress_info_messages = false;
1874 }
1875 
1876 static int cs_dsp_wmfw_test_halo_init(struct kunit *test)
1877 {
1878 	struct cs_dsp *dsp;
1879 
1880 	/* Fill in cs_dsp and initialize */
1881 	dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
1882 	if (!dsp)
1883 		return -ENOMEM;
1884 
1885 	dsp->num = 1;
1886 	dsp->type = WMFW_HALO;
1887 	dsp->mem = cs_dsp_mock_halo_dsp1_regions;
1888 	dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_halo_dsp1_region_sizes);
1889 	dsp->base = cs_dsp_mock_halo_core_base;
1890 	dsp->base_sysinfo = cs_dsp_mock_halo_sysinfo_base;
1891 
1892 	return cs_dsp_wmfw_test_common_init(test, dsp, 3);
1893 }
1894 
1895 static int cs_dsp_wmfw_test_adsp2_32bit_init(struct kunit *test, int wmfw_ver)
1896 {
1897 	struct cs_dsp *dsp;
1898 
1899 	/* Fill in cs_dsp and initialize */
1900 	dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
1901 	if (!dsp)
1902 		return -ENOMEM;
1903 
1904 	dsp->num = 1;
1905 	dsp->type = WMFW_ADSP2;
1906 	dsp->rev = 1;
1907 	dsp->mem = cs_dsp_mock_adsp2_32bit_dsp1_regions;
1908 	dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_32bit_dsp1_region_sizes);
1909 	dsp->base = cs_dsp_mock_adsp2_32bit_sysbase;
1910 
1911 	return cs_dsp_wmfw_test_common_init(test, dsp, wmfw_ver);
1912 }
1913 
1914 static int cs_dsp_wmfw_test_adsp2_32bit_wmfw0_init(struct kunit *test)
1915 {
1916 	return cs_dsp_wmfw_test_adsp2_32bit_init(test, 0);
1917 }
1918 
1919 static int cs_dsp_wmfw_test_adsp2_32bit_wmfw1_init(struct kunit *test)
1920 {
1921 	return cs_dsp_wmfw_test_adsp2_32bit_init(test, 1);
1922 }
1923 
1924 static int cs_dsp_wmfw_test_adsp2_32bit_wmfw2_init(struct kunit *test)
1925 {
1926 	return cs_dsp_wmfw_test_adsp2_32bit_init(test, 2);
1927 }
1928 
1929 static int cs_dsp_wmfw_test_adsp2_16bit_init(struct kunit *test, int wmfw_ver)
1930 {
1931 	struct cs_dsp *dsp;
1932 
1933 	/* Fill in cs_dsp and initialize */
1934 	dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
1935 	if (!dsp)
1936 		return -ENOMEM;
1937 
1938 	dsp->num = 1;
1939 	dsp->type = WMFW_ADSP2;
1940 	dsp->rev = 0;
1941 	dsp->mem = cs_dsp_mock_adsp2_16bit_dsp1_regions;
1942 	dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_16bit_dsp1_region_sizes);
1943 	dsp->base = cs_dsp_mock_adsp2_16bit_sysbase;
1944 
1945 	return cs_dsp_wmfw_test_common_init(test, dsp, wmfw_ver);
1946 }
1947 
1948 static int cs_dsp_wmfw_test_adsp2_16bit_wmfw0_init(struct kunit *test)
1949 {
1950 	return cs_dsp_wmfw_test_adsp2_16bit_init(test, 0);
1951 }
1952 
1953 static int cs_dsp_wmfw_test_adsp2_16bit_wmfw1_init(struct kunit *test)
1954 {
1955 	return cs_dsp_wmfw_test_adsp2_16bit_init(test, 1);
1956 }
1957 
1958 static int cs_dsp_wmfw_test_adsp2_16bit_wmfw2_init(struct kunit *test)
1959 {
1960 	return cs_dsp_wmfw_test_adsp2_16bit_init(test, 2);
1961 }
1962 
1963 static void cs_dsp_mem_param_desc(const struct cs_dsp_wmfw_test_param *param, char *desc)
1964 {
1965 	snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s num_blocks:%u",
1966 		 cs_dsp_mem_region_name(param->mem_type),
1967 		 param->num_blocks);
1968 }
1969 
1970 static const struct cs_dsp_wmfw_test_param adsp2_all_num_blocks_param_cases[] = {
1971 	{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 1 },
1972 	{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 2 },
1973 	{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 3 },
1974 	{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 4 },
1975 	{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 5 },
1976 	{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 6 },
1977 	{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 12 },
1978 	{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 13 },
1979 	{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 14 },
1980 	{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 15 },
1981 	{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 16 },
1982 
1983 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 1 },
1984 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 2 },
1985 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 3 },
1986 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 4 },
1987 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 5 },
1988 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 6 },
1989 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 12 },
1990 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 13 },
1991 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 14 },
1992 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 15 },
1993 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 16 },
1994 
1995 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 1 },
1996 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 2 },
1997 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 3 },
1998 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 4 },
1999 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 5 },
2000 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 6 },
2001 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 12 },
2002 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 13 },
2003 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 14 },
2004 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 15 },
2005 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 16 },
2006 
2007 	{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 1 },
2008 	{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 2 },
2009 	{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 3 },
2010 	{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 4 },
2011 	{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 5 },
2012 	{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 6 },
2013 	{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 12 },
2014 	{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 13 },
2015 	{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 14 },
2016 	{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 15 },
2017 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 16 },
2018 };
2019 
2020 KUNIT_ARRAY_PARAM(adsp2_all_num_blocks,
2021 		  adsp2_all_num_blocks_param_cases,
2022 		  cs_dsp_mem_param_desc);
2023 
2024 static const struct cs_dsp_wmfw_test_param halo_all_num_blocks_param_cases[] = {
2025 	{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 1 },
2026 	{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 2 },
2027 	{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 3 },
2028 	{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 4 },
2029 	{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 5 },
2030 	{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 6 },
2031 	{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 12 },
2032 	{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 13 },
2033 	{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 14 },
2034 	{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 15 },
2035 	{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 16 },
2036 
2037 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 1 },
2038 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 2 },
2039 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 3 },
2040 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 4 },
2041 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 5 },
2042 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 6 },
2043 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 12 },
2044 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 13 },
2045 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 14 },
2046 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 15 },
2047 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 16 },
2048 
2049 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 1 },
2050 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 2 },
2051 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 3 },
2052 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 4 },
2053 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 5 },
2054 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 6 },
2055 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 12 },
2056 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 13 },
2057 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 14 },
2058 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 15 },
2059 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 16 },
2060 
2061 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 1 },
2062 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 2 },
2063 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 3 },
2064 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 4 },
2065 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 5 },
2066 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 6 },
2067 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 12 },
2068 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 13 },
2069 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 14 },
2070 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 15 },
2071 	{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 16 },
2072 
2073 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 1 },
2074 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 2 },
2075 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 3 },
2076 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 4 },
2077 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 5 },
2078 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 6 },
2079 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 12 },
2080 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 13 },
2081 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 14 },
2082 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 15 },
2083 	{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 16 },
2084 };
2085 
2086 KUNIT_ARRAY_PARAM(halo_all_num_blocks,
2087 		  halo_all_num_blocks_param_cases,
2088 		  cs_dsp_mem_param_desc);
2089 
2090 static const struct cs_dsp_wmfw_test_param packed_xy_num_blocks_param_cases[] = {
2091 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 1 },
2092 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 2 },
2093 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 3 },
2094 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 4 },
2095 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 5 },
2096 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 6 },
2097 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 12 },
2098 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 13 },
2099 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 14 },
2100 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 15 },
2101 	{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 16 },
2102 
2103 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 1 },
2104 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 2 },
2105 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 3 },
2106 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 4 },
2107 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 5 },
2108 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 6 },
2109 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 12 },
2110 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 13 },
2111 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 14 },
2112 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 15 },
2113 	{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 16 },
2114 };
2115 
2116 KUNIT_ARRAY_PARAM(packed_xy_num_blocks,
2117 		  packed_xy_num_blocks_param_cases,
2118 		  cs_dsp_mem_param_desc);
2119 
2120 static struct kunit_case cs_dsp_wmfw_test_cases_halo[] = {
2121 	KUNIT_CASE(wmfw_write_xm_header_unpacked),
2122 
2123 	KUNIT_CASE_PARAM(wmfw_write_one_payload,
2124 			 halo_all_num_blocks_gen_params),
2125 	KUNIT_CASE_PARAM(wmfw_write_multiple_oneblock_payloads,
2126 			 halo_all_num_blocks_gen_params),
2127 	KUNIT_CASE_PARAM(wmfw_write_multiple_oneblock_payloads_reverse,
2128 			 halo_all_num_blocks_gen_params),
2129 	KUNIT_CASE_PARAM(wmfw_write_multiple_payloads_sparse_unordered,
2130 			 halo_all_num_blocks_gen_params),
2131 
2132 	KUNIT_CASE(wmfw_write_all_packed_pm),
2133 	KUNIT_CASE(wmfw_write_multiple_packed_unpacked_mem),
2134 
2135 	KUNIT_CASE_PARAM(wmfw_write_packed_1_unpacked_trailing,
2136 			 packed_xy_num_blocks_gen_params),
2137 	KUNIT_CASE_PARAM(wmfw_write_packed_2_unpacked_trailing,
2138 			 packed_xy_num_blocks_gen_params),
2139 	KUNIT_CASE_PARAM(wmfw_write_packed_3_unpacked_trailing,
2140 			 packed_xy_num_blocks_gen_params),
2141 	KUNIT_CASE_PARAM(wmfw_write_packed_2_single_unpacked_trailing,
2142 			 packed_xy_num_blocks_gen_params),
2143 	KUNIT_CASE_PARAM(wmfw_write_packed_3_single_unpacked_trailing,
2144 			 packed_xy_num_blocks_gen_params),
2145 	KUNIT_CASE_PARAM(wmfw_write_packed_1_unpacked_leading,
2146 			 packed_xy_num_blocks_gen_params),
2147 	KUNIT_CASE_PARAM(wmfw_write_packed_2_unpacked_leading,
2148 			 packed_xy_num_blocks_gen_params),
2149 	KUNIT_CASE_PARAM(wmfw_write_packed_3_unpacked_leading,
2150 			 packed_xy_num_blocks_gen_params),
2151 	KUNIT_CASE_PARAM(wmfw_write_packed_2_single_unpacked_leading,
2152 			 packed_xy_num_blocks_gen_params),
2153 	KUNIT_CASE_PARAM(wmfw_write_packed_3_single_unpacked_leading,
2154 			 packed_xy_num_blocks_gen_params),
2155 
2156 	KUNIT_CASE(wmfw_load_with_info),
2157 
2158 	{ } /* terminator */
2159 };
2160 
2161 static struct kunit_case cs_dsp_wmfw_test_cases_adsp2[] = {
2162 	KUNIT_CASE(wmfw_write_xm_header_unpacked),
2163 	KUNIT_CASE_PARAM(wmfw_write_one_payload,
2164 			 adsp2_all_num_blocks_gen_params),
2165 	KUNIT_CASE_PARAM(wmfw_write_multiple_oneblock_payloads,
2166 			 adsp2_all_num_blocks_gen_params),
2167 	KUNIT_CASE_PARAM(wmfw_write_multiple_oneblock_payloads_reverse,
2168 			 adsp2_all_num_blocks_gen_params),
2169 	KUNIT_CASE_PARAM(wmfw_write_multiple_payloads_sparse_unordered,
2170 			 adsp2_all_num_blocks_gen_params),
2171 
2172 	KUNIT_CASE(wmfw_write_all_unpacked_pm),
2173 	KUNIT_CASE(wmfw_write_multiple_unpacked_mem),
2174 
2175 	KUNIT_CASE(wmfw_load_with_info),
2176 
2177 	{ } /* terminator */
2178 };
2179 
2180 static struct kunit_suite cs_dsp_wmfw_test_halo = {
2181 	.name = "cs_dsp_wmfwV3_halo",
2182 	.init = cs_dsp_wmfw_test_halo_init,
2183 	.exit = cs_dsp_wmfw_test_exit,
2184 	.test_cases = cs_dsp_wmfw_test_cases_halo,
2185 };
2186 
2187 static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw0 = {
2188 	.name = "cs_dsp_wmfwV0_adsp2_32bit",
2189 	.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw0_init,
2190 	.exit = cs_dsp_wmfw_test_exit,
2191 	.test_cases = cs_dsp_wmfw_test_cases_adsp2,
2192 };
2193 
2194 static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw1 = {
2195 	.name = "cs_dsp_wmfwV1_adsp2_32bit",
2196 	.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw1_init,
2197 	.exit = cs_dsp_wmfw_test_exit,
2198 	.test_cases = cs_dsp_wmfw_test_cases_adsp2,
2199 };
2200 
2201 static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw2 = {
2202 	.name = "cs_dsp_wmfwV2_adsp2_32bit",
2203 	.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw2_init,
2204 	.exit = cs_dsp_wmfw_test_exit,
2205 	.test_cases = cs_dsp_wmfw_test_cases_adsp2,
2206 };
2207 
2208 static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw0 = {
2209 	.name = "cs_dsp_wmfwV0_adsp2_16bit",
2210 	.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw0_init,
2211 	.exit = cs_dsp_wmfw_test_exit,
2212 	.test_cases = cs_dsp_wmfw_test_cases_adsp2,
2213 };
2214 
2215 static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw1 = {
2216 	.name = "cs_dsp_wmfwV1_adsp2_16bit",
2217 	.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw1_init,
2218 	.exit = cs_dsp_wmfw_test_exit,
2219 	.test_cases = cs_dsp_wmfw_test_cases_adsp2,
2220 };
2221 
2222 static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw2 = {
2223 	.name = "cs_dsp_wmfwV2_adsp2_16bit",
2224 	.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw2_init,
2225 	.exit = cs_dsp_wmfw_test_exit,
2226 	.test_cases = cs_dsp_wmfw_test_cases_adsp2,
2227 };
2228 
2229 kunit_test_suites(&cs_dsp_wmfw_test_halo,
2230 		  &cs_dsp_wmfw_test_adsp2_32bit_wmfw0,
2231 		  &cs_dsp_wmfw_test_adsp2_32bit_wmfw1,
2232 		  &cs_dsp_wmfw_test_adsp2_32bit_wmfw2,
2233 		  &cs_dsp_wmfw_test_adsp2_16bit_wmfw0,
2234 		  &cs_dsp_wmfw_test_adsp2_16bit_wmfw1,
2235 		  &cs_dsp_wmfw_test_adsp2_16bit_wmfw2);
2236