/* * Test method is: * * 1) Create a mock regmap in cache-only mode so that all writes will be cached. * 2) Create dummy wmfw file. * 3) Call cs_dsp_power_up() with the bin file. * 4) Readback the cached value of registers that should have been written and * check they have the correct value. * 5) All the registers that are expected to have been written are dropped from * the cache. This should leave the cache clean. * 6) If the cache is still dirty there have been unexpected writes.
*/
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */ do {
payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);
} while (payload_size_bytes % 4);
/* Tests on XM must be after the XM header */ if (param->mem_type == WMFW_ADSP2_XM)
mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);
/* Add a single payload */
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
param->mem_type, mem_offset_dsp_words,
payload_data, payload_size_bytes);
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* Write several smallest possible payloads for the given memory type */ staticvoid wmfw_write_multiple_oneblock_payloads(struct kunit *test)
{ conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct firmware *wmfw; unsignedint reg_addr;
u8 *payload_data, *readback; unsignedint mem_offset_dsp_words = 0; unsignedint payload_size_bytes, payload_size_dsp_words; constunsignedint num_payloads = param->num_blocks; int i;
/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */
payload_size_dsp_words = 0;
payload_size_bytes = 0; do {
payload_size_dsp_words += cs_dsp_mock_reg_block_length_dsp_words(priv,
param->mem_type);
payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);
} while (payload_size_bytes % 4);
/* Tests on XM must be after the XM header */ if (param->mem_type == WMFW_ADSP2_XM)
mem_offset_dsp_words += local->xm_header->blob_size_bytes / payload_size_bytes;
/* Add multiple payloads of one block each */ for (i = 0; i < num_payloads; ++i) {
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
param->mem_type,
mem_offset_dsp_words + (i * payload_size_dsp_words),
&payload_data[i * payload_size_bytes],
payload_size_bytes);
}
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, num_payloads * payload_size_bytes);
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write several smallest possible payloads of the given memory type * in reverse address order
*/ staticvoid wmfw_write_multiple_oneblock_payloads_reverse(struct kunit *test)
{ conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct firmware *wmfw; unsignedint reg_addr;
u8 *payload_data, *readback; unsignedint mem_offset_dsp_words = 0; unsignedint payload_size_bytes, payload_size_dsp_words; constunsignedint num_payloads = param->num_blocks; int i;
/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */
payload_size_dsp_words = 0;
payload_size_bytes = 0; do {
payload_size_dsp_words += cs_dsp_mock_reg_block_length_dsp_words(priv,
param->mem_type);
payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);
} while (payload_size_bytes % 4);
/* Tests on XM must be after the XM header */ if (param->mem_type == WMFW_ADSP2_XM)
mem_offset_dsp_words += local->xm_header->blob_size_bytes / payload_size_bytes;
/* Add multiple payloads of one block each */ for (i = num_payloads - 1; i >= 0; --i) {
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
param->mem_type,
mem_offset_dsp_words + (i * payload_size_dsp_words),
&payload_data[i * payload_size_bytes],
payload_size_bytes);
}
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, num_payloads * payload_size_bytes);
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write multiple payloads of length param->num_blocks. * The payloads are not in address order and collectively do not patch * a contiguous block of memory.
*/ staticvoid wmfw_write_multiple_payloads_sparse_unordered(struct kunit *test)
{ staticconstunsignedint random_offsets[] = {
11, 69, 59, 61, 32, 75, 4, 38, 70, 13, 79, 47, 46, 53, 18, 44,
54, 35, 51, 21, 26, 45, 27, 41, 66, 2, 17, 56, 40, 9, 8, 20,
29, 19, 63, 42, 12, 16, 43, 3, 5, 55, 52, 22
}; conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct firmware *wmfw; unsignedint reg_addr;
u8 *payload_data, *readback; unsignedint mem_offset_dsp_words = 0; unsignedint payload_size_bytes, payload_size_dsp_words; constint num_payloads = ARRAY_SIZE(random_offsets); int i;
/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */ do {
payload_size_dsp_words += cs_dsp_mock_reg_block_length_dsp_words(priv,
param->mem_type);
payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);
} while (payload_size_bytes % 4);
/* Tests on XM must be after the XM header */ if (param->mem_type == WMFW_ADSP2_XM)
mem_offset_dsp_words += local->xm_header->blob_size_bytes / payload_size_bytes;
/* Add multiple payloads of one block each at "random" locations */ for (i = 0; i < num_payloads; ++i) { unsignedint offset = random_offsets[i] * payload_size_dsp_words;
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* Write the whole of PM in a single unpacked payload */ staticvoid wmfw_write_all_unpacked_pm(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct firmware *wmfw; unsignedint reg_addr;
u8 *payload_data, *readback; unsignedint payload_size_bytes;
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* Write the whole of PM in a single packed payload */ staticvoid wmfw_write_all_packed_pm(struct kunit *test)
{ struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct firmware *wmfw; unsignedint reg_addr;
u8 *payload_data, *readback; unsignedint payload_size_bytes;
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write a series of payloads to various unpacked memory regions. * The payloads are of various lengths and offsets, driven by the * payload_defs table. The offset and length are both given as a * number of minimum-sized register blocks to keep the maths simpler. * (Where a minimum-sized register block is the smallest number of * registers that contain a whole number of DSP words.)
*/ staticvoid wmfw_write_multiple_unpacked_mem(struct kunit *test)
{ staticconststruct { int mem_type; unsignedint offset_num_blocks; unsignedint num_blocks;
} payload_defs[] = {
{ WMFW_ADSP2_PM, 11, 60 },
{ WMFW_ADSP2_ZM, 69, 8 },
{ WMFW_ADSP2_YM, 32, 74 },
{ WMFW_ADSP2_XM, 70, 38 },
{ WMFW_ADSP2_PM, 84, 48 },
{ WMFW_ADSP2_XM, 46, 18 },
{ WMFW_ADSP2_PM, 0, 8 },
{ WMFW_ADSP2_YM, 0, 30 },
{ WMFW_ADSP2_PM, 160, 50 },
{ WMFW_ADSP2_ZM, 21, 26 },
}; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct firmware *wmfw; unsignedint payload_size_bytes, offset_num_dsp_words; unsignedint reg_addr, offset_bytes, offset_num_regs; void **payload_data; void *readback; int i, ret;
for (i = 0; i < ARRAY_SIZE(payload_defs); ++i) {
payload_size_bytes = payload_defs[i].num_blocks *
cs_dsp_mock_reg_block_length_bytes(priv,
payload_defs[i].mem_type);
for (i = 0; i < ARRAY_SIZE(payload_defs); ++i) {
payload_size_bytes = payload_defs[i].num_blocks *
cs_dsp_mock_reg_block_length_bytes(priv,
payload_defs[i].mem_type);
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write a series of payloads to various packed and unpacked memory regions. * The payloads are of various lengths and offsets, driven by the * payload_defs table. The offset and length are both given as a * number of minimum-sized register blocks to keep the maths simpler. * (Where a minimum-sized register block is the smallest number of * registers that contain a whole number of DSP words.)
*/ staticvoid wmfw_write_multiple_packed_unpacked_mem(struct kunit *test)
{ staticconststruct { int mem_type; unsignedint offset_num_blocks; unsignedint num_blocks;
} payload_defs[] = {
{ WMFW_HALO_PM_PACKED, 11, 60 },
{ WMFW_ADSP2_YM, 69, 8 },
{ WMFW_HALO_YM_PACKED, 32, 74 },
{ WMFW_HALO_XM_PACKED, 70, 38 },
{ WMFW_HALO_PM_PACKED, 84, 48 },
{ WMFW_HALO_XM_PACKED, 46, 18 },
{ WMFW_HALO_PM_PACKED, 0, 8 },
{ WMFW_HALO_YM_PACKED, 0, 30 },
{ WMFW_HALO_PM_PACKED, 160, 50 },
{ WMFW_ADSP2_XM, 21, 26 },
}; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; struct firmware *wmfw; unsignedint payload_size_bytes, offset_num_dsp_words; unsignedint reg_addr, offset_bytes, offset_num_regs; void **payload_data; void *readback; int i, ret;
for (i = 0; i < ARRAY_SIZE(payload_defs); ++i) {
payload_size_bytes = payload_defs[i].num_blocks *
cs_dsp_mock_reg_block_length_bytes(priv,
payload_defs[i].mem_type);
for (i = 0; i < ARRAY_SIZE(payload_defs); ++i) {
payload_size_bytes = payload_defs[i].num_blocks *
cs_dsp_mock_reg_block_length_bytes(priv,
payload_defs[i].mem_type);
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write XM/YM data that is one word longer than a packed block multiple, * using one packed payload followed by one unpacked word.
*/ staticvoid wmfw_write_packed_1_unpacked_trailing(struct kunit *test)
{ conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; int packed_mem_type = param->mem_type; int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type); unsignedint dsp_words_per_packed_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type); unsignedint dsp_words_per_unpacked_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type); unsignedint mem_offset_dsp_words = 0; struct firmware *wmfw; unsignedint reg_addr; void *packed_payload_data, *readback;
u32 unpacked_payload_data[1]; unsignedint packed_payload_size_bytes, packed_payload_size_dsp_words; unsignedint offset_num_regs;
/* Tests on XM must be after the XM header */ if (unpacked_mem_type == WMFW_ADSP2_XM) {
mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);
/* Round up to multiple of packed block length */
mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);
}
/* Add a single packed payload */
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
packed_mem_type, mem_offset_dsp_words,
packed_payload_data, packed_payload_size_bytes); /* * Add payload of one unpacked word to DSP memory right after * the packed payload words.
*/
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
mem_offset_dsp_words + packed_payload_size_dsp_words,
unpacked_payload_data, sizeof(unpacked_payload_data));
/* * Check that the unpacked word was written correctly and drop * it from the regmap cache. The unpacked payload is offset within * unpacked register space by the number of DSP words that were * written in the packed payload.
*/
offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(unpacked_payload_data)),
0);
KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write XM/YM data that is two words longer than a packed block multiple, * using one packed payload followed by one payload of two unpacked words.
*/ staticvoid wmfw_write_packed_2_unpacked_trailing(struct kunit *test)
{ conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; int packed_mem_type = param->mem_type; int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type); unsignedint dsp_words_per_packed_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type); unsignedint dsp_words_per_unpacked_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type); unsignedint mem_offset_dsp_words = 0; struct firmware *wmfw; unsignedint reg_addr; void *packed_payload_data, *readback;
u32 unpacked_payload_data[2]; unsignedint packed_payload_size_bytes, packed_payload_size_dsp_words; unsignedint offset_num_regs;
/* Tests on XM must be after the XM header */ if (unpacked_mem_type == WMFW_ADSP2_XM) {
mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);
/* Round up to multiple of packed block length */
mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);
}
/* Add a single packed payload */
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
packed_mem_type, mem_offset_dsp_words,
packed_payload_data, packed_payload_size_bytes); /* * Add payload of two unpacked words to DSP memory right after * the packed payload words.
*/
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
mem_offset_dsp_words + packed_payload_size_dsp_words,
unpacked_payload_data, sizeof(unpacked_payload_data));
/* * Check that the unpacked words were written correctly and drop * them from the regmap cache. The unpacked payload is offset * within unpacked register space by the number of DSP words * that were written in the packed payload.
*/
offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(unpacked_payload_data)),
0);
KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write XM/YM data that is three words longer than a packed block multiple, * using one packed payload followed by one payload of three unpacked words.
*/ staticvoid wmfw_write_packed_3_unpacked_trailing(struct kunit *test)
{ conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; int packed_mem_type = param->mem_type; int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type); unsignedint dsp_words_per_packed_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type); unsignedint dsp_words_per_unpacked_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type); unsignedint mem_offset_dsp_words = 0; struct firmware *wmfw; unsignedint reg_addr; void *packed_payload_data, *readback;
u32 unpacked_payload_data[3]; unsignedint packed_payload_size_bytes, packed_payload_size_dsp_words; unsignedint offset_num_regs;
/* Tests on XM must be after the XM header */ if (unpacked_mem_type == WMFW_ADSP2_XM) {
mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);
/* Round up to multiple of packed block length */
mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);
}
/* Add a single packed payload */
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
packed_mem_type, mem_offset_dsp_words,
packed_payload_data, packed_payload_size_bytes); /* * Add payload of three unpacked words to DSP memory right after * the packed payload words.
*/
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
mem_offset_dsp_words + packed_payload_size_dsp_words,
unpacked_payload_data, sizeof(unpacked_payload_data));
/* * Check that the unpacked words were written correctly and drop * them from the regmap cache. The unpacked payload is offset * within unpacked register space by the number of DSP words * that were written in the packed payload.
*/
offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(unpacked_payload_data)),
0);
KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write XM/YM data that is two words longer than a packed block multiple, * using one packed payload followed by two payloads of one unpacked word each.
*/ staticvoid wmfw_write_packed_2_single_unpacked_trailing(struct kunit *test)
{ conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; int packed_mem_type = param->mem_type; int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type); unsignedint dsp_words_per_packed_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type); unsignedint dsp_words_per_unpacked_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type); unsignedint mem_offset_dsp_words = 0; struct firmware *wmfw; unsignedint reg_addr; void *packed_payload_data, *readback;
u32 unpacked_payload_data[2]; unsignedint packed_payload_size_bytes, packed_payload_size_dsp_words; unsignedint offset_num_regs;
/* Tests on XM must be after the XM header */ if (unpacked_mem_type == WMFW_ADSP2_XM) {
mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);
/* Round up to multiple of packed block length */
mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);
}
/* Add a single packed payload */
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
packed_mem_type, mem_offset_dsp_words,
packed_payload_data, packed_payload_size_bytes); /* * Add two unpacked words to DSP memory right after the packed * payload words. Each unpacked word in its own payload.
*/
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
mem_offset_dsp_words + packed_payload_size_dsp_words,
&unpacked_payload_data[0], sizeof(unpacked_payload_data[0]));
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
mem_offset_dsp_words + packed_payload_size_dsp_words + 1,
&unpacked_payload_data[1], sizeof(unpacked_payload_data[1]));
/* * Check that the unpacked words were written correctly and drop * them from the regmap cache. The unpacked words are offset * within unpacked register space by the number of DSP words * that were written in the packed payload.
*/
offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(unpacked_payload_data)),
0);
KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write XM/YM data that is three words longer than a packed block multiple, * using one packed payload followed by three payloads of one unpacked word each.
*/ staticvoid wmfw_write_packed_3_single_unpacked_trailing(struct kunit *test)
{ conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; int packed_mem_type = param->mem_type; int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type); unsignedint dsp_words_per_packed_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type); unsignedint dsp_words_per_unpacked_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type); unsignedint mem_offset_dsp_words = 0; struct firmware *wmfw; unsignedint reg_addr; void *packed_payload_data, *readback;
u32 unpacked_payload_data[3]; unsignedint packed_payload_size_bytes, packed_payload_size_dsp_words; unsignedint offset_num_regs;
/* Tests on XM must be after the XM header */ if (unpacked_mem_type == WMFW_ADSP2_XM) {
mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);
/* Round up to multiple of packed block length */
mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);
}
/* Add a single packed payload */
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
packed_mem_type, mem_offset_dsp_words,
packed_payload_data, packed_payload_size_bytes); /* * Add three unpacked words to DSP memory right after the packed * payload words. Each unpacked word in its own payload.
*/
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
mem_offset_dsp_words + packed_payload_size_dsp_words,
&unpacked_payload_data[0], sizeof(unpacked_payload_data[0]));
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
mem_offset_dsp_words + packed_payload_size_dsp_words + 1,
&unpacked_payload_data[1], sizeof(unpacked_payload_data[1]));
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
mem_offset_dsp_words + packed_payload_size_dsp_words + 2,
&unpacked_payload_data[2], sizeof(unpacked_payload_data[2]));
/* Download the wmfw */
wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
KUNIT_EXPECT_EQ(test,
cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
0); /* * Check that the packed payload was written correctly and drop * it from the regmap cache.
*/
offset_num_regs = (mem_offset_dsp_words / dsp_words_per_packed_block) *
cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
packed_payload_size_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
/* * Check that the unpacked words were written correctly and drop * them from the regmap cache. The unpacked words are offset * within unpacked register space by the number of DSP words * that were written in the packed payload.
*/
offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(unpacked_payload_data)),
0);
KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write XM/YM data that is one word longer than a packed block multiple, * and does not start on a packed alignment. Use one unpacked word * followed by a packed payload.
*/ staticvoid wmfw_write_packed_1_unpacked_leading(struct kunit *test)
{ conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; int packed_mem_type = param->mem_type; int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type); unsignedint dsp_words_per_packed_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type); unsignedint dsp_words_per_unpacked_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type); unsignedint packed_payload_offset_dsp_words = 0; struct firmware *wmfw; unsignedint reg_addr; void *packed_payload_data, *readback;
u32 unpacked_payload_data[1]; unsignedint packed_payload_size_bytes; unsignedint offset_num_regs;
/* Tests on XM must be after the XM header */ if (unpacked_mem_type == WMFW_ADSP2_XM)
packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32); /* * Leave space for an unaligned word before the packed block and * round the packed block start to multiple of packed block length.
*/
packed_payload_offset_dsp_words += 1;
packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,
dsp_words_per_packed_block);
/* Add a single unpacked word right before the first word of packed data */
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
packed_payload_offset_dsp_words - 1,
unpacked_payload_data, sizeof(unpacked_payload_data));
/* Add payload of packed data to the DSP memory after the unpacked word. */
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
packed_mem_type,
packed_payload_offset_dsp_words,
packed_payload_data, packed_payload_size_bytes);
/* Download the wmfw */
wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
KUNIT_EXPECT_EQ(test,
cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
0); /* * Check that the packed payload was written correctly and drop * it from the regmap cache.
*/
offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *
cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
packed_payload_size_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
/* * Check that the unpacked word was written correctly and drop * it from the regmap cache.
*/
offset_num_regs = ((packed_payload_offset_dsp_words - 1) / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(unpacked_payload_data)),
0);
KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write XM/YM data that is two words longer than a packed block multiple, * and does not start on a packed alignment. Use one payload of two unpacked * words followed by a packed payload.
*/ staticvoid wmfw_write_packed_2_unpacked_leading(struct kunit *test)
{ conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; int packed_mem_type = param->mem_type; int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type); unsignedint dsp_words_per_packed_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type); unsignedint dsp_words_per_unpacked_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type); unsignedint packed_payload_offset_dsp_words = 0; struct firmware *wmfw; unsignedint reg_addr; void *packed_payload_data, *readback;
u32 unpacked_payload_data[2]; unsignedint packed_payload_size_bytes; unsignedint offset_num_regs;
/* Tests on XM must be after the XM header */ if (unpacked_mem_type == WMFW_ADSP2_XM)
packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32); /* * Leave space for two unaligned words before the packed block and * round the packed block start to multiple of packed block length.
*/
packed_payload_offset_dsp_words += 2;
packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,
dsp_words_per_packed_block);
/* * Add two unpacked words as a single payload right before the * first word of packed data
*/
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
packed_payload_offset_dsp_words - 2,
unpacked_payload_data, sizeof(unpacked_payload_data));
/* Add payload of packed data to the DSP memory after the unpacked words. */
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
packed_mem_type,
packed_payload_offset_dsp_words,
packed_payload_data, packed_payload_size_bytes);
/* Download the wmfw */
wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
KUNIT_EXPECT_EQ(test,
cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
0); /* * Check that the packed payload was written correctly and drop * it from the regmap cache.
*/
offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *
cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
packed_payload_size_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
/* * Check that the unpacked words were written correctly and drop * them from the regmap cache.
*/
offset_num_regs = ((packed_payload_offset_dsp_words - 2) / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(unpacked_payload_data)),
0);
KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write XM/YM data that is three words longer than a packed block multiple, * and does not start on a packed alignment. Use one payload of three unpacked * words followed by a packed payload.
*/ staticvoid wmfw_write_packed_3_unpacked_leading(struct kunit *test)
{ conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; int packed_mem_type = param->mem_type; int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type); unsignedint dsp_words_per_packed_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type); unsignedint dsp_words_per_unpacked_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type); unsignedint packed_payload_offset_dsp_words = 0; struct firmware *wmfw; unsignedint reg_addr; void *packed_payload_data, *readback;
u32 unpacked_payload_data[3]; unsignedint packed_payload_size_bytes; unsignedint offset_num_regs;
/* Tests on XM must be after the XM header */ if (unpacked_mem_type == WMFW_ADSP2_XM)
packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32); /* * Leave space for three unaligned words before the packed block and * round the packed block start to multiple of packed block length.
*/
packed_payload_offset_dsp_words += 3;
packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,
dsp_words_per_packed_block);
/* * Add three unpacked words as a single payload right before the * first word of packed data
*/
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
packed_payload_offset_dsp_words - 3,
unpacked_payload_data, sizeof(unpacked_payload_data));
/* Add payload of packed data to the DSP memory after the unpacked words. */
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
packed_mem_type,
packed_payload_offset_dsp_words,
packed_payload_data, packed_payload_size_bytes);
/* Download the wmfw */
wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
KUNIT_EXPECT_EQ(test,
cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
0); /* * Check that the packed payload was written correctly and drop * it from the regmap cache.
*/
offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *
cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
packed_payload_size_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
/* * Check that the unpacked words were written correctly and drop * them from the regmap cache.
*/
offset_num_regs = ((packed_payload_offset_dsp_words - 3) / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(unpacked_payload_data)),
0);
KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write XM/YM data that is two words longer than a packed block multiple, * and does not start on a packed alignment. Use two payloads of one unpacked * word each, followed by a packed payload.
*/ staticvoid wmfw_write_packed_2_single_unpacked_leading(struct kunit *test)
{ conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; int packed_mem_type = param->mem_type; int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type); unsignedint dsp_words_per_packed_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type); unsignedint dsp_words_per_unpacked_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type); unsignedint packed_payload_offset_dsp_words = 0; struct firmware *wmfw; unsignedint reg_addr; void *packed_payload_data, *readback;
u32 unpacked_payload_data[2]; unsignedint packed_payload_size_bytes; unsignedint offset_num_regs;
/* Tests on XM must be after the XM header */ if (unpacked_mem_type == WMFW_ADSP2_XM)
packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32); /* * Leave space for two unaligned words before the packed block and * round the packed block start to multiple of packed block length.
*/
packed_payload_offset_dsp_words += 2;
packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,
dsp_words_per_packed_block);
/* * Add two unpacked words as two payloads each containing a single * unpacked word.
*/
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
packed_payload_offset_dsp_words - 2,
&unpacked_payload_data[0], sizeof(unpacked_payload_data[0]));
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
unpacked_mem_type,
packed_payload_offset_dsp_words - 1,
&unpacked_payload_data[1], sizeof(unpacked_payload_data[1]));
/* Add payload of packed data to the DSP memory after the unpacked words. */
cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,
packed_mem_type,
packed_payload_offset_dsp_words,
packed_payload_data, packed_payload_size_bytes);
/* Download the wmfw */
wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);
KUNIT_EXPECT_EQ(test,
cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),
0); /* * Check that the packed payload was written correctly and drop * it from the regmap cache.
*/
offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *
cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback,
packed_payload_size_bytes),
0);
KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);
/* * Check that the unpacked words were written correctly and drop * them from the regmap cache.
*/
offset_num_regs = ((packed_payload_offset_dsp_words - 2) / dsp_words_per_unpacked_block) *
cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);
reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);
reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);
KUNIT_EXPECT_EQ(test,
regmap_raw_read(priv->dsp->regmap, reg_addr, readback, sizeof(unpacked_payload_data)),
0);
KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));
/* Drop expected writes and the cache should then be clean */
cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);
KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));
}
/* * Write XM/YM data that is three words longer than a packed block multiple, * and does not start on a packed alignment. Use three payloads of one unpacked * word each, followed by a packed payload.
*/ staticvoid wmfw_write_packed_3_single_unpacked_leading(struct kunit *test)
{ conststruct cs_dsp_wmfw_test_param *param = test->param_value; struct cs_dsp_test *priv = test->priv; struct cs_dsp_test_local *local = priv->local; int packed_mem_type = param->mem_type; int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type); unsignedint dsp_words_per_packed_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type); unsignedint dsp_words_per_unpacked_block =
cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type); unsignedint packed_payload_offset_dsp_words = 0; struct firmware *wmfw; unsignedint reg_addr; void *packed_payload_data, *readback;
u32 unpacked_payload_data[3]; unsignedint packed_payload_size_bytes; unsignedint offset_num_regs;
/* Tests on XM must be after the XM header */ if (unpacked_mem_type == WMFW_ADSP2_XM)
packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32); /* * Leave space for two unaligned words before the packed block and
--> --------------------
--> maximum size reached
--> --------------------
Messung V0.5
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet)
¤
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.