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