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