1 // SPDX-License-Identifier: GPL-2.0-only 2 // 3 // KUnit tests for cs_dsp. 4 // 5 // Copyright (C) 2024 Cirrus Logic, Inc. and 6 // Cirrus Logic International Semiconductor Ltd. 7 8 #include <kunit/device.h> 9 #include <kunit/resource.h> 10 #include <kunit/test.h> 11 #include <linux/build_bug.h> 12 #include <linux/firmware/cirrus/cs_dsp.h> 13 #include <linux/firmware/cirrus/cs_dsp_test_utils.h> 14 #include <linux/firmware/cirrus/wmfw.h> 15 #include <linux/list.h> 16 #include <linux/random.h> 17 #include <linux/regmap.h> 18 19 KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *); 20 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_stop_wrapper, cs_dsp_stop, struct cs_dsp *); 21 KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *); 22 23 struct cs_dsp_test_local { 24 struct cs_dsp_mock_xm_header *xm_header; 25 struct cs_dsp_mock_wmfw_builder *wmfw_builder; 26 int wmfw_version; 27 }; 28 29 struct cs_dsp_ctl_rw_test_param { 30 int mem_type; 31 int alg_id; 32 unsigned int offs_words; 33 unsigned int len_bytes; 34 u16 ctl_type; 35 u16 flags; 36 }; 37 38 static const struct cs_dsp_mock_alg_def cs_dsp_ctl_rw_test_algs[] = { 39 { 40 .id = 0xfafa, 41 .ver = 0x100000, 42 .xm_base_words = 60, 43 .xm_size_words = 1000, 44 .ym_base_words = 0, 45 .ym_size_words = 1000, 46 .zm_base_words = 0, 47 .zm_size_words = 1000, 48 }, 49 { 50 .id = 0xb, 51 .ver = 0x100001, 52 .xm_base_words = 1060, 53 .xm_size_words = 1000, 54 .ym_base_words = 1000, 55 .ym_size_words = 1000, 56 .zm_base_words = 1000, 57 .zm_size_words = 1000, 58 }, 59 { 60 .id = 0x9f1234, 61 .ver = 0x100500, 62 .xm_base_words = 2060, 63 .xm_size_words = 32, 64 .ym_base_words = 2000, 65 .ym_size_words = 32, 66 .zm_base_words = 2000, 67 .zm_size_words = 32, 68 }, 69 { 70 .id = 0xff00ff, 71 .ver = 0x300113, 72 .xm_base_words = 2100, 73 .xm_size_words = 32, 74 .ym_base_words = 2032, 75 .ym_size_words = 32, 76 .zm_base_words = 2032, 77 .zm_size_words = 32, 78 }, 79 }; 80 81 static const struct cs_dsp_mock_coeff_def mock_coeff_template = { 82 .shortname = "Dummy Coeff", 83 .type = WMFW_CTL_TYPE_BYTES, 84 .mem_type = WMFW_ADSP2_YM, 85 .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 86 .length_bytes = 4, 87 }; 88 89 static int _find_alg_entry(struct kunit *test, unsigned int alg_id) 90 { 91 int i; 92 93 for (i = 0; i < ARRAY_SIZE(cs_dsp_ctl_rw_test_algs); ++i) { 94 if (cs_dsp_ctl_rw_test_algs[i].id == alg_id) 95 break; 96 } 97 98 KUNIT_ASSERT_LT(test, i, ARRAY_SIZE(cs_dsp_ctl_rw_test_algs)); 99 100 return i; 101 } 102 103 static int _get_alg_mem_base_words(struct kunit *test, int alg_index, int mem_type) 104 { 105 switch (mem_type) { 106 case WMFW_ADSP2_XM: 107 return cs_dsp_ctl_rw_test_algs[alg_index].xm_base_words; 108 case WMFW_ADSP2_YM: 109 return cs_dsp_ctl_rw_test_algs[alg_index].ym_base_words; 110 case WMFW_ADSP2_ZM: 111 return cs_dsp_ctl_rw_test_algs[alg_index].zm_base_words; 112 default: 113 KUNIT_FAIL(test, "Bug in test: illegal memory type %d\n", mem_type); 114 return 0; 115 } 116 } 117 118 static struct cs_dsp_mock_wmfw_builder *_create_dummy_wmfw(struct kunit *test) 119 { 120 struct cs_dsp_test *priv = test->priv; 121 struct cs_dsp_test_local *local = priv->local; 122 struct cs_dsp_mock_wmfw_builder *builder; 123 124 builder = cs_dsp_mock_wmfw_init(priv, local->wmfw_version); 125 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, builder); 126 127 /* Init an XM header */ 128 cs_dsp_mock_wmfw_add_data_block(builder, 129 WMFW_ADSP2_XM, 0, 130 local->xm_header->blob_data, 131 local->xm_header->blob_size_bytes); 132 133 return builder; 134 } 135 136 /* 137 * Write to a control while the firmware is running. 138 * This should write to the underlying registers. 139 */ 140 static void cs_dsp_ctl_write_running(struct kunit *test) 141 { 142 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 143 struct cs_dsp_test *priv = test->priv; 144 struct cs_dsp_test_local *local = priv->local; 145 struct cs_dsp *dsp = priv->dsp; 146 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 147 int alg_idx = _find_alg_entry(test, param->alg_id); 148 unsigned int reg, alg_base_words; 149 struct cs_dsp_coeff_ctl *ctl; 150 struct firmware *wmfw; 151 u32 *reg_vals, *readback; 152 153 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 154 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 155 156 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 157 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 158 159 /* Create some initial register content */ 160 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 161 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 162 reg += (alg_base_words + param->offs_words) * 163 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 164 memset(reg_vals, 0, param->len_bytes); 165 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 166 167 /* Create control pointing to this data */ 168 def.flags = param->flags; 169 def.mem_type = param->mem_type; 170 def.offset_dsp_words = param->offs_words; 171 def.length_bytes = param->len_bytes; 172 173 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 174 cs_dsp_ctl_rw_test_algs[alg_idx].id, 175 "dummyalg", NULL); 176 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 177 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 178 179 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 180 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 181 182 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 183 KUNIT_ASSERT_NOT_NULL(test, ctl); 184 185 /* Start the firmware and add an action to stop it during cleanup */ 186 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 187 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 188 189 /* 190 * Write new data to the control, it should be written to the registers 191 * and cs_dsp_coeff_lock_and_write_ctrl() should return 1 to indicate 192 * that the control content changed. 193 */ 194 get_random_bytes(reg_vals, param->len_bytes); 195 KUNIT_EXPECT_EQ(test, 196 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 197 1); 198 KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0); 199 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 200 201 /* Drop expected writes and the regmap cache should be clean */ 202 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 203 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 204 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 205 } 206 207 /* 208 * Read from a volatile control while the firmware is running. 209 * This should return the current state of the underlying registers. 210 */ 211 static void cs_dsp_ctl_read_volatile_running(struct kunit *test) 212 { 213 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 214 struct cs_dsp_test *priv = test->priv; 215 struct cs_dsp_test_local *local = priv->local; 216 struct cs_dsp *dsp = priv->dsp; 217 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 218 int alg_idx = _find_alg_entry(test, param->alg_id); 219 unsigned int reg, alg_base_words; 220 struct cs_dsp_coeff_ctl *ctl; 221 struct firmware *wmfw; 222 u32 *reg_vals, *readback; 223 224 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 225 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 226 227 readback = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 228 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 229 230 /* Create some initial register content */ 231 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 232 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 233 reg += (alg_base_words + param->offs_words) * 234 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 235 memset(reg_vals, 0, param->len_bytes); 236 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 237 238 /* Create control pointing to this data */ 239 def.flags = param->flags | WMFW_CTL_FLAG_VOLATILE; 240 def.mem_type = param->mem_type; 241 def.offset_dsp_words = param->offs_words; 242 def.length_bytes = param->len_bytes; 243 244 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 245 cs_dsp_ctl_rw_test_algs[alg_idx].id, 246 "dummyalg", NULL); 247 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 248 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 249 250 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 251 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 252 253 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 254 KUNIT_ASSERT_NOT_NULL(test, ctl); 255 256 /* Start the firmware and add an action to stop it during cleanup */ 257 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 258 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 259 260 /* Read the control, it should return the current register content */ 261 KUNIT_EXPECT_EQ(test, 262 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 263 0); 264 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 265 266 /* 267 * Change the register content and read the control, it should return 268 * the new register content 269 */ 270 get_random_bytes(reg_vals, param->len_bytes); 271 KUNIT_ASSERT_EQ(test, regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes), 0); 272 KUNIT_EXPECT_EQ(test, 273 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes), 274 0); 275 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes); 276 } 277 278 /* 279 * Read from a volatile control before the firmware is started. 280 * This should return an error. 281 */ 282 static void cs_dsp_ctl_read_volatile_not_started(struct kunit *test) 283 { 284 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 285 struct cs_dsp_test *priv = test->priv; 286 struct cs_dsp_test_local *local = priv->local; 287 struct cs_dsp *dsp = priv->dsp; 288 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 289 int alg_idx = _find_alg_entry(test, param->alg_id); 290 unsigned int reg, alg_base_words; 291 struct cs_dsp_coeff_ctl *ctl; 292 struct firmware *wmfw; 293 u32 *reg_vals; 294 295 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 296 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 297 298 /* Create some initial register content */ 299 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 300 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 301 reg += (alg_base_words + param->offs_words) * 302 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 303 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 304 305 /* Create control pointing to this data */ 306 def.flags = param->flags | WMFW_CTL_FLAG_VOLATILE; 307 def.mem_type = param->mem_type; 308 def.offset_dsp_words = param->offs_words; 309 def.length_bytes = param->len_bytes; 310 311 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 312 cs_dsp_ctl_rw_test_algs[alg_idx].id, 313 "dummyalg", NULL); 314 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 315 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 316 317 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 318 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 319 320 /* Read the control, it should return an error */ 321 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 322 KUNIT_ASSERT_NOT_NULL(test, ctl); 323 KUNIT_EXPECT_LT(test, 324 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, reg_vals, param->len_bytes), 325 0); 326 } 327 328 /* 329 * Read from a volatile control after the firmware has stopped. 330 * This should return an error. 331 */ 332 static void cs_dsp_ctl_read_volatile_stopped(struct kunit *test) 333 { 334 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 335 struct cs_dsp_test *priv = test->priv; 336 struct cs_dsp_test_local *local = priv->local; 337 struct cs_dsp *dsp = priv->dsp; 338 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 339 int alg_idx = _find_alg_entry(test, param->alg_id); 340 unsigned int reg, alg_base_words; 341 struct cs_dsp_coeff_ctl *ctl; 342 struct firmware *wmfw; 343 u32 *reg_vals; 344 345 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 346 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 347 348 /* Create some initial register content */ 349 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 350 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 351 reg += (alg_base_words + param->offs_words) * 352 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 353 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 354 355 /* Create control pointing to this data */ 356 def.flags = param->flags | WMFW_CTL_FLAG_VOLATILE; 357 def.mem_type = param->mem_type; 358 def.offset_dsp_words = param->offs_words; 359 def.length_bytes = param->len_bytes; 360 361 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 362 cs_dsp_ctl_rw_test_algs[alg_idx].id, 363 "dummyalg", NULL); 364 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 365 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 366 367 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 368 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 369 370 /* Start and stop the firmware */ 371 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 372 cs_dsp_stop(dsp); 373 374 /* Read the control, it should return an error */ 375 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 376 KUNIT_ASSERT_NOT_NULL(test, ctl); 377 KUNIT_EXPECT_LT(test, 378 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, reg_vals, param->len_bytes), 379 0); 380 } 381 382 /* 383 * Read from a volatile control after the DSP has been powered down. 384 * This should return an error. 385 */ 386 static void cs_dsp_ctl_read_volatile_stopped_powered_down(struct kunit *test) 387 { 388 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 389 struct cs_dsp_test *priv = test->priv; 390 struct cs_dsp_test_local *local = priv->local; 391 struct cs_dsp *dsp = priv->dsp; 392 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 393 int alg_idx = _find_alg_entry(test, param->alg_id); 394 unsigned int reg, alg_base_words; 395 struct cs_dsp_coeff_ctl *ctl; 396 struct firmware *wmfw; 397 u32 *reg_vals; 398 399 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 400 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 401 402 /* Create some initial register content */ 403 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 404 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 405 reg += (alg_base_words + param->offs_words) * 406 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 407 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 408 409 /* Create control pointing to this data */ 410 def.flags = param->flags | WMFW_CTL_FLAG_VOLATILE; 411 def.mem_type = param->mem_type; 412 def.offset_dsp_words = param->offs_words; 413 def.length_bytes = param->len_bytes; 414 415 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 416 cs_dsp_ctl_rw_test_algs[alg_idx].id, 417 "dummyalg", NULL); 418 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 419 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 420 421 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 422 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 423 424 /* Start and stop the firmware then power down */ 425 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 426 cs_dsp_stop(dsp); 427 cs_dsp_power_down(dsp); 428 429 /* Read the control, it should return an error */ 430 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 431 KUNIT_ASSERT_NOT_NULL(test, ctl); 432 KUNIT_EXPECT_LT(test, 433 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, reg_vals, param->len_bytes), 434 0); 435 } 436 437 /* 438 * Read from a volatile control when a different firmware is currently 439 * loaded into the DSP. 440 * Should return an error. 441 */ 442 static void cs_dsp_ctl_read_volatile_not_current_loaded_fw(struct kunit *test) 443 { 444 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 445 struct cs_dsp_test *priv = test->priv; 446 struct cs_dsp_test_local *local = priv->local; 447 struct cs_dsp *dsp = priv->dsp; 448 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 449 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); 450 int alg_idx = _find_alg_entry(test, param->alg_id); 451 unsigned int reg, alg_base_words; 452 struct cs_dsp_coeff_ctl *ctl; 453 struct firmware *wmfw; 454 u32 *reg_vals; 455 456 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 457 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 458 459 /* Create some DSP data to be read into the control cache */ 460 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 461 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 462 reg += (alg_base_words + param->offs_words) * 463 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 464 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 465 466 /* Create control pointing to this data */ 467 def.flags = param->flags | WMFW_CTL_FLAG_VOLATILE; 468 def.mem_type = param->mem_type; 469 def.offset_dsp_words = param->offs_words; 470 def.length_bytes = param->len_bytes; 471 472 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 473 cs_dsp_ctl_rw_test_algs[alg_idx].id, 474 "dummyalg", NULL); 475 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 476 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 477 478 /* Power-up DSP */ 479 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 480 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 481 482 /* Power-down DSP then power-up with a different firmware */ 483 cs_dsp_power_down(dsp); 484 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2); 485 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0); 486 487 /* Read the control, it should return an error */ 488 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 489 KUNIT_ASSERT_NOT_NULL(test, ctl); 490 KUNIT_EXPECT_LT(test, 491 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, reg_vals, param->len_bytes), 492 0); 493 } 494 495 /* 496 * Read from a volatile control when a different firmware is currently 497 * running. 498 * Should return an error. 499 */ 500 static void cs_dsp_ctl_read_volatile_not_current_running_fw(struct kunit *test) 501 { 502 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 503 struct cs_dsp_test *priv = test->priv; 504 struct cs_dsp_test_local *local = priv->local; 505 struct cs_dsp *dsp = priv->dsp; 506 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 507 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); 508 int alg_idx = _find_alg_entry(test, param->alg_id); 509 unsigned int reg, alg_base_words; 510 struct cs_dsp_coeff_ctl *ctl; 511 struct firmware *wmfw; 512 u32 *reg_vals; 513 514 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 515 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 516 517 /* Create some DSP data to be read into the control cache */ 518 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 519 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 520 reg += (alg_base_words + param->offs_words) * 521 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 522 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 523 524 /* Create control pointing to this data */ 525 def.flags = param->flags | WMFW_CTL_FLAG_VOLATILE; 526 def.mem_type = param->mem_type; 527 def.offset_dsp_words = param->offs_words; 528 def.length_bytes = param->len_bytes; 529 530 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 531 cs_dsp_ctl_rw_test_algs[alg_idx].id, 532 "dummyalg", NULL); 533 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 534 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 535 536 /* Power-up DSP */ 537 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 538 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 539 540 /* Power-down DSP then power-up with a different firmware */ 541 cs_dsp_power_down(dsp); 542 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2); 543 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0); 544 545 /* Start the firmware and add an action to stop it during cleanup */ 546 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 547 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 548 549 /* Read the control, it should return an error */ 550 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 551 KUNIT_ASSERT_NOT_NULL(test, ctl); 552 KUNIT_EXPECT_LT(test, 553 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, reg_vals, param->len_bytes), 554 0); 555 } 556 557 /* 558 * Write to a volatile control before the firmware is started. 559 * This should return an error. 560 */ 561 static void cs_dsp_ctl_write_volatile_not_started(struct kunit *test) 562 { 563 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 564 struct cs_dsp_test *priv = test->priv; 565 struct cs_dsp_test_local *local = priv->local; 566 struct cs_dsp *dsp = priv->dsp; 567 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 568 int alg_idx = _find_alg_entry(test, param->alg_id); 569 unsigned int reg, alg_base_words; 570 struct cs_dsp_coeff_ctl *ctl; 571 struct firmware *wmfw; 572 u32 *reg_vals; 573 574 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 575 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 576 577 /* Create some initial register content */ 578 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 579 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 580 reg += (alg_base_words + param->offs_words) * 581 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 582 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 583 584 /* Create control pointing to this data */ 585 def.flags = param->flags | WMFW_CTL_FLAG_VOLATILE; 586 def.mem_type = param->mem_type; 587 def.offset_dsp_words = param->offs_words; 588 def.length_bytes = param->len_bytes; 589 590 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 591 cs_dsp_ctl_rw_test_algs[alg_idx].id, 592 "dummyalg", NULL); 593 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 594 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 595 596 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 597 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 598 599 /* Drop expected writes and the regmap cache should be clean */ 600 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 601 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 602 603 /* Write the control, it should return an error */ 604 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 605 KUNIT_ASSERT_NOT_NULL(test, ctl); 606 KUNIT_EXPECT_LT(test, 607 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 608 0); 609 610 /* Should not have been any writes to registers */ 611 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 612 } 613 614 /* 615 * Write to a volatile control after the firmware has stopped. 616 * This should return an error. 617 */ 618 static void cs_dsp_ctl_write_volatile_stopped(struct kunit *test) 619 { 620 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 621 struct cs_dsp_test *priv = test->priv; 622 struct cs_dsp_test_local *local = priv->local; 623 struct cs_dsp *dsp = priv->dsp; 624 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 625 int alg_idx = _find_alg_entry(test, param->alg_id); 626 unsigned int reg, alg_base_words; 627 struct cs_dsp_coeff_ctl *ctl; 628 struct firmware *wmfw; 629 u32 *reg_vals; 630 631 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 632 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 633 634 /* Create some initial register content */ 635 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 636 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 637 reg += (alg_base_words + param->offs_words) * 638 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 639 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 640 641 /* Create control pointing to this data */ 642 def.flags = param->flags | WMFW_CTL_FLAG_VOLATILE; 643 def.mem_type = param->mem_type; 644 def.offset_dsp_words = param->offs_words; 645 def.length_bytes = param->len_bytes; 646 647 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 648 cs_dsp_ctl_rw_test_algs[alg_idx].id, 649 "dummyalg", NULL); 650 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 651 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 652 653 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 654 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 655 656 /* Start and stop the firmware */ 657 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 658 cs_dsp_stop(dsp); 659 660 /* Drop expected writes and the regmap cache should be clean */ 661 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 662 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 663 664 /* Write the control, it should return an error */ 665 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 666 KUNIT_ASSERT_NOT_NULL(test, ctl); 667 KUNIT_EXPECT_LT(test, 668 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 669 0); 670 671 /* Should not have been any writes to registers */ 672 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 673 } 674 675 /* 676 * Write to a volatile control after the DSP has been powered down. 677 * This should return an error. 678 */ 679 static void cs_dsp_ctl_write_volatile_stopped_powered_down(struct kunit *test) 680 { 681 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 682 struct cs_dsp_test *priv = test->priv; 683 struct cs_dsp_test_local *local = priv->local; 684 struct cs_dsp *dsp = priv->dsp; 685 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 686 int alg_idx = _find_alg_entry(test, param->alg_id); 687 unsigned int reg, alg_base_words; 688 struct cs_dsp_coeff_ctl *ctl; 689 struct firmware *wmfw; 690 u32 *reg_vals; 691 692 reg_vals = kunit_kzalloc(test, param->len_bytes, GFP_KERNEL); 693 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 694 695 /* Create some initial register content */ 696 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 697 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 698 reg += (alg_base_words + param->offs_words) * 699 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 700 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 701 702 /* Create control pointing to this data */ 703 def.flags = param->flags | WMFW_CTL_FLAG_VOLATILE; 704 def.mem_type = param->mem_type; 705 def.offset_dsp_words = param->offs_words; 706 def.length_bytes = param->len_bytes; 707 708 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 709 cs_dsp_ctl_rw_test_algs[alg_idx].id, 710 "dummyalg", NULL); 711 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 712 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 713 714 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 715 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 716 717 /* Start and stop the firmware then power down */ 718 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 719 cs_dsp_stop(dsp); 720 cs_dsp_power_down(dsp); 721 722 /* Drop expected writes and the regmap cache should be clean */ 723 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 724 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 725 726 /* Write the control, it should return an error */ 727 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 728 KUNIT_ASSERT_NOT_NULL(test, ctl); 729 KUNIT_EXPECT_LT(test, 730 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 731 0); 732 733 /* Should not have been any writes to registers */ 734 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 735 } 736 737 /* 738 * Write to a volatile control when a different firmware is currently 739 * loaded into the DSP. 740 * Should return an error. 741 */ 742 static void cs_dsp_ctl_write_volatile_not_current_loaded_fw(struct kunit *test) 743 { 744 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 745 struct cs_dsp_test *priv = test->priv; 746 struct cs_dsp_test_local *local = priv->local; 747 struct cs_dsp *dsp = priv->dsp; 748 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 749 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); 750 int alg_idx = _find_alg_entry(test, param->alg_id); 751 unsigned int reg, alg_base_words; 752 struct cs_dsp_coeff_ctl *ctl; 753 struct firmware *wmfw; 754 u32 *reg_vals; 755 756 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 757 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 758 759 /* Create some DSP data to be read into the control cache */ 760 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 761 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 762 reg += (alg_base_words + param->offs_words) * 763 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 764 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 765 766 /* Create control pointing to this data */ 767 def.flags = param->flags | WMFW_CTL_FLAG_VOLATILE; 768 def.mem_type = param->mem_type; 769 def.offset_dsp_words = param->offs_words; 770 def.length_bytes = param->len_bytes; 771 772 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 773 cs_dsp_ctl_rw_test_algs[alg_idx].id, 774 "dummyalg", NULL); 775 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 776 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 777 778 /* Power-up DSP */ 779 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 780 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 781 782 /* Power-down DSP then power-up with a different firmware */ 783 cs_dsp_power_down(dsp); 784 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2); 785 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0); 786 787 /* Drop expected writes and the regmap cache should be clean */ 788 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 789 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 790 791 /* Write the control, it should return an error */ 792 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 793 KUNIT_ASSERT_NOT_NULL(test, ctl); 794 KUNIT_EXPECT_LT(test, 795 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 796 0); 797 798 /* Should not have been any writes to registers */ 799 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 800 } 801 802 /* 803 * Write to a volatile control when a different firmware is currently 804 * running. 805 * Should return an error. 806 */ 807 static void cs_dsp_ctl_write_volatile_not_current_running_fw(struct kunit *test) 808 { 809 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 810 struct cs_dsp_test *priv = test->priv; 811 struct cs_dsp_test_local *local = priv->local; 812 struct cs_dsp *dsp = priv->dsp; 813 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 814 struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); 815 int alg_idx = _find_alg_entry(test, param->alg_id); 816 unsigned int reg, alg_base_words; 817 struct cs_dsp_coeff_ctl *ctl; 818 struct firmware *wmfw; 819 u32 *reg_vals; 820 821 reg_vals = kunit_kmalloc(test, param->len_bytes, GFP_KERNEL); 822 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 823 824 /* Create some DSP data to be read into the control cache */ 825 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 826 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 827 reg += (alg_base_words + param->offs_words) * 828 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 829 regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes); 830 831 /* Create control pointing to this data */ 832 def.flags = param->flags | WMFW_CTL_FLAG_VOLATILE; 833 def.mem_type = param->mem_type; 834 def.offset_dsp_words = param->offs_words; 835 def.length_bytes = param->len_bytes; 836 837 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 838 cs_dsp_ctl_rw_test_algs[alg_idx].id, 839 "dummyalg", NULL); 840 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 841 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 842 843 /* Power-up DSP */ 844 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 845 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 846 847 /* Power-down DSP then power-up with a different firmware */ 848 cs_dsp_power_down(dsp); 849 wmfw = cs_dsp_mock_wmfw_get_firmware(builder2); 850 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0); 851 852 /* Start the firmware and add an action to stop it during cleanup */ 853 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 854 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 855 856 /* Drop expected writes and the regmap cache should be clean */ 857 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 858 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 859 860 /* Write the control, it should return an error */ 861 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 862 KUNIT_ASSERT_NOT_NULL(test, ctl); 863 KUNIT_EXPECT_LT(test, 864 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes), 865 0); 866 867 /* Should not have been any writes to registers */ 868 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 869 } 870 871 /* 872 * Read from an offset into the control data. Should return only the 873 * portion of data from the offset position. 874 */ 875 static void cs_dsp_ctl_read_with_seek(struct kunit *test) 876 { 877 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 878 struct cs_dsp_test *priv = test->priv; 879 struct cs_dsp_test_local *local = priv->local; 880 struct cs_dsp *dsp = priv->dsp; 881 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 882 int alg_idx = _find_alg_entry(test, param->alg_id); 883 unsigned int reg, alg_base_words; 884 struct cs_dsp_coeff_ctl *ctl; 885 struct firmware *wmfw; 886 u32 *reg_vals, *readback; 887 unsigned int seek_words; 888 889 def.flags = param->flags; 890 def.mem_type = param->mem_type; 891 def.offset_dsp_words = param->offs_words; 892 def.length_bytes = 48; 893 894 reg_vals = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 895 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 896 897 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 898 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 899 900 /* Create some initial register content */ 901 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 902 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 903 reg += (alg_base_words + param->offs_words) * 904 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 905 get_random_bytes(reg_vals, def.length_bytes); 906 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 907 908 /* Create control pointing to this data */ 909 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 910 cs_dsp_ctl_rw_test_algs[alg_idx].id, 911 "dummyalg", NULL); 912 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 913 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 914 915 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 916 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 917 918 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 919 KUNIT_ASSERT_NOT_NULL(test, ctl); 920 921 /* Start the firmware and add an action to stop it during cleanup */ 922 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 923 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 924 925 for (seek_words = 1; seek_words < (def.length_bytes / sizeof(u32)); seek_words++) { 926 unsigned int len_bytes = def.length_bytes - (seek_words * sizeof(u32)); 927 928 KUNIT_EXPECT_EQ(test, 929 cs_dsp_coeff_lock_and_read_ctrl(ctl, seek_words, 930 readback, len_bytes), 931 0); 932 KUNIT_EXPECT_MEMEQ(test, readback, ®_vals[seek_words], len_bytes); 933 } 934 } 935 936 /* 937 * Read from an offset into the control cache. Should return only the 938 * portion of data from the offset position. 939 * Same as cs_dsp_ctl_read_with_seek() except the control is cached 940 * and the firmware is not running. 941 */ 942 static void cs_dsp_ctl_read_cache_with_seek(struct kunit *test) 943 { 944 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 945 struct cs_dsp_test *priv = test->priv; 946 struct cs_dsp_test_local *local = priv->local; 947 struct cs_dsp *dsp = priv->dsp; 948 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 949 int alg_idx = _find_alg_entry(test, param->alg_id); 950 unsigned int reg, alg_base_words; 951 struct cs_dsp_coeff_ctl *ctl; 952 struct firmware *wmfw; 953 u32 *reg_vals, *readback; 954 unsigned int seek_words; 955 956 def.flags = param->flags; 957 def.mem_type = param->mem_type; 958 def.offset_dsp_words = param->offs_words; 959 def.length_bytes = 48; 960 961 reg_vals = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 962 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 963 964 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 965 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 966 967 /* Create some initial register content */ 968 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 969 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 970 reg += (alg_base_words + param->offs_words) * 971 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 972 get_random_bytes(reg_vals, def.length_bytes); 973 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 974 975 /* Create control pointing to this data */ 976 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 977 cs_dsp_ctl_rw_test_algs[alg_idx].id, 978 "dummyalg", NULL); 979 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 980 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 981 982 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 983 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 984 985 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 986 KUNIT_ASSERT_NOT_NULL(test, ctl); 987 988 /* Start and stop the firmware so the read will come from the cache */ 989 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 990 cs_dsp_stop(dsp); 991 992 for (seek_words = 1; seek_words < (def.length_bytes / sizeof(u32)); seek_words++) { 993 unsigned int len_bytes = def.length_bytes - (seek_words * sizeof(u32)); 994 995 KUNIT_EXPECT_EQ(test, 996 cs_dsp_coeff_lock_and_read_ctrl(ctl, seek_words, 997 readback, len_bytes), 998 0); 999 KUNIT_EXPECT_MEMEQ(test, readback, ®_vals[seek_words], len_bytes); 1000 } 1001 } 1002 1003 /* 1004 * Read less than the full length of data from a control. Should return 1005 * only the requested number of bytes. 1006 */ 1007 static void cs_dsp_ctl_read_truncated(struct kunit *test) 1008 { 1009 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1010 struct cs_dsp_test *priv = test->priv; 1011 struct cs_dsp_test_local *local = priv->local; 1012 struct cs_dsp *dsp = priv->dsp; 1013 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1014 int alg_idx = _find_alg_entry(test, param->alg_id); 1015 unsigned int reg, alg_base_words; 1016 struct cs_dsp_coeff_ctl *ctl; 1017 struct firmware *wmfw; 1018 u32 *reg_vals, *readback; 1019 unsigned int len_bytes; 1020 1021 def.flags = param->flags; 1022 def.mem_type = param->mem_type; 1023 def.offset_dsp_words = param->offs_words; 1024 def.length_bytes = 48; 1025 1026 reg_vals = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1027 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1028 1029 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 1030 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1031 1032 /* Create some initial register content */ 1033 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1034 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1035 reg += (alg_base_words + param->offs_words) * 1036 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1037 get_random_bytes(reg_vals, def.length_bytes); 1038 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1039 1040 /* Create control pointing to this data */ 1041 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1042 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1043 "dummyalg", NULL); 1044 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1045 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1046 1047 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1048 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1049 1050 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1051 KUNIT_ASSERT_NOT_NULL(test, ctl); 1052 1053 /* Start the firmware and add an action to stop it during cleanup */ 1054 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1055 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1056 1057 /* Reads are only allowed to be a multiple of the DSP word length */ 1058 for (len_bytes = sizeof(u32); len_bytes < def.length_bytes; len_bytes += sizeof(u32)) { 1059 memset(readback, 0, def.length_bytes); 1060 KUNIT_EXPECT_EQ(test, 1061 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, len_bytes), 1062 0); 1063 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, len_bytes); 1064 KUNIT_EXPECT_MEMNEQ(test, 1065 (u8 *)readback + len_bytes, 1066 (u8 *)reg_vals + len_bytes, 1067 def.length_bytes - len_bytes); 1068 } 1069 } 1070 1071 /* 1072 * Read less than the full length of data from a cached control. 1073 * Should return only the requested number of bytes. 1074 * Same as cs_dsp_ctl_read_truncated() except the control is cached 1075 * and the firmware is not running. 1076 */ 1077 static void cs_dsp_ctl_read_cache_truncated(struct kunit *test) 1078 { 1079 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1080 struct cs_dsp_test *priv = test->priv; 1081 struct cs_dsp_test_local *local = priv->local; 1082 struct cs_dsp *dsp = priv->dsp; 1083 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1084 int alg_idx = _find_alg_entry(test, param->alg_id); 1085 unsigned int reg, alg_base_words; 1086 struct cs_dsp_coeff_ctl *ctl; 1087 struct firmware *wmfw; 1088 u32 *reg_vals, *readback; 1089 unsigned int len_bytes; 1090 1091 def.flags = param->flags; 1092 def.mem_type = param->mem_type; 1093 def.offset_dsp_words = param->offs_words; 1094 def.length_bytes = 48; 1095 1096 reg_vals = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1097 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1098 1099 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 1100 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1101 1102 /* Create some initial register content */ 1103 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1104 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1105 reg += (alg_base_words + param->offs_words) * 1106 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1107 get_random_bytes(reg_vals, def.length_bytes); 1108 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1109 1110 /* Create control pointing to this data */ 1111 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1112 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1113 "dummyalg", NULL); 1114 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1115 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1116 1117 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1118 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1119 1120 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1121 KUNIT_ASSERT_NOT_NULL(test, ctl); 1122 1123 /* Start and stop the firmware so the read will come from the cache */ 1124 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1125 cs_dsp_stop(dsp); 1126 1127 /* Reads are only allowed to be a multiple of the DSP word length */ 1128 for (len_bytes = sizeof(u32); len_bytes < def.length_bytes; len_bytes += sizeof(u32)) { 1129 memset(readback, 0, def.length_bytes); 1130 KUNIT_EXPECT_EQ(test, 1131 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, len_bytes), 1132 0); 1133 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, len_bytes); 1134 KUNIT_EXPECT_MEMNEQ(test, 1135 (u8 *)readback + len_bytes, 1136 (u8 *)reg_vals + len_bytes, 1137 def.length_bytes - len_bytes); 1138 } 1139 } 1140 1141 /* 1142 * Write to an offset into the control data. Should only change the 1143 * portion of data from the offset position. 1144 */ 1145 static void cs_dsp_ctl_write_with_seek(struct kunit *test) 1146 { 1147 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1148 struct cs_dsp_test *priv = test->priv; 1149 struct cs_dsp_test_local *local = priv->local; 1150 struct cs_dsp *dsp = priv->dsp; 1151 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1152 int alg_idx = _find_alg_entry(test, param->alg_id); 1153 unsigned int reg, alg_base_words; 1154 struct cs_dsp_coeff_ctl *ctl; 1155 struct firmware *wmfw; 1156 u32 *reg_vals, *readback, *new_data; 1157 unsigned int seek_words; 1158 1159 def.flags = param->flags; 1160 def.mem_type = param->mem_type; 1161 def.offset_dsp_words = param->offs_words; 1162 def.length_bytes = 48; 1163 1164 reg_vals = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1165 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1166 1167 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 1168 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1169 1170 new_data = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1171 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_data); 1172 1173 /* Create some initial register content */ 1174 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1175 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1176 reg += (alg_base_words + param->offs_words) * 1177 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1178 get_random_bytes(reg_vals, def.length_bytes); 1179 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1180 1181 /* Create control pointing to this data */ 1182 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1183 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1184 "dummyalg", NULL); 1185 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1186 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1187 1188 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1189 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1190 1191 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1192 KUNIT_ASSERT_NOT_NULL(test, ctl); 1193 1194 /* Start the firmware and add an action to stop it during cleanup */ 1195 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1196 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1197 1198 for (seek_words = 1; seek_words < (def.length_bytes / sizeof(u32)); seek_words++) { 1199 unsigned int len_bytes = def.length_bytes - (seek_words * sizeof(u32)); 1200 1201 /* Reset the register values to the test data */ 1202 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1203 1204 get_random_bytes(new_data, def.length_bytes); 1205 KUNIT_EXPECT_EQ(test, 1206 cs_dsp_coeff_lock_and_write_ctrl(ctl, seek_words, 1207 new_data, len_bytes), 1208 1); 1209 KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, def.length_bytes), 1210 0); 1211 /* Initial portion of readback should be unchanged */ 1212 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, seek_words * sizeof(u32)); 1213 KUNIT_EXPECT_MEMEQ(test, &readback[seek_words], new_data, len_bytes); 1214 } 1215 } 1216 1217 /* 1218 * Write to an offset into the control cache. Should only change the 1219 * portion of data from the offset position. 1220 * Same as cs_dsp_ctl_write_with_seek() except the control is cached 1221 * and the firmware is not running. 1222 */ 1223 static void cs_dsp_ctl_write_cache_with_seek(struct kunit *test) 1224 { 1225 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1226 struct cs_dsp_test *priv = test->priv; 1227 struct cs_dsp_test_local *local = priv->local; 1228 struct cs_dsp *dsp = priv->dsp; 1229 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1230 int alg_idx = _find_alg_entry(test, param->alg_id); 1231 unsigned int reg, alg_base_words; 1232 struct cs_dsp_coeff_ctl *ctl; 1233 struct firmware *wmfw; 1234 u32 *reg_vals, *readback, *new_data; 1235 unsigned int seek_words; 1236 1237 def.flags = param->flags; 1238 def.mem_type = param->mem_type; 1239 def.offset_dsp_words = param->offs_words; 1240 def.length_bytes = 48; 1241 1242 reg_vals = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1243 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1244 1245 readback = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1246 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1247 1248 new_data = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1249 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_data); 1250 1251 /* Create some initial register content */ 1252 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1253 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1254 reg += (alg_base_words + param->offs_words) * 1255 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1256 get_random_bytes(reg_vals, def.length_bytes); 1257 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1258 1259 /* Create control pointing to this data */ 1260 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1261 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1262 "dummyalg", NULL); 1263 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1264 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1265 1266 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1267 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1268 1269 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1270 KUNIT_ASSERT_NOT_NULL(test, ctl); 1271 1272 /* Start and stop the firmware so the read will come from the cache */ 1273 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1274 cs_dsp_stop(dsp); 1275 1276 for (seek_words = 1; seek_words < (def.length_bytes / sizeof(u32)); seek_words++) { 1277 unsigned int len_bytes = def.length_bytes - (seek_words * sizeof(u32)); 1278 1279 /* Reset the cache to the test data */ 1280 KUNIT_EXPECT_GE(test, 1281 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, 1282 def.length_bytes), 1283 0); 1284 1285 get_random_bytes(new_data, def.length_bytes); 1286 KUNIT_EXPECT_EQ(test, 1287 cs_dsp_coeff_lock_and_write_ctrl(ctl, seek_words, 1288 new_data, len_bytes), 1289 1); 1290 1291 memset(readback, 0, def.length_bytes); 1292 KUNIT_EXPECT_EQ(test, 1293 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, 1294 def.length_bytes), 1295 0); 1296 /* Initial portion of readback should be unchanged */ 1297 KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, seek_words * sizeof(u32)); 1298 KUNIT_EXPECT_MEMEQ(test, &readback[seek_words], new_data, len_bytes); 1299 } 1300 } 1301 1302 /* 1303 * Write less than the full length of data to a control. Should only 1304 * change the requested number of bytes. 1305 */ 1306 static void cs_dsp_ctl_write_truncated(struct kunit *test) 1307 { 1308 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1309 struct cs_dsp_test *priv = test->priv; 1310 struct cs_dsp_test_local *local = priv->local; 1311 struct cs_dsp *dsp = priv->dsp; 1312 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1313 int alg_idx = _find_alg_entry(test, param->alg_id); 1314 unsigned int reg, alg_base_words; 1315 struct cs_dsp_coeff_ctl *ctl; 1316 struct firmware *wmfw; 1317 u32 *reg_vals, *readback, *new_data; 1318 unsigned int len_bytes; 1319 1320 def.flags = param->flags; 1321 def.mem_type = param->mem_type; 1322 def.offset_dsp_words = param->offs_words; 1323 def.length_bytes = 48; 1324 1325 reg_vals = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1326 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1327 1328 readback = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1329 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1330 1331 new_data = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1332 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_data); 1333 1334 /* Create some initial register content */ 1335 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1336 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1337 reg += (alg_base_words + param->offs_words) * 1338 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1339 get_random_bytes(reg_vals, def.length_bytes); 1340 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1341 1342 /* Create control pointing to this data */ 1343 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1344 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1345 "dummyalg", NULL); 1346 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1347 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1348 1349 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1350 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1351 1352 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1353 KUNIT_ASSERT_NOT_NULL(test, ctl); 1354 1355 /* Start the firmware and add an action to stop it during cleanup */ 1356 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1357 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1358 1359 /* Writes are only allowed to be a multiple of the DSP word length */ 1360 for (len_bytes = sizeof(u32); len_bytes < def.length_bytes; len_bytes += sizeof(u32)) { 1361 /* Reset the register values to the test data */ 1362 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1363 1364 get_random_bytes(new_data, def.length_bytes); 1365 KUNIT_EXPECT_EQ(test, 1366 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, new_data, len_bytes), 1367 1); 1368 1369 memset(readback, 0, def.length_bytes); 1370 KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, def.length_bytes), 1371 0); 1372 KUNIT_EXPECT_MEMEQ(test, readback, new_data, len_bytes); 1373 KUNIT_EXPECT_MEMEQ(test, 1374 (u8 *)readback + len_bytes, 1375 (u8 *)reg_vals + len_bytes, 1376 def.length_bytes - len_bytes); 1377 } 1378 } 1379 1380 /* 1381 * Write less than the full length of data to a cached control. 1382 * Should only change the requested number of bytes. 1383 * Same as cs_dsp_ctl_write_truncated() except the control is cached 1384 * and the firmware is not running. 1385 */ 1386 static void cs_dsp_ctl_write_cache_truncated(struct kunit *test) 1387 { 1388 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1389 struct cs_dsp_test *priv = test->priv; 1390 struct cs_dsp_test_local *local = priv->local; 1391 struct cs_dsp *dsp = priv->dsp; 1392 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1393 int alg_idx = _find_alg_entry(test, param->alg_id); 1394 unsigned int reg, alg_base_words; 1395 struct cs_dsp_coeff_ctl *ctl; 1396 struct firmware *wmfw; 1397 u32 *reg_vals, *readback, *new_data; 1398 unsigned int len_bytes; 1399 1400 def.flags = param->flags; 1401 def.mem_type = param->mem_type; 1402 def.offset_dsp_words = param->offs_words; 1403 def.length_bytes = 48; 1404 1405 reg_vals = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1406 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1407 1408 readback = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1409 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1410 1411 new_data = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1412 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, new_data); 1413 1414 /* Create some initial register content */ 1415 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1416 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1417 reg += (alg_base_words + param->offs_words) * 1418 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1419 get_random_bytes(reg_vals, def.length_bytes); 1420 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1421 1422 /* Create control pointing to this data */ 1423 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1424 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1425 "dummyalg", NULL); 1426 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1427 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1428 1429 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1430 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1431 1432 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1433 KUNIT_ASSERT_NOT_NULL(test, ctl); 1434 1435 /* Start and stop the firmware so the read will come from the cache */ 1436 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1437 cs_dsp_stop(dsp); 1438 1439 /* Writes are only allowed to be a multiple of the DSP word length */ 1440 for (len_bytes = sizeof(u32); len_bytes < def.length_bytes; len_bytes += sizeof(u32)) { 1441 /* Reset the cache to the test data */ 1442 KUNIT_EXPECT_GE(test, 1443 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, 1444 def.length_bytes), 1445 0); 1446 1447 get_random_bytes(new_data, def.length_bytes); 1448 KUNIT_EXPECT_EQ(test, 1449 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, new_data, len_bytes), 1450 1); 1451 1452 memset(readback, 0, def.length_bytes); 1453 KUNIT_EXPECT_EQ(test, 1454 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, 1455 def.length_bytes), 1456 0); 1457 KUNIT_EXPECT_MEMEQ(test, readback, new_data, len_bytes); 1458 KUNIT_EXPECT_MEMEQ(test, 1459 (u8 *)readback + len_bytes, 1460 (u8 *)reg_vals + len_bytes, 1461 def.length_bytes - len_bytes); 1462 } 1463 } 1464 1465 /* 1466 * Read from an offset that is beyond the end of the control data. 1467 * Should return an error. 1468 */ 1469 static void cs_dsp_ctl_read_with_seek_oob(struct kunit *test) 1470 { 1471 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1472 struct cs_dsp_test *priv = test->priv; 1473 struct cs_dsp_test_local *local = priv->local; 1474 struct cs_dsp *dsp = priv->dsp; 1475 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1476 int alg_idx = _find_alg_entry(test, param->alg_id); 1477 unsigned int reg, alg_base_words; 1478 struct cs_dsp_coeff_ctl *ctl; 1479 struct firmware *wmfw; 1480 u32 *reg_vals; 1481 unsigned int seek_words; 1482 1483 def.flags = param->flags; 1484 def.mem_type = param->mem_type; 1485 def.offset_dsp_words = param->offs_words; 1486 def.length_bytes = param->len_bytes; 1487 1488 reg_vals = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 1489 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1490 1491 /* Create some initial register content */ 1492 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1493 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1494 reg += (alg_base_words + param->offs_words) * 1495 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1496 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1497 1498 /* Create control pointing to this data */ 1499 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1500 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1501 "dummyalg", NULL); 1502 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1503 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1504 1505 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1506 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1507 1508 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1509 KUNIT_ASSERT_NOT_NULL(test, ctl); 1510 1511 /* Start the firmware and add an action to stop it during cleanup */ 1512 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1513 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1514 1515 seek_words = def.length_bytes / sizeof(u32); 1516 KUNIT_EXPECT_LT(test, 1517 cs_dsp_coeff_lock_and_read_ctrl(ctl, seek_words, 1518 reg_vals, def.length_bytes), 1519 0); 1520 1521 if (!(def.flags & WMFW_CTL_FLAG_VOLATILE)) { 1522 /* Stop firmware and repeat the read from the cache */ 1523 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 1524 KUNIT_ASSERT_FALSE(test, dsp->running); 1525 1526 KUNIT_EXPECT_LT(test, 1527 cs_dsp_coeff_lock_and_read_ctrl(ctl, seek_words, 1528 reg_vals, def.length_bytes), 1529 0); 1530 } 1531 } 1532 1533 /* 1534 * Read more data than the length of the control data. 1535 * Should return an error. 1536 */ 1537 static void cs_dsp_ctl_read_with_length_overflow(struct kunit *test) 1538 { 1539 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1540 struct cs_dsp_test *priv = test->priv; 1541 struct cs_dsp_test_local *local = priv->local; 1542 struct cs_dsp *dsp = priv->dsp; 1543 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1544 int alg_idx = _find_alg_entry(test, param->alg_id); 1545 unsigned int reg, alg_base_words; 1546 struct cs_dsp_coeff_ctl *ctl; 1547 struct firmware *wmfw; 1548 u32 *reg_vals; 1549 1550 def.flags = param->flags; 1551 def.mem_type = param->mem_type; 1552 def.offset_dsp_words = param->offs_words; 1553 def.length_bytes = param->len_bytes; 1554 1555 reg_vals = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 1556 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1557 1558 /* Create some initial register content */ 1559 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1560 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1561 reg += (alg_base_words + param->offs_words) * 1562 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1563 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1564 1565 /* Create control pointing to this data */ 1566 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1567 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1568 "dummyalg", NULL); 1569 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1570 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1571 1572 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1573 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1574 1575 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1576 KUNIT_ASSERT_NOT_NULL(test, ctl); 1577 1578 /* Start the firmware and add an action to stop it during cleanup */ 1579 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1580 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1581 1582 KUNIT_EXPECT_LT(test, 1583 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, reg_vals, def.length_bytes + 1), 1584 0); 1585 1586 if (!(def.flags & WMFW_CTL_FLAG_VOLATILE)) { 1587 /* Stop firmware and repeat the read from the cache */ 1588 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 1589 KUNIT_ASSERT_FALSE(test, dsp->running); 1590 1591 KUNIT_EXPECT_LT(test, 1592 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, reg_vals, 1593 def.length_bytes + 1), 1594 0); 1595 } 1596 } 1597 1598 /* 1599 * Read with a seek and length that ends beyond the end of control data. 1600 * Should return an error. 1601 */ 1602 static void cs_dsp_ctl_read_with_seek_and_length_oob(struct kunit *test) 1603 { 1604 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1605 struct cs_dsp_test *priv = test->priv; 1606 struct cs_dsp_test_local *local = priv->local; 1607 struct cs_dsp *dsp = priv->dsp; 1608 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1609 int alg_idx = _find_alg_entry(test, param->alg_id); 1610 unsigned int reg, alg_base_words; 1611 struct cs_dsp_coeff_ctl *ctl; 1612 struct firmware *wmfw; 1613 u32 *reg_vals; 1614 1615 def.flags = param->flags; 1616 def.mem_type = param->mem_type; 1617 def.offset_dsp_words = param->offs_words; 1618 def.length_bytes = param->len_bytes; 1619 1620 reg_vals = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 1621 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1622 1623 /* Create some initial register content */ 1624 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1625 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1626 reg += (alg_base_words + param->offs_words) * 1627 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1628 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1629 1630 /* Create control pointing to this data */ 1631 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1632 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1633 "dummyalg", NULL); 1634 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1635 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1636 1637 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1638 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1639 1640 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1641 KUNIT_ASSERT_NOT_NULL(test, ctl); 1642 1643 /* Start the firmware and add an action to stop it during cleanup */ 1644 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1645 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1646 1647 /* 1648 * Read full control length but at a start offset of 1 so that 1649 * offset + length exceeds the length of the control. 1650 */ 1651 KUNIT_EXPECT_LT(test, 1652 cs_dsp_coeff_lock_and_read_ctrl(ctl, 1, reg_vals, def.length_bytes), 1653 0); 1654 1655 if (!(def.flags & WMFW_CTL_FLAG_VOLATILE)) { 1656 /* Stop firmware and repeat the read from the cache */ 1657 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 1658 KUNIT_ASSERT_FALSE(test, dsp->running); 1659 1660 KUNIT_EXPECT_LT(test, 1661 cs_dsp_coeff_lock_and_read_ctrl(ctl, 1, reg_vals, 1662 def.length_bytes), 1663 0); 1664 } 1665 } 1666 1667 /* 1668 * Write to an offset that is beyond the end of the control data. 1669 * Should return an error without touching any registers. 1670 */ 1671 static void cs_dsp_ctl_write_with_seek_oob(struct kunit *test) 1672 { 1673 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1674 struct cs_dsp_test *priv = test->priv; 1675 struct cs_dsp_test_local *local = priv->local; 1676 struct cs_dsp *dsp = priv->dsp; 1677 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1678 int alg_idx = _find_alg_entry(test, param->alg_id); 1679 unsigned int reg, alg_base_words; 1680 struct cs_dsp_coeff_ctl *ctl; 1681 struct firmware *wmfw; 1682 u32 *reg_vals; 1683 unsigned int seek_words; 1684 1685 def.flags = param->flags; 1686 def.mem_type = param->mem_type; 1687 def.offset_dsp_words = param->offs_words; 1688 def.length_bytes = param->len_bytes; 1689 1690 reg_vals = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 1691 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1692 1693 /* Create some initial register content */ 1694 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1695 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1696 reg += (alg_base_words + param->offs_words) * 1697 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1698 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1699 1700 /* Create control pointing to this data */ 1701 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1702 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1703 "dummyalg", NULL); 1704 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1705 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1706 1707 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1708 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1709 1710 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1711 KUNIT_ASSERT_NOT_NULL(test, ctl); 1712 1713 /* Start the firmware and add an action to stop it during cleanup */ 1714 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1715 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1716 1717 /* Drop expected writes and the regmap cache should be clean */ 1718 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 1719 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1720 1721 get_random_bytes(reg_vals, def.length_bytes); 1722 seek_words = def.length_bytes / sizeof(u32); 1723 KUNIT_EXPECT_LT(test, 1724 cs_dsp_coeff_lock_and_write_ctrl(ctl, seek_words, 1725 reg_vals, def.length_bytes), 1726 0); 1727 1728 if (!(def.flags & WMFW_CTL_FLAG_VOLATILE)) { 1729 /* Stop firmware and repeat the write to the cache */ 1730 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 1731 KUNIT_ASSERT_FALSE(test, dsp->running); 1732 1733 get_random_bytes(reg_vals, def.length_bytes); 1734 KUNIT_EXPECT_LT(test, 1735 cs_dsp_coeff_lock_and_write_ctrl(ctl, seek_words, 1736 reg_vals, def.length_bytes), 1737 0); 1738 } 1739 1740 /* Check that it didn't write any registers */ 1741 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1742 } 1743 1744 /* 1745 * Write more data than the length of the control data. 1746 * Should return an error. 1747 */ 1748 static void cs_dsp_ctl_write_with_length_overflow(struct kunit *test) 1749 { 1750 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1751 struct cs_dsp_test *priv = test->priv; 1752 struct cs_dsp_test_local *local = priv->local; 1753 struct cs_dsp *dsp = priv->dsp; 1754 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1755 int alg_idx = _find_alg_entry(test, param->alg_id); 1756 unsigned int reg, alg_base_words; 1757 struct cs_dsp_coeff_ctl *ctl; 1758 struct firmware *wmfw; 1759 u32 *reg_vals; 1760 1761 def.flags = param->flags; 1762 def.mem_type = param->mem_type; 1763 def.offset_dsp_words = param->offs_words; 1764 def.length_bytes = param->len_bytes; 1765 1766 reg_vals = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 1767 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1768 1769 /* Create some initial register content */ 1770 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1771 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1772 reg += (alg_base_words + param->offs_words) * 1773 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1774 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1775 1776 /* Create control pointing to this data */ 1777 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1778 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1779 "dummyalg", NULL); 1780 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1781 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1782 1783 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1784 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1785 1786 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1787 KUNIT_ASSERT_NOT_NULL(test, ctl); 1788 1789 /* Start the firmware and add an action to stop it during cleanup */ 1790 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1791 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1792 1793 /* Drop expected writes and the regmap cache should be clean */ 1794 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 1795 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1796 1797 get_random_bytes(reg_vals, def.length_bytes); 1798 KUNIT_EXPECT_LT(test, 1799 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, def.length_bytes + 1), 1800 0); 1801 1802 if (!(def.flags & WMFW_CTL_FLAG_VOLATILE)) { 1803 /* Stop firmware and repeat the write to the cache */ 1804 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 1805 KUNIT_ASSERT_FALSE(test, dsp->running); 1806 1807 get_random_bytes(reg_vals, def.length_bytes); 1808 KUNIT_EXPECT_LT(test, 1809 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, 1810 def.length_bytes + 1), 1811 0); 1812 } 1813 1814 /* Check that it didn't write any registers */ 1815 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1816 } 1817 1818 /* 1819 * Write with a seek and length that ends beyond the end of control data. 1820 * Should return an error. 1821 */ 1822 static void cs_dsp_ctl_write_with_seek_and_length_oob(struct kunit *test) 1823 { 1824 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1825 struct cs_dsp_test *priv = test->priv; 1826 struct cs_dsp_test_local *local = priv->local; 1827 struct cs_dsp *dsp = priv->dsp; 1828 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1829 int alg_idx = _find_alg_entry(test, param->alg_id); 1830 unsigned int reg, alg_base_words; 1831 struct cs_dsp_coeff_ctl *ctl; 1832 struct firmware *wmfw; 1833 u32 *reg_vals; 1834 1835 def.flags = param->flags; 1836 def.mem_type = param->mem_type; 1837 def.offset_dsp_words = param->offs_words; 1838 def.length_bytes = param->len_bytes; 1839 1840 reg_vals = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 1841 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1842 1843 /* Create some initial register content */ 1844 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 1845 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 1846 reg += (alg_base_words + param->offs_words) * 1847 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 1848 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 1849 1850 /* Create control pointing to this data */ 1851 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1852 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1853 "dummyalg", NULL); 1854 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1855 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1856 1857 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1858 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1859 1860 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1861 KUNIT_ASSERT_NOT_NULL(test, ctl); 1862 1863 /* Start the firmware and add an action to stop it during cleanup */ 1864 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1865 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1866 1867 /* Drop expected writes and the regmap cache should be clean */ 1868 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 1869 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 1870 1871 /* 1872 * Write full control length but at a start offset of 1 so that 1873 * offset + length exceeeds the length of the control. 1874 */ 1875 get_random_bytes(reg_vals, def.length_bytes); 1876 KUNIT_EXPECT_LT(test, 1877 cs_dsp_coeff_lock_and_write_ctrl(ctl, 1, reg_vals, def.length_bytes), 1878 0); 1879 1880 if (!(def.flags & WMFW_CTL_FLAG_VOLATILE)) { 1881 /* Stop firmware and repeat the write to the cache */ 1882 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 1883 KUNIT_ASSERT_FALSE(test, dsp->running); 1884 1885 get_random_bytes(reg_vals, def.length_bytes); 1886 KUNIT_EXPECT_LT(test, 1887 cs_dsp_coeff_lock_and_write_ctrl(ctl, 1, reg_vals, 1888 def.length_bytes), 1889 0); 1890 } 1891 1892 /* Check that it didn't write any registers */ 1893 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 1894 } 1895 1896 /* 1897 * Read from a write-only control. This is legal because controls can 1898 * always be read. Write-only only indicates that it is not useful to 1899 * populate the cache from the DSP memory. 1900 */ 1901 static void cs_dsp_ctl_read_from_writeonly(struct kunit *test) 1902 { 1903 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1904 struct cs_dsp_test *priv = test->priv; 1905 struct cs_dsp_test_local *local = priv->local; 1906 struct cs_dsp *dsp = priv->dsp; 1907 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1908 int alg_idx = _find_alg_entry(test, param->alg_id); 1909 struct cs_dsp_coeff_ctl *ctl; 1910 struct firmware *wmfw; 1911 u32 *ctl_vals, *readback; 1912 1913 /* Sanity check parameters */ 1914 KUNIT_ASSERT_TRUE(test, param->flags & WMFW_CTL_FLAG_WRITEABLE); 1915 KUNIT_ASSERT_FALSE(test, param->flags & WMFW_CTL_FLAG_READABLE); 1916 1917 def.flags = param->flags; 1918 def.mem_type = param->mem_type; 1919 def.offset_dsp_words = param->offs_words; 1920 def.length_bytes = param->len_bytes; 1921 1922 ctl_vals = kunit_kmalloc(test, def.length_bytes, GFP_KERNEL); 1923 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctl_vals); 1924 1925 readback = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 1926 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback); 1927 1928 /* Create control pointing to this data */ 1929 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 1930 cs_dsp_ctl_rw_test_algs[alg_idx].id, 1931 "dummyalg", NULL); 1932 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 1933 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 1934 1935 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 1936 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 1937 1938 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 1939 KUNIT_ASSERT_NOT_NULL(test, ctl); 1940 1941 /* Start the firmware and add an action to stop it during cleanup */ 1942 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 1943 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 1944 1945 /* Write some test data to the control */ 1946 get_random_bytes(ctl_vals, def.length_bytes); 1947 KUNIT_EXPECT_EQ(test, 1948 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, ctl_vals, def.length_bytes), 1949 1); 1950 1951 /* Read back the data */ 1952 KUNIT_EXPECT_EQ(test, 1953 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, def.length_bytes), 1954 0); 1955 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, def.length_bytes); 1956 1957 if (!(def.flags & WMFW_CTL_FLAG_VOLATILE)) { 1958 /* Stop firmware and repeat the read from the cache */ 1959 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 1960 KUNIT_ASSERT_FALSE(test, dsp->running); 1961 1962 memset(readback, 0, def.length_bytes); 1963 KUNIT_EXPECT_EQ(test, 1964 cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, 1965 def.length_bytes), 1966 0); 1967 KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, def.length_bytes); 1968 } 1969 } 1970 1971 /* 1972 * Write to a read-only control. 1973 * This should return an error without writing registers. 1974 */ 1975 static void cs_dsp_ctl_write_to_readonly(struct kunit *test) 1976 { 1977 const struct cs_dsp_ctl_rw_test_param *param = test->param_value; 1978 struct cs_dsp_test *priv = test->priv; 1979 struct cs_dsp_test_local *local = priv->local; 1980 struct cs_dsp *dsp = priv->dsp; 1981 struct cs_dsp_mock_coeff_def def = mock_coeff_template; 1982 int alg_idx = _find_alg_entry(test, param->alg_id); 1983 unsigned int reg, alg_base_words; 1984 struct cs_dsp_coeff_ctl *ctl; 1985 struct firmware *wmfw; 1986 u32 *reg_vals; 1987 1988 /* Sanity check parameters */ 1989 KUNIT_ASSERT_FALSE(test, param->flags & WMFW_CTL_FLAG_WRITEABLE); 1990 KUNIT_ASSERT_TRUE(test, param->flags & WMFW_CTL_FLAG_READABLE); 1991 1992 def.flags = param->flags; 1993 def.mem_type = param->mem_type; 1994 def.offset_dsp_words = param->offs_words; 1995 def.length_bytes = param->len_bytes; 1996 1997 reg_vals = kunit_kzalloc(test, def.length_bytes, GFP_KERNEL); 1998 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals); 1999 2000 /* Create some initial register content */ 2001 alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type); 2002 reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type); 2003 reg += (alg_base_words + param->offs_words) * 2004 cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); 2005 regmap_raw_write(dsp->regmap, reg, reg_vals, def.length_bytes); 2006 2007 /* Create control pointing to this data */ 2008 cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, 2009 cs_dsp_ctl_rw_test_algs[alg_idx].id, 2010 "dummyalg", NULL); 2011 cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); 2012 cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder); 2013 2014 wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder); 2015 KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0); 2016 2017 ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); 2018 KUNIT_ASSERT_NOT_NULL(test, ctl); 2019 2020 /* Start the firmware and add an action to stop it during cleanup */ 2021 KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0); 2022 KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0); 2023 2024 /* Drop expected writes and the regmap cache should be clean */ 2025 cs_dsp_mock_xm_header_drop_from_regmap_cache(priv); 2026 cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes); 2027 2028 get_random_bytes(reg_vals, def.length_bytes); 2029 KUNIT_EXPECT_LT(test, 2030 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, def.length_bytes), 2031 0); 2032 2033 if (!(def.flags & WMFW_CTL_FLAG_VOLATILE)) { 2034 /* Stop firmware and repeat the write to the cache */ 2035 kunit_release_action(test, _cs_dsp_stop_wrapper, dsp); 2036 KUNIT_ASSERT_FALSE(test, dsp->running); 2037 2038 get_random_bytes(reg_vals, def.length_bytes); 2039 KUNIT_EXPECT_LT(test, 2040 cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, 2041 def.length_bytes), 2042 0); 2043 } 2044 2045 /* Check that it didn't write any registers */ 2046 KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true)); 2047 } 2048 2049 static int cs_dsp_ctl_rw_test_common_init(struct kunit *test, struct cs_dsp *dsp, 2050 int wmfw_version) 2051 { 2052 struct cs_dsp_test *priv; 2053 struct cs_dsp_test_local *local; 2054 struct device *test_dev; 2055 int ret; 2056 2057 priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL); 2058 if (!priv) 2059 return -ENOMEM; 2060 2061 local = kunit_kzalloc(test, sizeof(struct cs_dsp_test_local), GFP_KERNEL); 2062 if (!local) 2063 return -ENOMEM; 2064 2065 priv->test = test; 2066 priv->dsp = dsp; 2067 test->priv = priv; 2068 priv->local = local; 2069 priv->local->wmfw_version = wmfw_version; 2070 2071 /* Create dummy struct device */ 2072 test_dev = kunit_device_register(test, "cs_dsp_test_drv"); 2073 if (IS_ERR(test_dev)) 2074 return PTR_ERR(test_dev); 2075 2076 dsp->dev = get_device(test_dev); 2077 if (!dsp->dev) 2078 return -ENODEV; 2079 2080 ret = kunit_add_action_or_reset(test, _put_device_wrapper, dsp->dev); 2081 if (ret) 2082 return ret; 2083 2084 dev_set_drvdata(dsp->dev, priv); 2085 2086 /* Allocate regmap */ 2087 ret = cs_dsp_mock_regmap_init(priv); 2088 if (ret) 2089 return ret; 2090 2091 /* 2092 * There must always be a XM header with at least 1 algorithm, so create 2093 * a dummy one that tests can use and extract it to a data blob. 2094 */ 2095 local->xm_header = cs_dsp_create_mock_xm_header(priv, 2096 cs_dsp_ctl_rw_test_algs, 2097 ARRAY_SIZE(cs_dsp_ctl_rw_test_algs)); 2098 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->xm_header); 2099 2100 /* Create wmfw builder */ 2101 local->wmfw_builder = _create_dummy_wmfw(test); 2102 2103 /* Init cs_dsp */ 2104 dsp->client_ops = kunit_kzalloc(test, sizeof(*dsp->client_ops), GFP_KERNEL); 2105 KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dsp->client_ops); 2106 2107 switch (dsp->type) { 2108 case WMFW_ADSP2: 2109 ret = cs_dsp_adsp2_init(dsp); 2110 break; 2111 case WMFW_HALO: 2112 ret = cs_dsp_halo_init(dsp); 2113 break; 2114 default: 2115 KUNIT_FAIL(test, "Untested DSP type %d\n", dsp->type); 2116 return -EINVAL; 2117 } 2118 2119 if (ret) 2120 return ret; 2121 2122 /* Automatically call cs_dsp_remove() when test case ends */ 2123 return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); 2124 } 2125 2126 static int cs_dsp_ctl_rw_test_halo_init(struct kunit *test) 2127 { 2128 struct cs_dsp *dsp; 2129 2130 /* Fill in cs_dsp and initialize */ 2131 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL); 2132 if (!dsp) 2133 return -ENOMEM; 2134 2135 dsp->num = 1; 2136 dsp->type = WMFW_HALO; 2137 dsp->mem = cs_dsp_mock_halo_dsp1_regions; 2138 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_halo_dsp1_region_sizes); 2139 dsp->base = cs_dsp_mock_halo_core_base; 2140 dsp->base_sysinfo = cs_dsp_mock_halo_sysinfo_base; 2141 2142 return cs_dsp_ctl_rw_test_common_init(test, dsp, 3); 2143 } 2144 2145 static int cs_dsp_ctl_rw_test_adsp2_32bit_init(struct kunit *test, int wmfw_ver) 2146 { 2147 struct cs_dsp *dsp; 2148 2149 /* Fill in cs_dsp and initialize */ 2150 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL); 2151 if (!dsp) 2152 return -ENOMEM; 2153 2154 dsp->num = 1; 2155 dsp->type = WMFW_ADSP2; 2156 dsp->rev = 1; 2157 dsp->mem = cs_dsp_mock_adsp2_32bit_dsp1_regions; 2158 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_32bit_dsp1_region_sizes); 2159 dsp->base = cs_dsp_mock_adsp2_32bit_sysbase; 2160 2161 return cs_dsp_ctl_rw_test_common_init(test, dsp, wmfw_ver); 2162 } 2163 2164 static int cs_dsp_ctl_rw_test_adsp2_32bit_wmfw1_init(struct kunit *test) 2165 { 2166 return cs_dsp_ctl_rw_test_adsp2_32bit_init(test, 1); 2167 } 2168 2169 static int cs_dsp_ctl_rw_test_adsp2_32bit_wmfw2_init(struct kunit *test) 2170 { 2171 return cs_dsp_ctl_rw_test_adsp2_32bit_init(test, 2); 2172 } 2173 2174 static int cs_dsp_ctl_rw_test_adsp2_16bit_init(struct kunit *test, int wmfw_ver) 2175 { 2176 struct cs_dsp *dsp; 2177 2178 /* Fill in cs_dsp and initialize */ 2179 dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL); 2180 if (!dsp) 2181 return -ENOMEM; 2182 2183 dsp->num = 1; 2184 dsp->type = WMFW_ADSP2; 2185 dsp->rev = 0; 2186 dsp->mem = cs_dsp_mock_adsp2_16bit_dsp1_regions; 2187 dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_16bit_dsp1_region_sizes); 2188 dsp->base = cs_dsp_mock_adsp2_16bit_sysbase; 2189 2190 return cs_dsp_ctl_rw_test_common_init(test, dsp, wmfw_ver); 2191 } 2192 2193 static int cs_dsp_ctl_rw_test_adsp2_16bit_wmfw1_init(struct kunit *test) 2194 { 2195 return cs_dsp_ctl_rw_test_adsp2_16bit_init(test, 1); 2196 } 2197 2198 static int cs_dsp_ctl_rw_test_adsp2_16bit_wmfw2_init(struct kunit *test) 2199 { 2200 return cs_dsp_ctl_rw_test_adsp2_16bit_init(test, 2); 2201 } 2202 2203 static void cs_dsp_ctl_all_param_desc(const struct cs_dsp_ctl_rw_test_param *param, 2204 char *desc) 2205 { 2206 snprintf(desc, KUNIT_PARAM_DESC_SIZE, "alg:%#x %s@%u len:%u flags:%#x", 2207 param->alg_id, cs_dsp_mem_region_name(param->mem_type), 2208 param->offs_words, param->len_bytes, param->flags); 2209 } 2210 2211 /* All parameters populated, with various lengths */ 2212 static const struct cs_dsp_ctl_rw_test_param all_pop_varying_len_cases[] = { 2213 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2214 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 8 }, 2215 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 12 }, 2216 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 16 }, 2217 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 48 }, 2218 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 100 }, 2219 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 512 }, 2220 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 1000 }, 2221 }; 2222 KUNIT_ARRAY_PARAM(all_pop_varying_len, all_pop_varying_len_cases, 2223 cs_dsp_ctl_all_param_desc); 2224 2225 /* All parameters populated, with various offsets */ 2226 static const struct cs_dsp_ctl_rw_test_param all_pop_varying_offset_cases[] = { 2227 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 0, .len_bytes = 4 }, 2228 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2229 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 2, .len_bytes = 4 }, 2230 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 3, .len_bytes = 4 }, 2231 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 8, .len_bytes = 4 }, 2232 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 10, .len_bytes = 4 }, 2233 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 128, .len_bytes = 4 }, 2234 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 180, .len_bytes = 4 }, 2235 }; 2236 KUNIT_ARRAY_PARAM(all_pop_varying_offset, all_pop_varying_offset_cases, 2237 cs_dsp_ctl_all_param_desc); 2238 2239 /* All parameters populated, with various X and Y memory regions */ 2240 static const struct cs_dsp_ctl_rw_test_param all_pop_varying_xy_cases[] = { 2241 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_XM, .offs_words = 1, .len_bytes = 4 }, 2242 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2243 }; 2244 KUNIT_ARRAY_PARAM(all_pop_varying_xy, all_pop_varying_xy_cases, 2245 cs_dsp_ctl_all_param_desc); 2246 2247 /* All parameters populated, using ZM */ 2248 static const struct cs_dsp_ctl_rw_test_param all_pop_z_cases[] = { 2249 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_ZM, .offs_words = 1, .len_bytes = 4 }, 2250 }; 2251 KUNIT_ARRAY_PARAM(all_pop_z, all_pop_z_cases, cs_dsp_ctl_all_param_desc); 2252 2253 /* All parameters populated, with various algorithm ids */ 2254 static const struct cs_dsp_ctl_rw_test_param all_pop_varying_alg_cases[] = { 2255 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2256 { .alg_id = 0xb, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2257 { .alg_id = 0x9f1234, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2258 { .alg_id = 0xff00ff, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4 }, 2259 }; 2260 KUNIT_ARRAY_PARAM(all_pop_varying_alg, all_pop_varying_alg_cases, 2261 cs_dsp_ctl_all_param_desc); 2262 2263 /* 2264 * All parameters populated, with all combinations of flags for a 2265 * readable control. 2266 */ 2267 static const struct cs_dsp_ctl_rw_test_param all_pop_readable_flags_cases[] = { 2268 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2269 .flags = 0 2270 }, 2271 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2272 .flags = WMFW_CTL_FLAG_READABLE, 2273 }, 2274 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2275 .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2276 }, 2277 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2278 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE, 2279 }, 2280 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2281 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2282 }, 2283 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2284 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_READABLE, 2285 }, 2286 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2287 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2288 }, 2289 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2290 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE, 2291 }, 2292 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2293 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_SYS | 2294 WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2295 }, 2296 }; 2297 KUNIT_ARRAY_PARAM(all_pop_readable_flags, 2298 all_pop_readable_flags_cases, 2299 cs_dsp_ctl_all_param_desc); 2300 2301 /* 2302 * All parameters populated, with all combinations of flags for a 2303 * read-only control 2304 */ 2305 static const struct cs_dsp_ctl_rw_test_param all_pop_readonly_flags_cases[] = { 2306 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2307 .flags = WMFW_CTL_FLAG_READABLE, 2308 }, 2309 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2310 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE, 2311 }, 2312 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2313 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_READABLE, 2314 }, 2315 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2316 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE, 2317 }, 2318 }; 2319 KUNIT_ARRAY_PARAM(all_pop_readonly_flags, 2320 all_pop_readonly_flags_cases, 2321 cs_dsp_ctl_all_param_desc); 2322 2323 /* 2324 * All parameters populated, with all combinations of flags for a 2325 * non-volatile readable control 2326 */ 2327 static const struct cs_dsp_ctl_rw_test_param all_pop_nonvol_readable_flags_cases[] = { 2328 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2329 .flags = 0 2330 }, 2331 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2332 .flags = WMFW_CTL_FLAG_READABLE, 2333 }, 2334 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2335 .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2336 }, 2337 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2338 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE, 2339 }, 2340 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2341 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2342 }, 2343 }; 2344 KUNIT_ARRAY_PARAM(all_pop_nonvol_readable_flags, 2345 all_pop_nonvol_readable_flags_cases, 2346 cs_dsp_ctl_all_param_desc); 2347 2348 /* 2349 * All parameters populated, with all combinations of flags for a 2350 * writeable control 2351 */ 2352 static const struct cs_dsp_ctl_rw_test_param all_pop_writeable_flags_cases[] = { 2353 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2354 .flags = 0 2355 }, 2356 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2357 .flags = WMFW_CTL_FLAG_WRITEABLE, 2358 }, 2359 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2360 .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2361 }, 2362 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2363 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE, 2364 }, 2365 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2366 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2367 }, 2368 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2369 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_WRITEABLE, 2370 }, 2371 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2372 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2373 }, 2374 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2375 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE, 2376 }, 2377 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2378 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_SYS | 2379 WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2380 }, 2381 }; 2382 KUNIT_ARRAY_PARAM(all_pop_writeable_flags, 2383 all_pop_writeable_flags_cases, 2384 cs_dsp_ctl_all_param_desc); 2385 2386 /* 2387 * All parameters populated, with all combinations of flags for a 2388 * write-only control 2389 */ 2390 static const struct cs_dsp_ctl_rw_test_param all_pop_writeonly_flags_cases[] = { 2391 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2392 .flags = WMFW_CTL_FLAG_WRITEABLE, 2393 }, 2394 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2395 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE, 2396 }, 2397 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2398 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_WRITEABLE, 2399 }, 2400 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2401 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE, 2402 }, 2403 }; 2404 KUNIT_ARRAY_PARAM(all_pop_writeonly_flags, 2405 all_pop_writeonly_flags_cases, 2406 cs_dsp_ctl_all_param_desc); 2407 2408 /* 2409 * All parameters populated, with all combinations of flags for a 2410 * non-volatile writeable control 2411 */ 2412 static const struct cs_dsp_ctl_rw_test_param all_pop_nonvol_writeable_flags_cases[] = { 2413 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2414 .flags = 0 2415 }, 2416 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2417 .flags = WMFW_CTL_FLAG_WRITEABLE, 2418 }, 2419 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2420 .flags = WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2421 }, 2422 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2423 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE, 2424 }, 2425 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2426 .flags = WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2427 }, 2428 }; 2429 KUNIT_ARRAY_PARAM(all_pop_nonvol_writeable_flags, 2430 all_pop_nonvol_writeable_flags_cases, 2431 cs_dsp_ctl_all_param_desc); 2432 2433 /* 2434 * All parameters populated, with all combinations of flags for a 2435 * volatile readable control. 2436 */ 2437 static const struct cs_dsp_ctl_rw_test_param all_pop_volatile_readable_flags_cases[] = { 2438 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2439 .flags = 0 /* flags == 0 is volatile while firmware is running */ 2440 }, 2441 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2442 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_READABLE, 2443 }, 2444 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2445 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2446 }, 2447 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2448 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_READABLE, 2449 }, 2450 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2451 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_SYS | 2452 WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2453 }, 2454 }; 2455 KUNIT_ARRAY_PARAM(all_pop_volatile_readable_flags, 2456 all_pop_volatile_readable_flags_cases, 2457 cs_dsp_ctl_all_param_desc); 2458 2459 /* 2460 * All parameters populated, with all combinations of flags for a 2461 * volatile readable control. 2462 */ 2463 static const struct cs_dsp_ctl_rw_test_param all_pop_volatile_writeable_flags_cases[] = { 2464 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2465 .flags = 0 /* flags == 0 is volatile while firmware is running */ 2466 }, 2467 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2468 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_WRITEABLE, 2469 }, 2470 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2471 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2472 }, 2473 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2474 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_SYS | WMFW_CTL_FLAG_WRITEABLE, 2475 }, 2476 { .alg_id = 0xfafa, .mem_type = WMFW_ADSP2_YM, .offs_words = 1, .len_bytes = 4, 2477 .flags = WMFW_CTL_FLAG_VOLATILE | WMFW_CTL_FLAG_SYS | 2478 WMFW_CTL_FLAG_READABLE | WMFW_CTL_FLAG_WRITEABLE, 2479 }, 2480 }; 2481 KUNIT_ARRAY_PARAM(all_pop_volatile_writeable_flags, 2482 all_pop_volatile_writeable_flags_cases, 2483 cs_dsp_ctl_all_param_desc); 2484 2485 static struct kunit_case cs_dsp_ctl_rw_test_cases_adsp[] = { 2486 KUNIT_CASE_PARAM(cs_dsp_ctl_write_running, all_pop_varying_len_gen_params), 2487 KUNIT_CASE_PARAM(cs_dsp_ctl_write_running, all_pop_varying_offset_gen_params), 2488 KUNIT_CASE_PARAM(cs_dsp_ctl_write_running, all_pop_varying_xy_gen_params), 2489 KUNIT_CASE_PARAM(cs_dsp_ctl_write_running, all_pop_z_gen_params), 2490 KUNIT_CASE_PARAM(cs_dsp_ctl_write_running, all_pop_varying_alg_gen_params), 2491 KUNIT_CASE_PARAM(cs_dsp_ctl_write_running, all_pop_writeable_flags_gen_params), 2492 2493 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_running, all_pop_varying_len_gen_params), 2494 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_running, all_pop_varying_offset_gen_params), 2495 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_running, all_pop_varying_xy_gen_params), 2496 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_running, all_pop_z_gen_params), 2497 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_running, 2498 all_pop_volatile_readable_flags_gen_params), 2499 2500 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_not_started, 2501 all_pop_volatile_readable_flags_gen_params), 2502 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_stopped, 2503 all_pop_volatile_readable_flags_gen_params), 2504 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_stopped_powered_down, 2505 all_pop_volatile_readable_flags_gen_params), 2506 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_not_current_loaded_fw, 2507 all_pop_volatile_readable_flags_gen_params), 2508 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_not_current_running_fw, 2509 all_pop_volatile_readable_flags_gen_params), 2510 2511 KUNIT_CASE_PARAM(cs_dsp_ctl_write_volatile_not_started, 2512 all_pop_volatile_writeable_flags_gen_params), 2513 KUNIT_CASE_PARAM(cs_dsp_ctl_write_volatile_stopped, 2514 all_pop_volatile_writeable_flags_gen_params), 2515 KUNIT_CASE_PARAM(cs_dsp_ctl_write_volatile_stopped_powered_down, 2516 all_pop_volatile_writeable_flags_gen_params), 2517 KUNIT_CASE_PARAM(cs_dsp_ctl_write_volatile_not_current_loaded_fw, 2518 all_pop_volatile_writeable_flags_gen_params), 2519 KUNIT_CASE_PARAM(cs_dsp_ctl_write_volatile_not_current_running_fw, 2520 all_pop_volatile_writeable_flags_gen_params), 2521 2522 KUNIT_CASE_PARAM(cs_dsp_ctl_read_with_seek, 2523 all_pop_readable_flags_gen_params), 2524 KUNIT_CASE_PARAM(cs_dsp_ctl_read_cache_with_seek, 2525 all_pop_nonvol_readable_flags_gen_params), 2526 KUNIT_CASE_PARAM(cs_dsp_ctl_read_truncated, 2527 all_pop_readable_flags_gen_params), 2528 KUNIT_CASE_PARAM(cs_dsp_ctl_read_cache_truncated, 2529 all_pop_nonvol_readable_flags_gen_params), 2530 2531 KUNIT_CASE_PARAM(cs_dsp_ctl_write_with_seek, 2532 all_pop_writeable_flags_gen_params), 2533 KUNIT_CASE_PARAM(cs_dsp_ctl_write_cache_with_seek, 2534 all_pop_nonvol_writeable_flags_gen_params), 2535 KUNIT_CASE_PARAM(cs_dsp_ctl_write_truncated, 2536 all_pop_writeable_flags_gen_params), 2537 KUNIT_CASE_PARAM(cs_dsp_ctl_write_cache_truncated, 2538 all_pop_nonvol_writeable_flags_gen_params), 2539 2540 KUNIT_CASE_PARAM(cs_dsp_ctl_read_with_seek_oob, 2541 all_pop_varying_len_gen_params), 2542 KUNIT_CASE_PARAM(cs_dsp_ctl_read_with_length_overflow, 2543 all_pop_varying_len_gen_params), 2544 KUNIT_CASE_PARAM(cs_dsp_ctl_read_with_seek_and_length_oob, 2545 all_pop_varying_len_gen_params), 2546 KUNIT_CASE_PARAM(cs_dsp_ctl_write_with_seek_oob, 2547 all_pop_varying_len_gen_params), 2548 KUNIT_CASE_PARAM(cs_dsp_ctl_write_with_length_overflow, 2549 all_pop_varying_len_gen_params), 2550 KUNIT_CASE_PARAM(cs_dsp_ctl_write_with_seek_and_length_oob, 2551 all_pop_varying_len_gen_params), 2552 2553 KUNIT_CASE_PARAM(cs_dsp_ctl_read_from_writeonly, 2554 all_pop_writeonly_flags_gen_params), 2555 KUNIT_CASE_PARAM(cs_dsp_ctl_write_to_readonly, 2556 all_pop_readonly_flags_gen_params), 2557 2558 { } /* terminator */ 2559 }; 2560 2561 static struct kunit_case cs_dsp_ctl_rw_test_cases_halo[] = { 2562 KUNIT_CASE_PARAM(cs_dsp_ctl_write_running, all_pop_varying_len_gen_params), 2563 KUNIT_CASE_PARAM(cs_dsp_ctl_write_running, all_pop_varying_offset_gen_params), 2564 KUNIT_CASE_PARAM(cs_dsp_ctl_write_running, all_pop_varying_xy_gen_params), 2565 KUNIT_CASE_PARAM(cs_dsp_ctl_write_running, all_pop_varying_alg_gen_params), 2566 KUNIT_CASE_PARAM(cs_dsp_ctl_write_running, all_pop_writeable_flags_gen_params), 2567 2568 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_running, all_pop_varying_len_gen_params), 2569 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_running, all_pop_varying_offset_gen_params), 2570 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_running, all_pop_varying_xy_gen_params), 2571 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_running, 2572 all_pop_volatile_readable_flags_gen_params), 2573 2574 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_not_started, 2575 all_pop_volatile_readable_flags_gen_params), 2576 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_stopped, 2577 all_pop_volatile_readable_flags_gen_params), 2578 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_stopped_powered_down, 2579 all_pop_volatile_readable_flags_gen_params), 2580 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_not_current_loaded_fw, 2581 all_pop_volatile_readable_flags_gen_params), 2582 KUNIT_CASE_PARAM(cs_dsp_ctl_read_volatile_not_current_running_fw, 2583 all_pop_volatile_readable_flags_gen_params), 2584 2585 KUNIT_CASE_PARAM(cs_dsp_ctl_write_volatile_not_started, 2586 all_pop_volatile_writeable_flags_gen_params), 2587 KUNIT_CASE_PARAM(cs_dsp_ctl_write_volatile_stopped, 2588 all_pop_volatile_writeable_flags_gen_params), 2589 KUNIT_CASE_PARAM(cs_dsp_ctl_write_volatile_stopped_powered_down, 2590 all_pop_volatile_writeable_flags_gen_params), 2591 KUNIT_CASE_PARAM(cs_dsp_ctl_write_volatile_not_current_loaded_fw, 2592 all_pop_volatile_writeable_flags_gen_params), 2593 KUNIT_CASE_PARAM(cs_dsp_ctl_write_volatile_not_current_running_fw, 2594 all_pop_volatile_writeable_flags_gen_params), 2595 2596 KUNIT_CASE_PARAM(cs_dsp_ctl_read_with_seek, 2597 all_pop_readable_flags_gen_params), 2598 KUNIT_CASE_PARAM(cs_dsp_ctl_read_cache_with_seek, 2599 all_pop_nonvol_readable_flags_gen_params), 2600 KUNIT_CASE_PARAM(cs_dsp_ctl_read_truncated, 2601 all_pop_readable_flags_gen_params), 2602 KUNIT_CASE_PARAM(cs_dsp_ctl_read_cache_truncated, 2603 all_pop_nonvol_readable_flags_gen_params), 2604 2605 KUNIT_CASE_PARAM(cs_dsp_ctl_write_with_seek, 2606 all_pop_writeable_flags_gen_params), 2607 KUNIT_CASE_PARAM(cs_dsp_ctl_write_cache_with_seek, 2608 all_pop_nonvol_writeable_flags_gen_params), 2609 KUNIT_CASE_PARAM(cs_dsp_ctl_write_truncated, 2610 all_pop_writeable_flags_gen_params), 2611 KUNIT_CASE_PARAM(cs_dsp_ctl_write_cache_truncated, 2612 all_pop_nonvol_writeable_flags_gen_params), 2613 2614 KUNIT_CASE_PARAM(cs_dsp_ctl_read_with_seek_oob, 2615 all_pop_varying_len_gen_params), 2616 KUNIT_CASE_PARAM(cs_dsp_ctl_read_with_length_overflow, 2617 all_pop_varying_len_gen_params), 2618 KUNIT_CASE_PARAM(cs_dsp_ctl_read_with_seek_and_length_oob, 2619 all_pop_varying_len_gen_params), 2620 KUNIT_CASE_PARAM(cs_dsp_ctl_write_with_seek_oob, 2621 all_pop_varying_len_gen_params), 2622 KUNIT_CASE_PARAM(cs_dsp_ctl_write_with_length_overflow, 2623 all_pop_varying_len_gen_params), 2624 KUNIT_CASE_PARAM(cs_dsp_ctl_write_with_seek_and_length_oob, 2625 all_pop_varying_len_gen_params), 2626 2627 KUNIT_CASE_PARAM(cs_dsp_ctl_read_from_writeonly, 2628 all_pop_writeonly_flags_gen_params), 2629 KUNIT_CASE_PARAM(cs_dsp_ctl_write_to_readonly, 2630 all_pop_readonly_flags_gen_params), 2631 2632 { } /* terminator */ 2633 }; 2634 2635 static struct kunit_suite cs_dsp_ctl_rw_test_halo = { 2636 .name = "cs_dsp_ctl_rw_wmfwV3_halo", 2637 .init = cs_dsp_ctl_rw_test_halo_init, 2638 .test_cases = cs_dsp_ctl_rw_test_cases_halo, 2639 }; 2640 2641 static struct kunit_suite cs_dsp_ctl_rw_test_adsp2_32bit_wmfw1 = { 2642 .name = "cs_dsp_ctl_rw_wmfwV1_adsp2_32bit", 2643 .init = cs_dsp_ctl_rw_test_adsp2_32bit_wmfw1_init, 2644 .test_cases = cs_dsp_ctl_rw_test_cases_adsp, 2645 }; 2646 2647 static struct kunit_suite cs_dsp_ctl_rw_test_adsp2_32bit_wmfw2 = { 2648 .name = "cs_dsp_ctl_rw_wmfwV2_adsp2_32bit", 2649 .init = cs_dsp_ctl_rw_test_adsp2_32bit_wmfw2_init, 2650 .test_cases = cs_dsp_ctl_rw_test_cases_adsp, 2651 }; 2652 2653 static struct kunit_suite cs_dsp_ctl_rw_test_adsp2_16bit_wmfw1 = { 2654 .name = "cs_dsp_ctl_rw_wmfwV1_adsp2_16bit", 2655 .init = cs_dsp_ctl_rw_test_adsp2_16bit_wmfw1_init, 2656 .test_cases = cs_dsp_ctl_rw_test_cases_adsp, 2657 }; 2658 2659 static struct kunit_suite cs_dsp_ctl_rw_test_adsp2_16bit_wmfw2 = { 2660 .name = "cs_dsp_ctl_rw_wmfwV2_adsp2_16bit", 2661 .init = cs_dsp_ctl_rw_test_adsp2_16bit_wmfw2_init, 2662 .test_cases = cs_dsp_ctl_rw_test_cases_adsp, 2663 }; 2664 2665 kunit_test_suites(&cs_dsp_ctl_rw_test_halo, 2666 &cs_dsp_ctl_rw_test_adsp2_32bit_wmfw1, 2667 &cs_dsp_ctl_rw_test_adsp2_32bit_wmfw2, 2668 &cs_dsp_ctl_rw_test_adsp2_16bit_wmfw1, 2669 &cs_dsp_ctl_rw_test_adsp2_16bit_wmfw2); 2670