Path: blob/master/drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c
26444 views
// SPDX-License-Identifier: GPL-2.0-only1//2// KUnit tests for cs_dsp.3//4// Copyright (C) 2024 Cirrus Logic, Inc. and5// Cirrus Logic International Semiconductor Ltd.6//78#include <kunit/device.h>9#include <kunit/resource.h>10#include <kunit/test.h>11#include <linux/build_bug.h>12#include <linux/firmware/cirrus/cs_dsp.h>13#include <linux/firmware/cirrus/cs_dsp_test_utils.h>14#include <linux/firmware/cirrus/wmfw.h>15#include <linux/random.h>16#include <linux/regmap.h>17#include <linux/string.h>18#include <linux/vmalloc.h>1920/*21* Test method is:22*23* 1) Create a mock regmap in cache-only mode so that all writes will be cached.24* 2) Create dummy wmfw file.25* 3) Call cs_dsp_power_up() with the bin file.26* 4) Readback the cached value of registers that should have been written and27* check they have the correct value.28* 5) All the registers that are expected to have been written are dropped from29* the cache. This should leave the cache clean.30* 6) If the cache is still dirty there have been unexpected writes.31*/3233KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *)34KUNIT_DEFINE_ACTION_WRAPPER(_vfree_wrapper, vfree, void *)35KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *)3637struct cs_dsp_test_local {38struct cs_dsp_mock_xm_header *xm_header;39struct cs_dsp_mock_wmfw_builder *wmfw_builder;40int wmfw_version;41};4243struct cs_dsp_wmfw_test_param {44unsigned int num_blocks;45int mem_type;46};4748static const struct cs_dsp_mock_alg_def cs_dsp_wmfw_test_mock_algs[] = {49{50.id = 0xfafa,51.ver = 0x100000,52.xm_size_words = 164,53.ym_size_words = 164,54.zm_size_words = 164,55},56};5758/*59* wmfw that writes the XM header.60* cs_dsp always reads this back from unpacked XM.61*/62static void wmfw_write_xm_header_unpacked(struct kunit *test)63{64struct cs_dsp_test *priv = test->priv;65struct cs_dsp_test_local *local = priv->local;66struct firmware *wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);67unsigned int reg_addr;68u8 *readback;6970/* XM header payload was added to wmfw by test case init function */7172KUNIT_EXPECT_EQ(test,73cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),740);7576/* Read raw so endianness and register width don't matter */77readback = kunit_kzalloc(test, local->xm_header->blob_size_bytes, GFP_KERNEL);78KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);7980reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_XM);81KUNIT_EXPECT_EQ(test,82regmap_raw_read(priv->dsp->regmap, reg_addr, readback,83local->xm_header->blob_size_bytes),840);85KUNIT_EXPECT_MEMEQ(test, readback, local->xm_header->blob_data,86local->xm_header->blob_size_bytes);8788/* Drop expected writes and the cache should then be clean */89cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);90KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));91}9293/* Write one payload of length param->num_blocks */94static void wmfw_write_one_payload(struct kunit *test)95{96const struct cs_dsp_wmfw_test_param *param = test->param_value;97struct cs_dsp_test *priv = test->priv;98struct cs_dsp_test_local *local = priv->local;99struct firmware *wmfw;100unsigned int reg_addr;101u8 *payload_data, *readback;102unsigned int mem_offset_dsp_words = 0;103unsigned int payload_size_bytes;104105payload_size_bytes = param->num_blocks *106cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);107108/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */109do {110payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);111} while (payload_size_bytes % 4);112113payload_data = kunit_kmalloc(test, payload_size_bytes, GFP_KERNEL);114KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);115get_random_bytes(payload_data, payload_size_bytes);116117readback = kunit_kzalloc(test, payload_size_bytes, GFP_KERNEL);118KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);119120/* Tests on XM must be after the XM header */121if (param->mem_type == WMFW_ADSP2_XM)122mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);123124/* Add a single payload */125cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,126param->mem_type, mem_offset_dsp_words,127payload_data, payload_size_bytes);128129wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);130131KUNIT_EXPECT_EQ(test,132cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),1330);134135reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);136reg_addr += cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv) * mem_offset_dsp_words;137KUNIT_EXPECT_EQ(test,138regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes),1390);140KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);141142/* Drop expected writes and the cache should then be clean */143cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);144cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);145KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));146}147148/* Write several smallest possible payloads for the given memory type */149static void wmfw_write_multiple_oneblock_payloads(struct kunit *test)150{151const struct cs_dsp_wmfw_test_param *param = test->param_value;152struct cs_dsp_test *priv = test->priv;153struct cs_dsp_test_local *local = priv->local;154struct firmware *wmfw;155unsigned int reg_addr;156u8 *payload_data, *readback;157unsigned int mem_offset_dsp_words = 0;158unsigned int payload_size_bytes, payload_size_dsp_words;159const unsigned int num_payloads = param->num_blocks;160int i;161162/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */163payload_size_dsp_words = 0;164payload_size_bytes = 0;165do {166payload_size_dsp_words += cs_dsp_mock_reg_block_length_dsp_words(priv,167param->mem_type);168payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);169} while (payload_size_bytes % 4);170171payload_data = kunit_kcalloc(test, num_payloads, payload_size_bytes, GFP_KERNEL);172KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);173174readback = kunit_kcalloc(test, num_payloads, payload_size_bytes, GFP_KERNEL);175KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);176177get_random_bytes(payload_data, num_payloads * payload_size_bytes);178179/* Tests on XM must be after the XM header */180if (param->mem_type == WMFW_ADSP2_XM)181mem_offset_dsp_words += local->xm_header->blob_size_bytes / payload_size_bytes;182183/* Add multiple payloads of one block each */184for (i = 0; i < num_payloads; ++i) {185cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,186param->mem_type,187mem_offset_dsp_words + (i * payload_size_dsp_words),188&payload_data[i * payload_size_bytes],189payload_size_bytes);190}191192wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);193194KUNIT_EXPECT_EQ(test,195cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),1960);197198reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);199reg_addr += cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv) * mem_offset_dsp_words;200KUNIT_EXPECT_EQ(test,201regmap_raw_read(priv->dsp->regmap, reg_addr, readback,202num_payloads * payload_size_bytes),2030);204KUNIT_EXPECT_MEMEQ(test, readback, payload_data, num_payloads * payload_size_bytes);205206/* Drop expected writes and the cache should then be clean */207cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, num_payloads * payload_size_bytes);208cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);209KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));210}211212/*213* Write several smallest possible payloads of the given memory type214* in reverse address order215*/216static void wmfw_write_multiple_oneblock_payloads_reverse(struct kunit *test)217{218const struct cs_dsp_wmfw_test_param *param = test->param_value;219struct cs_dsp_test *priv = test->priv;220struct cs_dsp_test_local *local = priv->local;221struct firmware *wmfw;222unsigned int reg_addr;223u8 *payload_data, *readback;224unsigned int mem_offset_dsp_words = 0;225unsigned int payload_size_bytes, payload_size_dsp_words;226const unsigned int num_payloads = param->num_blocks;227int i;228229/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */230payload_size_dsp_words = 0;231payload_size_bytes = 0;232do {233payload_size_dsp_words += cs_dsp_mock_reg_block_length_dsp_words(priv,234param->mem_type);235payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);236} while (payload_size_bytes % 4);237238payload_data = kunit_kcalloc(test, num_payloads, payload_size_bytes, GFP_KERNEL);239KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);240241readback = kunit_kcalloc(test, num_payloads, payload_size_bytes, GFP_KERNEL);242KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);243244get_random_bytes(payload_data, num_payloads * payload_size_bytes);245246/* Tests on XM must be after the XM header */247if (param->mem_type == WMFW_ADSP2_XM)248mem_offset_dsp_words += local->xm_header->blob_size_bytes / payload_size_bytes;249250/* Add multiple payloads of one block each */251for (i = num_payloads - 1; i >= 0; --i) {252cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,253param->mem_type,254mem_offset_dsp_words + (i * payload_size_dsp_words),255&payload_data[i * payload_size_bytes],256payload_size_bytes);257}258259wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);260261KUNIT_EXPECT_EQ(test,262cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),2630);264265reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);266reg_addr += cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv) * mem_offset_dsp_words;267KUNIT_EXPECT_EQ(test,268regmap_raw_read(priv->dsp->regmap, reg_addr, readback,269num_payloads * payload_size_bytes),2700);271KUNIT_EXPECT_MEMEQ(test, readback, payload_data, num_payloads * payload_size_bytes);272273/* Drop expected writes and the cache should then be clean */274cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, num_payloads * payload_size_bytes);275cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);276KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));277}278279/*280* Write multiple payloads of length param->num_blocks.281* The payloads are not in address order and collectively do not patch282* a contiguous block of memory.283*/284static void wmfw_write_multiple_payloads_sparse_unordered(struct kunit *test)285{286static const unsigned int random_offsets[] = {28711, 69, 59, 61, 32, 75, 4, 38, 70, 13, 79, 47, 46, 53, 18, 44,28854, 35, 51, 21, 26, 45, 27, 41, 66, 2, 17, 56, 40, 9, 8, 20,28929, 19, 63, 42, 12, 16, 43, 3, 5, 55, 52, 22290};291const struct cs_dsp_wmfw_test_param *param = test->param_value;292struct cs_dsp_test *priv = test->priv;293struct cs_dsp_test_local *local = priv->local;294struct firmware *wmfw;295unsigned int reg_addr;296u8 *payload_data, *readback;297unsigned int mem_offset_dsp_words = 0;298unsigned int payload_size_bytes, payload_size_dsp_words;299const int num_payloads = ARRAY_SIZE(random_offsets);300int i;301302payload_size_bytes = param->num_blocks *303cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);304payload_size_dsp_words = param->num_blocks *305cs_dsp_mock_reg_block_length_dsp_words(priv, param->mem_type);306307/* payloads must be a multiple of 4 bytes and a whole number of DSP registers */308do {309payload_size_dsp_words += cs_dsp_mock_reg_block_length_dsp_words(priv,310param->mem_type);311payload_size_bytes += cs_dsp_mock_reg_block_length_bytes(priv, param->mem_type);312} while (payload_size_bytes % 4);313314payload_data = kunit_kcalloc(test, num_payloads, payload_size_bytes, GFP_KERNEL);315KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);316get_random_bytes(payload_data, payload_size_bytes);317318readback = kunit_kcalloc(test, num_payloads, payload_size_bytes, GFP_KERNEL);319KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);320321/* Tests on XM must be after the XM header */322if (param->mem_type == WMFW_ADSP2_XM)323mem_offset_dsp_words += local->xm_header->blob_size_bytes / payload_size_bytes;324325/* Add multiple payloads of one block each at "random" locations */326for (i = 0; i < num_payloads; ++i) {327unsigned int offset = random_offsets[i] * payload_size_dsp_words;328329cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,330param->mem_type,331mem_offset_dsp_words + offset,332&payload_data[i * payload_size_bytes],333payload_size_bytes);334}335336wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);337338KUNIT_EXPECT_EQ(test,339cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),3400);341342for (i = 0; i < num_payloads; ++i) {343unsigned int offset_num_regs = (random_offsets[i] * payload_size_bytes) /344regmap_get_val_bytes(priv->dsp->regmap);345reg_addr = cs_dsp_mock_base_addr_for_mem(priv, param->mem_type);346reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);347reg_addr += cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv) * mem_offset_dsp_words;348KUNIT_EXPECT_EQ(test,349regmap_raw_read(priv->dsp->regmap, reg_addr,350&readback[i * payload_size_bytes],351payload_size_bytes),3520);353354cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);355}356357KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);358359/* Drop expected writes and the cache should then be clean */360cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);361KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));362}363364/* Write the whole of PM in a single unpacked payload */365static void wmfw_write_all_unpacked_pm(struct kunit *test)366{367struct cs_dsp_test *priv = test->priv;368struct cs_dsp_test_local *local = priv->local;369struct firmware *wmfw;370unsigned int reg_addr;371u8 *payload_data, *readback;372unsigned int payload_size_bytes;373374payload_size_bytes = cs_dsp_mock_size_of_region(priv->dsp, WMFW_ADSP2_PM);375payload_data = vmalloc(payload_size_bytes);376KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);377kunit_add_action_or_reset(priv->test, _vfree_wrapper, payload_data);378379readback = vmalloc(payload_size_bytes);380KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);381kunit_add_action_or_reset(priv->test, _vfree_wrapper, readback);382memset(readback, 0, payload_size_bytes);383384/* Add a single PM payload */385get_random_bytes(payload_data, payload_size_bytes);386cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,387WMFW_ADSP2_PM, 0,388payload_data, payload_size_bytes);389390wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);391392KUNIT_EXPECT_EQ(test,393cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),3940);395396reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_PM);397KUNIT_EXPECT_EQ(test,398regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes),3990);400KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);401402/* Drop expected writes and the cache should then be clean */403cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);404cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);405KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));406}407408/* Write the whole of PM in a single packed payload */409static void wmfw_write_all_packed_pm(struct kunit *test)410{411struct cs_dsp_test *priv = test->priv;412struct cs_dsp_test_local *local = priv->local;413struct firmware *wmfw;414unsigned int reg_addr;415u8 *payload_data, *readback;416unsigned int payload_size_bytes;417418payload_size_bytes = cs_dsp_mock_size_of_region(priv->dsp, WMFW_HALO_PM_PACKED);419payload_data = vmalloc(payload_size_bytes);420KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);421kunit_add_action_or_reset(priv->test, _vfree_wrapper, payload_data);422423readback = vmalloc(payload_size_bytes);424KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);425kunit_add_action_or_reset(priv->test, _vfree_wrapper, readback);426memset(readback, 0, payload_size_bytes);427428/* Add a single PM payload */429get_random_bytes(payload_data, payload_size_bytes);430cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,431WMFW_HALO_PM_PACKED, 0,432payload_data, payload_size_bytes);433434wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);435436KUNIT_EXPECT_EQ(test,437cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),4380);439440reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_HALO_PM_PACKED);441KUNIT_EXPECT_EQ(test,442regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes),4430);444KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);445446/* Drop expected writes and the cache should then be clean */447cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);448cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);449KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));450}451452/*453* Write a series of payloads to various unpacked memory regions.454* The payloads are of various lengths and offsets, driven by the455* payload_defs table. The offset and length are both given as a456* number of minimum-sized register blocks to keep the maths simpler.457* (Where a minimum-sized register block is the smallest number of458* registers that contain a whole number of DSP words.)459*/460static void wmfw_write_multiple_unpacked_mem(struct kunit *test)461{462static const struct {463int mem_type;464unsigned int offset_num_blocks;465unsigned int num_blocks;466} payload_defs[] = {467{ WMFW_ADSP2_PM, 11, 60 },468{ WMFW_ADSP2_ZM, 69, 8 },469{ WMFW_ADSP2_YM, 32, 74 },470{ WMFW_ADSP2_XM, 70, 38 },471{ WMFW_ADSP2_PM, 84, 48 },472{ WMFW_ADSP2_XM, 46, 18 },473{ WMFW_ADSP2_PM, 0, 8 },474{ WMFW_ADSP2_YM, 0, 30 },475{ WMFW_ADSP2_PM, 160, 50 },476{ WMFW_ADSP2_ZM, 21, 26 },477};478struct cs_dsp_test *priv = test->priv;479struct cs_dsp_test_local *local = priv->local;480struct firmware *wmfw;481unsigned int payload_size_bytes, offset_num_dsp_words;482unsigned int reg_addr, offset_bytes, offset_num_regs;483void **payload_data;484void *readback;485int i, ret;486487payload_data = kunit_kcalloc(test, ARRAY_SIZE(payload_defs), sizeof(*payload_data),488GFP_KERNEL);489KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);490491for (i = 0; i < ARRAY_SIZE(payload_defs); ++i) {492payload_size_bytes = payload_defs[i].num_blocks *493cs_dsp_mock_reg_block_length_bytes(priv,494payload_defs[i].mem_type);495496payload_data[i] = kunit_kmalloc(test, payload_size_bytes, GFP_KERNEL);497KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data[i]);498get_random_bytes(payload_data[i], payload_size_bytes);499500offset_num_dsp_words = payload_defs[i].offset_num_blocks *501cs_dsp_mock_reg_block_length_dsp_words(priv,502payload_defs[i].mem_type);503cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,504payload_defs[i].mem_type,505offset_num_dsp_words,506payload_data[i],507payload_size_bytes);508}509510wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);511512KUNIT_EXPECT_EQ(test,513cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),5140);515516for (i = 0; i < ARRAY_SIZE(payload_defs); ++i) {517payload_size_bytes = payload_defs[i].num_blocks *518cs_dsp_mock_reg_block_length_bytes(priv,519payload_defs[i].mem_type);520521readback = kunit_kzalloc(test, payload_size_bytes, GFP_KERNEL);522KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);523524offset_bytes = payload_defs[i].offset_num_blocks *525cs_dsp_mock_reg_block_length_bytes(priv, payload_defs[i].mem_type);526offset_num_regs = offset_bytes / regmap_get_val_bytes(priv->dsp->regmap);527reg_addr = cs_dsp_mock_base_addr_for_mem(priv, payload_defs[i].mem_type);528reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);529ret = regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes);530KUNIT_EXPECT_EQ_MSG(test, ret, 0, "%s @%u num:%u\n",531cs_dsp_mem_region_name(payload_defs[i].mem_type),532payload_defs[i].offset_num_blocks, payload_defs[i].num_blocks);533KUNIT_EXPECT_MEMEQ_MSG(test, readback, payload_data[i], payload_size_bytes,534"%s @%u num:%u\n",535cs_dsp_mem_region_name(payload_defs[i].mem_type),536payload_defs[i].offset_num_blocks,537payload_defs[i].num_blocks);538539kunit_kfree(test, readback);540541cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);542}543544/* Drop expected writes and the cache should then be clean */545cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);546KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));547}548549/*550* Write a series of payloads to various packed and unpacked memory regions.551* The payloads are of various lengths and offsets, driven by the552* payload_defs table. The offset and length are both given as a553* number of minimum-sized register blocks to keep the maths simpler.554* (Where a minimum-sized register block is the smallest number of555* registers that contain a whole number of DSP words.)556*/557static void wmfw_write_multiple_packed_unpacked_mem(struct kunit *test)558{559static const struct {560int mem_type;561unsigned int offset_num_blocks;562unsigned int num_blocks;563} payload_defs[] = {564{ WMFW_HALO_PM_PACKED, 11, 60 },565{ WMFW_ADSP2_YM, 69, 8 },566{ WMFW_HALO_YM_PACKED, 32, 74 },567{ WMFW_HALO_XM_PACKED, 70, 38 },568{ WMFW_HALO_PM_PACKED, 84, 48 },569{ WMFW_HALO_XM_PACKED, 46, 18 },570{ WMFW_HALO_PM_PACKED, 0, 8 },571{ WMFW_HALO_YM_PACKED, 0, 30 },572{ WMFW_HALO_PM_PACKED, 160, 50 },573{ WMFW_ADSP2_XM, 21, 26 },574};575struct cs_dsp_test *priv = test->priv;576struct cs_dsp_test_local *local = priv->local;577struct firmware *wmfw;578unsigned int payload_size_bytes, offset_num_dsp_words;579unsigned int reg_addr, offset_bytes, offset_num_regs;580void **payload_data;581void *readback;582int i, ret;583584payload_data = kunit_kcalloc(test, ARRAY_SIZE(payload_defs), sizeof(*payload_data),585GFP_KERNEL);586KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);587588for (i = 0; i < ARRAY_SIZE(payload_defs); ++i) {589payload_size_bytes = payload_defs[i].num_blocks *590cs_dsp_mock_reg_block_length_bytes(priv,591payload_defs[i].mem_type);592593payload_data[i] = kunit_kmalloc(test, payload_size_bytes, GFP_KERNEL);594KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data[i]);595get_random_bytes(payload_data[i], payload_size_bytes);596597offset_num_dsp_words = payload_defs[i].offset_num_blocks *598cs_dsp_mock_reg_block_length_dsp_words(priv,599payload_defs[i].mem_type);600cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,601payload_defs[i].mem_type,602offset_num_dsp_words,603payload_data[i],604payload_size_bytes);605}606607wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);608609KUNIT_EXPECT_EQ(test,610cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),6110);612613for (i = 0; i < ARRAY_SIZE(payload_defs); ++i) {614payload_size_bytes = payload_defs[i].num_blocks *615cs_dsp_mock_reg_block_length_bytes(priv,616payload_defs[i].mem_type);617618readback = kunit_kzalloc(test, payload_size_bytes, GFP_KERNEL);619KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);620621offset_bytes = payload_defs[i].offset_num_blocks *622cs_dsp_mock_reg_block_length_bytes(priv, payload_defs[i].mem_type);623offset_num_regs = offset_bytes / regmap_get_val_bytes(priv->dsp->regmap);624reg_addr = cs_dsp_mock_base_addr_for_mem(priv, payload_defs[i].mem_type);625reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);626ret = regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes);627KUNIT_EXPECT_EQ_MSG(test, ret, 0, "%s @%u num:%u\n",628cs_dsp_mem_region_name(payload_defs[i].mem_type),629payload_defs[i].offset_num_blocks,630payload_defs[i].num_blocks);631KUNIT_EXPECT_MEMEQ_MSG(test, readback, payload_data[i], payload_size_bytes,632"%s @%u num:%u\n",633cs_dsp_mem_region_name(payload_defs[i].mem_type),634payload_defs[i].offset_num_blocks,635payload_defs[i].num_blocks);636637kunit_kfree(test, readback);638639cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, payload_size_bytes);640}641642/* Drop expected writes and the cache should then be clean */643cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);644KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));645}646647/*648* Write XM/YM data that is one word longer than a packed block multiple,649* using one packed payload followed by one unpacked word.650*/651static void wmfw_write_packed_1_unpacked_trailing(struct kunit *test)652{653const struct cs_dsp_wmfw_test_param *param = test->param_value;654struct cs_dsp_test *priv = test->priv;655struct cs_dsp_test_local *local = priv->local;656int packed_mem_type = param->mem_type;657int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);658unsigned int dsp_words_per_packed_block =659cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);660unsigned int dsp_words_per_unpacked_block =661cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);662unsigned int mem_offset_dsp_words = 0;663struct firmware *wmfw;664unsigned int reg_addr;665void *packed_payload_data, *readback;666u32 unpacked_payload_data[1];667unsigned int packed_payload_size_bytes, packed_payload_size_dsp_words;668unsigned int offset_num_regs;669670packed_payload_size_bytes = param->num_blocks *671cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);672packed_payload_size_dsp_words = param->num_blocks * dsp_words_per_packed_block;673674packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);675KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);676get_random_bytes(packed_payload_data, packed_payload_size_bytes);677678get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));679680readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);681682/* Tests on XM must be after the XM header */683if (unpacked_mem_type == WMFW_ADSP2_XM) {684mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);685686/* Round up to multiple of packed block length */687mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);688}689690/* Add a single packed payload */691cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,692packed_mem_type, mem_offset_dsp_words,693packed_payload_data, packed_payload_size_bytes);694/*695* Add payload of one unpacked word to DSP memory right after696* the packed payload words.697*/698cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,699unpacked_mem_type,700mem_offset_dsp_words + packed_payload_size_dsp_words,701unpacked_payload_data, sizeof(unpacked_payload_data));702703/* Download the wmfw */704wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);705KUNIT_EXPECT_EQ(test,706cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),7070);708709/*710* Check that the packed payload was written correctly and drop711* it from the regmap cache.712*/713offset_num_regs = (mem_offset_dsp_words / dsp_words_per_packed_block) *714cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);715reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);716reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);717KUNIT_EXPECT_EQ(test,718regmap_raw_read(priv->dsp->regmap, reg_addr, readback,719packed_payload_size_bytes),7200);721KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);722723cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);724725/*726* Check that the unpacked word was written correctly and drop727* it from the regmap cache. The unpacked payload is offset within728* unpacked register space by the number of DSP words that were729* written in the packed payload.730*/731offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *732cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);733offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *734cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);735reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);736reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);737KUNIT_EXPECT_EQ(test,738regmap_raw_read(priv->dsp->regmap, reg_addr, readback,739sizeof(unpacked_payload_data)),7400);741KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));742743cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));744745/* Drop expected writes and the cache should then be clean */746cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);747KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));748}749750/*751* Write XM/YM data that is two words longer than a packed block multiple,752* using one packed payload followed by one payload of two unpacked words.753*/754static void wmfw_write_packed_2_unpacked_trailing(struct kunit *test)755{756const struct cs_dsp_wmfw_test_param *param = test->param_value;757struct cs_dsp_test *priv = test->priv;758struct cs_dsp_test_local *local = priv->local;759int packed_mem_type = param->mem_type;760int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);761unsigned int dsp_words_per_packed_block =762cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);763unsigned int dsp_words_per_unpacked_block =764cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);765unsigned int mem_offset_dsp_words = 0;766struct firmware *wmfw;767unsigned int reg_addr;768void *packed_payload_data, *readback;769u32 unpacked_payload_data[2];770unsigned int packed_payload_size_bytes, packed_payload_size_dsp_words;771unsigned int offset_num_regs;772773packed_payload_size_bytes = param->num_blocks *774cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);775packed_payload_size_dsp_words = param->num_blocks * dsp_words_per_packed_block;776777packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);778KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);779get_random_bytes(packed_payload_data, packed_payload_size_bytes);780781get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));782783readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);784785/* Tests on XM must be after the XM header */786if (unpacked_mem_type == WMFW_ADSP2_XM) {787mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);788789/* Round up to multiple of packed block length */790mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);791}792793/* Add a single packed payload */794cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,795packed_mem_type, mem_offset_dsp_words,796packed_payload_data, packed_payload_size_bytes);797/*798* Add payload of two unpacked words to DSP memory right after799* the packed payload words.800*/801cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,802unpacked_mem_type,803mem_offset_dsp_words + packed_payload_size_dsp_words,804unpacked_payload_data, sizeof(unpacked_payload_data));805806/* Download the wmfw */807wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);808KUNIT_EXPECT_EQ(test,809cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),8100);811812/*813* Check that the packed payload was written correctly and drop814* it from the regmap cache.815*/816offset_num_regs = (mem_offset_dsp_words / dsp_words_per_packed_block) *817cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);818reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);819reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);820KUNIT_EXPECT_EQ(test,821regmap_raw_read(priv->dsp->regmap, reg_addr, readback,822packed_payload_size_bytes),8230);824KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);825826cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);827828/*829* Check that the unpacked words were written correctly and drop830* them from the regmap cache. The unpacked payload is offset831* within unpacked register space by the number of DSP words832* that were written in the packed payload.833*/834offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *835cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);836offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *837cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);838reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);839reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);840KUNIT_EXPECT_EQ(test,841regmap_raw_read(priv->dsp->regmap, reg_addr, readback,842sizeof(unpacked_payload_data)),8430);844KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));845846cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));847848/* Drop expected writes and the cache should then be clean */849cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);850KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));851}852853/*854* Write XM/YM data that is three words longer than a packed block multiple,855* using one packed payload followed by one payload of three unpacked words.856*/857static void wmfw_write_packed_3_unpacked_trailing(struct kunit *test)858{859const struct cs_dsp_wmfw_test_param *param = test->param_value;860struct cs_dsp_test *priv = test->priv;861struct cs_dsp_test_local *local = priv->local;862int packed_mem_type = param->mem_type;863int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);864unsigned int dsp_words_per_packed_block =865cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);866unsigned int dsp_words_per_unpacked_block =867cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);868unsigned int mem_offset_dsp_words = 0;869struct firmware *wmfw;870unsigned int reg_addr;871void *packed_payload_data, *readback;872u32 unpacked_payload_data[3];873unsigned int packed_payload_size_bytes, packed_payload_size_dsp_words;874unsigned int offset_num_regs;875876packed_payload_size_bytes = param->num_blocks *877cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);878packed_payload_size_dsp_words = param->num_blocks * dsp_words_per_packed_block;879880packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);881KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);882get_random_bytes(packed_payload_data, packed_payload_size_bytes);883884get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));885886readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);887888/* Tests on XM must be after the XM header */889if (unpacked_mem_type == WMFW_ADSP2_XM) {890mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);891892/* Round up to multiple of packed block length */893mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);894}895896/* Add a single packed payload */897cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,898packed_mem_type, mem_offset_dsp_words,899packed_payload_data, packed_payload_size_bytes);900/*901* Add payload of three unpacked words to DSP memory right after902* the packed payload words.903*/904cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,905unpacked_mem_type,906mem_offset_dsp_words + packed_payload_size_dsp_words,907unpacked_payload_data, sizeof(unpacked_payload_data));908909/* Download the wmfw */910wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);911KUNIT_EXPECT_EQ(test,912cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),9130);914915/*916* Check that the packed payload was written correctly and drop917* it from the regmap cache.918*/919offset_num_regs = (mem_offset_dsp_words / dsp_words_per_packed_block) *920cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);921reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);922reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);923KUNIT_EXPECT_EQ(test,924regmap_raw_read(priv->dsp->regmap, reg_addr, readback,925packed_payload_size_bytes),9260);927KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);928929cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);930931/*932* Check that the unpacked words were written correctly and drop933* them from the regmap cache. The unpacked payload is offset934* within unpacked register space by the number of DSP words935* that were written in the packed payload.936*/937offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *938cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);939offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *940cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);941reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);942reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);943KUNIT_EXPECT_EQ(test,944regmap_raw_read(priv->dsp->regmap, reg_addr, readback,945sizeof(unpacked_payload_data)),9460);947KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));948949cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));950951/* Drop expected writes and the cache should then be clean */952cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);953KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));954}955956/*957* Write XM/YM data that is two words longer than a packed block multiple,958* using one packed payload followed by two payloads of one unpacked word each.959*/960static void wmfw_write_packed_2_single_unpacked_trailing(struct kunit *test)961{962const struct cs_dsp_wmfw_test_param *param = test->param_value;963struct cs_dsp_test *priv = test->priv;964struct cs_dsp_test_local *local = priv->local;965int packed_mem_type = param->mem_type;966int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);967unsigned int dsp_words_per_packed_block =968cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);969unsigned int dsp_words_per_unpacked_block =970cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);971unsigned int mem_offset_dsp_words = 0;972struct firmware *wmfw;973unsigned int reg_addr;974void *packed_payload_data, *readback;975u32 unpacked_payload_data[2];976unsigned int packed_payload_size_bytes, packed_payload_size_dsp_words;977unsigned int offset_num_regs;978979packed_payload_size_bytes = param->num_blocks *980cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);981packed_payload_size_dsp_words = param->num_blocks * dsp_words_per_packed_block;982983packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);984KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);985get_random_bytes(packed_payload_data, packed_payload_size_bytes);986987get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));988989readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);990991/* Tests on XM must be after the XM header */992if (unpacked_mem_type == WMFW_ADSP2_XM) {993mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);994995/* Round up to multiple of packed block length */996mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);997}998999/* Add a single packed payload */1000cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1001packed_mem_type, mem_offset_dsp_words,1002packed_payload_data, packed_payload_size_bytes);1003/*1004* Add two unpacked words to DSP memory right after the packed1005* payload words. Each unpacked word in its own payload.1006*/1007cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1008unpacked_mem_type,1009mem_offset_dsp_words + packed_payload_size_dsp_words,1010&unpacked_payload_data[0],1011sizeof(unpacked_payload_data[0]));1012cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1013unpacked_mem_type,1014mem_offset_dsp_words + packed_payload_size_dsp_words + 1,1015&unpacked_payload_data[1],1016sizeof(unpacked_payload_data[1]));10171018/* Download the wmfw */1019wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);1020KUNIT_EXPECT_EQ(test,1021cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),10220);10231024/*1025* Check that the packed payload was written correctly and drop1026* it from the regmap cache.1027*/1028offset_num_regs = (mem_offset_dsp_words / dsp_words_per_packed_block) *1029cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);1030reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);1031reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1032KUNIT_EXPECT_EQ(test,1033regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1034packed_payload_size_bytes),10350);1036KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);10371038cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);10391040/*1041* Check that the unpacked words were written correctly and drop1042* them from the regmap cache. The unpacked words are offset1043* within unpacked register space by the number of DSP words1044* that were written in the packed payload.1045*/1046offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *1047cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);1048offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *1049cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);1050reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);1051reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1052KUNIT_EXPECT_EQ(test,1053regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1054sizeof(unpacked_payload_data)),10550);1056KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));10571058cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));10591060/* Drop expected writes and the cache should then be clean */1061cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);1062KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));1063}10641065/*1066* Write XM/YM data that is three words longer than a packed block multiple,1067* using one packed payload followed by three payloads of one unpacked word each.1068*/1069static void wmfw_write_packed_3_single_unpacked_trailing(struct kunit *test)1070{1071const struct cs_dsp_wmfw_test_param *param = test->param_value;1072struct cs_dsp_test *priv = test->priv;1073struct cs_dsp_test_local *local = priv->local;1074int packed_mem_type = param->mem_type;1075int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);1076unsigned int dsp_words_per_packed_block =1077cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);1078unsigned int dsp_words_per_unpacked_block =1079cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);1080unsigned int mem_offset_dsp_words = 0;1081struct firmware *wmfw;1082unsigned int reg_addr;1083void *packed_payload_data, *readback;1084u32 unpacked_payload_data[3];1085unsigned int packed_payload_size_bytes, packed_payload_size_dsp_words;1086unsigned int offset_num_regs;10871088packed_payload_size_bytes = param->num_blocks *1089cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);1090packed_payload_size_dsp_words = param->num_blocks * dsp_words_per_packed_block;10911092packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);1093KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);1094get_random_bytes(packed_payload_data, packed_payload_size_bytes);10951096get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));10971098readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);10991100/* Tests on XM must be after the XM header */1101if (unpacked_mem_type == WMFW_ADSP2_XM) {1102mem_offset_dsp_words += local->xm_header->blob_size_bytes / sizeof(u32);11031104/* Round up to multiple of packed block length */1105mem_offset_dsp_words = roundup(mem_offset_dsp_words, dsp_words_per_packed_block);1106}11071108/* Add a single packed payload */1109cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1110packed_mem_type, mem_offset_dsp_words,1111packed_payload_data, packed_payload_size_bytes);1112/*1113* Add three unpacked words to DSP memory right after the packed1114* payload words. Each unpacked word in its own payload.1115*/1116cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1117unpacked_mem_type,1118mem_offset_dsp_words + packed_payload_size_dsp_words,1119&unpacked_payload_data[0],1120sizeof(unpacked_payload_data[0]));1121cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1122unpacked_mem_type,1123mem_offset_dsp_words + packed_payload_size_dsp_words + 1,1124&unpacked_payload_data[1],1125sizeof(unpacked_payload_data[1]));1126cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1127unpacked_mem_type,1128mem_offset_dsp_words + packed_payload_size_dsp_words + 2,1129&unpacked_payload_data[2],1130sizeof(unpacked_payload_data[2]));11311132/* Download the wmfw */1133wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);1134KUNIT_EXPECT_EQ(test,1135cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),11360);1137/*1138* Check that the packed payload was written correctly and drop1139* it from the regmap cache.1140*/1141offset_num_regs = (mem_offset_dsp_words / dsp_words_per_packed_block) *1142cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);1143reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);1144reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1145KUNIT_EXPECT_EQ(test,1146regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1147packed_payload_size_bytes),11480);1149KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);11501151cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);11521153/*1154* Check that the unpacked words were written correctly and drop1155* them from the regmap cache. The unpacked words are offset1156* within unpacked register space by the number of DSP words1157* that were written in the packed payload.1158*/1159offset_num_regs = (mem_offset_dsp_words / dsp_words_per_unpacked_block) *1160cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);1161offset_num_regs += (packed_payload_size_dsp_words / dsp_words_per_unpacked_block) *1162cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);1163reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);1164reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1165KUNIT_EXPECT_EQ(test,1166regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1167sizeof(unpacked_payload_data)),11680);1169KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));11701171cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));11721173/* Drop expected writes and the cache should then be clean */1174cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);1175KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));1176}11771178/*1179* Write XM/YM data that is one word longer than a packed block multiple,1180* and does not start on a packed alignment. Use one unpacked word1181* followed by a packed payload.1182*/1183static void wmfw_write_packed_1_unpacked_leading(struct kunit *test)1184{1185const struct cs_dsp_wmfw_test_param *param = test->param_value;1186struct cs_dsp_test *priv = test->priv;1187struct cs_dsp_test_local *local = priv->local;1188int packed_mem_type = param->mem_type;1189int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);1190unsigned int dsp_words_per_packed_block =1191cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);1192unsigned int dsp_words_per_unpacked_block =1193cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);1194unsigned int packed_payload_offset_dsp_words = 0;1195struct firmware *wmfw;1196unsigned int reg_addr;1197void *packed_payload_data, *readback;1198u32 unpacked_payload_data[1];1199unsigned int packed_payload_size_bytes;1200unsigned int offset_num_regs;12011202packed_payload_size_bytes = param->num_blocks *1203cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);12041205packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);1206KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);1207get_random_bytes(packed_payload_data, packed_payload_size_bytes);12081209get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));12101211readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);12121213/* Tests on XM must be after the XM header */1214if (unpacked_mem_type == WMFW_ADSP2_XM)1215packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes /1216sizeof(u32);1217/*1218* Leave space for an unaligned word before the packed block and1219* round the packed block start to multiple of packed block length.1220*/1221packed_payload_offset_dsp_words += 1;1222packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,1223dsp_words_per_packed_block);12241225/* Add a single unpacked word right before the first word of packed data */1226cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1227unpacked_mem_type,1228packed_payload_offset_dsp_words - 1,1229unpacked_payload_data, sizeof(unpacked_payload_data));12301231/* Add payload of packed data to the DSP memory after the unpacked word. */1232cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1233packed_mem_type,1234packed_payload_offset_dsp_words,1235packed_payload_data, packed_payload_size_bytes);12361237/* Download the wmfw */1238wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);1239KUNIT_EXPECT_EQ(test,1240cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),12410);1242/*1243* Check that the packed payload was written correctly and drop1244* it from the regmap cache.1245*/1246offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *1247cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);1248reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);1249reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1250KUNIT_EXPECT_EQ(test,1251regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1252packed_payload_size_bytes),12530);1254KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);12551256cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);12571258/*1259* Check that the unpacked word was written correctly and drop1260* it from the regmap cache.1261*/1262offset_num_regs = ((packed_payload_offset_dsp_words - 1) / dsp_words_per_unpacked_block) *1263cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);1264reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);1265reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1266KUNIT_EXPECT_EQ(test,1267regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1268sizeof(unpacked_payload_data)),12690);1270KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));12711272cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));12731274/* Drop expected writes and the cache should then be clean */1275cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);1276KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));1277}12781279/*1280* Write XM/YM data that is two words longer than a packed block multiple,1281* and does not start on a packed alignment. Use one payload of two unpacked1282* words followed by a packed payload.1283*/1284static void wmfw_write_packed_2_unpacked_leading(struct kunit *test)1285{1286const struct cs_dsp_wmfw_test_param *param = test->param_value;1287struct cs_dsp_test *priv = test->priv;1288struct cs_dsp_test_local *local = priv->local;1289int packed_mem_type = param->mem_type;1290int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);1291unsigned int dsp_words_per_packed_block =1292cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);1293unsigned int dsp_words_per_unpacked_block =1294cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);1295unsigned int packed_payload_offset_dsp_words = 0;1296struct firmware *wmfw;1297unsigned int reg_addr;1298void *packed_payload_data, *readback;1299u32 unpacked_payload_data[2];1300unsigned int packed_payload_size_bytes;1301unsigned int offset_num_regs;13021303packed_payload_size_bytes = param->num_blocks *1304cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);13051306packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);1307KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);1308get_random_bytes(packed_payload_data, packed_payload_size_bytes);13091310get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));13111312readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);13131314/* Tests on XM must be after the XM header */1315if (unpacked_mem_type == WMFW_ADSP2_XM)1316packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes /1317sizeof(u32);1318/*1319* Leave space for two unaligned words before the packed block and1320* round the packed block start to multiple of packed block length.1321*/1322packed_payload_offset_dsp_words += 2;1323packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,1324dsp_words_per_packed_block);13251326/*1327* Add two unpacked words as a single payload right before the1328* first word of packed data1329*/1330cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1331unpacked_mem_type,1332packed_payload_offset_dsp_words - 2,1333unpacked_payload_data, sizeof(unpacked_payload_data));13341335/* Add payload of packed data to the DSP memory after the unpacked words. */1336cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1337packed_mem_type,1338packed_payload_offset_dsp_words,1339packed_payload_data, packed_payload_size_bytes);13401341/* Download the wmfw */1342wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);1343KUNIT_EXPECT_EQ(test,1344cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),13450);1346/*1347* Check that the packed payload was written correctly and drop1348* it from the regmap cache.1349*/1350offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *1351cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);1352reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);1353reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1354KUNIT_EXPECT_EQ(test,1355regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1356packed_payload_size_bytes),13570);1358KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);13591360cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);13611362/*1363* Check that the unpacked words were written correctly and drop1364* them from the regmap cache.1365*/1366offset_num_regs = ((packed_payload_offset_dsp_words - 2) / dsp_words_per_unpacked_block) *1367cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);1368reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);1369reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1370KUNIT_EXPECT_EQ(test,1371regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1372sizeof(unpacked_payload_data)),13730);1374KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));13751376cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));13771378/* Drop expected writes and the cache should then be clean */1379cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);1380KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));1381}13821383/*1384* Write XM/YM data that is three words longer than a packed block multiple,1385* and does not start on a packed alignment. Use one payload of three unpacked1386* words followed by a packed payload.1387*/1388static void wmfw_write_packed_3_unpacked_leading(struct kunit *test)1389{1390const struct cs_dsp_wmfw_test_param *param = test->param_value;1391struct cs_dsp_test *priv = test->priv;1392struct cs_dsp_test_local *local = priv->local;1393int packed_mem_type = param->mem_type;1394int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);1395unsigned int dsp_words_per_packed_block =1396cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);1397unsigned int dsp_words_per_unpacked_block =1398cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);1399unsigned int packed_payload_offset_dsp_words = 0;1400struct firmware *wmfw;1401unsigned int reg_addr;1402void *packed_payload_data, *readback;1403u32 unpacked_payload_data[3];1404unsigned int packed_payload_size_bytes;1405unsigned int offset_num_regs;14061407packed_payload_size_bytes = param->num_blocks *1408cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);14091410packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);1411KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);1412get_random_bytes(packed_payload_data, packed_payload_size_bytes);14131414get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));14151416readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);14171418/* Tests on XM must be after the XM header */1419if (unpacked_mem_type == WMFW_ADSP2_XM)1420packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes /1421sizeof(u32);1422/*1423* Leave space for three unaligned words before the packed block and1424* round the packed block start to multiple of packed block length.1425*/1426packed_payload_offset_dsp_words += 3;1427packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,1428dsp_words_per_packed_block);14291430/*1431* Add three unpacked words as a single payload right before the1432* first word of packed data1433*/1434cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1435unpacked_mem_type,1436packed_payload_offset_dsp_words - 3,1437unpacked_payload_data, sizeof(unpacked_payload_data));14381439/* Add payload of packed data to the DSP memory after the unpacked words. */1440cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1441packed_mem_type,1442packed_payload_offset_dsp_words,1443packed_payload_data, packed_payload_size_bytes);14441445/* Download the wmfw */1446wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);1447KUNIT_EXPECT_EQ(test,1448cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),14490);1450/*1451* Check that the packed payload was written correctly and drop1452* it from the regmap cache.1453*/1454offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *1455cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);1456reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);1457reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1458KUNIT_EXPECT_EQ(test,1459regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1460packed_payload_size_bytes),14610);1462KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);14631464cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);14651466/*1467* Check that the unpacked words were written correctly and drop1468* them from the regmap cache.1469*/1470offset_num_regs = ((packed_payload_offset_dsp_words - 3) / dsp_words_per_unpacked_block) *1471cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);1472reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);1473reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1474KUNIT_EXPECT_EQ(test,1475regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1476sizeof(unpacked_payload_data)),14770);1478KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));14791480cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));14811482/* Drop expected writes and the cache should then be clean */1483cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);1484KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));1485}14861487/*1488* Write XM/YM data that is two words longer than a packed block multiple,1489* and does not start on a packed alignment. Use two payloads of one unpacked1490* word each, followed by a packed payload.1491*/1492static void wmfw_write_packed_2_single_unpacked_leading(struct kunit *test)1493{1494const struct cs_dsp_wmfw_test_param *param = test->param_value;1495struct cs_dsp_test *priv = test->priv;1496struct cs_dsp_test_local *local = priv->local;1497int packed_mem_type = param->mem_type;1498int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);1499unsigned int dsp_words_per_packed_block =1500cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);1501unsigned int dsp_words_per_unpacked_block =1502cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);1503unsigned int packed_payload_offset_dsp_words = 0;1504struct firmware *wmfw;1505unsigned int reg_addr;1506void *packed_payload_data, *readback;1507u32 unpacked_payload_data[2];1508unsigned int packed_payload_size_bytes;1509unsigned int offset_num_regs;15101511packed_payload_size_bytes = param->num_blocks *1512cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);15131514packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);1515KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);1516get_random_bytes(packed_payload_data, packed_payload_size_bytes);15171518get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));15191520readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);15211522/* Tests on XM must be after the XM header */1523if (unpacked_mem_type == WMFW_ADSP2_XM)1524packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes /1525sizeof(u32);1526/*1527* Leave space for two unaligned words before the packed block and1528* round the packed block start to multiple of packed block length.1529*/1530packed_payload_offset_dsp_words += 2;1531packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,1532dsp_words_per_packed_block);15331534/*1535* Add two unpacked words as two payloads each containing a single1536* unpacked word.1537*/1538cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1539unpacked_mem_type,1540packed_payload_offset_dsp_words - 2,1541&unpacked_payload_data[0],1542sizeof(unpacked_payload_data[0]));1543cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1544unpacked_mem_type,1545packed_payload_offset_dsp_words - 1,1546&unpacked_payload_data[1],1547sizeof(unpacked_payload_data[1]));15481549/* Add payload of packed data to the DSP memory after the unpacked words. */1550cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1551packed_mem_type,1552packed_payload_offset_dsp_words,1553packed_payload_data, packed_payload_size_bytes);15541555/* Download the wmfw */1556wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);1557KUNIT_EXPECT_EQ(test,1558cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),15590);1560/*1561* Check that the packed payload was written correctly and drop1562* it from the regmap cache.1563*/1564offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *1565cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);1566reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);1567reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1568KUNIT_EXPECT_EQ(test,1569regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1570packed_payload_size_bytes),15710);1572KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);15731574cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);15751576/*1577* Check that the unpacked words were written correctly and drop1578* them from the regmap cache.1579*/1580offset_num_regs = ((packed_payload_offset_dsp_words - 2) / dsp_words_per_unpacked_block) *1581cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);1582reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);1583reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1584KUNIT_EXPECT_EQ(test,1585regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1586sizeof(unpacked_payload_data)),15870);1588KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));15891590cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));15911592/* Drop expected writes and the cache should then be clean */1593cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);1594KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));1595}15961597/*1598* Write XM/YM data that is three words longer than a packed block multiple,1599* and does not start on a packed alignment. Use three payloads of one unpacked1600* word each, followed by a packed payload.1601*/1602static void wmfw_write_packed_3_single_unpacked_leading(struct kunit *test)1603{1604const struct cs_dsp_wmfw_test_param *param = test->param_value;1605struct cs_dsp_test *priv = test->priv;1606struct cs_dsp_test_local *local = priv->local;1607int packed_mem_type = param->mem_type;1608int unpacked_mem_type = cs_dsp_mock_packed_to_unpacked_mem_type(param->mem_type);1609unsigned int dsp_words_per_packed_block =1610cs_dsp_mock_reg_block_length_dsp_words(priv, packed_mem_type);1611unsigned int dsp_words_per_unpacked_block =1612cs_dsp_mock_reg_block_length_dsp_words(priv, unpacked_mem_type);1613unsigned int packed_payload_offset_dsp_words = 0;1614struct firmware *wmfw;1615unsigned int reg_addr;1616void *packed_payload_data, *readback;1617u32 unpacked_payload_data[3];1618unsigned int packed_payload_size_bytes;1619unsigned int offset_num_regs;16201621packed_payload_size_bytes = param->num_blocks *1622cs_dsp_mock_reg_block_length_bytes(priv, packed_mem_type);16231624packed_payload_data = kunit_kmalloc(test, packed_payload_size_bytes, GFP_KERNEL);1625KUNIT_ASSERT_NOT_ERR_OR_NULL(test, packed_payload_data);1626get_random_bytes(packed_payload_data, packed_payload_size_bytes);16271628get_random_bytes(unpacked_payload_data, sizeof(unpacked_payload_data));16291630readback = kunit_kzalloc(test, packed_payload_size_bytes, GFP_KERNEL);16311632/* Tests on XM must be after the XM header */1633if (unpacked_mem_type == WMFW_ADSP2_XM)1634packed_payload_offset_dsp_words += local->xm_header->blob_size_bytes /1635sizeof(u32);1636/*1637* Leave space for two unaligned words before the packed block and1638* round the packed block start to multiple of packed block length.1639*/1640packed_payload_offset_dsp_words += 3;1641packed_payload_offset_dsp_words = roundup(packed_payload_offset_dsp_words,1642dsp_words_per_packed_block);16431644/*1645* Add three unpacked words as three payloads each containing a single1646* unpacked word.1647*/1648cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1649unpacked_mem_type,1650packed_payload_offset_dsp_words - 3,1651&unpacked_payload_data[0],1652sizeof(unpacked_payload_data[0]));1653cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1654unpacked_mem_type,1655packed_payload_offset_dsp_words - 2,1656&unpacked_payload_data[1],1657sizeof(unpacked_payload_data[1]));1658cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1659unpacked_mem_type,1660packed_payload_offset_dsp_words - 1,1661&unpacked_payload_data[2],1662sizeof(unpacked_payload_data[2]));16631664/* Add payload of packed data to the DSP memory after the unpacked words. */1665cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1666packed_mem_type,1667packed_payload_offset_dsp_words,1668packed_payload_data, packed_payload_size_bytes);16691670/* Download the wmfw */1671wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);1672KUNIT_EXPECT_EQ(test,1673cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc"),16740);1675/*1676* Check that the packed payload was written correctly and drop1677* it from the regmap cache.1678*/1679offset_num_regs = (packed_payload_offset_dsp_words / dsp_words_per_packed_block) *1680cs_dsp_mock_reg_block_length_registers(priv, packed_mem_type);1681reg_addr = cs_dsp_mock_base_addr_for_mem(priv, packed_mem_type);1682reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1683KUNIT_EXPECT_EQ(test,1684regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1685packed_payload_size_bytes),16860);1687KUNIT_EXPECT_MEMEQ(test, readback, packed_payload_data, packed_payload_size_bytes);16881689cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, packed_payload_size_bytes);16901691/*1692* Check that the unpacked words were written correctly and drop1693* them from the regmap cache.1694*/1695offset_num_regs = ((packed_payload_offset_dsp_words - 3) / dsp_words_per_unpacked_block) *1696cs_dsp_mock_reg_block_length_registers(priv, unpacked_mem_type);1697reg_addr = cs_dsp_mock_base_addr_for_mem(priv, unpacked_mem_type);1698reg_addr += offset_num_regs * regmap_get_reg_stride(priv->dsp->regmap);1699KUNIT_EXPECT_EQ(test,1700regmap_raw_read(priv->dsp->regmap, reg_addr, readback,1701sizeof(unpacked_payload_data)),17020);1703KUNIT_EXPECT_MEMEQ(test, readback, unpacked_payload_data, sizeof(unpacked_payload_data));17041705cs_dsp_mock_regmap_drop_bytes(priv, reg_addr, sizeof(unpacked_payload_data));17061707/* Drop expected writes and the cache should then be clean */1708cs_dsp_mock_xm_header_drop_from_regmap_cache(priv);1709KUNIT_EXPECT_FALSE(test, cs_dsp_mock_regmap_is_dirty(priv, true));1710}17111712/* Load a wmfw containing multiple info blocks */1713static void wmfw_load_with_info(struct kunit *test)1714{1715struct cs_dsp_test *priv = test->priv;1716struct cs_dsp_test_local *local = priv->local;1717struct firmware *wmfw;1718unsigned int reg_addr;1719u8 *payload_data, *readback;1720char *infobuf;1721const unsigned int payload_size_bytes = 48;1722int ret;17231724payload_data = kunit_kmalloc(test, payload_size_bytes, GFP_KERNEL);1725KUNIT_ASSERT_NOT_ERR_OR_NULL(test, payload_data);1726get_random_bytes(payload_data, payload_size_bytes);17271728readback = kunit_kzalloc(test, payload_size_bytes, GFP_KERNEL);1729KUNIT_ASSERT_NOT_ERR_OR_NULL(test, readback);17301731/* Add a couple of info blocks at the start of the wmfw */1732cs_dsp_mock_wmfw_add_info(local->wmfw_builder, "This is a timestamp");1733cs_dsp_mock_wmfw_add_info(local->wmfw_builder, "This is some more info");17341735/* Add a single payload */1736cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1737WMFW_ADSP2_YM, 0,1738payload_data, payload_size_bytes);17391740/* Add a bigger info block then another small one*/1741infobuf = kunit_kzalloc(test, 512, GFP_KERNEL);1742KUNIT_ASSERT_NOT_ERR_OR_NULL(test, infobuf);17431744for (; strlcat(infobuf, "Waffle{Blah}\n", 512) < 512;)1745;17461747cs_dsp_mock_wmfw_add_info(local->wmfw_builder, infobuf);1748cs_dsp_mock_wmfw_add_info(local->wmfw_builder, "Another block of info");17491750/* Add another payload */1751cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1752WMFW_ADSP2_YM, 64,1753payload_data, payload_size_bytes);17541755wmfw = cs_dsp_mock_wmfw_get_firmware(priv->local->wmfw_builder);17561757ret = cs_dsp_power_up(priv->dsp, wmfw, "mock_wmfw", NULL, NULL, "misc");1758KUNIT_EXPECT_EQ_MSG(test, ret, 0, "cs_dsp_power_up failed: %d\n", ret);17591760/* Check first payload was written */1761reg_addr = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_YM);1762KUNIT_EXPECT_EQ(test,1763regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes),17640);1765KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);17661767/* Check second payload was written */1768reg_addr += cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv) * 64;1769KUNIT_EXPECT_EQ(test,1770regmap_raw_read(priv->dsp->regmap, reg_addr, readback, payload_size_bytes),17710);1772KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes);1773}17741775static int cs_dsp_wmfw_test_common_init(struct kunit *test, struct cs_dsp *dsp,1776int wmfw_version)1777{1778struct cs_dsp_test *priv;1779struct cs_dsp_test_local *local;1780struct device *test_dev;1781int ret;17821783priv = kunit_kzalloc(test, sizeof(*priv), GFP_KERNEL);1784if (!priv)1785return -ENOMEM;17861787local = kunit_kzalloc(test, sizeof(struct cs_dsp_test_local), GFP_KERNEL);1788if (!local)1789return -ENOMEM;17901791priv->test = test;1792priv->dsp = dsp;1793test->priv = priv;1794priv->local = local;1795priv->local->wmfw_version = wmfw_version;17961797/* Create dummy struct device */1798test_dev = kunit_device_register(test, "cs_dsp_test_drv");1799if (IS_ERR(test_dev))1800return PTR_ERR(test_dev);18011802dsp->dev = get_device(test_dev);1803if (!dsp->dev)1804return -ENODEV;18051806ret = kunit_add_action_or_reset(test, _put_device_wrapper, dsp->dev);1807if (ret)1808return ret;18091810dev_set_drvdata(dsp->dev, priv);18111812/* Allocate regmap */1813ret = cs_dsp_mock_regmap_init(priv);1814if (ret)1815return ret;18161817/*1818* There must always be a XM header with at least 1 algorithm, so create1819* a dummy one that tests can use and extract it to a data payload.1820*/1821local->xm_header = cs_dsp_create_mock_xm_header(priv,1822cs_dsp_wmfw_test_mock_algs,1823ARRAY_SIZE(cs_dsp_wmfw_test_mock_algs));1824KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->xm_header);18251826local->wmfw_builder = cs_dsp_mock_wmfw_init(priv, priv->local->wmfw_version);1827KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->wmfw_builder);18281829/* Add dummy XM header payload to wmfw */1830cs_dsp_mock_wmfw_add_data_block(local->wmfw_builder,1831WMFW_ADSP2_XM, 0,1832local->xm_header->blob_data,1833local->xm_header->blob_size_bytes);18341835/* Init cs_dsp */1836dsp->client_ops = kunit_kzalloc(test, sizeof(*dsp->client_ops), GFP_KERNEL);1837KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dsp->client_ops);18381839switch (dsp->type) {1840case WMFW_ADSP2:1841ret = cs_dsp_adsp2_init(dsp);1842break;1843case WMFW_HALO:1844ret = cs_dsp_halo_init(dsp);1845break;1846default:1847KUNIT_FAIL(test, "Untested DSP type %d\n", dsp->type);1848return -EINVAL;1849}18501851if (ret)1852return ret;18531854/* Automatically call cs_dsp_remove() when test case ends */1855return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp);1856}18571858static int cs_dsp_wmfw_test_halo_init(struct kunit *test)1859{1860struct cs_dsp *dsp;18611862/* Fill in cs_dsp and initialize */1863dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);1864if (!dsp)1865return -ENOMEM;18661867dsp->num = 1;1868dsp->type = WMFW_HALO;1869dsp->mem = cs_dsp_mock_halo_dsp1_regions;1870dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_halo_dsp1_region_sizes);1871dsp->base = cs_dsp_mock_halo_core_base;1872dsp->base_sysinfo = cs_dsp_mock_halo_sysinfo_base;18731874return cs_dsp_wmfw_test_common_init(test, dsp, 3);1875}18761877static int cs_dsp_wmfw_test_adsp2_32bit_init(struct kunit *test, int wmfw_ver)1878{1879struct cs_dsp *dsp;18801881/* Fill in cs_dsp and initialize */1882dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);1883if (!dsp)1884return -ENOMEM;18851886dsp->num = 1;1887dsp->type = WMFW_ADSP2;1888dsp->rev = 1;1889dsp->mem = cs_dsp_mock_adsp2_32bit_dsp1_regions;1890dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_32bit_dsp1_region_sizes);1891dsp->base = cs_dsp_mock_adsp2_32bit_sysbase;18921893return cs_dsp_wmfw_test_common_init(test, dsp, wmfw_ver);1894}18951896static int cs_dsp_wmfw_test_adsp2_32bit_wmfw0_init(struct kunit *test)1897{1898return cs_dsp_wmfw_test_adsp2_32bit_init(test, 0);1899}19001901static int cs_dsp_wmfw_test_adsp2_32bit_wmfw1_init(struct kunit *test)1902{1903return cs_dsp_wmfw_test_adsp2_32bit_init(test, 1);1904}19051906static int cs_dsp_wmfw_test_adsp2_32bit_wmfw2_init(struct kunit *test)1907{1908return cs_dsp_wmfw_test_adsp2_32bit_init(test, 2);1909}19101911static int cs_dsp_wmfw_test_adsp2_16bit_init(struct kunit *test, int wmfw_ver)1912{1913struct cs_dsp *dsp;19141915/* Fill in cs_dsp and initialize */1916dsp = kunit_kzalloc(test, sizeof(*dsp), GFP_KERNEL);1917if (!dsp)1918return -ENOMEM;19191920dsp->num = 1;1921dsp->type = WMFW_ADSP2;1922dsp->rev = 0;1923dsp->mem = cs_dsp_mock_adsp2_16bit_dsp1_regions;1924dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_16bit_dsp1_region_sizes);1925dsp->base = cs_dsp_mock_adsp2_16bit_sysbase;19261927return cs_dsp_wmfw_test_common_init(test, dsp, wmfw_ver);1928}19291930static int cs_dsp_wmfw_test_adsp2_16bit_wmfw0_init(struct kunit *test)1931{1932return cs_dsp_wmfw_test_adsp2_16bit_init(test, 0);1933}19341935static int cs_dsp_wmfw_test_adsp2_16bit_wmfw1_init(struct kunit *test)1936{1937return cs_dsp_wmfw_test_adsp2_16bit_init(test, 1);1938}19391940static int cs_dsp_wmfw_test_adsp2_16bit_wmfw2_init(struct kunit *test)1941{1942return cs_dsp_wmfw_test_adsp2_16bit_init(test, 2);1943}19441945static void cs_dsp_mem_param_desc(const struct cs_dsp_wmfw_test_param *param, char *desc)1946{1947snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s num_blocks:%u",1948cs_dsp_mem_region_name(param->mem_type),1949param->num_blocks);1950}19511952static const struct cs_dsp_wmfw_test_param adsp2_all_num_blocks_param_cases[] = {1953{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 1 },1954{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 2 },1955{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 3 },1956{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 4 },1957{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 5 },1958{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 6 },1959{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 12 },1960{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 13 },1961{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 14 },1962{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 15 },1963{ .mem_type = WMFW_ADSP2_PM, .num_blocks = 16 },19641965{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 1 },1966{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 2 },1967{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 3 },1968{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 4 },1969{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 5 },1970{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 6 },1971{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 12 },1972{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 13 },1973{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 14 },1974{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 15 },1975{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 16 },19761977{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 1 },1978{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 2 },1979{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 3 },1980{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 4 },1981{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 5 },1982{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 6 },1983{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 12 },1984{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 13 },1985{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 14 },1986{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 15 },1987{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 16 },19881989{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 1 },1990{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 2 },1991{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 3 },1992{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 4 },1993{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 5 },1994{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 6 },1995{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 12 },1996{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 13 },1997{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 14 },1998{ .mem_type = WMFW_ADSP2_ZM, .num_blocks = 15 },1999{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 16 },2000};20012002KUNIT_ARRAY_PARAM(adsp2_all_num_blocks,2003adsp2_all_num_blocks_param_cases,2004cs_dsp_mem_param_desc);20052006static const struct cs_dsp_wmfw_test_param halo_all_num_blocks_param_cases[] = {2007{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 1 },2008{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 2 },2009{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 3 },2010{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 4 },2011{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 5 },2012{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 6 },2013{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 12 },2014{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 13 },2015{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 14 },2016{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 15 },2017{ .mem_type = WMFW_HALO_PM_PACKED, .num_blocks = 16 },20182019{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 1 },2020{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 2 },2021{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 3 },2022{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 4 },2023{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 5 },2024{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 6 },2025{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 12 },2026{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 13 },2027{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 14 },2028{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 15 },2029{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 16 },20302031{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 1 },2032{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 2 },2033{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 3 },2034{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 4 },2035{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 5 },2036{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 6 },2037{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 12 },2038{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 13 },2039{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 14 },2040{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 15 },2041{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 16 },20422043{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 1 },2044{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 2 },2045{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 3 },2046{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 4 },2047{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 5 },2048{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 6 },2049{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 12 },2050{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 13 },2051{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 14 },2052{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 15 },2053{ .mem_type = WMFW_ADSP2_XM, .num_blocks = 16 },20542055{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 1 },2056{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 2 },2057{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 3 },2058{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 4 },2059{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 5 },2060{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 6 },2061{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 12 },2062{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 13 },2063{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 14 },2064{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 15 },2065{ .mem_type = WMFW_ADSP2_YM, .num_blocks = 16 },2066};20672068KUNIT_ARRAY_PARAM(halo_all_num_blocks,2069halo_all_num_blocks_param_cases,2070cs_dsp_mem_param_desc);20712072static const struct cs_dsp_wmfw_test_param packed_xy_num_blocks_param_cases[] = {2073{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 1 },2074{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 2 },2075{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 3 },2076{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 4 },2077{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 5 },2078{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 6 },2079{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 12 },2080{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 13 },2081{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 14 },2082{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 15 },2083{ .mem_type = WMFW_HALO_XM_PACKED, .num_blocks = 16 },20842085{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 1 },2086{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 2 },2087{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 3 },2088{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 4 },2089{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 5 },2090{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 6 },2091{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 12 },2092{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 13 },2093{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 14 },2094{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 15 },2095{ .mem_type = WMFW_HALO_YM_PACKED, .num_blocks = 16 },2096};20972098KUNIT_ARRAY_PARAM(packed_xy_num_blocks,2099packed_xy_num_blocks_param_cases,2100cs_dsp_mem_param_desc);21012102static struct kunit_case cs_dsp_wmfw_test_cases_halo[] = {2103KUNIT_CASE(wmfw_write_xm_header_unpacked),21042105KUNIT_CASE_PARAM(wmfw_write_one_payload,2106halo_all_num_blocks_gen_params),2107KUNIT_CASE_PARAM(wmfw_write_multiple_oneblock_payloads,2108halo_all_num_blocks_gen_params),2109KUNIT_CASE_PARAM(wmfw_write_multiple_oneblock_payloads_reverse,2110halo_all_num_blocks_gen_params),2111KUNIT_CASE_PARAM(wmfw_write_multiple_payloads_sparse_unordered,2112halo_all_num_blocks_gen_params),21132114KUNIT_CASE(wmfw_write_all_packed_pm),2115KUNIT_CASE(wmfw_write_multiple_packed_unpacked_mem),21162117KUNIT_CASE_PARAM(wmfw_write_packed_1_unpacked_trailing,2118packed_xy_num_blocks_gen_params),2119KUNIT_CASE_PARAM(wmfw_write_packed_2_unpacked_trailing,2120packed_xy_num_blocks_gen_params),2121KUNIT_CASE_PARAM(wmfw_write_packed_3_unpacked_trailing,2122packed_xy_num_blocks_gen_params),2123KUNIT_CASE_PARAM(wmfw_write_packed_2_single_unpacked_trailing,2124packed_xy_num_blocks_gen_params),2125KUNIT_CASE_PARAM(wmfw_write_packed_3_single_unpacked_trailing,2126packed_xy_num_blocks_gen_params),2127KUNIT_CASE_PARAM(wmfw_write_packed_1_unpacked_leading,2128packed_xy_num_blocks_gen_params),2129KUNIT_CASE_PARAM(wmfw_write_packed_2_unpacked_leading,2130packed_xy_num_blocks_gen_params),2131KUNIT_CASE_PARAM(wmfw_write_packed_3_unpacked_leading,2132packed_xy_num_blocks_gen_params),2133KUNIT_CASE_PARAM(wmfw_write_packed_2_single_unpacked_leading,2134packed_xy_num_blocks_gen_params),2135KUNIT_CASE_PARAM(wmfw_write_packed_3_single_unpacked_leading,2136packed_xy_num_blocks_gen_params),21372138KUNIT_CASE(wmfw_load_with_info),21392140{ } /* terminator */2141};21422143static struct kunit_case cs_dsp_wmfw_test_cases_adsp2[] = {2144KUNIT_CASE(wmfw_write_xm_header_unpacked),2145KUNIT_CASE_PARAM(wmfw_write_one_payload,2146adsp2_all_num_blocks_gen_params),2147KUNIT_CASE_PARAM(wmfw_write_multiple_oneblock_payloads,2148adsp2_all_num_blocks_gen_params),2149KUNIT_CASE_PARAM(wmfw_write_multiple_oneblock_payloads_reverse,2150adsp2_all_num_blocks_gen_params),2151KUNIT_CASE_PARAM(wmfw_write_multiple_payloads_sparse_unordered,2152adsp2_all_num_blocks_gen_params),21532154KUNIT_CASE(wmfw_write_all_unpacked_pm),2155KUNIT_CASE(wmfw_write_multiple_unpacked_mem),21562157KUNIT_CASE(wmfw_load_with_info),21582159{ } /* terminator */2160};21612162static struct kunit_suite cs_dsp_wmfw_test_halo = {2163.name = "cs_dsp_wmfwV3_halo",2164.init = cs_dsp_wmfw_test_halo_init,2165.test_cases = cs_dsp_wmfw_test_cases_halo,2166};21672168static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw0 = {2169.name = "cs_dsp_wmfwV0_adsp2_32bit",2170.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw0_init,2171.test_cases = cs_dsp_wmfw_test_cases_adsp2,2172};21732174static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw1 = {2175.name = "cs_dsp_wmfwV1_adsp2_32bit",2176.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw1_init,2177.test_cases = cs_dsp_wmfw_test_cases_adsp2,2178};21792180static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw2 = {2181.name = "cs_dsp_wmfwV2_adsp2_32bit",2182.init = cs_dsp_wmfw_test_adsp2_32bit_wmfw2_init,2183.test_cases = cs_dsp_wmfw_test_cases_adsp2,2184};21852186static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw0 = {2187.name = "cs_dsp_wmfwV0_adsp2_16bit",2188.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw0_init,2189.test_cases = cs_dsp_wmfw_test_cases_adsp2,2190};21912192static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw1 = {2193.name = "cs_dsp_wmfwV1_adsp2_16bit",2194.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw1_init,2195.test_cases = cs_dsp_wmfw_test_cases_adsp2,2196};21972198static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw2 = {2199.name = "cs_dsp_wmfwV2_adsp2_16bit",2200.init = cs_dsp_wmfw_test_adsp2_16bit_wmfw2_init,2201.test_cases = cs_dsp_wmfw_test_cases_adsp2,2202};22032204kunit_test_suites(&cs_dsp_wmfw_test_halo,2205&cs_dsp_wmfw_test_adsp2_32bit_wmfw0,2206&cs_dsp_wmfw_test_adsp2_32bit_wmfw1,2207&cs_dsp_wmfw_test_adsp2_32bit_wmfw2,2208&cs_dsp_wmfw_test_adsp2_16bit_wmfw0,2209&cs_dsp_wmfw_test_adsp2_16bit_wmfw1,2210&cs_dsp_wmfw_test_adsp2_16bit_wmfw2);221122122213