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