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