/* * Memory allocated for control cache must be large enough. * This creates multiple controls of different sizes so only works on * wmfw V2 and later.
*/ staticvoid cs_dsp_ctl_v2_cache_alloc(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; unsignedint reg, alg_base_words, alg_size_bytes; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw; char ctl_name[4];
u32 *reg_vals; int num_ctls;
/* Create some DSP data to initialize the control cache */
alg_base_words = _get_alg_mem_base_words(test, 0, WMFW_ADSP2_YM);
alg_size_bytes = cs_dsp_ctl_cache_test_algs[0].ym_size_words *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
reg_vals = kunit_kzalloc(test, alg_size_bytes, GFP_KERNEL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, reg_vals);
reg = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_YM);
reg += alg_base_words * cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, reg_vals, alg_size_bytes);
/* Check that the block allocated for the cache is large enough */
list_for_each_entry(ctl, &dsp->ctl_list, list)
KUNIT_EXPECT_GE(test, ksize(ctl->cache), ctl->len);
}
/* * Content of registers backing a control should be read into the * control cache when the firmware is downloaded.
*/ staticvoid cs_dsp_ctl_cache_init(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
get_random_bytes(reg_vals, param->len_bytes);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* * The data should have been populated into the control cache * so should be readable through the control.
*/
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * For a non-volatile write-only control the cache should be zero-filled * when the firmware is downloaded.
*/ staticvoid cs_dsp_ctl_cache_init_write_only(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *readback, *zeros;
/* * The control cache should have been zero-filled so should be * readable through the control.
*/
get_random_bytes(readback, param->len_bytes);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, zeros, param->len_bytes);
}
/* * Multiple different firmware with identical controls. * This is legal because different firmwares could contain the same * algorithm. * The control cache should be initialized only with the data from * the firmware containing it.
*/ staticvoid cs_dsp_ctl_cache_init_multiple_fw_same_controls(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_mock_wmfw_builder *builder[3]; unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *walkctl, *ctl[3]; struct firmware *wmfw;
u32 *reg_vals[3], *readback; int i;
/* Create an identical control in each firmware but with different alg id */ for (i = 0; i < ARRAY_SIZE(builder); i++) {
builder[i] = _create_dummy_wmfw(test);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, builder[i]);
/* * For each firmware create random content in the register backing * the control. Then download, start, stop and power-down.
*/ for (i = 0; i < ARRAY_SIZE(builder); i++) {
alg_base_words = _get_alg_mem_base_words(test, 0, def.mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type);
reg += (alg_base_words + def.offset_dsp_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
/* There should now be 3 controls */
KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
/* * There's no requirement for the control list to be in any * particular order, so don't assume the order.
*/ for (i = 0; i < ARRAY_SIZE(ctl); i++)
ctl[i] = NULL;
/* * The data should have been populated into the control cache * so should be readable through the control.
*/
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
/* * Multiple different firmware with controls identical except for alg id. * This is legal because the controls are qualified by algorithm id. * The control cache should be initialized only with the data from * the firmware containing it.
*/ staticvoid cs_dsp_ctl_cache_init_multiple_fwalgid_same_controls(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_mock_wmfw_builder *builder[3]; unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *walkctl, *ctl[3]; struct firmware *wmfw;
u32 *reg_vals[3], *readback; int i;
/* Create an identical control in each firmware but with different alg id */ for (i = 0; i < ARRAY_SIZE(builder); i++) {
builder[i] = _create_dummy_wmfw(test);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, builder[i]);
/* * For each firmware create random content in the register backing * the control. Then download, start, stop and power-down.
*/ for (i = 0; i < ARRAY_SIZE(builder); i++) {
alg_base_words = _get_alg_mem_base_words(test, i, def.mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type);
reg += (alg_base_words + def.offset_dsp_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
/* There should now be 3 controls */
KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
/* * There's no requirement for the control list to be in any * particular order, so don't assume the order.
*/ for (i = 0; i < ARRAY_SIZE(ctl); i++)
ctl[i] = NULL;
/* * The data should have been populated into the control cache * so should be readable through the control.
*/
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
/* * Firmware with controls at the same position in different memories. * The control cache should be initialized with content from the * correct memory region.
*/ staticvoid cs_dsp_ctl_cache_init_multiple_mems(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *walkctl, *ctl[3]; struct firmware *wmfw;
u32 *reg_vals[3], *readback; int i;
/* There should now be 2 or 3 controls */
KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list),
cs_dsp_mock_has_zm(priv) ? 3 : 2);
/* * There's no requirement for the control list to be in any * particular order, so don't assume the order.
*/ for (i = 0; i < ARRAY_SIZE(ctl); i++)
ctl[i] = NULL;
list_for_each_entry(walkctl, &dsp->ctl_list, list) { if (walkctl->alg_region.type == WMFW_ADSP2_YM)
ctl[0] = walkctl; if (walkctl->alg_region.type == WMFW_ADSP2_XM)
ctl[1] = walkctl; if (walkctl->alg_region.type == WMFW_ADSP2_ZM)
ctl[2] = walkctl;
}
/* * The data should have been populated into the control cache * so should be readable through the control.
*/
KUNIT_ASSERT_NOT_NULL(test, ctl[0]);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
/* * Firmware with controls at the same position in different algorithms * The control cache should be initialized with content from the * memory of the algorithm it points to.
*/ staticvoid cs_dsp_ctl_cache_init_multiple_algs(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *walkctl, *ctl[3]; struct firmware *wmfw;
u32 *reg_vals[3], *readback; int i;
/* Create controls identical except for algorithm */ for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder,
cs_dsp_ctl_cache_test_algs[i].id, "dummyalg", NULL);
cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def);
cs_dsp_mock_wmfw_end_alg_info_block(local->wmfw_builder);
}
/* Create random content in the registers backing each control */ for (i = 0; i < ARRAY_SIZE(reg_vals); i++) {
alg_base_words = _get_alg_mem_base_words(test, i, def.mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type);
reg += (alg_base_words + def.offset_dsp_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, reg_vals[i], def.length_bytes);
}
/* There should now be 3 controls */
KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
/* * There's no requirement for the control list to be in any * particular order, so don't assume the order.
*/ for (i = 0; i < ARRAY_SIZE(ctl); i++)
ctl[i] = NULL;
list_for_each_entry(walkctl, &dsp->ctl_list, list) { if (walkctl->alg_region.alg == cs_dsp_ctl_cache_test_algs[0].id)
ctl[0] = walkctl; if (walkctl->alg_region.alg == cs_dsp_ctl_cache_test_algs[1].id)
ctl[1] = walkctl; if (walkctl->alg_region.alg == cs_dsp_ctl_cache_test_algs[2].id)
ctl[2] = walkctl;
}
/* * The data should have been populated into the control cache * so should be readable through the control.
*/
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
/* * Firmware with controls in the same algorithm and memory but at * different offsets. * The control cache should be initialized with content from the * correct offset. * Only for wmfw format V2 and later. V1 only supports one control per * memory per algorithm.
*/ staticvoid cs_dsp_ctl_cache_init_multiple_offsets(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; unsignedint reg, alg_base_words, alg_base_reg; struct cs_dsp_coeff_ctl *walkctl, *ctl[3]; struct firmware *wmfw;
u32 *reg_vals[3], *readback; int i;
/* Create random content in the registers backing each control */
alg_base_words = _get_alg_mem_base_words(test, 0, def.mem_type);
alg_base_reg = cs_dsp_mock_base_addr_for_mem(priv, def.mem_type);
alg_base_reg += alg_base_words * cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
/* There should now be 3 controls */
KUNIT_ASSERT_EQ(test, list_count_nodes(&dsp->ctl_list), 3);
/* * There's no requirement for the control list to be in any * particular order, so don't assume the order.
*/ for (i = 0; i < ARRAY_SIZE(ctl); i++)
ctl[i] = NULL;
list_for_each_entry(walkctl, &dsp->ctl_list, list) { if (walkctl->offset == 0)
ctl[0] = walkctl; if (walkctl->offset == 5)
ctl[1] = walkctl; if (walkctl->offset == 8)
ctl[2] = walkctl;
}
/* * The data should have been populated into the control cache * so should be readable through the control.
*/
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl[0], 0, readback, def.length_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals[0], def.length_bytes);
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
get_random_bytes(reg_vals, param->len_bytes);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Drop expected writes and the regmap cache should be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Control should readback the data from the control cache */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Read from a cached control after the firmware has been stopped. * Should return the data in the cache.
*/ staticvoid cs_dsp_ctl_cache_read_stopped(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
get_random_bytes(reg_vals, param->len_bytes);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Start and stop the firmware */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
cs_dsp_stop(dsp);
/* Drop expected writes and the regmap cache should be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Control should readback the data from the control cache */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Read from a cached control after the DSP has been powered-up and * then powered-down without running. * Should return the data in the cache.
*/ staticvoid cs_dsp_ctl_cache_read_powered_down(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
get_random_bytes(reg_vals, param->len_bytes);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Drop expected writes and the regmap cache should be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Control should readback the data from the control cache */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Read from a cached control after the firmware has been run and * stopped, then the DSP has been powered-down. * Should return the data in the cache.
*/ staticvoid cs_dsp_ctl_cache_read_stopped_powered_down(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
get_random_bytes(reg_vals, param->len_bytes);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Start and stop the firmware then power-down */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
cs_dsp_stop(dsp);
cs_dsp_power_down(dsp);
/* Drop expected writes and the regmap cache should be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Control should readback the data from the control cache */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Read from a cached control when a different firmware is currently * loaded into the DSP. * Should return the data in the cache.
*/ staticvoid cs_dsp_ctl_cache_read_not_current_loaded_fw(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
get_random_bytes(reg_vals, param->len_bytes);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Power-down DSP then power-up with a different firmware */
cs_dsp_power_down(dsp);
wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
/* Drop expected writes and the regmap cache should be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Control should readback the data from the control cache */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Read from a cached control when a different firmware is currently * running. * Should return the data in the cache.
*/ staticvoid cs_dsp_ctl_cache_read_not_current_running_fw(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
get_random_bytes(reg_vals, param->len_bytes);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Power-up with a different firmware and run it */
wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
/* Drop expected writes and the regmap cache should be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Control should readback the data from the control cache */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Read from a cached control with non-zero flags while the firmware is * running. * Should return the data in the cache, not from the registers.
*/ staticvoid cs_dsp_ctl_cache_read_running(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *init_reg_vals, *new_reg_vals, *readback;
/* Create data in the registers backing the control */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
get_random_bytes(init_reg_vals, param->len_bytes);
regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* * Change the values in the registers backing the control then drop * them from the regmap cache. This allows checking that the control * read is returning values from the control cache and not accessing * the registers.
*/
KUNIT_ASSERT_EQ(test,
regmap_raw_write(dsp->regmap, reg, new_reg_vals, param->len_bytes),
0);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
/* Control should readback the origin data from its cache */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, init_reg_vals, param->len_bytes);
/* Stop and power-down the DSP */
kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
cs_dsp_power_down(dsp);
/* Control should readback from the cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, init_reg_vals, param->len_bytes);
}
/* * Read from a cached control with flags == 0 while the firmware is * running. * Should behave as volatile and read from the registers. * (This is for backwards compatibility with old firmware versions)
*/ staticvoid cs_dsp_ctl_cache_read_running_zero_flags(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *init_reg_vals, *new_reg_vals, *readback;
/* Zero-fill the registers backing the control */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = 0;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Change the values in the registers backing the control */
get_random_bytes(new_reg_vals, param->len_bytes);
regmap_raw_write(dsp->regmap, reg, new_reg_vals, param->len_bytes);
/* Control should readback the new data from the registers */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, new_reg_vals, param->len_bytes);
/* Stop and power-down the DSP */
kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
cs_dsp_power_down(dsp);
/* Change the values in the registers backing the control */
regmap_raw_write(dsp->regmap, reg, init_reg_vals, param->len_bytes);
/* Control should readback from the cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, new_reg_vals, param->len_bytes);
}
/* * Write to a cached control while the firmware is running. * This should be a writethrough operation, writing to the cache and * the registers.
*/ staticvoid cs_dsp_ctl_cache_writethrough(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
memset(reg_vals, 0, param->len_bytes);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Start the firmware and add an action to stop it during cleanup */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
/* Write new data to the control, it should be written to the registers */
get_random_bytes(reg_vals, param->len_bytes);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1);
KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Write unchanged data to a cached control while the firmware is running. * The control write should return 0 to indicate that the content * didn't change.
*/ staticvoid cs_dsp_ctl_cache_writethrough_unchanged(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
get_random_bytes(reg_vals, param->len_bytes);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Start the firmware and add an action to stop it during cleanup */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
/* * If the control is write-only the cache will have been zero-initialized * so the first write will always indicate a change.
*/ if (def.flags && !(def.flags & WMFW_CTL_FLAG_READABLE)) {
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals,
param->len_bytes),
1);
}
/* * Write the same data to the control, cs_dsp_coeff_lock_and_write_ctrl() * should return 0 to indicate the content didn't change.
*/
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
0);
KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Write unchanged data to a cached control while the firmware is not started. * The control write should return 0 to indicate that the cache content * didn't change.
*/ staticvoid cs_dsp_ctl_cache_write_unchanged_not_started(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
get_random_bytes(reg_vals, param->len_bytes);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* * If the control is write-only the cache will have been zero-initialized * so the first write will always indicate a change.
*/ if (def.flags && !(def.flags & WMFW_CTL_FLAG_READABLE)) {
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals,
param->len_bytes),
1);
}
/* * Write the same data to the control, cs_dsp_coeff_lock_and_write_ctrl() * should return 0 to indicate the content didn't change.
*/
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
0);
KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Write to a cached control while the firmware is loaded but not * started. * This should write to the cache only.
*/ staticvoid cs_dsp_ctl_cache_write_not_started(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Drop expected writes and the regmap cache should be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Write new data to the control, it should not be written to the registers */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
/* Registers should not have been written so regmap cache should still be clean */
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Write to a cached control after the firmware has been loaded, * started and stopped. * This should write to the cache only.
*/ staticvoid cs_dsp_ctl_cache_write_stopped(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Start and stop the firmware */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
cs_dsp_stop(dsp);
/* Drop expected writes and the regmap cache should be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Write new data to the control, it should not be written to the registers */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
/* Registers should not have been written so regmap cache should still be clean */
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Write to a cached control after the firmware has been loaded, * then the DSP powered-down. * This should write to the cache only.
*/ staticvoid cs_dsp_ctl_cache_write_powered_down(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Drop expected writes and the regmap cache should be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Write new data to the control, it should not be written to the registers */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
/* Registers should not have been written so regmap cache should still be clean */
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Write to a cached control after the firmware has been loaded, * started, stopped, and then the DSP powered-down. * This should write to the cache only.
*/ staticvoid cs_dsp_ctl_cache_write_stopped_powered_down(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Start and stop the firmware then power-down */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
cs_dsp_stop(dsp);
cs_dsp_power_down(dsp);
/* Drop expected writes and the regmap cache should be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Write new data to the control, it should not be written to the registers */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
/* Registers should not have been written so regmap cache should still be clean */
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Write to a cached control that is not in the currently loaded firmware. * This should write to the cache only.
*/ staticvoid cs_dsp_ctl_cache_write_not_current_loaded_fw(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Get the control */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
/* Power-down DSP then power-up with a different firmware */
cs_dsp_power_down(dsp);
wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
/* Control from unloaded firmware should be disabled */
KUNIT_EXPECT_FALSE(test, ctl->enabled);
/* Drop expected writes and the regmap cache should be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* * It should be possible to write new data to the control from * the first firmware. But this should not be written to the * registers.
*/
get_random_bytes(reg_vals, param->len_bytes);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1);
/* Registers should not have been written so regmap cache should still be clean */
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Write to a cached control that is not in the currently running firmware. * This should write to the cache only.
*/ staticvoid cs_dsp_ctl_cache_write_not_current_running_fw(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Get the control */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
/* Power-up with a different firmware and run it */
wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
/* Control from unloaded firmware should be disabled */
KUNIT_EXPECT_FALSE(test, ctl->enabled);
/* Drop expected writes and the regmap cache should be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
cs_dsp_mock_regmap_drop_bytes(priv, reg, param->len_bytes);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* * It should be possible to write new data to the control from * the first firmware. But this should not be written to the * registers.
*/
get_random_bytes(reg_vals, param->len_bytes);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1);
/* Registers should not have been written so regmap cache should still be clean */
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Write to a cached control before running the firmware. * The value written to the cache should be synced out to the registers * backing the control when the firmware is run.
*/ staticvoid cs_dsp_ctl_cache_sync_write_before_run(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Write new data to the control, it should not be written to the registers */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
/* Start the firmware and the cached data should be written to registers */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Write to a cached control while the firmware is running. * The value written should be synced out to the registers * backing the control when the firmware is next run.
*/ staticvoid cs_dsp_ctl_cache_sync_write_while_running(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *init_vals, *ctl_vals, *readback;
/* Zero-fill the registers backing the control */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Stop firmware and zero the registers backing the control */
kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
KUNIT_ASSERT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
KUNIT_EXPECT_MEMEQ(test, readback, init_vals, param->len_bytes);
/* Start the firmware and the cached data should be written to registers */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
}
/* * Write to a cached control after stopping the firmware. * The value written to the cache should be synced out to the registers * backing the control when the firmware is next run.
*/ staticvoid cs_dsp_ctl_cache_sync_write_after_stop(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Start and stop the firmware */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
cs_dsp_stop(dsp);
/* Write new data to the control, it should not be written to the registers */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
/* Start the firmware and the cached data should be written to registers */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * Write to a cached control that is not in the currently loaded firmware. * The value written to the cache should be synced out to the registers * backing the control the next time the firmware containing the * control is run.
*/ staticvoid cs_dsp_ctl_cache_sync_write_not_current_fw(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *reg_vals, *readback;
/* Create some DSP data to be read into the control cache */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, reg_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Get the control */
ctl = list_first_entry_or_null(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list);
KUNIT_ASSERT_NOT_NULL(test, ctl);
/* Power-down DSP then power-up with a different firmware */
cs_dsp_power_down(dsp);
wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
/* Write new data to the control, it should not be written to the registers */
get_random_bytes(reg_vals, param->len_bytes);
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_write_ctrl(ctl, 0, reg_vals, param->len_bytes),
1);
/* Power-down DSP then power-up with the original firmware */
cs_dsp_power_down(dsp);
wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
/* Start the firmware and the cached data should be written to registers */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, reg_vals, param->len_bytes);
}
/* * The value in the control cache should be synced out to the registers * backing the control every time the firmware containing the control * is run.
*/ staticvoid cs_dsp_ctl_cache_sync_reapply_every_run(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *init_vals, *readback, *ctl_vals;
/* Zero-fill the registers backing the control */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Start the firmware and the cached data should be written to registers */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
/* Stop the firmware and reset the registers */
kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
/* Start the firmware again and the cached data should be written to registers */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
}
/* * The value in the control cache should be retained if the same * firmware is downloaded again. It should be synced out to the * registers backing the control after the firmware containing the * control is downloaded again and run.
*/ staticvoid cs_dsp_ctl_cache_sync_reapply_after_fw_reload(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *init_vals, *readback, *ctl_vals;
/* Zero-fill the registers backing the control */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Start the firmware and the cached data should be written to registers */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
/* Stop the firmware and power-down the DSP */
kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
cs_dsp_power_down(dsp);
/* Reset the registers */
regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
/* Download the firmware again, the cache content should not change */
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
/* Start the firmware and the cached data should be written to registers */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
}
/* * The value in the control cache should be retained after a different * firmware is downloaded. * When the firmware containing the control is downloaded and run * the value in the control cache should be synced out to the registers * backing the control.
*/ staticvoid cs_dsp_ctl_cache_sync_reapply_after_fw_swap(struct kunit *test)
{ conststruct cs_dsp_ctl_cache_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct cs_dsp *dsp = priv->dsp; struct cs_dsp_mock_coeff_def def = mock_coeff_template; int alg_idx = _find_alg_entry(test, param->alg_id); struct cs_dsp_mock_wmfw_builder *builder2 = _create_dummy_wmfw(test); unsignedint reg, alg_base_words; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw;
u32 *init_vals, *readback, *ctl_vals;
/* Zero-fill the registers backing the control */
alg_base_words = _get_alg_mem_base_words(test, alg_idx, param->mem_type);
reg = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);
reg += (alg_base_words + param->offs_words) *
cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv);
regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
/* Create control pointing to this data */
def.flags = param->flags;
def.mem_type = param->mem_type;
def.offset_dsp_words = param->offs_words;
def.length_bytes = param->len_bytes;
/* Start the firmware and the cached data should be written to registers */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
/* Stop the firmware and power-down the DSP */
kunit_release_action(test, _cs_dsp_stop_wrapper, dsp);
cs_dsp_power_down(dsp);
/* Reset the registers */
regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
/* Download and run a different firmware */
wmfw = cs_dsp_mock_wmfw_get_firmware(builder2);
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw2", NULL, NULL, "mbc.vss"), 0);
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
cs_dsp_power_down(dsp);
/* Reset the registers */
regmap_raw_write(dsp->regmap, reg, init_vals, param->len_bytes);
/* Download the original firmware again */
wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
KUNIT_ASSERT_EQ(test, cs_dsp_power_up(dsp, wmfw, "mock_fw", NULL, NULL, "misc"), 0);
KUNIT_EXPECT_TRUE(test, ctl->set);
/* Start the firmware and the cached data should be written to registers */
KUNIT_ASSERT_EQ(test, cs_dsp_run(dsp), 0);
KUNIT_ASSERT_EQ(test, kunit_add_action_or_reset(test, _cs_dsp_stop_wrapper, dsp), 0);
KUNIT_EXPECT_EQ(test, regmap_raw_read(dsp->regmap, reg, readback, param->len_bytes), 0);
KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
/* Control should readback the new data from the control cache */
KUNIT_EXPECT_EQ(test,
cs_dsp_coeff_lock_and_read_ctrl(ctl, 0, readback, param->len_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, ctl_vals, param->len_bytes);
}
dsp->dev = get_device(test_dev); if (!dsp->dev) return -ENODEV;
ret = kunit_add_action_or_reset(test, _put_device_wrapper, dsp->dev); if (ret) return ret;
dev_set_drvdata(dsp->dev, priv);
/* Allocate regmap */
ret = cs_dsp_mock_regmap_init(priv); if (ret) return ret;
/* * There must always be a XM header with at least 1 algorithm, so create * a dummy one that tests can use and extract it to a data blob.
*/
local->xm_header = cs_dsp_create_mock_xm_header(priv,
cs_dsp_ctl_cache_test_algs,
ARRAY_SIZE(cs_dsp_ctl_cache_test_algs));
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->xm_header);
switch (dsp->type) { case WMFW_ADSP2:
ret = cs_dsp_adsp2_init(dsp); break; case WMFW_HALO:
ret = cs_dsp_halo_init(dsp); break; default:
KUNIT_FAIL(test, "Untested DSP type %d\n", dsp->type); return -EINVAL;
}
if (ret) return ret;
/* Automatically call cs_dsp_remove() when test case ends */ return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);
}
¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.36Angebot
(Wie Sie bei der Firma Beratungs- und Dienstleistungen beauftragen können 2026-04-26)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.