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