1 // SPDX-License-Identifier: GPL-2.0-only
2 //
3 // KUnit tests for cs_dsp.
4 //
5 // Copyright (C) 2024 Cirrus Logic, Inc. and
6 // Cirrus Logic International Semiconductor Ltd.
7
8 #include <kunit/device.h>
9 #include <kunit/resource.h>
10 #include <kunit/test.h>
11 #include <linux/build_bug.h>
12 #include <linux/firmware/cirrus/cs_dsp.h>
13 #include <linux/firmware/cirrus/cs_dsp_test_utils.h>
14 #include <linux/firmware/cirrus/wmfw.h>
15 #include <linux/firmware.h>
16 #include <linux/math.h>
17 #include <linux/random.h>
18 #include <linux/regmap.h>
19
20 #include "../cs_dsp.h"
21
22 /*
23 * Test method is:
24 *
25 * 1) Create a mock regmap in cache-only mode so that all writes will be cached.
26 * 2) Create a XM header with an algorithm list in the cached regmap.
27 * 3) Create dummy wmfw file to satisfy cs_dsp.
28 * 4) Create bin file content.
29 * 5) Call cs_dsp_power_up() with the bin file.
30 * 6) Readback the cached value of registers that should have been written and
31 * check they have the correct value.
32 * 7) All the registers that are expected to have been written are dropped from
33 * the cache (including the XM header). This should leave the cache clean.
34 * 8) If the cache is still dirty there have been unexpected writes.
35 *
36 * There are multiple different schemes used for addressing across
37 * ADSP2 and Halo Core DSPs:
38 *
39 * dsp words: The addressing scheme used by the DSP, pointers and lengths
40 * in DSP memory use this. A memory region (XM, YM, ZM) is
41 * also required to create a unique DSP memory address.
42 * registers: Addresses in the register map. Older ADSP2 devices have
43 * 16-bit registers with an address stride of 1. Newer ADSP2
44 * devices have 32-bit registers with an address stride of 2.
45 * Halo Core devices have 32-bit registers with a stride of 4.
46 * unpacked: Registers that have a 1:1 mapping to DSP words
47 * packed: Registers that pack multiple DSP words more efficiently into
48 * multiple 32-bit registers. Because of this the relationship
49 * between a packed _register_ address and the corresponding
50 * _dsp word_ address is different from unpacked registers.
51 * Packed registers can only be accessed as a group of
52 * multiple registers, therefore can only read/write a group
53 * of multiple DSP words.
54 * Packed registers only exist on Halo Core DSPs.
55 *
56 * Addresses can also be relative to the start of an algorithm, and this
57 * can be expressed in dsp words, register addresses, or bytes.
58 */
59
60 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *)
61 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *)
62
63 struct cs_dsp_test_local {
64 struct cs_dsp_mock_bin_builder *bin_builder;
65 struct cs_dsp_mock_wmfw_builder *wmfw_builder;
66 struct firmware *wmfw;
67 };
68
69 struct bin_test_param {
70 const char *name;
71 int mem_type;
72 unsigned int offset_words;
73 int alg_idx;
74 void (*add_patch)(struct cs_dsp_mock_bin_builder *builder,
75 unsigned int alg_id, unsigned int alg_ver,
76 int mem_region, unsigned int reg_addr_offset,
77 const void *payload_data, size_t payload_len_bytes);
78 };
79
80 static const struct cs_dsp_mock_alg_def bin_test_mock_algs[] = {
81 {
82 .id = 0xfafa,
83 .ver = 0x100000,
84 .xm_size_words = 164,
85 .ym_size_words = 164,
86 .zm_size_words = 164,
87 },
88 {
89 .id = 0xfbfb,
90 .ver = 0x100000,
91 .xm_size_words = 99,
92 .ym_size_words = 99,
93 .zm_size_words = 99,
94 },
95 {
96 .id = 0xc321,
97 .ver = 0x100000,
98 .xm_size_words = 120,
99 .ym_size_words = 120,
100 .zm_size_words = 120,
101 },
102 {
103 .id = 0xb123,
104 .ver = 0x100000,
105 .xm_size_words = 96,
106 .ym_size_words = 96,
107 .zm_size_words = 96,
108 },
109 };
110
111 /*
112 * Convert number of DSP words to number of packed registers rounded
113 * down to the nearest register.
114 * There are 3 registers for every 4 packed words.
115 */
_num_words_to_num_packed_regs(unsigned int num_dsp_words)116 static unsigned int _num_words_to_num_packed_regs(unsigned int num_dsp_words)
117 {
118 return (num_dsp_words * 3) / 4;
119 }
120
121 /* bin file that patches a single DSP word */
bin_patch_one_word(struct kunit * test)122 static void bin_patch_one_word(struct kunit *test)
123 {
124 struct cs_dsp_test *priv = test->priv;
125 const struct bin_test_param *param = test->param_value;
126 unsigned int reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
127 u32 reg_val, payload_data;
128 unsigned int alg_base_words, reg_addr;
129 struct firmware *fw;
130
131 get_random_bytes(&payload_data, sizeof(payload_data));
132
133 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
134 bin_test_mock_algs[param->alg_idx].id,
135 param->mem_type);
136
137 param->add_patch(priv->local->bin_builder,
138 bin_test_mock_algs[param->alg_idx].id,
139 bin_test_mock_algs[param->alg_idx].ver,
140 param->mem_type,
141 param->offset_words * reg_inc_per_word,
142 &payload_data, sizeof(payload_data));
143
144 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
145 KUNIT_ASSERT_EQ(test,
146 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
147 fw, "mock_bin", "misc"),
148 0);
149
150 /* Content of registers should match payload_data */
151 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
152 ((alg_base_words + param->offset_words) * reg_inc_per_word);
153 reg_val = 0;
154 KUNIT_EXPECT_EQ(test,
155 regmap_raw_read(priv->dsp->regmap, reg_addr,
156 ®_val, sizeof(reg_val)),
157 0);
158 KUNIT_EXPECT_EQ(test, reg_val, payload_data);
159
160 /* Drop expected writes and the cache should then be clean */
161 cs_dsp_mock_regmap_drop_range(priv, reg_addr, reg_addr + reg_inc_per_word - 1);
162 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
163
164 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
165 }
166
167 /* bin file with a single payload that patches consecutive words */
bin_patch_one_multiword(struct kunit * test)168 static void bin_patch_one_multiword(struct kunit *test)
169 {
170 struct cs_dsp_test *priv = test->priv;
171 const struct bin_test_param *param = test->param_value;
172 unsigned int reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
173 u32 payload_data[16], readback[16];
174 unsigned int alg_base_words, reg_addr;
175 struct firmware *fw;
176
177 static_assert(ARRAY_SIZE(readback) == ARRAY_SIZE(payload_data));
178
179 get_random_bytes(&payload_data, sizeof(payload_data));
180 memset(readback, 0, sizeof(readback));
181
182 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
183 bin_test_mock_algs[param->alg_idx].id,
184 param->mem_type);
185
186 param->add_patch(priv->local->bin_builder,
187 bin_test_mock_algs[param->alg_idx].id,
188 bin_test_mock_algs[param->alg_idx].ver,
189 param->mem_type,
190 param->offset_words * reg_inc_per_word,
191 payload_data, sizeof(payload_data));
192
193 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
194 KUNIT_ASSERT_EQ(test,
195 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
196 fw, "mock_bin", "misc"),
197 0);
198
199 /* Content of registers should match payload_data */
200 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
201 ((alg_base_words + param->offset_words) * reg_inc_per_word);
202 KUNIT_EXPECT_EQ(test,
203 regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
204 sizeof(readback)),
205 0);
206 KUNIT_EXPECT_MEMEQ(test, readback, payload_data, sizeof(payload_data));
207
208 /* Drop expected writes and the cache should then be clean */
209 cs_dsp_mock_regmap_drop_range(priv, reg_addr,
210 reg_addr + (reg_inc_per_word * ARRAY_SIZE(payload_data)));
211 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
212 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
213 }
214
215 /* bin file with a multiple one-word payloads that patch consecutive words */
bin_patch_multi_oneword(struct kunit * test)216 static void bin_patch_multi_oneword(struct kunit *test)
217 {
218 struct cs_dsp_test *priv = test->priv;
219 const struct bin_test_param *param = test->param_value;
220 unsigned int reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
221 u32 payload_data[16], readback[16];
222 unsigned int alg_base_words, reg_addr;
223 struct firmware *fw;
224 int i;
225
226 static_assert(ARRAY_SIZE(readback) == ARRAY_SIZE(payload_data));
227
228 get_random_bytes(&payload_data, sizeof(payload_data));
229 memset(readback, 0, sizeof(readback));
230
231 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
232 bin_test_mock_algs[param->alg_idx].id,
233 param->mem_type);
234
235 /* Add one payload per word */
236 for (i = 0; i < ARRAY_SIZE(payload_data); ++i) {
237 param->add_patch(priv->local->bin_builder,
238 bin_test_mock_algs[param->alg_idx].id,
239 bin_test_mock_algs[param->alg_idx].ver,
240 param->mem_type,
241 (param->offset_words + i) * reg_inc_per_word,
242 &payload_data[i], sizeof(payload_data[i]));
243 }
244
245 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
246 KUNIT_ASSERT_EQ(test,
247 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
248 fw, "mock_bin", "misc"),
249 0);
250
251 /* Content of registers should match payload_data */
252 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
253 ((alg_base_words + param->offset_words) * reg_inc_per_word);
254 KUNIT_EXPECT_EQ(test,
255 regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
256 sizeof(readback)),
257 0);
258 KUNIT_EXPECT_MEMEQ(test, readback, payload_data, sizeof(payload_data));
259
260 /* Drop expected writes and the cache should then be clean */
261 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
262 cs_dsp_mock_regmap_drop_range(priv, reg_addr,
263 reg_addr + (reg_inc_per_word * ARRAY_SIZE(payload_data)));
264 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
265 }
266
267 /*
268 * bin file with a multiple one-word payloads that patch a block of consecutive
269 * words but the payloads are not in address order.
270 */
bin_patch_multi_oneword_unordered(struct kunit * test)271 static void bin_patch_multi_oneword_unordered(struct kunit *test)
272 {
273 struct cs_dsp_test *priv = test->priv;
274 const struct bin_test_param *param = test->param_value;
275 unsigned int reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
276 u32 payload_data[16], readback[16];
277 static const u8 word_order[] = { 10, 2, 12, 4, 0, 11, 6, 1, 3, 15, 5, 13, 8, 7, 9, 14 };
278 unsigned int alg_base_words, reg_addr;
279 struct firmware *fw;
280 int i;
281
282 static_assert(ARRAY_SIZE(readback) == ARRAY_SIZE(payload_data));
283 static_assert(ARRAY_SIZE(word_order) == ARRAY_SIZE(payload_data));
284
285 get_random_bytes(&payload_data, sizeof(payload_data));
286 memset(readback, 0, sizeof(readback));
287
288 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
289 bin_test_mock_algs[param->alg_idx].id,
290 param->mem_type);
291
292 /* Add one payload per word */
293 for (i = 0; i < ARRAY_SIZE(word_order); ++i) {
294 param->add_patch(priv->local->bin_builder,
295 bin_test_mock_algs[param->alg_idx].id,
296 bin_test_mock_algs[param->alg_idx].ver,
297 param->mem_type,
298 (param->offset_words + word_order[i]) *
299 reg_inc_per_word,
300 &payload_data[word_order[i]], sizeof(payload_data[0]));
301 }
302
303 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
304 KUNIT_ASSERT_EQ(test,
305 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
306 fw, "mock_bin", "misc"),
307 0);
308
309 /* Content of registers should match payload_data */
310 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
311 ((alg_base_words + param->offset_words) * reg_inc_per_word);
312 KUNIT_EXPECT_EQ(test,
313 regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
314 sizeof(readback)),
315 0);
316 KUNIT_EXPECT_MEMEQ(test, readback, payload_data, sizeof(payload_data));
317
318 /* Drop expected writes and the cache should then be clean */
319 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
320 cs_dsp_mock_regmap_drop_range(priv, reg_addr,
321 reg_addr + (reg_inc_per_word * ARRAY_SIZE(payload_data)));
322 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
323 }
324
325 /*
326 * bin file with a multiple one-word payloads. The payloads are not in address
327 * order and collectively do not patch a contiguous block of memory.
328 */
bin_patch_multi_oneword_sparse_unordered(struct kunit * test)329 static void bin_patch_multi_oneword_sparse_unordered(struct kunit *test)
330 {
331 struct cs_dsp_test *priv = test->priv;
332 const struct bin_test_param *param = test->param_value;
333 unsigned int reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
334 static const u8 word_offsets[] = {
335 11, 69, 59, 61, 32, 75, 4, 38, 70, 13, 79, 47, 46, 53, 18, 44,
336 54, 35, 51, 21, 26, 45, 27, 41, 66, 2, 17, 56, 40, 9, 8, 20,
337 29, 19, 63, 42, 12, 16, 43, 3, 5, 55, 52, 22
338 };
339 u32 payload_data[44];
340 unsigned int alg_base_words, reg_addr;
341 struct firmware *fw;
342 u32 reg_val;
343 int i;
344
345 static_assert(ARRAY_SIZE(word_offsets) == ARRAY_SIZE(payload_data));
346
347 get_random_bytes(&payload_data, sizeof(payload_data));
348
349 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
350 bin_test_mock_algs[param->alg_idx].id,
351 param->mem_type);
352
353 /* Add one payload per word */
354 for (i = 0; i < ARRAY_SIZE(word_offsets); ++i) {
355 param->add_patch(priv->local->bin_builder,
356 bin_test_mock_algs[param->alg_idx].id,
357 bin_test_mock_algs[param->alg_idx].ver,
358 param->mem_type,
359 word_offsets[i] * reg_inc_per_word,
360 &payload_data[i], sizeof(payload_data[i]));
361 }
362
363 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
364 KUNIT_ASSERT_EQ(test,
365 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
366 fw, "mock_bin", "misc"),
367 0);
368
369 /* Content of registers should match payload_data */
370 for (i = 0; i < ARRAY_SIZE(word_offsets); ++i) {
371 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
372 ((alg_base_words + word_offsets[i]) * reg_inc_per_word);
373 reg_val = 0;
374 KUNIT_EXPECT_EQ(test,
375 regmap_raw_read(priv->dsp->regmap, reg_addr, ®_val,
376 sizeof(reg_val)),
377 0);
378 KUNIT_EXPECT_MEMEQ(test, ®_val, &payload_data[i], sizeof(reg_val));
379
380 /* Drop expected writes from the cache */
381 cs_dsp_mock_regmap_drop_range(priv, reg_addr, reg_addr + reg_inc_per_word - 1);
382 }
383
384 /* Drop expected writes and the cache should then be clean */
385 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
386 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
387 }
388
389 /*
390 * bin file that patches a single DSP word in each of the memory regions
391 * of one algorithm.
392 */
bin_patch_one_word_multiple_mems(struct kunit * test)393 static void bin_patch_one_word_multiple_mems(struct kunit *test)
394 {
395 struct cs_dsp_test *priv = test->priv;
396 const struct bin_test_param *param = test->param_value;
397 unsigned int reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
398 unsigned int alg_xm_base_words, alg_ym_base_words, alg_zm_base_words;
399 unsigned int reg_addr;
400 u32 payload_data[3];
401 struct firmware *fw;
402 u32 reg_val;
403
404 get_random_bytes(&payload_data, sizeof(payload_data));
405
406 alg_xm_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
407 bin_test_mock_algs[param->alg_idx].id,
408 WMFW_ADSP2_XM);
409 alg_ym_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
410 bin_test_mock_algs[param->alg_idx].id,
411 WMFW_ADSP2_YM);
412
413 if (cs_dsp_mock_has_zm(priv)) {
414 alg_zm_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
415 bin_test_mock_algs[param->alg_idx].id,
416 WMFW_ADSP2_ZM);
417 } else {
418 alg_zm_base_words = 0;
419 }
420
421 /* Add words to XM, YM and ZM */
422 param->add_patch(priv->local->bin_builder,
423 bin_test_mock_algs[param->alg_idx].id,
424 bin_test_mock_algs[param->alg_idx].ver,
425 WMFW_ADSP2_XM,
426 param->offset_words * reg_inc_per_word,
427 &payload_data[0], sizeof(payload_data[0]));
428
429 param->add_patch(priv->local->bin_builder,
430 bin_test_mock_algs[param->alg_idx].id,
431 bin_test_mock_algs[param->alg_idx].ver,
432 WMFW_ADSP2_YM,
433 param->offset_words * reg_inc_per_word,
434 &payload_data[1], sizeof(payload_data[1]));
435
436 if (cs_dsp_mock_has_zm(priv)) {
437 param->add_patch(priv->local->bin_builder,
438 bin_test_mock_algs[param->alg_idx].id,
439 bin_test_mock_algs[param->alg_idx].ver,
440 WMFW_ADSP2_ZM,
441 param->offset_words * reg_inc_per_word,
442 &payload_data[2], sizeof(payload_data[2]));
443 }
444
445 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
446 KUNIT_ASSERT_EQ(test,
447 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
448 fw, "mock_bin", "misc"),
449 0);
450
451 /* Content of registers should match payload_data */
452 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_XM) +
453 ((alg_xm_base_words + param->offset_words) * reg_inc_per_word);
454 reg_val = 0;
455 KUNIT_EXPECT_EQ(test,
456 regmap_raw_read(priv->dsp->regmap, reg_addr, ®_val, sizeof(reg_val)),
457 0);
458 KUNIT_EXPECT_EQ(test, reg_val, payload_data[0]);
459
460 cs_dsp_mock_regmap_drop_range(priv, reg_addr, reg_addr + reg_inc_per_word - 1);
461
462 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_YM) +
463 ((alg_ym_base_words + param->offset_words) * reg_inc_per_word);
464 reg_val = 0;
465 KUNIT_EXPECT_EQ(test,
466 regmap_raw_read(priv->dsp->regmap, reg_addr, ®_val, sizeof(reg_val)),
467 0);
468 KUNIT_EXPECT_EQ(test, reg_val, payload_data[1]);
469
470 cs_dsp_mock_regmap_drop_range(priv, reg_addr, reg_addr + reg_inc_per_word - 1);
471
472 if (cs_dsp_mock_has_zm(priv)) {
473 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_ZM) +
474 ((alg_zm_base_words + param->offset_words) * reg_inc_per_word);
475 reg_val = 0;
476 KUNIT_EXPECT_EQ(test,
477 regmap_raw_read(priv->dsp->regmap, reg_addr, ®_val,
478 sizeof(reg_val)),
479 0);
480 KUNIT_EXPECT_EQ(test, reg_val, payload_data[2]);
481
482 /* Drop expected writes from the cache */
483 cs_dsp_mock_regmap_drop_range(priv, reg_addr, reg_addr + reg_inc_per_word - 1);
484 }
485
486 /* Drop expected writes and the cache should then be clean */
487 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
488 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
489 }
490
491 /*
492 * bin file that patches a single DSP word in multiple algorithms.
493 */
bin_patch_one_word_multiple_algs(struct kunit * test)494 static void bin_patch_one_word_multiple_algs(struct kunit *test)
495 {
496 struct cs_dsp_test *priv = test->priv;
497 const struct bin_test_param *param = test->param_value;
498 u32 payload_data[ARRAY_SIZE(bin_test_mock_algs)];
499 unsigned int alg_base_words;
500 unsigned int reg_inc_per_word, reg_addr;
501 struct firmware *fw;
502 u32 reg_val;
503 int i;
504
505 get_random_bytes(&payload_data, sizeof(payload_data));
506
507 /* Add one payload per algorithm */
508 for (i = 0; i < ARRAY_SIZE(bin_test_mock_algs); ++i) {
509 reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
510
511 param->add_patch(priv->local->bin_builder,
512 bin_test_mock_algs[i].id,
513 bin_test_mock_algs[i].ver,
514 param->mem_type,
515 param->offset_words * reg_inc_per_word,
516 &payload_data[i], sizeof(payload_data[i]));
517 }
518
519 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
520 KUNIT_ASSERT_EQ(test,
521 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
522 fw, "mock_bin", "misc"),
523 0);
524
525 /* Content of registers should match payload_data */
526 for (i = 0; i < ARRAY_SIZE(bin_test_mock_algs); ++i) {
527 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
528 bin_test_mock_algs[i].id,
529 param->mem_type);
530 reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
531 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
532 ((alg_base_words + param->offset_words) * reg_inc_per_word);
533 reg_val = 0;
534 KUNIT_EXPECT_EQ(test,
535 regmap_raw_read(priv->dsp->regmap, reg_addr, ®_val,
536 sizeof(reg_val)),
537 0);
538 KUNIT_EXPECT_EQ(test, reg_val, payload_data[i]);
539
540 /* Drop expected writes from the cache */
541 cs_dsp_mock_regmap_drop_range(priv, reg_addr, reg_addr + reg_inc_per_word - 1);
542 }
543
544 /* Drop expected writes and the cache should then be clean */
545 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
546 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
547 }
548
549 /*
550 * bin file that patches a single DSP word in multiple algorithms.
551 * The algorithms are not patched in the same order they appear in the XM header.
552 */
bin_patch_one_word_multiple_algs_unordered(struct kunit * test)553 static void bin_patch_one_word_multiple_algs_unordered(struct kunit *test)
554 {
555 struct cs_dsp_test *priv = test->priv;
556 const struct bin_test_param *param = test->param_value;
557 static const u8 alg_order[] = { 3, 0, 2, 1 };
558 u32 payload_data[ARRAY_SIZE(bin_test_mock_algs)];
559 unsigned int alg_base_words;
560 unsigned int reg_inc_per_word, reg_addr;
561 struct firmware *fw;
562 u32 reg_val;
563 int i, alg_idx;
564
565 static_assert(ARRAY_SIZE(alg_order) == ARRAY_SIZE(bin_test_mock_algs));
566
567 get_random_bytes(&payload_data, sizeof(payload_data));
568
569 /* Add one payload per algorithm */
570 for (i = 0; i < ARRAY_SIZE(bin_test_mock_algs); ++i) {
571 alg_idx = alg_order[i];
572 reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
573
574 param->add_patch(priv->local->bin_builder,
575 bin_test_mock_algs[alg_idx].id,
576 bin_test_mock_algs[alg_idx].ver,
577 param->mem_type,
578 param->offset_words * reg_inc_per_word,
579 &payload_data[i], sizeof(payload_data[i]));
580 }
581
582 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
583 KUNIT_ASSERT_EQ(test,
584 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
585 fw, "mock_bin", "misc"),
586 0);
587
588 /* Content of registers should match payload_data */
589 for (i = 0; i < ARRAY_SIZE(bin_test_mock_algs); ++i) {
590 alg_idx = alg_order[i];
591 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
592 bin_test_mock_algs[alg_idx].id,
593 param->mem_type);
594 reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
595 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
596 ((alg_base_words + param->offset_words) * reg_inc_per_word);
597 reg_val = 0;
598 KUNIT_EXPECT_EQ(test,
599 regmap_raw_read(priv->dsp->regmap, reg_addr, ®_val,
600 sizeof(reg_val)),
601 0);
602 KUNIT_EXPECT_EQ(test, reg_val, payload_data[i]);
603
604 /* Drop expected writes from the cache */
605 cs_dsp_mock_regmap_drop_range(priv, reg_addr, reg_addr + reg_inc_per_word - 1);
606 }
607
608 /* Drop expected writes and the cache should then be clean */
609 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
610 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
611 }
612
613 /* bin file that patches a single packed block of DSP words */
bin_patch_1_packed(struct kunit * test)614 static void bin_patch_1_packed(struct kunit *test)
615 {
616 struct cs_dsp_test *priv = test->priv;
617 const struct bin_test_param *param = test->param_value;
618 u32 packed_payload[3], readback[3];
619 unsigned int alg_base_words, patch_pos_words;
620 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
621 unsigned int reg_addr;
622 struct firmware *fw;
623
624 static_assert(sizeof(readback) == sizeof(packed_payload));
625
626 get_random_bytes(packed_payload, sizeof(packed_payload));
627
628 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
629 bin_test_mock_algs[param->alg_idx].id,
630 param->mem_type);
631 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
632
633 /* Round patch start word up to a packed boundary */
634 patch_pos_words = round_up(alg_base_words + param->offset_words, 4);
635 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
636
637 param->add_patch(priv->local->bin_builder,
638 bin_test_mock_algs[param->alg_idx].id,
639 bin_test_mock_algs[param->alg_idx].ver,
640 param->mem_type,
641 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
642 packed_payload, sizeof(packed_payload));
643
644 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
645 KUNIT_ASSERT_EQ(test,
646 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
647 fw, "mock_bin", "misc"),
648 0);
649
650 /* Content of registers should match payload_data */
651 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
652 (patch_pos_in_packed_regs * 4);
653 memset(readback, 0, sizeof(readback));
654 KUNIT_EXPECT_EQ(test,
655 regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
656 sizeof(readback)),
657 0);
658 KUNIT_EXPECT_MEMEQ(test, readback, packed_payload, sizeof(packed_payload));
659
660 /* Drop expected writes and the cache should then be clean */
661 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
662 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload));
663 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
664 }
665
666 /*
667 * Patch data that is one word longer than a packed block using one
668 * packed block followed by one unpacked word.
669 */
bin_patch_1_packed_1_single_trailing(struct kunit * test)670 static void bin_patch_1_packed_1_single_trailing(struct kunit *test)
671 {
672 struct cs_dsp_test *priv = test->priv;
673 const struct bin_test_param *param = test->param_value;
674 unsigned int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
675 u32 packed_payload[3], unpacked_payload[1], readback[3];
676 unsigned int alg_base_words, patch_pos_words;
677 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
678 unsigned int reg_addr;
679 struct firmware *fw;
680
681 static_assert(sizeof(readback) == sizeof(packed_payload));
682 static_assert(sizeof(readback) >= sizeof(unpacked_payload));
683
684 get_random_bytes(packed_payload, sizeof(packed_payload));
685 get_random_bytes(unpacked_payload, sizeof(unpacked_payload));
686
687 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
688 bin_test_mock_algs[param->alg_idx].id,
689 param->mem_type);
690 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
691
692 /* Round patch start word up to a packed boundary */
693 patch_pos_words = round_up(alg_base_words + param->offset_words, 4);
694 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
695
696 /* Patch packed block */
697 param->add_patch(priv->local->bin_builder,
698 bin_test_mock_algs[param->alg_idx].id,
699 bin_test_mock_algs[param->alg_idx].ver,
700 param->mem_type,
701 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
702 &packed_payload, sizeof(packed_payload));
703
704 /* ... and the unpacked word following that */
705 param->add_patch(priv->local->bin_builder,
706 bin_test_mock_algs[param->alg_idx].id,
707 bin_test_mock_algs[param->alg_idx].ver,
708 unpacked_mem_type,
709 ((patch_pos_words + 4) - alg_base_words) * 4,
710 unpacked_payload, sizeof(unpacked_payload));
711
712 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
713 KUNIT_ASSERT_EQ(test,
714 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
715 fw, "mock_bin", "misc"),
716 0);
717
718 /* Content of packed registers should match packed_payload */
719 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
720 (patch_pos_in_packed_regs * 4);
721 memset(readback, 0, sizeof(readback));
722 KUNIT_EXPECT_EQ(test,
723 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback, sizeof(readback)),
724 0);
725 KUNIT_EXPECT_MEMEQ(test, &readback, &packed_payload, sizeof(packed_payload));
726
727 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload));
728
729 /* Content of unpacked registers should match unpacked_payload */
730 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type) +
731 (patch_pos_words + 4) * 4;
732 memset(readback, 0, sizeof(readback));
733 KUNIT_EXPECT_EQ(test,
734 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback,
735 sizeof(unpacked_payload)),
736 0);
737 KUNIT_EXPECT_MEMEQ(test, &readback, unpacked_payload, sizeof(unpacked_payload));
738
739 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload));
740
741 /* Drop expected writes and the cache should then be clean */
742 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
743 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
744 }
745
746 /*
747 * Patch data that is two words longer than a packed block using one
748 * packed block followed by two blocks of one unpacked word.
749 */
bin_patch_1_packed_2_single_trailing(struct kunit * test)750 static void bin_patch_1_packed_2_single_trailing(struct kunit *test)
751 {
752 struct cs_dsp_test *priv = test->priv;
753 const struct bin_test_param *param = test->param_value;
754 unsigned int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
755 u32 packed_payload[3], unpacked_payloads[2], readback[3];
756 unsigned int alg_base_words, patch_pos_words;
757 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
758 unsigned int reg_addr;
759 struct firmware *fw;
760
761 static_assert(sizeof(readback) == sizeof(packed_payload));
762 static_assert(sizeof(readback) >= sizeof(unpacked_payloads));
763
764 get_random_bytes(packed_payload, sizeof(packed_payload));
765 get_random_bytes(unpacked_payloads, sizeof(unpacked_payloads));
766
767 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
768 bin_test_mock_algs[param->alg_idx].id,
769 param->mem_type);
770 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
771
772 /* Round patch start word up to a packed boundary */
773 patch_pos_words = round_up(alg_base_words + param->offset_words, 4);
774 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
775
776 /* Patch packed block */
777 param->add_patch(priv->local->bin_builder,
778 bin_test_mock_algs[param->alg_idx].id,
779 bin_test_mock_algs[param->alg_idx].ver,
780 param->mem_type,
781 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
782 &packed_payload, sizeof(packed_payload));
783
784 /* ... and the unpacked words following that */
785 param->add_patch(priv->local->bin_builder,
786 bin_test_mock_algs[param->alg_idx].id,
787 bin_test_mock_algs[param->alg_idx].ver,
788 unpacked_mem_type,
789 ((patch_pos_words + 4) - alg_base_words) * 4,
790 &unpacked_payloads[0], sizeof(unpacked_payloads[0]));
791
792 param->add_patch(priv->local->bin_builder,
793 bin_test_mock_algs[param->alg_idx].id,
794 bin_test_mock_algs[param->alg_idx].ver,
795 unpacked_mem_type,
796 ((patch_pos_words + 5) - alg_base_words) * 4,
797 &unpacked_payloads[1], sizeof(unpacked_payloads[1]));
798
799 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
800 KUNIT_ASSERT_EQ(test,
801 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
802 fw, "mock_bin", "misc"),
803 0);
804
805 /* Content of packed registers should match packed_payload */
806 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
807 (patch_pos_in_packed_regs * 4);
808 memset(readback, 0, sizeof(readback));
809 KUNIT_EXPECT_EQ(test,
810 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback, sizeof(readback)),
811 0);
812 KUNIT_EXPECT_MEMEQ(test, &readback, &packed_payload, sizeof(packed_payload));
813
814 /* Drop expected writes from the cache */
815 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload));
816
817 /* Content of unpacked registers should match unpacked_payloads */
818 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type) +
819 (patch_pos_words + 4) * 4;
820 memset(readback, 0, sizeof(readback));
821 KUNIT_EXPECT_EQ(test,
822 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback,
823 sizeof(unpacked_payloads)),
824 0);
825 KUNIT_EXPECT_MEMEQ(test, &readback, unpacked_payloads, sizeof(unpacked_payloads));
826
827 /* Drop expected writes from the cache */
828 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payloads));
829
830 /* Drop expected writes and the cache should then be clean */
831 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
832 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
833 }
834
835 /*
836 * Patch data that is three words longer than a packed block using one
837 * packed block followed by three blocks of one unpacked word.
838 */
bin_patch_1_packed_3_single_trailing(struct kunit * test)839 static void bin_patch_1_packed_3_single_trailing(struct kunit *test)
840 {
841 struct cs_dsp_test *priv = test->priv;
842 const struct bin_test_param *param = test->param_value;
843 unsigned int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
844 u32 packed_payload[3], unpacked_payloads[3], readback[3];
845 unsigned int alg_base_words, patch_pos_words;
846 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
847 unsigned int reg_addr;
848 struct firmware *fw;
849
850 static_assert(sizeof(readback) == sizeof(packed_payload));
851 static_assert(sizeof(readback) >= sizeof(unpacked_payloads));
852
853 get_random_bytes(packed_payload, sizeof(packed_payload));
854 get_random_bytes(unpacked_payloads, sizeof(unpacked_payloads));
855
856 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
857 bin_test_mock_algs[param->alg_idx].id,
858 param->mem_type);
859 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
860
861 /* Round patch start word up to a packed boundary */
862 patch_pos_words = round_up(alg_base_words + param->offset_words, 4);
863 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
864
865 /* Patch packed block */
866 param->add_patch(priv->local->bin_builder,
867 bin_test_mock_algs[param->alg_idx].id,
868 bin_test_mock_algs[param->alg_idx].ver,
869 param->mem_type,
870 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
871 &packed_payload, sizeof(packed_payload));
872
873 /* ... and the unpacked words following that */
874 param->add_patch(priv->local->bin_builder,
875 bin_test_mock_algs[param->alg_idx].id,
876 bin_test_mock_algs[param->alg_idx].ver,
877 unpacked_mem_type,
878 ((patch_pos_words + 4) - alg_base_words) * 4,
879 &unpacked_payloads[0], sizeof(unpacked_payloads[0]));
880
881 param->add_patch(priv->local->bin_builder,
882 bin_test_mock_algs[param->alg_idx].id,
883 bin_test_mock_algs[param->alg_idx].ver,
884 unpacked_mem_type,
885 ((patch_pos_words + 5) - alg_base_words) * 4,
886 &unpacked_payloads[1], sizeof(unpacked_payloads[1]));
887
888 param->add_patch(priv->local->bin_builder,
889 bin_test_mock_algs[param->alg_idx].id,
890 bin_test_mock_algs[param->alg_idx].ver,
891 unpacked_mem_type,
892 ((patch_pos_words + 6) - alg_base_words) * 4,
893 &unpacked_payloads[2], sizeof(unpacked_payloads[2]));
894
895 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
896 KUNIT_ASSERT_EQ(test,
897 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
898 fw, "mock_bin", "misc"),
899 0);
900
901 /* Content of packed registers should match packed_payload */
902 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
903 (patch_pos_in_packed_regs * 4);
904 memset(readback, 0, sizeof(readback));
905 KUNIT_EXPECT_EQ(test,
906 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback, sizeof(readback)),
907 0);
908 KUNIT_EXPECT_MEMEQ(test, &readback, &packed_payload, sizeof(packed_payload));
909
910 /* Drop expected writes from the cache */
911 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload));
912
913 /* Content of unpacked registers should match unpacked_payloads */
914 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type) +
915 (patch_pos_words + 4) * 4;
916 memset(readback, 0, sizeof(readback));
917 KUNIT_EXPECT_EQ(test,
918 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback,
919 sizeof(unpacked_payloads)),
920 0);
921 KUNIT_EXPECT_MEMEQ(test, &readback, unpacked_payloads, sizeof(unpacked_payloads));
922
923 /* Drop expected writes from the cache */
924 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payloads));
925
926 /* Drop expected writes and the cache should then be clean */
927 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
928 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
929 }
930
931 /*
932 * Patch data that is two words longer than a packed block using one
933 * packed block followed by a block of two unpacked words.
934 */
bin_patch_1_packed_2_trailing(struct kunit * test)935 static void bin_patch_1_packed_2_trailing(struct kunit *test)
936 {
937 struct cs_dsp_test *priv = test->priv;
938 const struct bin_test_param *param = test->param_value;
939 unsigned int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
940 u32 packed_payload[3], unpacked_payload[2], readback[3];
941 unsigned int alg_base_words, patch_pos_words;
942 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
943 unsigned int reg_addr;
944 struct firmware *fw;
945
946 static_assert(sizeof(readback) == sizeof(packed_payload));
947 static_assert(sizeof(readback) >= sizeof(unpacked_payload));
948
949 get_random_bytes(packed_payload, sizeof(packed_payload));
950 get_random_bytes(unpacked_payload, sizeof(unpacked_payload));
951
952 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
953 bin_test_mock_algs[param->alg_idx].id,
954 param->mem_type);
955 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
956
957 /* Round patch start word up to a packed boundary */
958 patch_pos_words = round_up(alg_base_words + param->offset_words, 4);
959 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
960
961 /* Patch packed block */
962 param->add_patch(priv->local->bin_builder,
963 bin_test_mock_algs[param->alg_idx].id,
964 bin_test_mock_algs[param->alg_idx].ver,
965 param->mem_type,
966 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
967 &packed_payload, sizeof(packed_payload));
968
969 /* ... and the unpacked words following that */
970 param->add_patch(priv->local->bin_builder,
971 bin_test_mock_algs[param->alg_idx].id,
972 bin_test_mock_algs[param->alg_idx].ver,
973 unpacked_mem_type,
974 ((patch_pos_words + 4) - alg_base_words) * 4,
975 unpacked_payload, sizeof(unpacked_payload));
976
977 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
978 KUNIT_ASSERT_EQ(test,
979 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
980 fw, "mock_bin", "misc"),
981 0);
982
983 /* Content of packed registers should match packed_payload */
984 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
985 (patch_pos_in_packed_regs * 4);
986 memset(readback, 0, sizeof(readback));
987 KUNIT_EXPECT_EQ(test,
988 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback, sizeof(readback)),
989 0);
990 KUNIT_EXPECT_MEMEQ(test, &readback, &packed_payload, sizeof(packed_payload));
991
992 /* Drop expected writes from the cache */
993 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload));
994
995 /* Content of unpacked registers should match unpacked_payload */
996 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type) +
997 (patch_pos_words + 4) * 4;
998 memset(readback, 0, sizeof(readback));
999 KUNIT_EXPECT_EQ(test,
1000 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback,
1001 sizeof(unpacked_payload)),
1002 0);
1003 KUNIT_EXPECT_MEMEQ(test, &readback, unpacked_payload, sizeof(unpacked_payload));
1004
1005 /* Drop expected writes from the cache */
1006 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload));
1007
1008 /* Drop expected writes and the cache should then be clean */
1009 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1010 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1011 }
1012
1013 /*
1014 * Patch data that is three words longer than a packed block using one
1015 * packed block followed by a block of three unpacked words.
1016 */
bin_patch_1_packed_3_trailing(struct kunit * test)1017 static void bin_patch_1_packed_3_trailing(struct kunit *test)
1018 {
1019 struct cs_dsp_test *priv = test->priv;
1020 const struct bin_test_param *param = test->param_value;
1021 unsigned int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1022 u32 packed_payload[3], unpacked_payload[3], readback[3];
1023 unsigned int alg_base_words, patch_pos_words;
1024 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
1025 unsigned int reg_addr;
1026 struct firmware *fw;
1027
1028 static_assert(sizeof(readback) == sizeof(packed_payload));
1029 static_assert(sizeof(readback) >= sizeof(unpacked_payload));
1030
1031 get_random_bytes(packed_payload, sizeof(packed_payload));
1032 get_random_bytes(unpacked_payload, sizeof(unpacked_payload));
1033
1034 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1035 bin_test_mock_algs[param->alg_idx].id,
1036 param->mem_type);
1037 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
1038
1039 /* Round patch start word up to a packed boundary */
1040 patch_pos_words = round_up(alg_base_words + param->offset_words, 4);
1041 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
1042
1043 /* Patch packed block */
1044 param->add_patch(priv->local->bin_builder,
1045 bin_test_mock_algs[param->alg_idx].id,
1046 bin_test_mock_algs[param->alg_idx].ver,
1047 param->mem_type,
1048 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
1049 &packed_payload, sizeof(packed_payload));
1050
1051 /* ... and the unpacked words following that */
1052 param->add_patch(priv->local->bin_builder,
1053 bin_test_mock_algs[param->alg_idx].id,
1054 bin_test_mock_algs[param->alg_idx].ver,
1055 unpacked_mem_type,
1056 ((patch_pos_words + 4) - alg_base_words) * 4,
1057 unpacked_payload, sizeof(unpacked_payload));
1058
1059 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
1060 KUNIT_ASSERT_EQ(test,
1061 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
1062 fw, "mock_bin", "misc"),
1063 0);
1064
1065 /* Content of packed registers should match packed_payload */
1066 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
1067 (patch_pos_in_packed_regs * 4);
1068 memset(readback, 0, sizeof(readback));
1069 KUNIT_EXPECT_EQ(test,
1070 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback, sizeof(readback)),
1071 0);
1072 KUNIT_EXPECT_MEMEQ(test, &readback, &packed_payload, sizeof(packed_payload));
1073
1074 /* Drop expected writes from the cache */
1075 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload));
1076
1077 /* Content of unpacked registers should match unpacked_payload */
1078 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type) +
1079 (patch_pos_words + 4) * 4;
1080 memset(readback, 0, sizeof(readback));
1081 KUNIT_EXPECT_EQ(test,
1082 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback,
1083 sizeof(unpacked_payload)),
1084 0);
1085 KUNIT_EXPECT_MEMEQ(test, &readback, unpacked_payload, sizeof(unpacked_payload));
1086
1087 /* Drop expected writes from the cache */
1088 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload));
1089
1090 /* Drop expected writes and the cache should then be clean */
1091 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1092 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1093 }
1094
1095 /*
1096 * Patch data that starts one word before a packed boundary using one
1097 * unpacked word followed by one packed block.
1098 */
bin_patch_1_single_leading_1_packed(struct kunit * test)1099 static void bin_patch_1_single_leading_1_packed(struct kunit *test)
1100 {
1101 struct cs_dsp_test *priv = test->priv;
1102 const struct bin_test_param *param = test->param_value;
1103 unsigned int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1104 u32 packed_payload[3], unpacked_payload[1], readback[3];
1105 unsigned int alg_base_words, packed_patch_pos_words;
1106 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
1107 unsigned int reg_addr;
1108 struct firmware *fw;
1109
1110 static_assert(sizeof(readback) == sizeof(packed_payload));
1111 static_assert(sizeof(readback) >= sizeof(unpacked_payload));
1112
1113 get_random_bytes(packed_payload, sizeof(packed_payload));
1114 get_random_bytes(unpacked_payload, sizeof(unpacked_payload));
1115 memset(readback, 0, sizeof(readback));
1116
1117 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1118 bin_test_mock_algs[param->alg_idx].id,
1119 param->mem_type);
1120 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
1121
1122 /* Round packed start word up to a packed boundary and move to the next boundary */
1123 packed_patch_pos_words = round_up(alg_base_words + param->offset_words, 4) + 4;
1124
1125 /* Patch the leading unpacked word */
1126 param->add_patch(priv->local->bin_builder,
1127 bin_test_mock_algs[param->alg_idx].id,
1128 bin_test_mock_algs[param->alg_idx].ver,
1129 unpacked_mem_type,
1130 ((packed_patch_pos_words - 1) - alg_base_words) * 4,
1131 unpacked_payload, sizeof(unpacked_payload));
1132 /* ... then the packed block */
1133 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(packed_patch_pos_words);
1134 param->add_patch(priv->local->bin_builder,
1135 bin_test_mock_algs[param->alg_idx].id,
1136 bin_test_mock_algs[param->alg_idx].ver,
1137 param->mem_type,
1138 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
1139 &packed_payload, sizeof(packed_payload));
1140
1141 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
1142 KUNIT_ASSERT_EQ(test,
1143 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
1144 fw, "mock_bin", "misc"),
1145 0);
1146
1147 /* Content of packed registers should match packed_payload */
1148 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
1149 (patch_pos_in_packed_regs * 4);
1150 KUNIT_EXPECT_EQ(test,
1151 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback, sizeof(readback)),
1152 0);
1153 KUNIT_EXPECT_MEMEQ(test, &readback, &packed_payload, sizeof(packed_payload));
1154
1155 /* Drop expected writes from the cache */
1156 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload));
1157
1158 /* Content of unpacked registers should match unpacked_payload */
1159 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type) +
1160 (packed_patch_pos_words - 1) * 4;
1161 KUNIT_EXPECT_EQ(test,
1162 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback,
1163 sizeof(unpacked_payload)),
1164 0);
1165 KUNIT_EXPECT_MEMEQ(test, &readback, unpacked_payload, sizeof(unpacked_payload));
1166
1167 /* Drop expected writes from the cache */
1168 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload));
1169
1170 /* Drop expected writes and the cache should then be clean */
1171 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1172 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1173 }
1174
1175 /*
1176 * Patch data that starts two words before a packed boundary using two
1177 * unpacked words followed by one packed block.
1178 */
bin_patch_2_single_leading_1_packed(struct kunit * test)1179 static void bin_patch_2_single_leading_1_packed(struct kunit *test)
1180 {
1181 struct cs_dsp_test *priv = test->priv;
1182 const struct bin_test_param *param = test->param_value;
1183 unsigned int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1184 u32 packed_payload[3], unpacked_payload[2], readback[3];
1185 unsigned int alg_base_words, packed_patch_pos_words;
1186 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
1187 unsigned int reg_addr;
1188 struct firmware *fw;
1189
1190 static_assert(sizeof(readback) == sizeof(packed_payload));
1191 static_assert(sizeof(readback) >= sizeof(unpacked_payload));
1192
1193 get_random_bytes(packed_payload, sizeof(packed_payload));
1194 get_random_bytes(unpacked_payload, sizeof(unpacked_payload));
1195
1196 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1197 bin_test_mock_algs[param->alg_idx].id,
1198 param->mem_type);
1199 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
1200
1201 /* Round packed start word up to a packed boundary and move to the next boundary */
1202 packed_patch_pos_words = round_up(alg_base_words + param->offset_words, 4) + 4;
1203
1204 /* Patch the leading unpacked words */
1205 param->add_patch(priv->local->bin_builder,
1206 bin_test_mock_algs[param->alg_idx].id,
1207 bin_test_mock_algs[param->alg_idx].ver,
1208 unpacked_mem_type,
1209 ((packed_patch_pos_words - 2) - alg_base_words) * 4,
1210 &unpacked_payload[0], sizeof(unpacked_payload[0]));
1211 param->add_patch(priv->local->bin_builder,
1212 bin_test_mock_algs[param->alg_idx].id,
1213 bin_test_mock_algs[param->alg_idx].ver,
1214 unpacked_mem_type,
1215 ((packed_patch_pos_words - 1) - alg_base_words) * 4,
1216 &unpacked_payload[1], sizeof(unpacked_payload[1]));
1217 /* ... then the packed block */
1218 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(packed_patch_pos_words);
1219 param->add_patch(priv->local->bin_builder,
1220 bin_test_mock_algs[param->alg_idx].id,
1221 bin_test_mock_algs[param->alg_idx].ver,
1222 param->mem_type,
1223 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
1224 &packed_payload, sizeof(packed_payload));
1225
1226 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
1227 KUNIT_ASSERT_EQ(test,
1228 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
1229 fw, "mock_bin", "misc"),
1230 0);
1231
1232 /* Content of packed registers should match packed_payload */
1233 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
1234 (patch_pos_in_packed_regs * 4);
1235 memset(readback, 0, sizeof(readback));
1236 KUNIT_EXPECT_EQ(test,
1237 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback, sizeof(readback)),
1238 0);
1239 KUNIT_EXPECT_MEMEQ(test, &readback, &packed_payload, sizeof(packed_payload));
1240
1241 /* Drop expected writes from the cache */
1242 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload));
1243
1244 /* Content of unpacked registers should match unpacked_payload */
1245 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type) +
1246 (packed_patch_pos_words - 2) * 4;
1247 memset(readback, 0, sizeof(readback));
1248 KUNIT_EXPECT_EQ(test,
1249 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback,
1250 sizeof(unpacked_payload)),
1251 0);
1252 KUNIT_EXPECT_MEMEQ(test, &readback, unpacked_payload, sizeof(unpacked_payload));
1253
1254 /* Drop expected writes from the cache */
1255 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload));
1256
1257 /* Drop expected writes and the cache should then be clean */
1258 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1259 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1260 }
1261
1262 /*
1263 * Patch data that starts two words before a packed boundary using one
1264 * block of two unpacked words followed by one packed block.
1265 */
bin_patch_2_leading_1_packed(struct kunit * test)1266 static void bin_patch_2_leading_1_packed(struct kunit *test)
1267 {
1268 struct cs_dsp_test *priv = test->priv;
1269 const struct bin_test_param *param = test->param_value;
1270 unsigned int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1271 u32 packed_payload[3], unpacked_payload[2], readback[3];
1272 unsigned int alg_base_words, packed_patch_pos_words;
1273 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
1274 unsigned int reg_addr;
1275 struct firmware *fw;
1276
1277 static_assert(sizeof(readback) == sizeof(packed_payload));
1278 static_assert(sizeof(readback) >= sizeof(unpacked_payload));
1279
1280 get_random_bytes(packed_payload, sizeof(packed_payload));
1281 get_random_bytes(unpacked_payload, sizeof(unpacked_payload));
1282
1283 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1284 bin_test_mock_algs[param->alg_idx].id,
1285 param->mem_type);
1286 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
1287
1288 /* Round packed start word up to a packed boundary and move to the next boundary */
1289 packed_patch_pos_words = round_up(alg_base_words + param->offset_words, 4) + 4;
1290
1291 /* Patch the leading unpacked words */
1292 param->add_patch(priv->local->bin_builder,
1293 bin_test_mock_algs[param->alg_idx].id,
1294 bin_test_mock_algs[param->alg_idx].ver,
1295 unpacked_mem_type,
1296 ((packed_patch_pos_words - 2) - alg_base_words) * 4,
1297 unpacked_payload, sizeof(unpacked_payload));
1298 /* ... then the packed block */
1299 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(packed_patch_pos_words);
1300 param->add_patch(priv->local->bin_builder,
1301 bin_test_mock_algs[param->alg_idx].id,
1302 bin_test_mock_algs[param->alg_idx].ver,
1303 param->mem_type,
1304 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
1305 &packed_payload, sizeof(packed_payload));
1306
1307 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
1308 KUNIT_ASSERT_EQ(test,
1309 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
1310 fw, "mock_bin", "misc"),
1311 0);
1312
1313 /* Content of packed registers should match packed_payload */
1314 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
1315 (patch_pos_in_packed_regs * 4);
1316 memset(readback, 0, sizeof(readback));
1317 KUNIT_EXPECT_EQ(test,
1318 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback, sizeof(readback)),
1319 0);
1320 KUNIT_EXPECT_MEMEQ(test, &readback, &packed_payload, sizeof(packed_payload));
1321
1322 /* Drop expected writes from the cache */
1323 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload));
1324
1325 /* Content of unpacked registers should match unpacked_payload */
1326 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type) +
1327 (packed_patch_pos_words - 2) * 4;
1328 memset(readback, 0, sizeof(readback));
1329 KUNIT_EXPECT_EQ(test,
1330 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback,
1331 sizeof(unpacked_payload)),
1332 0);
1333 KUNIT_EXPECT_MEMEQ(test, &readback, unpacked_payload, sizeof(unpacked_payload));
1334
1335 /* Drop expected writes from the cache */
1336 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload));
1337
1338 /* Drop expected writes and the cache should then be clean */
1339 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1340 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1341 }
1342
1343 /*
1344 * Patch data that starts three words before a packed boundary using three
1345 * unpacked words followed by one packed block.
1346 */
bin_patch_3_single_leading_1_packed(struct kunit * test)1347 static void bin_patch_3_single_leading_1_packed(struct kunit *test)
1348 {
1349 struct cs_dsp_test *priv = test->priv;
1350 const struct bin_test_param *param = test->param_value;
1351 unsigned int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1352 u32 packed_payload[3], unpacked_payload[3], readback[3];
1353 unsigned int alg_base_words, packed_patch_pos_words;
1354 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
1355 unsigned int reg_addr;
1356 struct firmware *fw;
1357
1358 static_assert(sizeof(readback) == sizeof(packed_payload));
1359 static_assert(sizeof(readback) >= sizeof(unpacked_payload));
1360
1361 get_random_bytes(packed_payload, sizeof(packed_payload));
1362 get_random_bytes(unpacked_payload, sizeof(unpacked_payload));
1363
1364 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1365 bin_test_mock_algs[param->alg_idx].id,
1366 param->mem_type);
1367 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
1368
1369 /* Round packed start word up to a packed boundary and move to the next boundary */
1370 packed_patch_pos_words = round_up(alg_base_words + param->offset_words, 4) + 4;
1371
1372 /* Patch the leading unpacked words */
1373 param->add_patch(priv->local->bin_builder,
1374 bin_test_mock_algs[param->alg_idx].id,
1375 bin_test_mock_algs[param->alg_idx].ver,
1376 unpacked_mem_type,
1377 ((packed_patch_pos_words - 3) - alg_base_words) * 4,
1378 &unpacked_payload[0], sizeof(unpacked_payload[0]));
1379 param->add_patch(priv->local->bin_builder,
1380 bin_test_mock_algs[param->alg_idx].id,
1381 bin_test_mock_algs[param->alg_idx].ver,
1382 unpacked_mem_type,
1383 ((packed_patch_pos_words - 2) - alg_base_words) * 4,
1384 &unpacked_payload[1], sizeof(unpacked_payload[1]));
1385 param->add_patch(priv->local->bin_builder,
1386 bin_test_mock_algs[param->alg_idx].id,
1387 bin_test_mock_algs[param->alg_idx].ver,
1388 unpacked_mem_type,
1389 ((packed_patch_pos_words - 1) - alg_base_words) * 4,
1390 &unpacked_payload[2], sizeof(unpacked_payload[2]));
1391 /* ... then the packed block */
1392 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(packed_patch_pos_words);
1393 param->add_patch(priv->local->bin_builder,
1394 bin_test_mock_algs[param->alg_idx].id,
1395 bin_test_mock_algs[param->alg_idx].ver,
1396 param->mem_type,
1397 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
1398 &packed_payload, sizeof(packed_payload));
1399
1400 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
1401 KUNIT_ASSERT_EQ(test,
1402 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
1403 fw, "mock_bin", "misc"),
1404 0);
1405
1406 /* Content of packed registers should match packed_payload */
1407 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
1408 (patch_pos_in_packed_regs * 4);
1409 memset(readback, 0, sizeof(readback));
1410 KUNIT_EXPECT_EQ(test,
1411 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback, sizeof(readback)),
1412 0);
1413 KUNIT_EXPECT_MEMEQ(test, &readback, &packed_payload, sizeof(packed_payload));
1414
1415 /* Drop expected writes from the cache */
1416 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload));
1417
1418 /* Content of unpacked registers should match unpacked_payload */
1419 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type) +
1420 (packed_patch_pos_words - 3) * 4;
1421 memset(readback, 0, sizeof(readback));
1422 KUNIT_EXPECT_EQ(test,
1423 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback,
1424 sizeof(unpacked_payload)),
1425 0);
1426 KUNIT_EXPECT_MEMEQ(test, &readback, unpacked_payload, sizeof(unpacked_payload));
1427
1428 /* Drop expected writes from the cache */
1429 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload));
1430
1431 /* Drop expected writes and the cache should then be clean */
1432 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1433 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1434 }
1435
1436 /*
1437 * Patch data that starts three words before a packed boundary using one
1438 * block of three unpacked words followed by one packed block.
1439 */
bin_patch_3_leading_1_packed(struct kunit * test)1440 static void bin_patch_3_leading_1_packed(struct kunit *test)
1441 {
1442 struct cs_dsp_test *priv = test->priv;
1443 const struct bin_test_param *param = test->param_value;
1444 unsigned int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1445 u32 packed_payload[3], unpacked_payload[3], readback[3];
1446 unsigned int alg_base_words, packed_patch_pos_words;
1447 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
1448 unsigned int reg_addr;
1449 struct firmware *fw;
1450
1451 static_assert(sizeof(readback) == sizeof(packed_payload));
1452 static_assert(sizeof(readback) >= sizeof(unpacked_payload));
1453
1454 get_random_bytes(packed_payload, sizeof(packed_payload));
1455 get_random_bytes(unpacked_payload, sizeof(unpacked_payload));
1456
1457 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1458 bin_test_mock_algs[param->alg_idx].id,
1459 param->mem_type);
1460 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
1461
1462 /* Round packed start word up to a packed boundary and move to the next boundary */
1463 packed_patch_pos_words = round_up(alg_base_words + param->offset_words, 4) + 4;
1464
1465 /* Patch the leading unpacked words */
1466 param->add_patch(priv->local->bin_builder,
1467 bin_test_mock_algs[param->alg_idx].id,
1468 bin_test_mock_algs[param->alg_idx].ver,
1469 unpacked_mem_type,
1470 ((packed_patch_pos_words - 3) - alg_base_words) * 4,
1471 unpacked_payload, sizeof(unpacked_payload));
1472 /* ... then the packed block */
1473 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(packed_patch_pos_words);
1474 param->add_patch(priv->local->bin_builder,
1475 bin_test_mock_algs[param->alg_idx].id,
1476 bin_test_mock_algs[param->alg_idx].ver,
1477 param->mem_type,
1478 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
1479 &packed_payload, sizeof(packed_payload));
1480
1481 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
1482 KUNIT_ASSERT_EQ(test,
1483 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
1484 fw, "mock_bin", "misc"),
1485 0);
1486
1487 /* Content of packed registers should match packed_payload */
1488 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
1489 (patch_pos_in_packed_regs * 4);
1490 memset(readback, 0, sizeof(readback));
1491 KUNIT_EXPECT_EQ(test,
1492 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback, sizeof(readback)),
1493 0);
1494 KUNIT_EXPECT_MEMEQ(test, &readback, &packed_payload, sizeof(packed_payload));
1495
1496 /* Drop expected writes from the cache */
1497 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload));
1498
1499 /* Content of unpacked registers should match unpacked_payload */
1500 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type) +
1501 (packed_patch_pos_words - 3) * 4;
1502 memset(readback, 0, sizeof(readback));
1503 KUNIT_EXPECT_EQ(test,
1504 regmap_raw_read(priv->dsp->regmap, reg_addr, &readback,
1505 sizeof(unpacked_payload)),
1506 0);
1507 KUNIT_EXPECT_MEMEQ(test, &readback, unpacked_payload, sizeof(unpacked_payload));
1508
1509 /* Drop expected writes from the cache */
1510 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload));
1511
1512 /* Drop expected writes and the cache should then be clean */
1513 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1514 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1515 }
1516
1517 /* bin file with a multiple payloads that each patch one packed block. */
bin_patch_multi_onepacked(struct kunit * test)1518 static void bin_patch_multi_onepacked(struct kunit *test)
1519 {
1520 struct cs_dsp_test *priv = test->priv;
1521 const struct bin_test_param *param = test->param_value;
1522 u32 packed_payloads[8][3], readback[8][3];
1523 unsigned int alg_base_words, patch_pos_words;
1524 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
1525 unsigned int payload_offset;
1526 unsigned int reg_addr;
1527 struct firmware *fw;
1528 int i;
1529
1530 static_assert(sizeof(readback) == sizeof(packed_payloads));
1531
1532 get_random_bytes(packed_payloads, sizeof(packed_payloads));
1533
1534 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1535 bin_test_mock_algs[param->alg_idx].id,
1536 param->mem_type);
1537 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
1538
1539 /* Round patch start word up to a packed boundary */
1540 patch_pos_words = round_up(alg_base_words + param->offset_words, 4);
1541
1542 /* Add one payload per packed block */
1543 for (i = 0; i < ARRAY_SIZE(packed_payloads); ++i) {
1544 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words + (i * 4));
1545 payload_offset = (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4;
1546 param->add_patch(priv->local->bin_builder,
1547 bin_test_mock_algs[param->alg_idx].id,
1548 bin_test_mock_algs[param->alg_idx].ver,
1549 param->mem_type,
1550 payload_offset,
1551 &packed_payloads[i], sizeof(packed_payloads[i]));
1552 }
1553
1554 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
1555 KUNIT_ASSERT_EQ(test,
1556 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
1557 fw, "mock_bin", "misc"),
1558 0);
1559
1560 /* Content of packed registers should match packed_payloads */
1561 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
1562 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
1563 (patch_pos_in_packed_regs * 4);
1564 memset(readback, 0, sizeof(readback));
1565 KUNIT_EXPECT_EQ(test,
1566 regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(readback)),
1567 0);
1568 KUNIT_EXPECT_MEMEQ(test, readback, packed_payloads, sizeof(packed_payloads));
1569
1570 /* Drop expected writes and the cache should then be clean */
1571 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1572 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payloads));
1573 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1574 }
1575
1576 /*
1577 * bin file with a multiple payloads that each patch one packed block.
1578 * The payloads are not in address order.
1579 */
bin_patch_multi_onepacked_unordered(struct kunit * test)1580 static void bin_patch_multi_onepacked_unordered(struct kunit *test)
1581 {
1582 struct cs_dsp_test *priv = test->priv;
1583 const struct bin_test_param *param = test->param_value;
1584 static const u8 payload_order[] = { 4, 3, 6, 1, 0, 7, 5, 2 };
1585 u32 packed_payloads[8][3], readback[8][3];
1586 unsigned int alg_base_words, patch_pos_words;
1587 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
1588 unsigned int payload_offset;
1589 unsigned int reg_addr;
1590 struct firmware *fw;
1591 int i;
1592
1593 static_assert(ARRAY_SIZE(payload_order) == ARRAY_SIZE(packed_payloads));
1594 static_assert(sizeof(readback) == sizeof(packed_payloads));
1595
1596 get_random_bytes(packed_payloads, sizeof(packed_payloads));
1597
1598 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1599 bin_test_mock_algs[param->alg_idx].id,
1600 param->mem_type);
1601 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
1602
1603 /* Round patch start word up to a packed boundary */
1604 patch_pos_words = round_up(alg_base_words + param->offset_words, 4);
1605
1606 /* Add one payload per packed block */
1607 for (i = 0; i < ARRAY_SIZE(payload_order); ++i) {
1608 patch_pos_in_packed_regs =
1609 _num_words_to_num_packed_regs(patch_pos_words + (payload_order[i] * 4));
1610 payload_offset = (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4;
1611 param->add_patch(priv->local->bin_builder,
1612 bin_test_mock_algs[param->alg_idx].id,
1613 bin_test_mock_algs[param->alg_idx].ver,
1614 param->mem_type,
1615 payload_offset,
1616 &packed_payloads[payload_order[i]],
1617 sizeof(packed_payloads[0]));
1618 }
1619
1620 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
1621 KUNIT_ASSERT_EQ(test,
1622 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
1623 fw, "mock_bin", "misc"),
1624 0);
1625
1626 /* Content in registers should match the order of data in packed_payloads */
1627 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
1628 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
1629 (patch_pos_in_packed_regs * 4);
1630 memset(readback, 0, sizeof(readback));
1631 KUNIT_EXPECT_EQ(test,
1632 regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(readback)),
1633 0);
1634 KUNIT_EXPECT_MEMEQ(test, readback, packed_payloads, sizeof(packed_payloads));
1635
1636 /* Drop expected writes and the cache should then be clean */
1637 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1638 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payloads));
1639 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1640 }
1641
1642 /*
1643 * bin file with a multiple payloads that each patch one packed block.
1644 * The payloads are not in address order. The patched memory is not contiguous.
1645 */
bin_patch_multi_onepacked_sparse_unordered(struct kunit * test)1646 static void bin_patch_multi_onepacked_sparse_unordered(struct kunit *test)
1647 {
1648 struct cs_dsp_test *priv = test->priv;
1649 const struct bin_test_param *param = test->param_value;
1650 static const u8 word_offsets[] = { 60, 24, 76, 4, 40, 52, 48, 36, 12 };
1651 u32 packed_payloads[9][3], readback[3];
1652 unsigned int alg_base_words, alg_base_in_packed_regs;
1653 unsigned int patch_pos_words, patch_pos_in_packed_regs, payload_offset;
1654 unsigned int reg_addr;
1655 struct firmware *fw;
1656 int i;
1657
1658 static_assert(ARRAY_SIZE(word_offsets) == ARRAY_SIZE(packed_payloads));
1659 static_assert(sizeof(readback) == sizeof(packed_payloads[0]));
1660
1661 get_random_bytes(packed_payloads, sizeof(packed_payloads));
1662
1663 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1664 bin_test_mock_algs[param->alg_idx].id,
1665 param->mem_type);
1666 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
1667
1668 /* Add one payload per packed block */
1669 for (i = 0; i < ARRAY_SIZE(word_offsets); ++i) {
1670 /* Round patch start word up to a packed boundary */
1671 patch_pos_words = round_up(alg_base_words + word_offsets[i], 4);
1672 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
1673 payload_offset = (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4;
1674 param->add_patch(priv->local->bin_builder,
1675 bin_test_mock_algs[param->alg_idx].id,
1676 bin_test_mock_algs[param->alg_idx].ver,
1677 param->mem_type,
1678 payload_offset,
1679 &packed_payloads[i],
1680 sizeof(packed_payloads[0]));
1681 }
1682
1683 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
1684 KUNIT_ASSERT_EQ(test,
1685 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
1686 fw, "mock_bin", "misc"),
1687 0);
1688
1689 /* Content of packed registers should match packed_payloads */
1690 for (i = 0; i < ARRAY_SIZE(word_offsets); ++i) {
1691 patch_pos_words = round_up(alg_base_words + word_offsets[i], 4);
1692 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
1693 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
1694 (patch_pos_in_packed_regs * 4);
1695 memset(readback, 0, sizeof(readback));
1696 KUNIT_EXPECT_EQ(test,
1697 regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
1698 sizeof(readback)),
1699 0);
1700 KUNIT_EXPECT_MEMEQ(test, readback, packed_payloads[i], sizeof(packed_payloads[i]));
1701
1702 /* Drop expected writes from the cache */
1703 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payloads[i]));
1704 }
1705
1706 /* Drop expected writes and the cache should then be clean */
1707 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1708 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1709 }
1710
1711 /*
1712 * bin file that patches a single packed block in each of the memory regions
1713 * of one algorithm.
1714 */
bin_patch_1_packed_multiple_mems(struct kunit * test)1715 static void bin_patch_1_packed_multiple_mems(struct kunit *test)
1716 {
1717 struct cs_dsp_test *priv = test->priv;
1718 const struct bin_test_param *param = test->param_value;
1719 u32 packed_xm_payload[3], packed_ym_payload[3], readback[3];
1720 unsigned int alg_xm_base_words, alg_ym_base_words;
1721 unsigned int xm_patch_pos_words, ym_patch_pos_words;
1722 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
1723 unsigned int reg_addr;
1724 struct firmware *fw;
1725
1726 static_assert(sizeof(readback) == sizeof(packed_xm_payload));
1727 static_assert(sizeof(readback) == sizeof(packed_ym_payload));
1728
1729 get_random_bytes(packed_xm_payload, sizeof(packed_xm_payload));
1730 get_random_bytes(packed_ym_payload, sizeof(packed_ym_payload));
1731
1732 alg_xm_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1733 bin_test_mock_algs[param->alg_idx].id,
1734 WMFW_HALO_XM_PACKED);
1735 alg_ym_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1736 bin_test_mock_algs[param->alg_idx].id,
1737 WMFW_HALO_YM_PACKED);
1738
1739 /* Round patch start word up to a packed boundary */
1740 xm_patch_pos_words = round_up(alg_xm_base_words + param->offset_words, 4);
1741 ym_patch_pos_words = round_up(alg_ym_base_words + param->offset_words, 4);
1742
1743 /* Add XM and YM patches */
1744 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_xm_base_words);
1745 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(xm_patch_pos_words);
1746 param->add_patch(priv->local->bin_builder,
1747 bin_test_mock_algs[param->alg_idx].id,
1748 bin_test_mock_algs[param->alg_idx].ver,
1749 WMFW_HALO_XM_PACKED,
1750 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
1751 packed_xm_payload, sizeof(packed_xm_payload));
1752
1753 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_ym_base_words);
1754 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(ym_patch_pos_words);
1755 param->add_patch(priv->local->bin_builder,
1756 bin_test_mock_algs[param->alg_idx].id,
1757 bin_test_mock_algs[param->alg_idx].ver,
1758 WMFW_HALO_YM_PACKED,
1759 (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4,
1760 packed_ym_payload, sizeof(packed_ym_payload));
1761
1762 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
1763 KUNIT_ASSERT_EQ(test,
1764 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
1765 fw, "mock_bin", "misc"),
1766 0);
1767
1768 /* Content of packed XM registers should match packed_xm_payload */
1769 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(xm_patch_pos_words);
1770 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_HALO_XM_PACKED) +
1771 (patch_pos_in_packed_regs * 4);
1772 memset(readback, 0, sizeof(readback));
1773 KUNIT_EXPECT_EQ(test,
1774 regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(readback)),
1775 0);
1776 KUNIT_EXPECT_MEMEQ(test, readback, packed_xm_payload, sizeof(packed_xm_payload));
1777
1778 /* Drop expected writes from the cache */
1779 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_xm_payload));
1780
1781 /* Content of packed YM registers should match packed_ym_payload */
1782 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(ym_patch_pos_words);
1783 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_HALO_YM_PACKED) +
1784 (patch_pos_in_packed_regs * 4);
1785 memset(readback, 0, sizeof(readback));
1786 KUNIT_EXPECT_EQ(test,
1787 regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(readback)),
1788 0);
1789 KUNIT_EXPECT_MEMEQ(test, readback, packed_ym_payload, sizeof(packed_ym_payload));
1790
1791 /* Drop expected writes from the cache */
1792 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_ym_payload));
1793
1794 /* Drop expected writes and the cache should then be clean */
1795 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1796 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1797 }
1798
1799 /*
1800 * bin file that patches a single packed block in multiple algorithms.
1801 */
bin_patch_1_packed_multiple_algs(struct kunit * test)1802 static void bin_patch_1_packed_multiple_algs(struct kunit *test)
1803 {
1804 struct cs_dsp_test *priv = test->priv;
1805 const struct bin_test_param *param = test->param_value;
1806 u32 packed_payload[ARRAY_SIZE(bin_test_mock_algs)][3];
1807 u32 readback[ARRAY_SIZE(bin_test_mock_algs)][3];
1808 unsigned int alg_base_words, patch_pos_words;
1809 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
1810 unsigned int reg_addr, payload_offset;
1811 struct firmware *fw;
1812 int i;
1813
1814 static_assert(sizeof(readback) == sizeof(packed_payload));
1815
1816 get_random_bytes(packed_payload, sizeof(packed_payload));
1817
1818 /* For each algorithm patch one DSP word to a value from packed_payload */
1819 for (i = 0; i < ARRAY_SIZE(bin_test_mock_algs); ++i) {
1820 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1821 bin_test_mock_algs[i].id,
1822 param->mem_type);
1823 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
1824
1825 /* Round patch start word up to a packed boundary */
1826 patch_pos_words = round_up(alg_base_words + param->offset_words, 4);
1827 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
1828
1829 payload_offset = (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4;
1830 param->add_patch(priv->local->bin_builder,
1831 bin_test_mock_algs[i].id,
1832 bin_test_mock_algs[i].ver,
1833 param->mem_type,
1834 payload_offset,
1835 packed_payload[i], sizeof(packed_payload[i]));
1836 }
1837
1838 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
1839 KUNIT_ASSERT_EQ(test,
1840 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
1841 fw, "mock_bin", "misc"),
1842 0);
1843
1844 memset(readback, 0, sizeof(readback));
1845
1846 /*
1847 * Readback the registers that should have been written. Place
1848 * the values into the expected location in readback[] so that
1849 * the content of readback[] should match packed_payload[]
1850 */
1851 for (i = 0; i < ARRAY_SIZE(bin_test_mock_algs); ++i) {
1852 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1853 bin_test_mock_algs[i].id,
1854 param->mem_type);
1855 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
1856
1857 patch_pos_words = round_up(alg_base_words + param->offset_words, 4);
1858 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
1859
1860 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
1861 (patch_pos_in_packed_regs * 4);
1862 KUNIT_EXPECT_EQ(test,
1863 regmap_raw_read(priv->dsp->regmap, reg_addr,
1864 readback[i], sizeof(readback[i])),
1865 0);
1866
1867 /* Drop expected writes from the cache */
1868 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload[i]));
1869 }
1870
1871 KUNIT_EXPECT_MEMEQ(test, readback, packed_payload, sizeof(packed_payload));
1872
1873 /* Drop expected writes and the cache should then be clean */
1874 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1875 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1876 }
1877
1878 /*
1879 * bin file that patches a single packed block in multiple algorithms.
1880 * The algorithms are not patched in the same order they appear in the XM header.
1881 */
bin_patch_1_packed_multiple_algs_unordered(struct kunit * test)1882 static void bin_patch_1_packed_multiple_algs_unordered(struct kunit *test)
1883 {
1884 struct cs_dsp_test *priv = test->priv;
1885 const struct bin_test_param *param = test->param_value;
1886 static const u8 alg_order[] = { 3, 0, 2, 1 };
1887 u32 packed_payload[ARRAY_SIZE(bin_test_mock_algs)][3];
1888 u32 readback[ARRAY_SIZE(bin_test_mock_algs)][3];
1889 unsigned int alg_base_words, patch_pos_words;
1890 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
1891 unsigned int reg_addr, payload_offset;
1892 struct firmware *fw;
1893 int i, alg_idx;
1894
1895 static_assert(ARRAY_SIZE(alg_order) == ARRAY_SIZE(bin_test_mock_algs));
1896 static_assert(sizeof(readback) == sizeof(packed_payload));
1897
1898 get_random_bytes(packed_payload, sizeof(packed_payload));
1899
1900 /*
1901 * For each algorithm index in alg_order[] patch one DSP word in
1902 * that algorithm to a value from packed_payload.
1903 */
1904 for (i = 0; i < ARRAY_SIZE(alg_order); ++i) {
1905 alg_idx = alg_order[i];
1906 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1907 bin_test_mock_algs[alg_idx].id,
1908 param->mem_type);
1909 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
1910
1911 /* Round patch start word up to a packed boundary */
1912 patch_pos_words = round_up(alg_base_words + param->offset_words, 4);
1913 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
1914
1915 payload_offset = (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4;
1916 param->add_patch(priv->local->bin_builder,
1917 bin_test_mock_algs[alg_idx].id,
1918 bin_test_mock_algs[alg_idx].ver,
1919 param->mem_type,
1920 payload_offset,
1921 packed_payload[i], sizeof(packed_payload[i]));
1922 }
1923
1924 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
1925 KUNIT_ASSERT_EQ(test,
1926 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
1927 fw, "mock_bin", "misc"),
1928 0);
1929
1930 memset(readback, 0, sizeof(readback));
1931
1932 /*
1933 * Readback the registers that should have been written. Place
1934 * the values into the expected location in readback[] so that
1935 * the content of readback[] should match packed_payload[]
1936 */
1937 for (i = 0; i < ARRAY_SIZE(alg_order); ++i) {
1938 alg_idx = alg_order[i];
1939 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
1940 bin_test_mock_algs[alg_idx].id,
1941 param->mem_type);
1942
1943 patch_pos_words = round_up(alg_base_words + param->offset_words, 4);
1944 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
1945
1946 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
1947 (patch_pos_in_packed_regs * 4);
1948 KUNIT_EXPECT_EQ(test,
1949 regmap_raw_read(priv->dsp->regmap, reg_addr,
1950 readback[i], sizeof(readback[i])),
1951 0);
1952
1953 /* Drop expected writes from the cache */
1954 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(packed_payload[i]));
1955 }
1956
1957 KUNIT_EXPECT_MEMEQ(test, readback, packed_payload, sizeof(packed_payload));
1958
1959 /* Drop expected writes and the cache should then be clean */
1960 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
1961 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
1962 }
1963
1964 /*
1965 * bin file that contains a mix of packed and unpacked words.
1966 * payloads are in random offset order. Offsets that are on a packed boundary
1967 * are written as a packed block. Offsets that are not on a packed boundary
1968 * are written as a single unpacked word.
1969 */
bin_patch_mixed_packed_unpacked_random(struct kunit * test)1970 static void bin_patch_mixed_packed_unpacked_random(struct kunit *test)
1971 {
1972 struct cs_dsp_test *priv = test->priv;
1973 const struct bin_test_param *param = test->param_value;
1974 static const u8 offset_words[] = {
1975 58, 68, 50, 10, 44, 17, 74, 36, 8, 7, 49, 11, 78, 57, 65, 2,
1976 48, 38, 22, 70, 77, 21, 61, 56, 75, 34, 27, 3, 31, 20, 43, 63,
1977 5, 30, 32, 25, 33, 79, 29, 0, 37, 60, 69, 52, 13, 12, 24, 26,
1978 4, 51, 76, 72, 16, 6, 39, 62, 15, 41, 28, 73, 53, 40, 45, 54,
1979 14, 55, 46, 66, 64, 59, 23, 9, 67, 47, 19, 71, 35, 18, 42, 1,
1980 };
1981 struct {
1982 u32 packed[80][3];
1983 u32 unpacked[80];
1984 } *payload;
1985 u32 readback[3];
1986 unsigned int alg_base_words, patch_pos_words;
1987 unsigned int alg_base_in_packed_regs, patch_pos_in_packed_regs;
1988 unsigned int reg_addr, payload_offset;
1989 int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);
1990 struct firmware *fw;
1991 int i;
1992
1993 payload = kunit_kmalloc(test, sizeof(*payload), GFP_KERNEL);
1994 KUNIT_ASSERT_NOT_NULL(test, payload);
1995
1996 get_random_bytes(payload->packed, sizeof(payload->packed));
1997 get_random_bytes(payload->unpacked, sizeof(payload->unpacked));
1998
1999 /* Create a patch entry for every offset in offset_words[] */
2000 for (i = 0; i < ARRAY_SIZE(offset_words); ++i) {
2001 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
2002 bin_test_mock_algs[0].id,
2003 param->mem_type);
2004 /*
2005 * If the offset is on a packed boundary use a packed payload else
2006 * use an unpacked word
2007 */
2008 patch_pos_words = alg_base_words + offset_words[i];
2009 if ((patch_pos_words % 4) == 0) {
2010 alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words);
2011 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
2012 payload_offset = (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4;
2013 param->add_patch(priv->local->bin_builder,
2014 bin_test_mock_algs[0].id,
2015 bin_test_mock_algs[0].ver,
2016 param->mem_type,
2017 payload_offset,
2018 payload->packed[i],
2019 sizeof(payload->packed[i]));
2020 } else {
2021 payload_offset = offset_words[i] * 4;
2022 param->add_patch(priv->local->bin_builder,
2023 bin_test_mock_algs[0].id,
2024 bin_test_mock_algs[0].ver,
2025 unpacked_mem_type,
2026 payload_offset,
2027 &payload->unpacked[i],
2028 sizeof(payload->unpacked[i]));
2029 }
2030 }
2031
2032 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
2033 KUNIT_ASSERT_EQ(test,
2034 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
2035 fw, "mock_bin", "misc"),
2036 0);
2037
2038 /*
2039 * Readback the packed registers that should have been written.
2040 * Place the values into the expected location in readback[] so
2041 * that the content of readback[] should match payload->packed[]
2042 */
2043 for (i = 0; i < ARRAY_SIZE(offset_words); ++i) {
2044 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
2045 bin_test_mock_algs[0].id,
2046 param->mem_type);
2047 patch_pos_words = alg_base_words + offset_words[i];
2048
2049 /* Skip if the offset is not on a packed boundary */
2050 if ((patch_pos_words % 4) != 0)
2051 continue;
2052
2053 patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words);
2054
2055 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type) +
2056 (patch_pos_in_packed_regs * 4);
2057
2058 memset(readback, 0, sizeof(readback));
2059 KUNIT_EXPECT_EQ(test,
2060 regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
2061 sizeof(readback)),
2062 0);
2063 KUNIT_EXPECT_MEMEQ(test, readback, payload->packed[i], sizeof(payload->packed[i]));
2064
2065 /* Drop expected writes from the cache */
2066 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(payload->packed[i]));
2067 }
2068
2069 /*
2070 * Readback the unpacked registers that should have been written.
2071 * Place the values into the expected location in readback[] so
2072 * that the content of readback[] should match payload->unpacked[]
2073 */
2074 for (i = 0; i < ARRAY_SIZE(offset_words); ++i) {
2075 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
2076 bin_test_mock_algs[0].id,
2077 unpacked_mem_type);
2078
2079 patch_pos_words = alg_base_words + offset_words[i];
2080
2081 /* Skip if the offset is on a packed boundary */
2082 if ((patch_pos_words % 4) == 0)
2083 continue;
2084
2085 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type) +
2086 ((patch_pos_words) * 4);
2087
2088 readback[0] = 0;
2089 KUNIT_EXPECT_EQ(test,
2090 regmap_raw_read(priv->dsp->regmap, reg_addr,
2091 &readback[0], sizeof(readback[0])),
2092 0);
2093 KUNIT_EXPECT_EQ(test, readback[0], payload->unpacked[i]);
2094
2095 /* Drop expected writes from the cache */
2096 cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(payload->unpacked[i]));
2097 }
2098
2099 /* Drop expected writes and the cache should then be clean */
2100 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
2101 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
2102 }
2103
2104 /* Bin file with name and multiple info blocks */
bin_patch_name_and_info(struct kunit * test)2105 static void bin_patch_name_and_info(struct kunit *test)
2106 {
2107 struct cs_dsp_test *priv = test->priv;
2108 unsigned int reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
2109 u32 reg_val, payload_data;
2110 char *infobuf;
2111 unsigned int alg_base_words, reg_addr;
2112 struct firmware *fw;
2113
2114 get_random_bytes(&payload_data, sizeof(payload_data));
2115
2116 alg_base_words = cs_dsp_mock_xm_header_get_alg_base_in_words(priv,
2117 bin_test_mock_algs[0].id,
2118 WMFW_ADSP2_YM);
2119
2120 /* Add a name block and info block */
2121 cs_dsp_mock_bin_add_name(priv->local->bin_builder, "The name");
2122 cs_dsp_mock_bin_add_info(priv->local->bin_builder, "Some info");
2123
2124 /* Add a big block of info */
2125 infobuf = kunit_kzalloc(test, 512, GFP_KERNEL);
2126 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, infobuf);
2127
2128 for (; strlcat(infobuf, "Waffle{Blah}\n", 512) < 512; )
2129 ;
2130
2131 cs_dsp_mock_bin_add_info(priv->local->bin_builder, infobuf);
2132
2133 /* Add a patch */
2134 cs_dsp_mock_bin_add_patch(priv->local->bin_builder,
2135 bin_test_mock_algs[0].id,
2136 bin_test_mock_algs[0].ver,
2137 WMFW_ADSP2_YM,
2138 0,
2139 &payload_data, sizeof(payload_data));
2140
2141 fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder);
2142 KUNIT_ASSERT_EQ(test,
2143 cs_dsp_power_up(priv->dsp, priv->local->wmfw, "mock_wmfw",
2144 fw, "mock_bin", "misc"),
2145 0);
2146
2147 /* Content of registers should match payload_data */
2148 reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_YM);
2149 reg_addr += alg_base_words * reg_inc_per_word;
2150 reg_val = 0;
2151 KUNIT_EXPECT_EQ(test,
2152 regmap_raw_read(priv->dsp->regmap, reg_addr,
2153 ®_val, sizeof(reg_val)),
2154 0);
2155 KUNIT_EXPECT_EQ(test, reg_val, payload_data);
2156 }
2157
cs_dsp_bin_test_common_init(struct kunit * test,struct cs_dsp * dsp,int wmdr_ver)2158 static int cs_dsp_bin_test_common_init(struct kunit *test, struct cs_dsp *dsp,
2159 int wmdr_ver)
2160 {
2161 struct cs_dsp_test *priv;
2162 struct cs_dsp_mock_xm_header *xm_hdr;
2163 struct device *test_dev;
2164 int ret;
2165
2166 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);
2167 if (!priv)
2168 return -ENOMEM;
2169
2170 priv->local = kunit_kzalloc(test, sizeof(struct cs_dsp_test_local), GFP_KERNEL);
2171 if (!priv->local)
2172 return -ENOMEM;
2173
2174 priv->test = test;
2175 priv->dsp = dsp;
2176 test->priv = priv;
2177
2178 /* Create dummy struct device */
2179 test_dev = kunit_device_register(test, "cs_dsp_test_drv");
2180 if (IS_ERR(test_dev))
2181 return PTR_ERR(test_dev);
2182
2183 dsp->dev = get_device(test_dev);
2184 if (!dsp->dev)
2185 return -ENODEV;
2186
2187 ret = kunit_add_action_or_reset(test, _put_device_wrapper, dsp->dev);
2188 if (ret)
2189 return ret;
2190
2191 dev_set_drvdata(dsp->dev, priv);
2192
2193 /* Allocate regmap */
2194 ret = cs_dsp_mock_regmap_init(priv);
2195 if (ret)
2196 return ret;
2197
2198 /* Create an XM header */
2199 xm_hdr = cs_dsp_create_mock_xm_header(priv,
2200 bin_test_mock_algs,
2201 ARRAY_SIZE(bin_test_mock_algs));
2202 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, xm_hdr);
2203 ret = cs_dsp_mock_xm_header_write_to_regmap(xm_hdr);
2204 KUNIT_ASSERT_EQ(test, ret, 0);
2205
2206 priv->local->bin_builder =
2207 cs_dsp_mock_bin_init(priv, wmdr_ver,
2208 cs_dsp_mock_xm_header_get_fw_version(xm_hdr));
2209 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->local->bin_builder);
2210
2211 /* We must provide a dummy wmfw to load */
2212 priv->local->wmfw_builder = cs_dsp_mock_wmfw_init(priv, -1);
2213 priv->local->wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
2214
2215 dsp->client_ops = kunit_kzalloc(test, sizeof(*dsp->client_ops), GFP_KERNEL);
2216 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dsp->client_ops);
2217
2218 switch (dsp->type) {
2219 case WMFW_ADSP2:
2220 ret = cs_dsp_adsp2_init(dsp);
2221 break;
2222 case WMFW_HALO:
2223 ret = cs_dsp_halo_init(dsp);
2224 break;
2225 default:
2226 KUNIT_FAIL(test, "Untested DSP type %d\n", dsp->type);
2227 return -EINVAL;
2228 }
2229
2230 if (ret)
2231 return ret;
2232
2233 /* Automatically call cs_dsp_remove() when test case ends */
2234 ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
2235 if (ret)
2236 return ret;
2237
2238 /*
2239 * The large number of test cases will cause an unusually large amount
2240 * of dev_info() messages from cs_dsp, so suppress these.
2241 */
2242 cs_dsp_suppress_info_messages = true;
2243
2244 return 0;
2245 }
2246
cs_dsp_bin_test_exit(struct kunit * test)2247 static void cs_dsp_bin_test_exit(struct kunit *test)
2248 {
2249 cs_dsp_suppress_info_messages = false;
2250 }
2251
cs_dsp_bin_test_halo_init_common(struct kunit * test,int wmdr_ver)2252 static int cs_dsp_bin_test_halo_init_common(struct kunit *test, int wmdr_ver)
2253 {
2254 struct cs_dsp *dsp;
2255
2256 /* Fill in cs_dsp and initialize */
2257 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
2258 if (!dsp)
2259 return -ENOMEM;
2260
2261 dsp->num = 1;
2262 dsp->type = WMFW_HALO;
2263 dsp->mem = cs_dsp_mock_halo_dsp1_regions;
2264 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_halo_dsp1_region_sizes);
2265 dsp->base = cs_dsp_mock_halo_core_base;
2266 dsp->base_sysinfo = cs_dsp_mock_halo_sysinfo_base;
2267
2268 return cs_dsp_bin_test_common_init(test, dsp, wmdr_ver);
2269 }
2270
cs_dsp_bin_test_halo_init(struct kunit * test)2271 static int cs_dsp_bin_test_halo_init(struct kunit *test)
2272 {
2273 return cs_dsp_bin_test_halo_init_common(test, 1);
2274 }
2275
cs_dsp_bin_test_halo_wmdr3_init(struct kunit * test)2276 static int cs_dsp_bin_test_halo_wmdr3_init(struct kunit *test)
2277 {
2278 return cs_dsp_bin_test_halo_init_common(test, 3);
2279 }
2280
cs_dsp_bin_test_adsp2_32bit_init(struct kunit * test)2281 static int cs_dsp_bin_test_adsp2_32bit_init(struct kunit *test)
2282 {
2283 struct cs_dsp *dsp;
2284
2285 /* Fill in cs_dsp and initialize */
2286 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
2287 if (!dsp)
2288 return -ENOMEM;
2289
2290 dsp->num = 1;
2291 dsp->type = WMFW_ADSP2;
2292 dsp->rev = 1;
2293 dsp->mem = cs_dsp_mock_adsp2_32bit_dsp1_regions;
2294 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_32bit_dsp1_region_sizes);
2295 dsp->base = cs_dsp_mock_adsp2_32bit_sysbase;
2296
2297 return cs_dsp_bin_test_common_init(test, dsp, 1);
2298 }
2299
cs_dsp_bin_test_adsp2_16bit_init(struct kunit * test)2300 static int cs_dsp_bin_test_adsp2_16bit_init(struct kunit *test)
2301 {
2302 struct cs_dsp *dsp;
2303
2304 /* Fill in cs_dsp and initialize */
2305 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);
2306 if (!dsp)
2307 return -ENOMEM;
2308
2309 dsp->num = 1;
2310 dsp->type = WMFW_ADSP2;
2311 dsp->rev = 0;
2312 dsp->mem = cs_dsp_mock_adsp2_16bit_dsp1_regions;
2313 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_16bit_dsp1_region_sizes);
2314 dsp->base = cs_dsp_mock_adsp2_16bit_sysbase;
2315
2316 return cs_dsp_bin_test_common_init(test, dsp, 1);
2317 }
2318
2319 #define WMDR_PATCH_SHORT .add_patch = cs_dsp_mock_bin_add_patch
2320 #define WMDR_PATCH_LONG .add_patch = cs_dsp_mock_bin_add_patch_off32
2321
2322 /* Parameterize on choice of XM or YM with a range of word offsets */
2323 static const struct bin_test_param x_or_y_and_offset_param_cases[] = {
2324 { .mem_type = WMFW_ADSP2_XM, .offset_words = 0, WMDR_PATCH_SHORT },
2325 { .mem_type = WMFW_ADSP2_XM, .offset_words = 1, WMDR_PATCH_SHORT },
2326 { .mem_type = WMFW_ADSP2_XM, .offset_words = 2, WMDR_PATCH_SHORT },
2327 { .mem_type = WMFW_ADSP2_XM, .offset_words = 3, WMDR_PATCH_SHORT },
2328 { .mem_type = WMFW_ADSP2_XM, .offset_words = 4, WMDR_PATCH_SHORT },
2329 { .mem_type = WMFW_ADSP2_XM, .offset_words = 23, WMDR_PATCH_SHORT },
2330 { .mem_type = WMFW_ADSP2_XM, .offset_words = 22, WMDR_PATCH_SHORT },
2331 { .mem_type = WMFW_ADSP2_XM, .offset_words = 21, WMDR_PATCH_SHORT },
2332 { .mem_type = WMFW_ADSP2_XM, .offset_words = 20, WMDR_PATCH_SHORT },
2333
2334 { .mem_type = WMFW_ADSP2_YM, .offset_words = 0, WMDR_PATCH_SHORT },
2335 { .mem_type = WMFW_ADSP2_YM, .offset_words = 1, WMDR_PATCH_SHORT },
2336 { .mem_type = WMFW_ADSP2_YM, .offset_words = 2, WMDR_PATCH_SHORT },
2337 { .mem_type = WMFW_ADSP2_YM, .offset_words = 3, WMDR_PATCH_SHORT },
2338 { .mem_type = WMFW_ADSP2_YM, .offset_words = 4, WMDR_PATCH_SHORT },
2339 { .mem_type = WMFW_ADSP2_YM, .offset_words = 23, WMDR_PATCH_SHORT },
2340 { .mem_type = WMFW_ADSP2_YM, .offset_words = 22, WMDR_PATCH_SHORT },
2341 { .mem_type = WMFW_ADSP2_YM, .offset_words = 21, WMDR_PATCH_SHORT },
2342 { .mem_type = WMFW_ADSP2_YM, .offset_words = 20, WMDR_PATCH_SHORT },
2343 };
2344
2345 static const struct bin_test_param x_or_y_and_long_offset_param_cases[] = {
2346 /* Offset < 0xffff in long-offset block type */
2347 { .mem_type = WMFW_ADSP2_XM, .offset_words = 0, WMDR_PATCH_LONG },
2348 { .mem_type = WMFW_ADSP2_XM, .offset_words = 1, WMDR_PATCH_LONG },
2349 { .mem_type = WMFW_ADSP2_XM, .offset_words = 2, WMDR_PATCH_LONG },
2350 { .mem_type = WMFW_ADSP2_XM, .offset_words = 3, WMDR_PATCH_LONG },
2351 { .mem_type = WMFW_ADSP2_XM, .offset_words = 4, WMDR_PATCH_LONG },
2352 { .mem_type = WMFW_ADSP2_XM, .offset_words = 23, WMDR_PATCH_LONG },
2353 { .mem_type = WMFW_ADSP2_XM, .offset_words = 22, WMDR_PATCH_LONG },
2354 { .mem_type = WMFW_ADSP2_XM, .offset_words = 21, WMDR_PATCH_LONG },
2355 { .mem_type = WMFW_ADSP2_XM, .offset_words = 20, WMDR_PATCH_LONG },
2356
2357 /* Offset < 0xffff in long-offset block type */
2358 { .mem_type = WMFW_ADSP2_YM, .offset_words = 0, WMDR_PATCH_LONG },
2359 { .mem_type = WMFW_ADSP2_YM, .offset_words = 1, WMDR_PATCH_LONG },
2360 { .mem_type = WMFW_ADSP2_YM, .offset_words = 2, WMDR_PATCH_LONG },
2361 { .mem_type = WMFW_ADSP2_YM, .offset_words = 3, WMDR_PATCH_LONG },
2362 { .mem_type = WMFW_ADSP2_YM, .offset_words = 4, WMDR_PATCH_LONG },
2363 { .mem_type = WMFW_ADSP2_YM, .offset_words = 23, WMDR_PATCH_LONG },
2364 { .mem_type = WMFW_ADSP2_YM, .offset_words = 22, WMDR_PATCH_LONG },
2365 { .mem_type = WMFW_ADSP2_YM, .offset_words = 21, WMDR_PATCH_LONG },
2366 { .mem_type = WMFW_ADSP2_YM, .offset_words = 20, WMDR_PATCH_LONG },
2367
2368 /* Offset > 0xffff in long-offset block type */
2369 { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x10000, WMDR_PATCH_LONG },
2370 { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x10001, WMDR_PATCH_LONG },
2371 { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x10002, WMDR_PATCH_LONG },
2372 { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x10003, WMDR_PATCH_LONG },
2373 { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x10004, WMDR_PATCH_LONG },
2374 { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x2f003, WMDR_PATCH_LONG },
2375 { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x2f002, WMDR_PATCH_LONG },
2376 { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x2f001, WMDR_PATCH_LONG },
2377 { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x2f000, WMDR_PATCH_LONG },
2378
2379 /* Offset > 0xffff in long-offset block type */
2380 { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x10000, WMDR_PATCH_LONG },
2381 { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x10001, WMDR_PATCH_LONG },
2382 { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x10002, WMDR_PATCH_LONG },
2383 { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x10003, WMDR_PATCH_LONG },
2384 { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x10004, WMDR_PATCH_LONG },
2385 { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x2f003, WMDR_PATCH_LONG },
2386 { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x2f002, WMDR_PATCH_LONG },
2387 { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x2f001, WMDR_PATCH_LONG },
2388 { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x2f000, WMDR_PATCH_LONG },
2389 };
2390
2391 /* Parameterize on ZM with a range of word offsets */
2392 static const struct bin_test_param z_and_offset_param_cases[] = {
2393 { .mem_type = WMFW_ADSP2_ZM, .offset_words = 0, WMDR_PATCH_SHORT },
2394 { .mem_type = WMFW_ADSP2_ZM, .offset_words = 1, WMDR_PATCH_SHORT },
2395 { .mem_type = WMFW_ADSP2_ZM, .offset_words = 2, WMDR_PATCH_SHORT },
2396 { .mem_type = WMFW_ADSP2_ZM, .offset_words = 3, WMDR_PATCH_SHORT },
2397 { .mem_type = WMFW_ADSP2_ZM, .offset_words = 4, WMDR_PATCH_SHORT },
2398 { .mem_type = WMFW_ADSP2_ZM, .offset_words = 23, WMDR_PATCH_SHORT },
2399 { .mem_type = WMFW_ADSP2_ZM, .offset_words = 22, WMDR_PATCH_SHORT },
2400 { .mem_type = WMFW_ADSP2_ZM, .offset_words = 21, WMDR_PATCH_SHORT },
2401 { .mem_type = WMFW_ADSP2_ZM, .offset_words = 20, WMDR_PATCH_SHORT },
2402 };
2403
2404 /* Parameterize on choice of packed XM or YM with a range of word offsets */
2405 static const struct bin_test_param packed_x_or_y_and_offset_param_cases[] = {
2406 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0, WMDR_PATCH_SHORT },
2407 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 4, WMDR_PATCH_SHORT },
2408 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 8, WMDR_PATCH_SHORT },
2409 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 12, WMDR_PATCH_SHORT },
2410
2411 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0, WMDR_PATCH_SHORT },
2412 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 4, WMDR_PATCH_SHORT },
2413 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 8, WMDR_PATCH_SHORT },
2414 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 12, WMDR_PATCH_SHORT },
2415 };
2416
2417 static const struct bin_test_param packed_x_or_y_and_long_offset_param_cases[] = {
2418 /* Offset < 0xffff in long-offset block type */
2419 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0, WMDR_PATCH_LONG },
2420 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 4, WMDR_PATCH_LONG },
2421 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 8, WMDR_PATCH_LONG },
2422 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 12, WMDR_PATCH_LONG },
2423
2424 /* Offset < 0xffff in long-offset block type */
2425 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0, WMDR_PATCH_LONG },
2426 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 4, WMDR_PATCH_LONG },
2427 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 8, WMDR_PATCH_LONG },
2428 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 12, WMDR_PATCH_LONG },
2429
2430 /* Offset > 0xffff in long-offset block type */
2431 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0x10000, WMDR_PATCH_LONG },
2432 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0x10004, WMDR_PATCH_LONG },
2433 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0x10008, WMDR_PATCH_LONG },
2434 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0x2f000, WMDR_PATCH_LONG },
2435 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0x2f004, WMDR_PATCH_LONG },
2436
2437 /* Offset > 0xffff in long-offset block type */
2438 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0x10000, WMDR_PATCH_LONG },
2439 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0x10004, WMDR_PATCH_LONG },
2440 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0x10008, WMDR_PATCH_LONG },
2441 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0x2f000, WMDR_PATCH_LONG },
2442 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0x2f004, WMDR_PATCH_LONG },
2443 };
2444
x_or_y_or_z_and_offset_param_desc(const struct bin_test_param * param,char * desc)2445 static void x_or_y_or_z_and_offset_param_desc(const struct bin_test_param *param,
2446 char *desc)
2447 {
2448 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s@%u %s",
2449 cs_dsp_mem_region_name(param->mem_type),
2450 param->offset_words,
2451 (param->add_patch == cs_dsp_mock_bin_add_patch_off32) ? "offs32" : "");
2452 }
2453
2454 KUNIT_ARRAY_PARAM(x_or_y_and_offset,
2455 x_or_y_and_offset_param_cases,
2456 x_or_y_or_z_and_offset_param_desc);
2457
2458 KUNIT_ARRAY_PARAM(x_or_y_and_long_offset,
2459 x_or_y_and_long_offset_param_cases,
2460 x_or_y_or_z_and_offset_param_desc);
2461
2462 KUNIT_ARRAY_PARAM(z_and_offset,
2463 z_and_offset_param_cases,
2464 x_or_y_or_z_and_offset_param_desc);
2465
2466 KUNIT_ARRAY_PARAM(packed_x_or_y_and_offset,
2467 packed_x_or_y_and_offset_param_cases,
2468 x_or_y_or_z_and_offset_param_desc);
2469
2470 KUNIT_ARRAY_PARAM(packed_x_or_y_and_long_offset,
2471 packed_x_or_y_and_long_offset_param_cases,
2472 x_or_y_or_z_and_offset_param_desc);
2473
2474 /* Parameterize on choice of packed XM or YM */
2475 static const struct bin_test_param packed_x_or_y_param_cases[] = {
2476 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0, WMDR_PATCH_SHORT },
2477 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0, WMDR_PATCH_SHORT },
2478 };
2479
2480 static const struct bin_test_param packed_x_or_y_long_param_cases[] = {
2481 { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0, WMDR_PATCH_LONG },
2482 { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0, WMDR_PATCH_LONG },
2483 };
2484
x_or_y_or_z_param_desc(const struct bin_test_param * param,char * desc)2485 static void x_or_y_or_z_param_desc(const struct bin_test_param *param,
2486 char *desc)
2487 {
2488 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s %s",
2489 cs_dsp_mem_region_name(param->mem_type),
2490 (param->add_patch == cs_dsp_mock_bin_add_patch_off32) ? "offs32" : "");
2491 }
2492
2493 KUNIT_ARRAY_PARAM(packed_x_or_y, packed_x_or_y_param_cases, x_or_y_or_z_param_desc);
2494 KUNIT_ARRAY_PARAM(packed_x_or_y_long, packed_x_or_y_long_param_cases, x_or_y_or_z_param_desc);
2495
2496 static const struct bin_test_param offset_param_cases[] = {
2497 { .offset_words = 0, WMDR_PATCH_SHORT },
2498 { .offset_words = 1, WMDR_PATCH_SHORT },
2499 { .offset_words = 2, WMDR_PATCH_SHORT },
2500 { .offset_words = 3, WMDR_PATCH_SHORT },
2501 { .offset_words = 4, WMDR_PATCH_SHORT },
2502 { .offset_words = 23, WMDR_PATCH_SHORT },
2503 { .offset_words = 22, WMDR_PATCH_SHORT },
2504 { .offset_words = 21, WMDR_PATCH_SHORT },
2505 { .offset_words = 20, WMDR_PATCH_SHORT },
2506 };
2507
2508 static const struct bin_test_param long_offset_param_cases[] = {
2509 /* Offset < 0xffff in long-offset block type */
2510 { .offset_words = 0, WMDR_PATCH_LONG },
2511 { .offset_words = 1, WMDR_PATCH_LONG },
2512 { .offset_words = 2, WMDR_PATCH_LONG },
2513 { .offset_words = 3, WMDR_PATCH_LONG },
2514 { .offset_words = 4, WMDR_PATCH_LONG },
2515 { .offset_words = 23, WMDR_PATCH_LONG },
2516 { .offset_words = 22, WMDR_PATCH_LONG },
2517 { .offset_words = 21, WMDR_PATCH_LONG },
2518 { .offset_words = 20, WMDR_PATCH_LONG },
2519
2520 /* Offset > 0xffff in long-offset block type */
2521 { .offset_words = 0x10000, WMDR_PATCH_LONG },
2522 { .offset_words = 0x10001, WMDR_PATCH_LONG },
2523 { .offset_words = 0x10002, WMDR_PATCH_LONG },
2524 { .offset_words = 0x10003, WMDR_PATCH_LONG },
2525 { .offset_words = 0x10004, WMDR_PATCH_LONG },
2526 { .offset_words = 0x2f000, WMDR_PATCH_LONG },
2527 { .offset_words = 0x2f001, WMDR_PATCH_LONG },
2528 { .offset_words = 0x2f002, WMDR_PATCH_LONG },
2529 { .offset_words = 0x2f003, WMDR_PATCH_LONG },
2530 };
2531
offset_param_desc(const struct bin_test_param * param,char * desc)2532 static void offset_param_desc(const struct bin_test_param *param, char *desc)
2533 {
2534 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "@%u %s",
2535 param->offset_words,
2536 (param->add_patch == cs_dsp_mock_bin_add_patch_off32) ? "offs32" : "");
2537 }
2538
2539 KUNIT_ARRAY_PARAM(offset, offset_param_cases, offset_param_desc);
2540 KUNIT_ARRAY_PARAM(long_offset, long_offset_param_cases, offset_param_desc);
2541
2542 static const struct bin_test_param alg_param_cases[] = {
2543 { .alg_idx = 0, WMDR_PATCH_SHORT },
2544 { .alg_idx = 1, WMDR_PATCH_SHORT },
2545 { .alg_idx = 2, WMDR_PATCH_SHORT },
2546 { .alg_idx = 3, WMDR_PATCH_SHORT },
2547 };
2548
2549 static const struct bin_test_param alg_long_param_cases[] = {
2550 { .alg_idx = 0, WMDR_PATCH_LONG },
2551 { .alg_idx = 1, WMDR_PATCH_LONG },
2552 { .alg_idx = 2, WMDR_PATCH_LONG },
2553 { .alg_idx = 3, WMDR_PATCH_LONG },
2554 };
2555
alg_param_desc(const struct bin_test_param * param,char * desc)2556 static void alg_param_desc(const struct bin_test_param *param, char *desc)
2557 {
2558 WARN_ON(param->alg_idx >= ARRAY_SIZE(bin_test_mock_algs));
2559
2560 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "alg[%u] (%#x) %s",
2561 param->alg_idx, bin_test_mock_algs[param->alg_idx].id,
2562 (param->add_patch == cs_dsp_mock_bin_add_patch_off32) ? "offs32" : "");
2563 }
2564
2565 KUNIT_ARRAY_PARAM(alg, alg_param_cases, alg_param_desc);
2566 KUNIT_ARRAY_PARAM(alg_long, alg_long_param_cases, alg_param_desc);
2567
2568 static const struct bin_test_param x_or_y_and_alg_param_cases[] = {
2569 { .mem_type = WMFW_ADSP2_XM, .alg_idx = 0, WMDR_PATCH_SHORT },
2570 { .mem_type = WMFW_ADSP2_XM, .alg_idx = 1, WMDR_PATCH_SHORT },
2571 { .mem_type = WMFW_ADSP2_XM, .alg_idx = 2, WMDR_PATCH_SHORT },
2572 { .mem_type = WMFW_ADSP2_XM, .alg_idx = 3, WMDR_PATCH_SHORT },
2573
2574 { .mem_type = WMFW_ADSP2_YM, .alg_idx = 0, WMDR_PATCH_SHORT },
2575 { .mem_type = WMFW_ADSP2_YM, .alg_idx = 1, WMDR_PATCH_SHORT },
2576 { .mem_type = WMFW_ADSP2_YM, .alg_idx = 2, WMDR_PATCH_SHORT },
2577 { .mem_type = WMFW_ADSP2_YM, .alg_idx = 3, WMDR_PATCH_SHORT },
2578 };
2579
2580 static const struct bin_test_param x_or_y_and_alg_long_param_cases[] = {
2581 { .mem_type = WMFW_ADSP2_XM, .alg_idx = 0, WMDR_PATCH_LONG },
2582 { .mem_type = WMFW_ADSP2_XM, .alg_idx = 1, WMDR_PATCH_LONG },
2583 { .mem_type = WMFW_ADSP2_XM, .alg_idx = 2, WMDR_PATCH_LONG },
2584 { .mem_type = WMFW_ADSP2_XM, .alg_idx = 3, WMDR_PATCH_LONG },
2585
2586 { .mem_type = WMFW_ADSP2_YM, .alg_idx = 0, WMDR_PATCH_LONG },
2587 { .mem_type = WMFW_ADSP2_YM, .alg_idx = 1, WMDR_PATCH_LONG },
2588 { .mem_type = WMFW_ADSP2_YM, .alg_idx = 2, WMDR_PATCH_LONG },
2589 { .mem_type = WMFW_ADSP2_YM, .alg_idx = 3, WMDR_PATCH_LONG },
2590 };
2591
x_or_y_or_z_and_alg_param_desc(const struct bin_test_param * param,char * desc)2592 static void x_or_y_or_z_and_alg_param_desc(const struct bin_test_param *param, char *desc)
2593 {
2594 WARN_ON(param->alg_idx >= ARRAY_SIZE(bin_test_mock_algs));
2595
2596 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s alg[%u] (%#x) %s",
2597 cs_dsp_mem_region_name(param->mem_type),
2598 param->alg_idx, bin_test_mock_algs[param->alg_idx].id,
2599 (param->add_patch == cs_dsp_mock_bin_add_patch_off32) ? "offs32" : "");
2600 }
2601
2602 KUNIT_ARRAY_PARAM(x_or_y_and_alg, x_or_y_and_alg_param_cases, x_or_y_or_z_and_alg_param_desc);
2603 KUNIT_ARRAY_PARAM(x_or_y_and_alg_long, x_or_y_and_alg_long_param_cases,
2604 x_or_y_or_z_and_alg_param_desc);
2605
2606 static const struct bin_test_param z_and_alg_param_cases[] = {
2607 { .mem_type = WMFW_ADSP2_ZM, .alg_idx = 0, WMDR_PATCH_SHORT },
2608 { .mem_type = WMFW_ADSP2_ZM, .alg_idx = 1, WMDR_PATCH_SHORT },
2609 { .mem_type = WMFW_ADSP2_ZM, .alg_idx = 2, WMDR_PATCH_SHORT },
2610 { .mem_type = WMFW_ADSP2_ZM, .alg_idx = 3, WMDR_PATCH_SHORT },
2611 };
2612
2613 KUNIT_ARRAY_PARAM(z_and_alg, z_and_alg_param_cases, x_or_y_or_z_and_alg_param_desc);
2614
2615 static const struct bin_test_param packed_x_or_y_and_alg_param_cases[] = {
2616 { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 0, WMDR_PATCH_SHORT },
2617 { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 1, WMDR_PATCH_SHORT },
2618 { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 2, WMDR_PATCH_SHORT },
2619 { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 3, WMDR_PATCH_SHORT },
2620
2621 { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 0, WMDR_PATCH_SHORT },
2622 { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 1, WMDR_PATCH_SHORT },
2623 { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 2, WMDR_PATCH_SHORT },
2624 { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 3, WMDR_PATCH_SHORT },
2625 };
2626
2627 static const struct bin_test_param packed_x_or_y_and_alg_long_param_cases[] = {
2628 { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 0, WMDR_PATCH_LONG },
2629 { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 1, WMDR_PATCH_LONG },
2630 { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 2, WMDR_PATCH_LONG },
2631 { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 3, WMDR_PATCH_LONG },
2632
2633 { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 0, WMDR_PATCH_LONG },
2634 { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 1, WMDR_PATCH_LONG },
2635 { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 2, WMDR_PATCH_LONG },
2636 { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 3, WMDR_PATCH_LONG },
2637 };
2638
2639 KUNIT_ARRAY_PARAM(packed_x_or_y_and_alg, packed_x_or_y_and_alg_param_cases,
2640 x_or_y_or_z_and_alg_param_desc);
2641
2642 KUNIT_ARRAY_PARAM(packed_x_or_y_and_alg_long, packed_x_or_y_and_alg_long_param_cases,
2643 x_or_y_or_z_and_alg_param_desc);
2644
2645 static struct kunit_case cs_dsp_bin_test_cases_halo[] = {
2646 /* Unpacked memory */
2647 KUNIT_CASE_PARAM(bin_patch_one_word, x_or_y_and_offset_gen_params),
2648 KUNIT_CASE_PARAM(bin_patch_one_multiword, x_or_y_and_offset_gen_params),
2649 KUNIT_CASE_PARAM(bin_patch_multi_oneword, x_or_y_and_offset_gen_params),
2650 KUNIT_CASE_PARAM(bin_patch_multi_oneword_unordered, x_or_y_and_offset_gen_params),
2651 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_mems, offset_gen_params),
2652 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_mems, alg_gen_params),
2653 KUNIT_CASE_PARAM(bin_patch_multi_oneword_sparse_unordered, x_or_y_and_alg_gen_params),
2654 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs, x_or_y_and_offset_gen_params),
2655 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs_unordered, x_or_y_and_offset_gen_params),
2656
2657 /* Packed memory tests */
2658 KUNIT_CASE_PARAM(bin_patch_1_packed,
2659 packed_x_or_y_and_offset_gen_params),
2660 KUNIT_CASE_PARAM(bin_patch_1_packed_1_single_trailing,
2661 packed_x_or_y_and_offset_gen_params),
2662 KUNIT_CASE_PARAM(bin_patch_1_packed_2_single_trailing,
2663 packed_x_or_y_and_offset_gen_params),
2664 KUNIT_CASE_PARAM(bin_patch_1_packed_3_single_trailing,
2665 packed_x_or_y_and_offset_gen_params),
2666 KUNIT_CASE_PARAM(bin_patch_1_packed_2_trailing,
2667 packed_x_or_y_and_offset_gen_params),
2668 KUNIT_CASE_PARAM(bin_patch_1_packed_3_trailing,
2669 packed_x_or_y_and_offset_gen_params),
2670 KUNIT_CASE_PARAM(bin_patch_1_single_leading_1_packed,
2671 packed_x_or_y_and_offset_gen_params),
2672 KUNIT_CASE_PARAM(bin_patch_2_single_leading_1_packed,
2673 packed_x_or_y_and_offset_gen_params),
2674 KUNIT_CASE_PARAM(bin_patch_2_leading_1_packed,
2675 packed_x_or_y_and_offset_gen_params),
2676 KUNIT_CASE_PARAM(bin_patch_3_single_leading_1_packed,
2677 packed_x_or_y_and_offset_gen_params),
2678 KUNIT_CASE_PARAM(bin_patch_3_leading_1_packed,
2679 packed_x_or_y_and_offset_gen_params),
2680 KUNIT_CASE_PARAM(bin_patch_multi_onepacked,
2681 packed_x_or_y_and_offset_gen_params),
2682 KUNIT_CASE_PARAM(bin_patch_multi_onepacked_unordered,
2683 packed_x_or_y_and_offset_gen_params),
2684 KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_mems, offset_gen_params),
2685 KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_mems, alg_gen_params),
2686 KUNIT_CASE_PARAM(bin_patch_multi_onepacked_sparse_unordered,
2687 packed_x_or_y_and_alg_gen_params),
2688 KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_algs,
2689 packed_x_or_y_and_offset_gen_params),
2690 KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_algs_unordered,
2691 packed_x_or_y_and_offset_gen_params),
2692 KUNIT_CASE_PARAM(bin_patch_mixed_packed_unpacked_random,
2693 packed_x_or_y_gen_params),
2694
2695 KUNIT_CASE(bin_patch_name_and_info),
2696
2697 { } /* terminator */
2698 };
2699
2700 static struct kunit_case cs_dsp_bin_test_cases_halo_wmdr3[] = {
2701 /* Unpacked memory */
2702 KUNIT_CASE_PARAM(bin_patch_one_word, x_or_y_and_offset_gen_params),
2703 KUNIT_CASE_PARAM(bin_patch_one_multiword, x_or_y_and_offset_gen_params),
2704 KUNIT_CASE_PARAM(bin_patch_multi_oneword, x_or_y_and_offset_gen_params),
2705 KUNIT_CASE_PARAM(bin_patch_multi_oneword_unordered, x_or_y_and_offset_gen_params),
2706 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_mems, offset_gen_params),
2707 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_mems, alg_gen_params),
2708 KUNIT_CASE_PARAM(bin_patch_multi_oneword_sparse_unordered, x_or_y_and_alg_gen_params),
2709 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs, x_or_y_and_offset_gen_params),
2710 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs_unordered, x_or_y_and_offset_gen_params),
2711
2712 /* Packed memory tests */
2713 KUNIT_CASE_PARAM(bin_patch_1_packed,
2714 packed_x_or_y_and_offset_gen_params),
2715 KUNIT_CASE_PARAM(bin_patch_1_packed_1_single_trailing,
2716 packed_x_or_y_and_offset_gen_params),
2717 KUNIT_CASE_PARAM(bin_patch_1_packed_2_single_trailing,
2718 packed_x_or_y_and_offset_gen_params),
2719 KUNIT_CASE_PARAM(bin_patch_1_packed_3_single_trailing,
2720 packed_x_or_y_and_offset_gen_params),
2721 KUNIT_CASE_PARAM(bin_patch_1_packed_2_trailing,
2722 packed_x_or_y_and_offset_gen_params),
2723 KUNIT_CASE_PARAM(bin_patch_1_packed_3_trailing,
2724 packed_x_or_y_and_offset_gen_params),
2725 KUNIT_CASE_PARAM(bin_patch_1_single_leading_1_packed,
2726 packed_x_or_y_and_offset_gen_params),
2727 KUNIT_CASE_PARAM(bin_patch_2_single_leading_1_packed,
2728 packed_x_or_y_and_offset_gen_params),
2729 KUNIT_CASE_PARAM(bin_patch_2_leading_1_packed,
2730 packed_x_or_y_and_offset_gen_params),
2731 KUNIT_CASE_PARAM(bin_patch_3_single_leading_1_packed,
2732 packed_x_or_y_and_offset_gen_params),
2733 KUNIT_CASE_PARAM(bin_patch_3_leading_1_packed,
2734 packed_x_or_y_and_offset_gen_params),
2735 KUNIT_CASE_PARAM(bin_patch_multi_onepacked,
2736 packed_x_or_y_and_offset_gen_params),
2737 KUNIT_CASE_PARAM(bin_patch_multi_onepacked_unordered,
2738 packed_x_or_y_and_offset_gen_params),
2739 KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_mems, offset_gen_params),
2740 KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_mems, alg_gen_params),
2741 KUNIT_CASE_PARAM(bin_patch_multi_onepacked_sparse_unordered,
2742 packed_x_or_y_and_alg_gen_params),
2743 KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_algs,
2744 packed_x_or_y_and_offset_gen_params),
2745 KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_algs_unordered,
2746 packed_x_or_y_and_offset_gen_params),
2747 KUNIT_CASE_PARAM(bin_patch_mixed_packed_unpacked_random,
2748 packed_x_or_y_gen_params),
2749
2750 /* Unpacked memory with long-offset blocks */
2751 KUNIT_CASE_PARAM(bin_patch_one_word, x_or_y_and_long_offset_gen_params),
2752 KUNIT_CASE_PARAM(bin_patch_one_multiword, x_or_y_and_long_offset_gen_params),
2753 KUNIT_CASE_PARAM(bin_patch_multi_oneword, x_or_y_and_long_offset_gen_params),
2754 KUNIT_CASE_PARAM(bin_patch_multi_oneword_unordered, x_or_y_and_long_offset_gen_params),
2755 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_mems, long_offset_gen_params),
2756 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_mems, alg_long_gen_params),
2757 KUNIT_CASE_PARAM(bin_patch_multi_oneword_sparse_unordered, x_or_y_and_alg_long_gen_params),
2758 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs, x_or_y_and_long_offset_gen_params),
2759 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs_unordered,
2760 x_or_y_and_long_offset_gen_params),
2761
2762 /* Packed memory tests with long offset blocks */
2763 KUNIT_CASE_PARAM(bin_patch_1_packed,
2764 packed_x_or_y_and_long_offset_gen_params),
2765 KUNIT_CASE_PARAM(bin_patch_1_packed_1_single_trailing,
2766 packed_x_or_y_and_long_offset_gen_params),
2767 KUNIT_CASE_PARAM(bin_patch_1_packed_2_single_trailing,
2768 packed_x_or_y_and_long_offset_gen_params),
2769 KUNIT_CASE_PARAM(bin_patch_1_packed_3_single_trailing,
2770 packed_x_or_y_and_long_offset_gen_params),
2771 KUNIT_CASE_PARAM(bin_patch_1_packed_2_trailing,
2772 packed_x_or_y_and_long_offset_gen_params),
2773 KUNIT_CASE_PARAM(bin_patch_1_packed_3_trailing,
2774 packed_x_or_y_and_long_offset_gen_params),
2775 KUNIT_CASE_PARAM(bin_patch_1_single_leading_1_packed,
2776 packed_x_or_y_and_long_offset_gen_params),
2777 KUNIT_CASE_PARAM(bin_patch_2_single_leading_1_packed,
2778 packed_x_or_y_and_long_offset_gen_params),
2779 KUNIT_CASE_PARAM(bin_patch_2_leading_1_packed,
2780 packed_x_or_y_and_long_offset_gen_params),
2781 KUNIT_CASE_PARAM(bin_patch_3_single_leading_1_packed,
2782 packed_x_or_y_and_long_offset_gen_params),
2783 KUNIT_CASE_PARAM(bin_patch_3_leading_1_packed,
2784 packed_x_or_y_and_long_offset_gen_params),
2785 KUNIT_CASE_PARAM(bin_patch_multi_onepacked,
2786 packed_x_or_y_and_long_offset_gen_params),
2787 KUNIT_CASE_PARAM(bin_patch_multi_onepacked_unordered,
2788 packed_x_or_y_and_long_offset_gen_params),
2789 KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_mems, long_offset_gen_params),
2790 KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_mems, alg_long_gen_params),
2791 KUNIT_CASE_PARAM(bin_patch_multi_onepacked_sparse_unordered,
2792 packed_x_or_y_and_alg_long_gen_params),
2793 KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_algs,
2794 packed_x_or_y_and_long_offset_gen_params),
2795 KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_algs_unordered,
2796 packed_x_or_y_and_long_offset_gen_params),
2797 KUNIT_CASE_PARAM(bin_patch_mixed_packed_unpacked_random,
2798 packed_x_or_y_long_gen_params),
2799
2800 KUNIT_CASE(bin_patch_name_and_info),
2801
2802 { } /* terminator */
2803 };
2804
2805 static struct kunit_case cs_dsp_bin_test_cases_adsp2[] = {
2806 /* XM and YM */
2807 KUNIT_CASE_PARAM(bin_patch_one_word, x_or_y_and_offset_gen_params),
2808 KUNIT_CASE_PARAM(bin_patch_one_multiword, x_or_y_and_offset_gen_params),
2809 KUNIT_CASE_PARAM(bin_patch_multi_oneword, x_or_y_and_offset_gen_params),
2810 KUNIT_CASE_PARAM(bin_patch_multi_oneword_unordered, x_or_y_and_offset_gen_params),
2811 KUNIT_CASE_PARAM(bin_patch_multi_oneword_sparse_unordered, x_or_y_and_alg_gen_params),
2812 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs, x_or_y_and_offset_gen_params),
2813 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs_unordered, x_or_y_and_offset_gen_params),
2814
2815 /* ZM */
2816 KUNIT_CASE_PARAM(bin_patch_one_word, z_and_offset_gen_params),
2817 KUNIT_CASE_PARAM(bin_patch_one_multiword, z_and_offset_gen_params),
2818 KUNIT_CASE_PARAM(bin_patch_multi_oneword, z_and_offset_gen_params),
2819 KUNIT_CASE_PARAM(bin_patch_multi_oneword_unordered, z_and_offset_gen_params),
2820 KUNIT_CASE_PARAM(bin_patch_multi_oneword_sparse_unordered, z_and_alg_gen_params),
2821 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs, z_and_offset_gen_params),
2822 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs_unordered, z_and_offset_gen_params),
2823
2824 /* Other */
2825 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_mems, offset_gen_params),
2826 KUNIT_CASE_PARAM(bin_patch_one_word_multiple_mems, alg_gen_params),
2827
2828 KUNIT_CASE(bin_patch_name_and_info),
2829
2830 { } /* terminator */
2831 };
2832
2833 static struct kunit_suite cs_dsp_bin_test_halo = {
2834 .name = "cs_dsp_bin_halo",
2835 .init = cs_dsp_bin_test_halo_init,
2836 .exit = cs_dsp_bin_test_exit,
2837 .test_cases = cs_dsp_bin_test_cases_halo,
2838 };
2839
2840 static struct kunit_suite cs_dsp_bin_test_halo_wmdr3 = {
2841 .name = "cs_dsp_bin_halo_wmdr_v3",
2842 .init = cs_dsp_bin_test_halo_wmdr3_init,
2843 .test_cases = cs_dsp_bin_test_cases_halo_wmdr3,
2844 };
2845
2846 static struct kunit_suite cs_dsp_bin_test_adsp2_32bit = {
2847 .name = "cs_dsp_bin_adsp2_32bit",
2848 .init = cs_dsp_bin_test_adsp2_32bit_init,
2849 .exit = cs_dsp_bin_test_exit,
2850 .test_cases = cs_dsp_bin_test_cases_adsp2,
2851 };
2852
2853 static struct kunit_suite cs_dsp_bin_test_adsp2_16bit = {
2854 .name = "cs_dsp_bin_adsp2_16bit",
2855 .init = cs_dsp_bin_test_adsp2_16bit_init,
2856 .exit = cs_dsp_bin_test_exit,
2857 .test_cases = cs_dsp_bin_test_cases_adsp2,
2858 };
2859
2860 kunit_test_suites(&cs_dsp_bin_test_halo,
2861 &cs_dsp_bin_test_halo_wmdr3,
2862 &cs_dsp_bin_test_adsp2_32bit,
2863 &cs_dsp_bin_test_adsp2_16bit);
2864