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