File Index
Files and directories
Sign in
FILE

cs_dsp_test_wmfw.c

File preview with syntax highlighting.

linux-6.19.14/drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c C
   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
  36KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *)
  37KUNIT_DEFINE_ACTION_WRAPPER(_vfree_wrapper, vfree, void *)
  38KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *)
  39
  40struct 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
  46struct cs_dsp_wmfw_test_param {
  47	unsigned int num_blocks;
  48	int mem_type;
  49};
  50
  51static 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 */
  65static 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 */
  97static 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 */
 152static 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 */
 219static 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 */
 287static 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 */
 368static 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 */
 412static 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 */
 463static 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 */
 560static 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 */
 654static 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 */
 757static 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 */
 860static 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 */
 963static 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 */
1072static 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 */
1186static 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 */
1287static 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 */
1391static 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 */
1495static 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 */
1605static 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 */
1716static 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
1778static 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
1871static void cs_dsp_wmfw_test_exit(struct kunit *test)
1872{
1873	cs_dsp_suppress_info_messages = false;
1874}
1875
1876static 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
1895static 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
1914static 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
1919static 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
1924static 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
1929static 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
1948static 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
1953static 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
1958static 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
1963static 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
1970static 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
2020KUNIT_ARRAY_PARAM(adsp2_all_num_blocks,
2021		  adsp2_all_num_blocks_param_cases,
2022		  cs_dsp_mem_param_desc);
2023
2024static 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
2086KUNIT_ARRAY_PARAM(halo_all_num_blocks,
2087		  halo_all_num_blocks_param_cases,
2088		  cs_dsp_mem_param_desc);
2089
2090static 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
2116KUNIT_ARRAY_PARAM(packed_xy_num_blocks,
2117		  packed_xy_num_blocks_param_cases,
2118		  cs_dsp_mem_param_desc);
2119
2120static 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
2161static 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
2180static 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
2187static 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
2194static 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
2201static 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
2208static 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
2215static 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
2222static 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
2229kunit_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);
~/ Read-only file preview.