diff options
Diffstat (limited to 'drivers/firmware/cirrus')
| -rw-r--r-- | drivers/firmware/cirrus/Kconfig | 5 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/cs_dsp.c | 360 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/cs_dsp.h | 16 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_mock_bin.c | 44 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_mock_mem_maps.c | 53 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_mock_regmap.c | 16 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_mock_wmfw.c | 7 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_test_bin.c | 1064 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c | 63 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c | 1 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_test_control_cache.c | 6 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_test_control_parse.c | 56 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_test_control_rw.c | 5 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c | 32 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c | 42 | ||||
| -rw-r--r-- | drivers/firmware/cirrus/test/cs_dsp_tests.c | 1 |
16 files changed, 1128 insertions, 643 deletions
diff --git a/drivers/firmware/cirrus/Kconfig b/drivers/firmware/cirrus/Kconfig index 0a883091259a..e3c2e38b746d 100644 --- a/drivers/firmware/cirrus/Kconfig +++ b/drivers/firmware/cirrus/Kconfig @@ -6,14 +6,11 @@ config FW_CS_DSP config FW_CS_DSP_KUNIT_TEST_UTILS tristate - depends on KUNIT && REGMAP - select FW_CS_DSP config FW_CS_DSP_KUNIT_TEST tristate "KUnit tests for Cirrus Logic cs_dsp" if !KUNIT_ALL_TESTS - depends on KUNIT && REGMAP + depends on KUNIT && REGMAP && FW_CS_DSP default KUNIT_ALL_TESTS - select FW_CS_DSP select FW_CS_DSP_KUNIT_TEST_UTILS help This builds KUnit tests for cs_dsp. diff --git a/drivers/firmware/cirrus/cs_dsp.c b/drivers/firmware/cirrus/cs_dsp.c index 42433c19eb30..bb93b24c659d 100644 --- a/drivers/firmware/cirrus/cs_dsp.c +++ b/drivers/firmware/cirrus/cs_dsp.c @@ -9,12 +9,17 @@ * Cirrus Logic International Semiconductor Ltd. */ +#include <kunit/static_stub.h> +#include <kunit/visibility.h> +#include <linux/cleanup.h> #include <linux/ctype.h> #include <linux/debugfs.h> #include <linux/delay.h> +#include <linux/math.h> #include <linux/minmax.h> #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/ratelimit.h> #include <linux/seq_file.h> #include <linux/slab.h> #include <linux/vmalloc.h> @@ -22,14 +27,52 @@ #include <linux/firmware/cirrus/cs_dsp.h> #include <linux/firmware/cirrus/wmfw.h> -#define cs_dsp_err(_dsp, fmt, ...) \ - dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) -#define cs_dsp_warn(_dsp, fmt, ...) \ - dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) -#define cs_dsp_info(_dsp, fmt, ...) \ - dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) -#define cs_dsp_dbg(_dsp, fmt, ...) \ - dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__) +#include "cs_dsp.h" + +/* + * When the KUnit test is running the error-case tests will cause a lot + * of messages. Rate-limit to prevent overflowing the kernel log buffer + * during KUnit test runs and allow the test to redirect this function. + * In normal (not KUnit) builds this collapses to only return true. + */ +VISIBLE_IF_KUNIT bool cs_dsp_can_emit_message(void) +{ + KUNIT_STATIC_STUB_REDIRECT(cs_dsp_can_emit_message); + + if (IS_ENABLED(CONFIG_FW_CS_DSP_KUNIT_TEST)) { + static DEFINE_RATELIMIT_STATE(_rs, + DEFAULT_RATELIMIT_INTERVAL, + DEFAULT_RATELIMIT_BURST); + return __ratelimit(&_rs); + } + + return true; +} +EXPORT_SYMBOL_IF_KUNIT(cs_dsp_can_emit_message); + +#define cs_dsp_err(_dsp, fmt, ...) \ + do { \ + if (cs_dsp_can_emit_message()) \ + dev_err(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \ + } while (false) + +#define cs_dsp_warn(_dsp, fmt, ...) \ + do { \ + if (cs_dsp_can_emit_message()) \ + dev_warn(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \ + } while (false) + +#define cs_dsp_info(_dsp, fmt, ...) \ + do { \ + if (cs_dsp_can_emit_message()) \ + dev_info(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \ + } while (false) + +#define cs_dsp_dbg(_dsp, fmt, ...) \ + do { \ + if (cs_dsp_can_emit_message()) \ + dev_dbg(_dsp->dev, "%s: " fmt, _dsp->name, ##__VA_ARGS__); \ + } while (false) #define ADSP1_CONTROL_1 0x00 #define ADSP1_CONTROL_2 0x02 @@ -311,44 +354,11 @@ static const struct cs_dsp_ops cs_dsp_adsp2_ops[]; static const struct cs_dsp_ops cs_dsp_halo_ops; static const struct cs_dsp_ops cs_dsp_halo_ao_ops; -struct cs_dsp_buf { +struct cs_dsp_alg_region_list_item { struct list_head list; - void *buf; + struct cs_dsp_alg_region alg_region; }; -static struct cs_dsp_buf *cs_dsp_buf_alloc(const void *src, size_t len, - struct list_head *list) -{ - struct cs_dsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); - - if (buf == NULL) - return NULL; - - buf->buf = vmalloc(len); - if (!buf->buf) { - kfree(buf); - return NULL; - } - memcpy(buf->buf, src, len); - - if (list) - list_add_tail(&buf->list, list); - - return buf; -} - -static void cs_dsp_buf_free(struct list_head *list) -{ - while (!list_empty(list)) { - struct cs_dsp_buf *buf = list_first_entry(list, - struct cs_dsp_buf, - list); - list_del(&buf->list); - vfree(buf->buf); - kfree(buf); - } -} - /** * cs_dsp_mem_region_name() - Return a name string for a memory type * @type: the memory type to match @@ -383,18 +393,14 @@ EXPORT_SYMBOL_NS_GPL(cs_dsp_mem_region_name, "FW_CS_DSP"); #ifdef CONFIG_DEBUG_FS static void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) { - char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); - kfree(dsp->wmfw_file_name); - dsp->wmfw_file_name = tmp; + dsp->wmfw_file_name = kstrdup(s, GFP_KERNEL); } static void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, const char *s) { - char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); - kfree(dsp->bin_file_name); - dsp->bin_file_name = tmp; + dsp->bin_file_name = kstrdup(s, GFP_KERNEL); } static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) @@ -405,24 +411,38 @@ static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) dsp->bin_file_name = NULL; } +static ssize_t cs_dsp_debugfs_string_read(struct cs_dsp *dsp, + char __user *user_buf, + size_t count, loff_t *ppos, + const char **pstr) +{ + const char *str; + ssize_t ret = 0; + + scoped_guard(mutex, &dsp->pwr_lock) { + if (*pstr) { + str = kasprintf(GFP_KERNEL, "%s\n", *pstr); + if (str) { + ret = simple_read_from_buffer(user_buf, count, + ppos, str, strlen(str)); + kfree(str); + } else { + ret = -ENOMEM; + } + } + } + + return ret; +} + static ssize_t cs_dsp_debugfs_wmfw_read(struct file *file, char __user *user_buf, size_t count, loff_t *ppos) { struct cs_dsp *dsp = file->private_data; - ssize_t ret; - - mutex_lock(&dsp->pwr_lock); - if (!dsp->wmfw_file_name || !dsp->booted) - ret = 0; - else - ret = simple_read_from_buffer(user_buf, count, ppos, - dsp->wmfw_file_name, - strlen(dsp->wmfw_file_name)); - - mutex_unlock(&dsp->pwr_lock); - return ret; + return cs_dsp_debugfs_string_read(dsp, user_buf, count, ppos, + &dsp->wmfw_file_name); } static ssize_t cs_dsp_debugfs_bin_read(struct file *file, @@ -430,19 +450,9 @@ static ssize_t cs_dsp_debugfs_bin_read(struct file *file, size_t count, loff_t *ppos) { struct cs_dsp *dsp = file->private_data; - ssize_t ret; - mutex_lock(&dsp->pwr_lock); - - if (!dsp->bin_file_name || !dsp->booted) - ret = 0; - else - ret = simple_read_from_buffer(user_buf, count, ppos, - dsp->bin_file_name, - strlen(dsp->bin_file_name)); - - mutex_unlock(&dsp->pwr_lock); - return ret; + return cs_dsp_debugfs_string_read(dsp, user_buf, count, ppos, + &dsp->bin_file_name); } static const struct { @@ -474,9 +484,11 @@ static int cs_dsp_debugfs_read_controls_show(struct seq_file *s, void *ignored) struct cs_dsp_coeff_ctl *ctl; unsigned int reg; + guard(mutex)(&dsp->pwr_lock); + list_for_each_entry(ctl, &dsp->ctl_list, list) { cs_dsp_coeff_base_reg(ctl, ®, 0); - seq_printf(s, "%22.*s: %#8zx %s:%08x %#8x %s %#8x %#4x %c%c%c%c %s %s\n", + seq_printf(s, "%22.*s: %#8x %s:%08x %#8x %s %#8x %#4x %c%c%c%c %s %s\n", ctl->subname_len, ctl->subname, ctl->len, cs_dsp_mem_region_name(ctl->alg_region.type), ctl->offset, reg, ctl->fw_name, ctl->alg_region.alg, ctl->type, @@ -507,6 +519,7 @@ void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root) debugfs_create_bool("booted", 0444, root, &dsp->booted); debugfs_create_bool("running", 0444, root, &dsp->running); + debugfs_create_bool("hibernating", 0444, root, &dsp->hibernating); debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id); debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version); @@ -695,7 +708,7 @@ int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int lockdep_assert_held(&dsp->pwr_lock); - if (!dsp->running) + if (!dsp->running || dsp->hibernating) return -EPERM; ret = cs_dsp_coeff_base_reg(ctl, ®, 0); @@ -819,7 +832,7 @@ int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, } ctl->set = 1; - if (ctl->enabled && ctl->dsp->running) + if (ctl->enabled && ctl->dsp->running && !ctl->dsp->hibernating) ret = cs_dsp_coeff_write_ctrl_raw(ctl, off, buf, len); if (ret < 0) @@ -912,12 +925,12 @@ int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, return -EINVAL; if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { - if (ctl->enabled && ctl->dsp->running) + if (ctl->enabled && ctl->dsp->running && !ctl->dsp->hibernating) return cs_dsp_coeff_read_ctrl_raw(ctl, off, buf, len); else return -EPERM; } else { - if (!ctl->flags && ctl->enabled && ctl->dsp->running) + if (!ctl->flags && ctl->enabled && ctl->dsp->running && !ctl->dsp->hibernating) ret = cs_dsp_coeff_read_ctrl_raw(ctl, 0, ctl->cache, ctl->len); if (buf != ctl->cache) @@ -1023,7 +1036,7 @@ static void cs_dsp_signal_event_controls(struct cs_dsp *dsp, static void cs_dsp_free_ctl_blk(struct cs_dsp_coeff_ctl *ctl) { - kfree(ctl->cache); + kvfree(ctl->cache); kfree(ctl->subname); kfree(ctl); } @@ -1051,7 +1064,7 @@ static int cs_dsp_create_control(struct cs_dsp *dsp, } } - ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); + ctl = kzalloc_obj(*ctl); if (!ctl) return -ENOMEM; @@ -1073,7 +1086,7 @@ static int cs_dsp_create_control(struct cs_dsp *dsp, ctl->type = type; ctl->offset = offset; ctl->len = len; - ctl->cache = kzalloc(ctl->len, GFP_KERNEL); + ctl->cache = kvzalloc(ctl->len, GFP_KERNEL); if (!ctl->cache) { ret = -ENOMEM; goto err_ctl_subname; @@ -1091,7 +1104,7 @@ static int cs_dsp_create_control(struct cs_dsp *dsp, err_list_del: list_del(&ctl->list); - kfree(ctl->cache); + kvfree(ctl->cache); err_ctl_subname: kfree(ctl->subname); err_ctl: @@ -1100,6 +1113,44 @@ err_ctl: return ret; } + +/** + * cs_dsp_hibernate() - Disable or enable all controls for a DSP + * @dsp: pointer to DSP structure + * @hibernate: whether to set controls to cache only mode + * + * When @hibernate is true, the DSP is entering hibernation mode where the + * regmap is inaccessible, and all controls become cache only. + * When @hibernate is false, the DSP has exited hibernation mode. If the DSP + * is running, all controls are re-synced to the DSP. + * + */ +void cs_dsp_hibernate(struct cs_dsp *dsp, bool hibernate) +{ + mutex_lock(&dsp->pwr_lock); + + if (!dsp->running) { + cs_dsp_dbg(dsp, "Cannot hibernate, DSP not running\n"); + goto out; + } + + if (dsp->hibernating == hibernate) + goto out; + + cs_dsp_dbg(dsp, "Set hibernating to %d\n", hibernate); + dsp->hibernating = hibernate; + + if (!dsp->hibernating && dsp->running) { + int ret = cs_dsp_coeff_sync_controls(dsp); + + if (ret) + cs_dsp_err(dsp, "Error syncing controls: %d\n", ret); + } +out: + mutex_unlock(&dsp->pwr_lock); +} +EXPORT_SYMBOL_NS_GPL(cs_dsp_hibernate, "FW_CS_DSP"); + struct cs_dsp_coeff_parsed_alg { int id; const u8 *name; @@ -1480,7 +1531,9 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, const struct wmfw_region *region; const struct cs_dsp_region *mem; const char *region_name; - struct cs_dsp_buf *buf; + u8 *buf = NULL; + size_t buf_len = 0; + size_t region_len; unsigned int reg; int regions = 0; int ret, offset, type; @@ -1600,23 +1653,29 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, region_name); if (reg) { - buf = cs_dsp_buf_alloc(region->data, - le32_to_cpu(region->len), - &buf_list); - if (!buf) { - cs_dsp_err(dsp, "Out of memory\n"); - ret = -ENOMEM; - goto out_fw; + /* + * Although we expect the underlying bus does not require + * physically-contiguous buffers, we pessimistically use + * a temporary buffer instead of trusting that the + * alignment of region->data is ok. + */ + region_len = le32_to_cpu(region->len); + if (region_len > buf_len) { + buf_len = round_up(region_len, PAGE_SIZE); + vfree(buf); + buf = vmalloc(buf_len); + if (!buf) { + ret = -ENOMEM; + goto out_fw; + } } - ret = regmap_raw_write(regmap, reg, buf->buf, - le32_to_cpu(region->len)); + memcpy(buf, region->data, region_len); + ret = regmap_raw_write(regmap, reg, buf, region_len); if (ret != 0) { cs_dsp_err(dsp, - "%s.%d: Failed to write %d bytes at %d in %s: %d\n", - file, regions, - le32_to_cpu(region->len), offset, - region_name, ret); + "%s.%d: Failed to write %zu bytes at %d in %s: %d\n", + file, regions, region_len, offset, region_name, ret); goto out_fw; } } @@ -1631,8 +1690,9 @@ static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, cs_dsp_debugfs_save_wmfwname(dsp, file); + ret = 0; out_fw: - cs_dsp_buf_free(&buf_list); + vfree(buf); if (ret == -EOVERFLOW) cs_dsp_err(dsp, "%s: file content overflows file data\n", file); @@ -1751,13 +1811,13 @@ static void *cs_dsp_read_algs(struct cs_dsp *dsp, size_t n_algs, struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, int type, unsigned int id) { - struct cs_dsp_alg_region *alg_region; + struct cs_dsp_alg_region_list_item *item; lockdep_assert_held(&dsp->pwr_lock); - list_for_each_entry(alg_region, &dsp->alg_regions, list) { - if (id == alg_region->alg && type == alg_region->type) - return alg_region; + list_for_each_entry(item, &dsp->alg_regions, list) { + if (id == item->alg_region.alg && type == item->alg_region.type) + return &item->alg_region; } return NULL; @@ -1768,35 +1828,35 @@ static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, int type, __be32 id, __be32 ver, __be32 base) { - struct cs_dsp_alg_region *alg_region; + struct cs_dsp_alg_region_list_item *item; - alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL); - if (!alg_region) + item = kzalloc_obj(*item); + if (!item) return ERR_PTR(-ENOMEM); - alg_region->type = type; - alg_region->alg = be32_to_cpu(id); - alg_region->ver = be32_to_cpu(ver); - alg_region->base = be32_to_cpu(base); + item->alg_region.type = type; + item->alg_region.alg = be32_to_cpu(id); + item->alg_region.ver = be32_to_cpu(ver); + item->alg_region.base = be32_to_cpu(base); - list_add_tail(&alg_region->list, &dsp->alg_regions); + list_add_tail(&item->list, &dsp->alg_regions); if (dsp->wmfw_ver > 0) - cs_dsp_ctl_fixup_base(dsp, alg_region); + cs_dsp_ctl_fixup_base(dsp, &item->alg_region); - return alg_region; + return &item->alg_region; } static void cs_dsp_free_alg_regions(struct cs_dsp *dsp) { - struct cs_dsp_alg_region *alg_region; + struct cs_dsp_alg_region_list_item *item; while (!list_empty(&dsp->alg_regions)) { - alg_region = list_first_entry(&dsp->alg_regions, - struct cs_dsp_alg_region, - list); - list_del(&alg_region->list); - kfree(alg_region); + item = list_first_entry(&dsp->alg_regions, + struct cs_dsp_alg_region_list_item, + list); + list_del(&item->list); + kfree(item); } } @@ -2164,8 +2224,11 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware const struct cs_dsp_region *mem; struct cs_dsp_alg_region *alg_region; const char *region_name; - int ret, pos, blocks, type, offset, reg, version; - struct cs_dsp_buf *buf; + int ret, pos, blocks, type, version; + unsigned int offset, reg; + u8 *buf = NULL; + size_t buf_len = 0; + size_t region_len; if (!firmware) return 0; @@ -2187,6 +2250,7 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware switch (be32_to_cpu(hdr->rev) & 0xff) { case 1: case 2: + case 3: break; default: cs_dsp_err(dsp, "%s: Unsupported coefficient file format %d\n", @@ -2195,7 +2259,8 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware goto out_fw; } - cs_dsp_info(dsp, "%s: v%d.%d.%d\n", file, + cs_dsp_info(dsp, "%s (v%d): v%d.%d.%d\n", file, + be32_to_cpu(hdr->rev) & 0xff, (le32_to_cpu(hdr->ver) >> 16) & 0xff, (le32_to_cpu(hdr->ver) >> 8) & 0xff, le32_to_cpu(hdr->ver) & 0xff); @@ -2226,8 +2291,9 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware (le32_to_cpu(blk->ver) >> 16) & 0xff, (le32_to_cpu(blk->ver) >> 8) & 0xff, le32_to_cpu(blk->ver) & 0xff); - cs_dsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", - file, blocks, le32_to_cpu(blk->len), offset, type); + cs_dsp_dbg(dsp, "%s.%d: %d bytes off:%#x off32:%#x in %#x\n", + file, blocks, le32_to_cpu(blk->len), offset, + le32_to_cpu(blk->offset32), type); reg = 0; region_name = "Unknown"; @@ -2260,6 +2326,13 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware } break; + case WMFW_ADSP2_XM_LONG: + case WMFW_ADSP2_YM_LONG: + case WMFW_HALO_XM_PACKED_LONG: + case WMFW_HALO_YM_PACKED_LONG: + offset = le32_to_cpu(blk->offset32); + type &= 0xff; /* strip extended block type flags */ + fallthrough; case WMFW_ADSP1_DM: case WMFW_ADSP1_ZM: case WMFW_ADSP2_XM: @@ -2307,20 +2380,28 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware } if (reg) { - buf = cs_dsp_buf_alloc(blk->data, - le32_to_cpu(blk->len), - &buf_list); - if (!buf) { - cs_dsp_err(dsp, "Out of memory\n"); - ret = -ENOMEM; - goto out_fw; + /* + * Although we expect the underlying bus does not require + * physically-contiguous buffers, we pessimistically use + * a temporary buffer instead of trusting that the + * alignment of blk->data is ok. + */ + region_len = le32_to_cpu(blk->len); + if (region_len > buf_len) { + buf_len = round_up(region_len, PAGE_SIZE); + vfree(buf); + buf = vmalloc(buf_len); + if (!buf) { + ret = -ENOMEM; + goto out_fw; + } } - cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", - file, blocks, le32_to_cpu(blk->len), - reg); - ret = regmap_raw_write(regmap, reg, buf->buf, - le32_to_cpu(blk->len)); + memcpy(buf, blk->data, region_len); + + cs_dsp_dbg(dsp, "%s.%d: Writing %zu bytes at %x\n", + file, blocks, region_len, reg); + ret = regmap_raw_write(regmap, reg, buf, region_len); if (ret != 0) { cs_dsp_err(dsp, "%s.%d: Failed to write to %x in %s: %d\n", @@ -2338,8 +2419,9 @@ static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware cs_dsp_debugfs_save_binname(dsp, file); + ret = 0; out_fw: - cs_dsp_buf_free(&buf_list); + vfree(buf); if (ret == -EOVERFLOW) cs_dsp_err(dsp, "%s: file content overflows file data\n", file); @@ -2359,6 +2441,9 @@ static int cs_dsp_create_name(struct cs_dsp *dsp) return 0; } +static const struct cs_dsp_client_ops cs_dsp_default_client_ops = { +}; + static int cs_dsp_common_init(struct cs_dsp *dsp) { int ret; @@ -2372,6 +2457,9 @@ static int cs_dsp_common_init(struct cs_dsp *dsp) mutex_init(&dsp->pwr_lock); + if (!dsp->client_ops) + dsp->client_ops = &cs_dsp_default_client_ops; + #ifdef CONFIG_DEBUG_FS /* Ensure this is invalid if client never provides a debugfs root */ dsp->debugfs_root = ERR_PTR(-ENODEV); @@ -2465,6 +2553,7 @@ int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, goto err_ena; dsp->booted = true; + dsp->hibernating = false; /* Start the core running */ regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, @@ -2743,6 +2832,7 @@ int cs_dsp_power_up(struct cs_dsp *dsp, dsp->ops->disable_core(dsp); dsp->booted = true; + dsp->hibernating = false; mutex_unlock(&dsp->pwr_lock); diff --git a/drivers/firmware/cirrus/cs_dsp.h b/drivers/firmware/cirrus/cs_dsp.h new file mode 100644 index 000000000000..04d768d08d03 --- /dev/null +++ b/drivers/firmware/cirrus/cs_dsp.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * cs_dsp.h -- Private header for cs_dsp driver. + * + * Copyright (C) 2026 Cirrus Logic, Inc. and + * Cirrus Logic International Semiconductor Ltd. + */ + +#ifndef FW_CS_DSP_H +#define FW_CS_DSP_H + +#if IS_ENABLED(CONFIG_KUNIT) +bool cs_dsp_can_emit_message(void); +#endif + +#endif /* ifndef FW_CS_DSP_H */ diff --git a/drivers/firmware/cirrus/test/cs_dsp_mock_bin.c b/drivers/firmware/cirrus/test/cs_dsp_mock_bin.c index 49d84f7e59e6..635e917e0516 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_mock_bin.c +++ b/drivers/firmware/cirrus/test/cs_dsp_mock_bin.c @@ -56,13 +56,14 @@ EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_bin_get_firmware, "FW_CS_DSP_KUNIT_TEST_UTILS") * @alg_id: Algorithm ID. * @alg_ver: Algorithm version. * @type: Type of the block. - * @offset: Offset. + * @offset: 16-bit offset. + * @offset32: 32-bit offset (sample rate on V1 and V2 file formats). * @payload_data: Pointer to buffer containing the payload data. * @payload_len_bytes: Length of payload data in bytes. */ void cs_dsp_mock_bin_add_raw_block(struct cs_dsp_mock_bin_builder *builder, unsigned int alg_id, unsigned int alg_ver, - int type, unsigned int offset, + int type, u16 offset, u32 offset32, const void *payload_data, size_t payload_len_bytes) { struct wmfw_coeff_item *item; @@ -75,6 +76,7 @@ void cs_dsp_mock_bin_add_raw_block(struct cs_dsp_mock_bin_builder *builder, item = builder->write_p; item->offset = cpu_to_le16(offset); + item->offset32 = cpu_to_le32(offset32); item->type = cpu_to_le16(type); item->id = cpu_to_le32(alg_id); item->ver = cpu_to_le32(alg_ver << 8); @@ -96,14 +98,15 @@ static void cs_dsp_mock_bin_add_name_or_info(struct cs_dsp_mock_bin_builder *bui if (info_len % 4) { /* Create a padded string with length a multiple of 4 */ + size_t copy_len = info_len; info_len = round_up(info_len, 4); tmp = kunit_kzalloc(builder->test_priv->test, info_len, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(builder->test_priv->test, tmp); - memcpy(tmp, info, info_len); + memcpy(tmp, info, copy_len); info = tmp; } - cs_dsp_mock_bin_add_raw_block(builder, 0, 0, WMFW_INFO_TEXT, 0, info, info_len); + cs_dsp_mock_bin_add_raw_block(builder, 0, 0, WMFW_INFO_TEXT, 0, 0, info, info_len); kunit_kfree(builder->test_priv->test, tmp); } @@ -155,12 +158,40 @@ void cs_dsp_mock_bin_add_patch(struct cs_dsp_mock_bin_builder *builder, KUNIT_ASSERT_EQ(builder->test_priv->test, payload_len_bytes % 4, 0); cs_dsp_mock_bin_add_raw_block(builder, alg_id, alg_ver, - mem_region, reg_addr_offset, + mem_region, (u16)reg_addr_offset, 0, payload_data, payload_len_bytes); } EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_bin_add_patch, "FW_CS_DSP_KUNIT_TEST_UTILS"); /** + * cs_dsp_mock_bin_add_patch_off32() - Add a patch data block with 32-bit offset. + * + * @builder: Pointer to struct cs_dsp_mock_bin_builder. + * @alg_id: Algorithm ID for the patch. + * @alg_ver: Algorithm version for the patch. + * @mem_region: Memory region for the patch. + * @reg_addr_offset: Offset to start of data in register addresses. + * @payload_data: Pointer to buffer containing the payload data. + * @payload_len_bytes: Length of payload data in bytes. + */ +void cs_dsp_mock_bin_add_patch_off32(struct cs_dsp_mock_bin_builder *builder, + unsigned int alg_id, unsigned int alg_ver, + int mem_region, unsigned int reg_addr_offset, + const void *payload_data, size_t payload_len_bytes) +{ + /* Payload length must be a multiple of 4 */ + KUNIT_ASSERT_EQ(builder->test_priv->test, payload_len_bytes % 4, 0); + + /* Mark the block as using the 32-bit offset */ + mem_region |= 0xf400; + + cs_dsp_mock_bin_add_raw_block(builder, alg_id, alg_ver, + mem_region, 0, reg_addr_offset, + payload_data, payload_len_bytes); +} +EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_bin_add_patch_off32, "FW_CS_DSP_KUNIT_TEST_UTILS"); + +/** * cs_dsp_mock_bin_init() - Initialize a struct cs_dsp_mock_bin_builder. * * @priv: Pointer to struct cs_dsp_test. @@ -176,6 +207,9 @@ struct cs_dsp_mock_bin_builder *cs_dsp_mock_bin_init(struct cs_dsp_test *priv, struct cs_dsp_mock_bin_builder *builder; struct wmfw_coeff_hdr *hdr; + KUNIT_ASSERT_LE(priv->test, format_version, 0xff); + KUNIT_ASSERT_LE(priv->test, fw_version, 0xffffff); + builder = kunit_kzalloc(priv->test, sizeof(*builder), GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(priv->test, builder); builder->test_priv = priv; diff --git a/drivers/firmware/cirrus/test/cs_dsp_mock_mem_maps.c b/drivers/firmware/cirrus/test/cs_dsp_mock_mem_maps.c index 161272e47bda..7fb404425fd6 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_mock_mem_maps.c +++ b/drivers/firmware/cirrus/test/cs_dsp_mock_mem_maps.c @@ -23,10 +23,10 @@ EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_halo_dsp1_regions, "FW_CS_DSP_KUNIT_TEST_UTILS" /* List of sizes in bytes, for each entry above */ const unsigned int cs_dsp_mock_halo_dsp1_region_sizes[] = { 0x5000, /* PM_PACKED */ - 0x6000, /* XM_PACKED */ - 0x47F4, /* YM_PACKED */ - 0x8000, /* XM_UNPACKED_24 */ - 0x5FF8, /* YM_UNPACKED_24 */ + 0x8fff4, /* XM_PACKED */ + 0x8fff4, /* YM_PACKED */ + 0xbfff8, /* XM_UNPACKED_24 */ + 0xbfff8, /* YM_UNPACKED_24 */ 0 /* terminator */ }; @@ -462,36 +462,6 @@ unsigned int cs_dsp_mock_xm_header_get_alg_base_in_words(struct cs_dsp_test *pri EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_xm_header_get_alg_base_in_words, "FW_CS_DSP_KUNIT_TEST_UTILS"); /** - * cs_dsp_mock_xm_header_get_fw_version_from_regmap() - Firmware version. - * - * @priv: Pointer to struct cs_dsp_test. - * - * Return: Firmware version word value. - */ -unsigned int cs_dsp_mock_xm_header_get_fw_version_from_regmap(struct cs_dsp_test *priv) -{ - unsigned int xm = cs_dsp_mock_base_addr_for_mem(priv, WMFW_ADSP2_XM); - union { - struct wmfw_id_hdr adsp2; - struct wmfw_v3_id_hdr halo; - } hdr; - - switch (priv->dsp->type) { - case WMFW_ADSP2: - regmap_raw_read(priv->dsp->regmap, xm, &hdr.adsp2, sizeof(hdr.adsp2)); - return be32_to_cpu(hdr.adsp2.ver); - case WMFW_HALO: - regmap_raw_read(priv->dsp->regmap, xm, &hdr.halo, sizeof(hdr.halo)); - return be32_to_cpu(hdr.halo.ver); - default: - KUNIT_FAIL(priv->test, NULL); - return 0; - } -} -EXPORT_SYMBOL_NS_GPL(cs_dsp_mock_xm_header_get_fw_version_from_regmap, - "FW_CS_DSP_KUNIT_TEST_UTILS"); - -/** * cs_dsp_mock_xm_header_get_fw_version() - Firmware version. * * @header: Pointer to struct cs_dsp_mock_xm_header. @@ -535,9 +505,11 @@ void cs_dsp_mock_xm_header_drop_from_regmap_cache(struct cs_dsp_test *priv) * Could be one 32-bit register or two 16-bit registers. * A raw read will read the requested number of bytes. */ - regmap_raw_read(priv->dsp->regmap, - xm + (offsetof(struct wmfw_adsp2_id_hdr, n_algs) / 2), - &num_algs_be32, sizeof(num_algs_be32)); + KUNIT_ASSERT_GE(priv->test, 0, + regmap_raw_read(priv->dsp->regmap, + xm + + (offsetof(struct wmfw_adsp2_id_hdr, n_algs) / 2), + &num_algs_be32, sizeof(num_algs_be32))); num_algs = be32_to_cpu(num_algs_be32); bytes = sizeof(struct wmfw_adsp2_id_hdr) + (num_algs * sizeof(struct wmfw_adsp2_alg_hdr)) + @@ -546,9 +518,10 @@ void cs_dsp_mock_xm_header_drop_from_regmap_cache(struct cs_dsp_test *priv) regcache_drop_region(priv->dsp->regmap, xm, xm + (bytes / 2) - 1); break; case WMFW_HALO: - regmap_read(priv->dsp->regmap, - xm + offsetof(struct wmfw_halo_id_hdr, n_algs), - &num_algs); + KUNIT_ASSERT_GE(priv->test, 0, + regmap_read(priv->dsp->regmap, + xm + offsetof(struct wmfw_halo_id_hdr, n_algs), + &num_algs)); bytes = sizeof(struct wmfw_halo_id_hdr) + (num_algs * sizeof(struct wmfw_halo_alg_hdr)) + 4 /* terminator word */; diff --git a/drivers/firmware/cirrus/test/cs_dsp_mock_regmap.c b/drivers/firmware/cirrus/test/cs_dsp_mock_regmap.c index fb8e4a5d189a..5167305521cd 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_mock_regmap.c +++ b/drivers/firmware/cirrus/test/cs_dsp_mock_regmap.c @@ -157,22 +157,22 @@ static const struct reg_default halo_register_defaults[] = { }; static const struct regmap_range halo_readable_registers[] = { - regmap_reg_range(0x2000000, 0x2005fff), /* XM_PACKED */ + regmap_reg_range(0x2000000, 0x208fff0), /* XM_PACKED */ regmap_reg_range(0x25e0000, 0x25e004f), /* SYSINFO */ regmap_reg_range(0x25e2000, 0x25e2047), /* SYSINFO */ - regmap_reg_range(0x2800000, 0x2807fff), /* XM */ + regmap_reg_range(0x2800000, 0x28bfff4), /* XM */ regmap_reg_range(0x2b80000, 0x2bc700b), /* CORE CTRL */ - regmap_reg_range(0x2c00000, 0x2c047f3), /* YM_PACKED */ - regmap_reg_range(0x3400000, 0x3405ff7), /* YM */ + regmap_reg_range(0x2c00000, 0x2c8fff0), /* YM_PACKED */ + regmap_reg_range(0x3400000, 0x34bfff4), /* YM */ regmap_reg_range(0x3800000, 0x3804fff), /* PM_PACKED */ }; static const struct regmap_range halo_writeable_registers[] = { - regmap_reg_range(0x2000000, 0x2005fff), /* XM_PACKED */ - regmap_reg_range(0x2800000, 0x2807fff), /* XM */ + regmap_reg_range(0x2000000, 0x208fff0), /* XM_PACKED */ + regmap_reg_range(0x2800000, 0x28bfff4), /* XM */ regmap_reg_range(0x2b80000, 0x2bc700b), /* CORE CTRL */ - regmap_reg_range(0x2c00000, 0x2c047f3), /* YM_PACKED */ - regmap_reg_range(0x3400000, 0x3405ff7), /* YM */ + regmap_reg_range(0x2c00000, 0x2c8fff0), /* YM_PACKED */ + regmap_reg_range(0x3400000, 0x34bfff4), /* YM */ regmap_reg_range(0x3800000, 0x3804fff), /* PM_PACKED */ }; diff --git a/drivers/firmware/cirrus/test/cs_dsp_mock_wmfw.c b/drivers/firmware/cirrus/test/cs_dsp_mock_wmfw.c index 5a3ac03ac37f..5e1d5a810afe 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_mock_wmfw.c +++ b/drivers/firmware/cirrus/test/cs_dsp_mock_wmfw.c @@ -133,10 +133,11 @@ void cs_dsp_mock_wmfw_add_info(struct cs_dsp_mock_wmfw_builder *builder, if (info_len % 4) { /* Create a padded string with length a multiple of 4 */ + size_t copy_len = info_len; info_len = round_up(info_len, 4); tmp = kunit_kzalloc(builder->test_priv->test, info_len, GFP_KERNEL); KUNIT_ASSERT_NOT_ERR_OR_NULL(builder->test_priv->test, tmp); - memcpy(tmp, info, info_len); + memcpy(tmp, info, copy_len); info = tmp; } @@ -178,6 +179,8 @@ void cs_dsp_mock_wmfw_start_alg_info_block(struct cs_dsp_mock_wmfw_builder *buil size_t bytes_needed, name_len, description_len; int offset; + KUNIT_ASSERT_LE(builder->test_priv->test, alg_id, 0xffffff); + /* Bytes needed for region header */ bytes_needed = offsetof(struct wmfw_region, data); @@ -435,6 +438,8 @@ struct cs_dsp_mock_wmfw_builder *cs_dsp_mock_wmfw_init(struct cs_dsp_test *priv, { struct cs_dsp_mock_wmfw_builder *builder; + KUNIT_ASSERT_LE(priv->test, format_version, 0xff); + /* If format version isn't given use the default for the target core */ if (format_version < 0) { switch (priv->dsp->type) { diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_bin.c b/drivers/firmware/cirrus/test/cs_dsp_test_bin.c index 1e161bbc5b4a..63416838f865 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_bin.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_bin.c @@ -7,6 +7,7 @@ #include <kunit/device.h> #include <kunit/resource.h> +#include <kunit/static_stub.h> #include <kunit/test.h> #include <linux/build_bug.h> #include <linux/firmware/cirrus/cs_dsp.h> @@ -17,6 +18,8 @@ #include <linux/random.h> #include <linux/regmap.h> +#include "../cs_dsp.h" + /* * Test method is: * @@ -69,6 +72,10 @@ struct bin_test_param { int mem_type; unsigned int offset_words; int alg_idx; + void (*add_patch)(struct cs_dsp_mock_bin_builder *builder, + unsigned int alg_id, unsigned int alg_ver, + int mem_region, unsigned int reg_addr_offset, + const void *payload_data, size_t payload_len_bytes); }; static const struct cs_dsp_mock_alg_def bin_test_mock_algs[] = { @@ -128,12 +135,12 @@ static void bin_patch_one_word(struct kunit *test) bin_test_mock_algs[param->alg_idx].id, param->mem_type); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - param->offset_words * reg_inc_per_word, - &payload_data, sizeof(payload_data)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + param->offset_words * reg_inc_per_word, + &payload_data, sizeof(payload_data)); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -177,12 +184,12 @@ static void bin_patch_one_multiword(struct kunit *test) bin_test_mock_algs[param->alg_idx].id, param->mem_type); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - param->offset_words * reg_inc_per_word, - payload_data, sizeof(payload_data)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + param->offset_words * reg_inc_per_word, + payload_data, sizeof(payload_data)); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -228,12 +235,12 @@ static void bin_patch_multi_oneword(struct kunit *test) /* Add one payload per word */ for (i = 0; i < ARRAY_SIZE(payload_data); ++i) { - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (param->offset_words + i) * reg_inc_per_word, - &payload_data[i], sizeof(payload_data[i])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (param->offset_words + i) * reg_inc_per_word, + &payload_data[i], sizeof(payload_data[i])); } fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); @@ -285,13 +292,13 @@ static void bin_patch_multi_oneword_unordered(struct kunit *test) /* Add one payload per word */ for (i = 0; i < ARRAY_SIZE(word_order); ++i) { - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (param->offset_words + word_order[i]) * - reg_inc_per_word, - &payload_data[word_order[i]], sizeof(payload_data[0])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (param->offset_words + word_order[i]) * + reg_inc_per_word, + &payload_data[word_order[i]], sizeof(payload_data[0])); } fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); @@ -346,12 +353,12 @@ static void bin_patch_multi_oneword_sparse_unordered(struct kunit *test) /* Add one payload per word */ for (i = 0; i < ARRAY_SIZE(word_offsets); ++i) { - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - word_offsets[i] * reg_inc_per_word, - &payload_data[i], sizeof(payload_data[i])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + word_offsets[i] * reg_inc_per_word, + &payload_data[i], sizeof(payload_data[i])); } fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); @@ -413,27 +420,27 @@ static void bin_patch_one_word_multiple_mems(struct kunit *test) } /* Add words to XM, YM and ZM */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - WMFW_ADSP2_XM, - param->offset_words * reg_inc_per_word, - &payload_data[0], sizeof(payload_data[0])); - - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - WMFW_ADSP2_YM, - param->offset_words * reg_inc_per_word, - &payload_data[1], sizeof(payload_data[1])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + WMFW_ADSP2_XM, + param->offset_words * reg_inc_per_word, + &payload_data[0], sizeof(payload_data[0])); + + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + WMFW_ADSP2_YM, + param->offset_words * reg_inc_per_word, + &payload_data[1], sizeof(payload_data[1])); if (cs_dsp_mock_has_zm(priv)) { - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - WMFW_ADSP2_ZM, - param->offset_words * reg_inc_per_word, - &payload_data[2], sizeof(payload_data[2])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + WMFW_ADSP2_ZM, + param->offset_words * reg_inc_per_word, + &payload_data[2], sizeof(payload_data[2])); } fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); @@ -502,12 +509,12 @@ static void bin_patch_one_word_multiple_algs(struct kunit *test) for (i = 0; i < ARRAY_SIZE(bin_test_mock_algs); ++i) { reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[i].id, - bin_test_mock_algs[i].ver, - param->mem_type, - param->offset_words * reg_inc_per_word, - &payload_data[i], sizeof(payload_data[i])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[i].id, + bin_test_mock_algs[i].ver, + param->mem_type, + param->offset_words * reg_inc_per_word, + &payload_data[i], sizeof(payload_data[i])); } fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); @@ -565,12 +572,12 @@ static void bin_patch_one_word_multiple_algs_unordered(struct kunit *test) alg_idx = alg_order[i]; reg_inc_per_word = cs_dsp_mock_reg_addr_inc_per_unpacked_word(priv); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[alg_idx].id, - bin_test_mock_algs[alg_idx].ver, - param->mem_type, - param->offset_words * reg_inc_per_word, - &payload_data[i], sizeof(payload_data[i])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[alg_idx].id, + bin_test_mock_algs[alg_idx].ver, + param->mem_type, + param->offset_words * reg_inc_per_word, + &payload_data[i], sizeof(payload_data[i])); } fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); @@ -628,12 +635,12 @@ static void bin_patch_1_packed(struct kunit *test) patch_pos_words = round_up(alg_base_words + param->offset_words, 4); patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - packed_payload, sizeof(packed_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + packed_payload, sizeof(packed_payload)); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -688,20 +695,20 @@ static void bin_patch_1_packed_1_single_trailing(struct kunit *test) patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words); /* Patch packed block */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - &packed_payload, sizeof(packed_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + &packed_payload, sizeof(packed_payload)); /* ... and the unpacked word following that */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((patch_pos_words + 4) - alg_base_words) * 4, - unpacked_payload, sizeof(unpacked_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((patch_pos_words + 4) - alg_base_words) * 4, + unpacked_payload, sizeof(unpacked_payload)); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -768,27 +775,27 @@ static void bin_patch_1_packed_2_single_trailing(struct kunit *test) patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words); /* Patch packed block */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - &packed_payload, sizeof(packed_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + &packed_payload, sizeof(packed_payload)); /* ... and the unpacked words following that */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((patch_pos_words + 4) - alg_base_words) * 4, - &unpacked_payloads[0], sizeof(unpacked_payloads[0])); - - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((patch_pos_words + 5) - alg_base_words) * 4, - &unpacked_payloads[1], sizeof(unpacked_payloads[1])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((patch_pos_words + 4) - alg_base_words) * 4, + &unpacked_payloads[0], sizeof(unpacked_payloads[0])); + + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((patch_pos_words + 5) - alg_base_words) * 4, + &unpacked_payloads[1], sizeof(unpacked_payloads[1])); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -857,34 +864,34 @@ static void bin_patch_1_packed_3_single_trailing(struct kunit *test) patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words); /* Patch packed block */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - &packed_payload, sizeof(packed_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + &packed_payload, sizeof(packed_payload)); /* ... and the unpacked words following that */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((patch_pos_words + 4) - alg_base_words) * 4, - &unpacked_payloads[0], sizeof(unpacked_payloads[0])); - - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((patch_pos_words + 5) - alg_base_words) * 4, - &unpacked_payloads[1], sizeof(unpacked_payloads[1])); - - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((patch_pos_words + 6) - alg_base_words) * 4, - &unpacked_payloads[2], sizeof(unpacked_payloads[2])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((patch_pos_words + 4) - alg_base_words) * 4, + &unpacked_payloads[0], sizeof(unpacked_payloads[0])); + + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((patch_pos_words + 5) - alg_base_words) * 4, + &unpacked_payloads[1], sizeof(unpacked_payloads[1])); + + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((patch_pos_words + 6) - alg_base_words) * 4, + &unpacked_payloads[2], sizeof(unpacked_payloads[2])); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -953,20 +960,20 @@ static void bin_patch_1_packed_2_trailing(struct kunit *test) patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words); /* Patch packed block */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - &packed_payload, sizeof(packed_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + &packed_payload, sizeof(packed_payload)); /* ... and the unpacked words following that */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((patch_pos_words + 4) - alg_base_words) * 4, - unpacked_payload, sizeof(unpacked_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((patch_pos_words + 4) - alg_base_words) * 4, + unpacked_payload, sizeof(unpacked_payload)); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -1035,20 +1042,20 @@ static void bin_patch_1_packed_3_trailing(struct kunit *test) patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words); /* Patch packed block */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - &packed_payload, sizeof(packed_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + &packed_payload, sizeof(packed_payload)); /* ... and the unpacked words following that */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((patch_pos_words + 4) - alg_base_words) * 4, - unpacked_payload, sizeof(unpacked_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((patch_pos_words + 4) - alg_base_words) * 4, + unpacked_payload, sizeof(unpacked_payload)); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -1117,20 +1124,20 @@ static void bin_patch_1_single_leading_1_packed(struct kunit *test) packed_patch_pos_words = round_up(alg_base_words + param->offset_words, 4) + 4; /* Patch the leading unpacked word */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((packed_patch_pos_words - 1) - alg_base_words) * 4, - unpacked_payload, sizeof(unpacked_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((packed_patch_pos_words - 1) - alg_base_words) * 4, + unpacked_payload, sizeof(unpacked_payload)); /* ... then the packed block */ patch_pos_in_packed_regs = _num_words_to_num_packed_regs(packed_patch_pos_words); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - &packed_payload, sizeof(packed_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + &packed_payload, sizeof(packed_payload)); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -1196,26 +1203,26 @@ static void bin_patch_2_single_leading_1_packed(struct kunit *test) packed_patch_pos_words = round_up(alg_base_words + param->offset_words, 4) + 4; /* Patch the leading unpacked words */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((packed_patch_pos_words - 2) - alg_base_words) * 4, - &unpacked_payload[0], sizeof(unpacked_payload[0])); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((packed_patch_pos_words - 1) - alg_base_words) * 4, - &unpacked_payload[1], sizeof(unpacked_payload[1])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((packed_patch_pos_words - 2) - alg_base_words) * 4, + &unpacked_payload[0], sizeof(unpacked_payload[0])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((packed_patch_pos_words - 1) - alg_base_words) * 4, + &unpacked_payload[1], sizeof(unpacked_payload[1])); /* ... then the packed block */ patch_pos_in_packed_regs = _num_words_to_num_packed_regs(packed_patch_pos_words); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - &packed_payload, sizeof(packed_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + &packed_payload, sizeof(packed_payload)); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -1283,20 +1290,20 @@ static void bin_patch_2_leading_1_packed(struct kunit *test) packed_patch_pos_words = round_up(alg_base_words + param->offset_words, 4) + 4; /* Patch the leading unpacked words */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((packed_patch_pos_words - 2) - alg_base_words) * 4, - unpacked_payload, sizeof(unpacked_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((packed_patch_pos_words - 2) - alg_base_words) * 4, + unpacked_payload, sizeof(unpacked_payload)); /* ... then the packed block */ patch_pos_in_packed_regs = _num_words_to_num_packed_regs(packed_patch_pos_words); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - &packed_payload, sizeof(packed_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + &packed_payload, sizeof(packed_payload)); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -1364,32 +1371,32 @@ static void bin_patch_3_single_leading_1_packed(struct kunit *test) packed_patch_pos_words = round_up(alg_base_words + param->offset_words, 4) + 4; /* Patch the leading unpacked words */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((packed_patch_pos_words - 3) - alg_base_words) * 4, - &unpacked_payload[0], sizeof(unpacked_payload[0])); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((packed_patch_pos_words - 2) - alg_base_words) * 4, - &unpacked_payload[1], sizeof(unpacked_payload[1])); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((packed_patch_pos_words - 1) - alg_base_words) * 4, - &unpacked_payload[2], sizeof(unpacked_payload[2])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((packed_patch_pos_words - 3) - alg_base_words) * 4, + &unpacked_payload[0], sizeof(unpacked_payload[0])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((packed_patch_pos_words - 2) - alg_base_words) * 4, + &unpacked_payload[1], sizeof(unpacked_payload[1])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((packed_patch_pos_words - 1) - alg_base_words) * 4, + &unpacked_payload[2], sizeof(unpacked_payload[2])); /* ... then the packed block */ patch_pos_in_packed_regs = _num_words_to_num_packed_regs(packed_patch_pos_words); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - &packed_payload, sizeof(packed_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + &packed_payload, sizeof(packed_payload)); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -1457,20 +1464,20 @@ static void bin_patch_3_leading_1_packed(struct kunit *test) packed_patch_pos_words = round_up(alg_base_words + param->offset_words, 4) + 4; /* Patch the leading unpacked words */ - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - unpacked_mem_type, - ((packed_patch_pos_words - 3) - alg_base_words) * 4, - unpacked_payload, sizeof(unpacked_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + unpacked_mem_type, + ((packed_patch_pos_words - 3) - alg_base_words) * 4, + unpacked_payload, sizeof(unpacked_payload)); /* ... then the packed block */ patch_pos_in_packed_regs = _num_words_to_num_packed_regs(packed_patch_pos_words); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - &packed_payload, sizeof(packed_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + &packed_payload, sizeof(packed_payload)); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -1537,12 +1544,12 @@ static void bin_patch_multi_onepacked(struct kunit *test) for (i = 0; i < ARRAY_SIZE(packed_payloads); ++i) { patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words + (i * 4)); payload_offset = (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4; - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - payload_offset, - &packed_payloads[i], sizeof(packed_payloads[i])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + payload_offset, + &packed_payloads[i], sizeof(packed_payloads[i])); } fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); @@ -1602,13 +1609,13 @@ static void bin_patch_multi_onepacked_unordered(struct kunit *test) patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words + (payload_order[i] * 4)); payload_offset = (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4; - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - payload_offset, - &packed_payloads[payload_order[i]], - sizeof(packed_payloads[0])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + payload_offset, + &packed_payloads[payload_order[i]], + sizeof(packed_payloads[0])); } fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); @@ -1665,13 +1672,13 @@ static void bin_patch_multi_onepacked_sparse_unordered(struct kunit *test) patch_pos_words = round_up(alg_base_words + word_offsets[i], 4); patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words); payload_offset = (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4; - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - param->mem_type, - payload_offset, - &packed_payloads[i], - sizeof(packed_payloads[0])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + param->mem_type, + payload_offset, + &packed_payloads[i], + sizeof(packed_payloads[0])); } fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); @@ -1737,21 +1744,21 @@ static void bin_patch_1_packed_multiple_mems(struct kunit *test) /* Add XM and YM patches */ alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_xm_base_words); patch_pos_in_packed_regs = _num_words_to_num_packed_regs(xm_patch_pos_words); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - WMFW_HALO_XM_PACKED, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - packed_xm_payload, sizeof(packed_xm_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + WMFW_HALO_XM_PACKED, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + packed_xm_payload, sizeof(packed_xm_payload)); alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_ym_base_words); patch_pos_in_packed_regs = _num_words_to_num_packed_regs(ym_patch_pos_words); - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[param->alg_idx].id, - bin_test_mock_algs[param->alg_idx].ver, - WMFW_HALO_YM_PACKED, - (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, - packed_ym_payload, sizeof(packed_ym_payload)); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[param->alg_idx].id, + bin_test_mock_algs[param->alg_idx].ver, + WMFW_HALO_YM_PACKED, + (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4, + packed_ym_payload, sizeof(packed_ym_payload)); fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); KUNIT_ASSERT_EQ(test, @@ -1821,12 +1828,12 @@ static void bin_patch_1_packed_multiple_algs(struct kunit *test) patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words); payload_offset = (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4; - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[i].id, - bin_test_mock_algs[i].ver, - param->mem_type, - payload_offset, - packed_payload[i], sizeof(packed_payload[i])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[i].id, + bin_test_mock_algs[i].ver, + param->mem_type, + payload_offset, + packed_payload[i], sizeof(packed_payload[i])); } fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); @@ -1907,12 +1914,12 @@ static void bin_patch_1_packed_multiple_algs_unordered(struct kunit *test) patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words); payload_offset = (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4; - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[alg_idx].id, - bin_test_mock_algs[alg_idx].ver, - param->mem_type, - payload_offset, - packed_payload[i], sizeof(packed_payload[i])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[alg_idx].id, + bin_test_mock_algs[alg_idx].ver, + param->mem_type, + payload_offset, + packed_payload[i], sizeof(packed_payload[i])); } fw = cs_dsp_mock_bin_get_firmware(priv->local->bin_builder); @@ -2004,22 +2011,22 @@ static void bin_patch_mixed_packed_unpacked_random(struct kunit *test) alg_base_in_packed_regs = _num_words_to_num_packed_regs(alg_base_words); patch_pos_in_packed_regs = _num_words_to_num_packed_regs(patch_pos_words); payload_offset = (patch_pos_in_packed_regs - alg_base_in_packed_regs) * 4; - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[0].id, - bin_test_mock_algs[0].ver, - param->mem_type, - payload_offset, - payload->packed[i], - sizeof(payload->packed[i])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[0].id, + bin_test_mock_algs[0].ver, + param->mem_type, + payload_offset, + payload->packed[i], + sizeof(payload->packed[i])); } else { payload_offset = offset_words[i] * 4; - cs_dsp_mock_bin_add_patch(priv->local->bin_builder, - bin_test_mock_algs[0].id, - bin_test_mock_algs[0].ver, - unpacked_mem_type, - payload_offset, - &payload->unpacked[i], - sizeof(payload->unpacked[i])); + param->add_patch(priv->local->bin_builder, + bin_test_mock_algs[0].id, + bin_test_mock_algs[0].ver, + unpacked_mem_type, + payload_offset, + &payload->unpacked[i], + sizeof(payload->unpacked[i])); } } @@ -2149,7 +2156,17 @@ static void bin_patch_name_and_info(struct kunit *test) KUNIT_EXPECT_EQ(test, reg_val, payload_data); } -static int cs_dsp_bin_test_common_init(struct kunit *test, struct cs_dsp *dsp) +static bool cs_dsp_bin_test_can_emit_message_hook(void) +{ +#if defined(DEBUG) + return true; +#else + return false; +#endif +} + +static int cs_dsp_bin_test_common_init(struct kunit *test, struct cs_dsp *dsp, + int wmdr_ver) { struct cs_dsp_test *priv; struct cs_dsp_mock_xm_header *xm_hdr; @@ -2197,8 +2214,8 @@ static int cs_dsp_bin_test_common_init(struct kunit *test, struct cs_dsp *dsp) KUNIT_ASSERT_EQ(test, ret, 0); priv->local->bin_builder = - cs_dsp_mock_bin_init(priv, 1, - cs_dsp_mock_xm_header_get_fw_version_from_regmap(priv)); + cs_dsp_mock_bin_init(priv, wmdr_ver, + cs_dsp_mock_xm_header_get_fw_version(xm_hdr)); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, priv->local->bin_builder); /* We must provide a dummy wmfw to load */ @@ -2224,10 +2241,21 @@ static int cs_dsp_bin_test_common_init(struct kunit *test, struct cs_dsp *dsp) return ret; /* Automatically call cs_dsp_remove() when test case ends */ - return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); + ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); + if (ret) + return ret; + + /* + * The large number of test cases will cause an unusually large amount + * of dev_info() messages from cs_dsp, so suppress these. + */ + kunit_activate_static_stub(test, cs_dsp_can_emit_message, + cs_dsp_bin_test_can_emit_message_hook); + + return 0; } -static int cs_dsp_bin_test_halo_init(struct kunit *test) +static int cs_dsp_bin_test_halo_init_common(struct kunit *test, int wmdr_ver) { struct cs_dsp *dsp; @@ -2243,7 +2271,17 @@ static int cs_dsp_bin_test_halo_init(struct kunit *test) dsp->base = cs_dsp_mock_halo_core_base; dsp->base_sysinfo = cs_dsp_mock_halo_sysinfo_base; - return cs_dsp_bin_test_common_init(test, dsp); + return cs_dsp_bin_test_common_init(test, dsp, wmdr_ver); +} + +static int cs_dsp_bin_test_halo_init(struct kunit *test) +{ + return cs_dsp_bin_test_halo_init_common(test, 1); +} + +static int cs_dsp_bin_test_halo_wmdr3_init(struct kunit *test) +{ + return cs_dsp_bin_test_halo_init_common(test, 3); } static int cs_dsp_bin_test_adsp2_32bit_init(struct kunit *test) @@ -2262,7 +2300,7 @@ static int cs_dsp_bin_test_adsp2_32bit_init(struct kunit *test) dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_32bit_dsp1_region_sizes); dsp->base = cs_dsp_mock_adsp2_32bit_sysbase; - return cs_dsp_bin_test_common_init(test, dsp); + return cs_dsp_bin_test_common_init(test, dsp, 1); } static int cs_dsp_bin_test_adsp2_16bit_init(struct kunit *test) @@ -2281,70 +2319,152 @@ static int cs_dsp_bin_test_adsp2_16bit_init(struct kunit *test) dsp->num_mems = cs_dsp_mock_count_regions(cs_dsp_mock_adsp2_16bit_dsp1_region_sizes); dsp->base = cs_dsp_mock_adsp2_16bit_sysbase; - return cs_dsp_bin_test_common_init(test, dsp); + return cs_dsp_bin_test_common_init(test, dsp, 1); } +#define WMDR_PATCH_SHORT .add_patch = cs_dsp_mock_bin_add_patch +#define WMDR_PATCH_LONG .add_patch = cs_dsp_mock_bin_add_patch_off32 + /* Parameterize on choice of XM or YM with a range of word offsets */ static const struct bin_test_param x_or_y_and_offset_param_cases[] = { - { .mem_type = WMFW_ADSP2_XM, .offset_words = 0 }, - { .mem_type = WMFW_ADSP2_XM, .offset_words = 1 }, - { .mem_type = WMFW_ADSP2_XM, .offset_words = 2 }, - { .mem_type = WMFW_ADSP2_XM, .offset_words = 3 }, - { .mem_type = WMFW_ADSP2_XM, .offset_words = 4 }, - { .mem_type = WMFW_ADSP2_XM, .offset_words = 23 }, - { .mem_type = WMFW_ADSP2_XM, .offset_words = 22 }, - { .mem_type = WMFW_ADSP2_XM, .offset_words = 21 }, - { .mem_type = WMFW_ADSP2_XM, .offset_words = 20 }, - - { .mem_type = WMFW_ADSP2_YM, .offset_words = 0 }, - { .mem_type = WMFW_ADSP2_YM, .offset_words = 1 }, - { .mem_type = WMFW_ADSP2_YM, .offset_words = 2 }, - { .mem_type = WMFW_ADSP2_YM, .offset_words = 3 }, - { .mem_type = WMFW_ADSP2_YM, .offset_words = 4 }, - { .mem_type = WMFW_ADSP2_YM, .offset_words = 23 }, - { .mem_type = WMFW_ADSP2_YM, .offset_words = 22 }, - { .mem_type = WMFW_ADSP2_YM, .offset_words = 21 }, - { .mem_type = WMFW_ADSP2_YM, .offset_words = 20 }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 0, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 1, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 2, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 3, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 4, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 23, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 22, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 21, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 20, WMDR_PATCH_SHORT }, + + { .mem_type = WMFW_ADSP2_YM, .offset_words = 0, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 1, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 2, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 3, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 4, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 23, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 22, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 21, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 20, WMDR_PATCH_SHORT }, +}; + +static const struct bin_test_param x_or_y_and_long_offset_param_cases[] = { + /* Offset < 0xffff in long-offset block type */ + { .mem_type = WMFW_ADSP2_XM, .offset_words = 0, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 1, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 2, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 3, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 4, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 23, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 22, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 21, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 20, WMDR_PATCH_LONG }, + + /* Offset < 0xffff in long-offset block type */ + { .mem_type = WMFW_ADSP2_YM, .offset_words = 0, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 1, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 2, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 3, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 4, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 23, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 22, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 21, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 20, WMDR_PATCH_LONG }, + + /* Offset > 0xffff in long-offset block type */ + { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x10000, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x10001, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x10002, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x10003, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x10004, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x2f003, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x2f002, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x2f001, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .offset_words = 0x2f000, WMDR_PATCH_LONG }, + + /* Offset > 0xffff in long-offset block type */ + { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x10000, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x10001, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x10002, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x10003, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x10004, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x2f003, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x2f002, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x2f001, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .offset_words = 0x2f000, WMDR_PATCH_LONG }, }; /* Parameterize on ZM with a range of word offsets */ static const struct bin_test_param z_and_offset_param_cases[] = { - { .mem_type = WMFW_ADSP2_ZM, .offset_words = 0 }, - { .mem_type = WMFW_ADSP2_ZM, .offset_words = 1 }, - { .mem_type = WMFW_ADSP2_ZM, .offset_words = 2 }, - { .mem_type = WMFW_ADSP2_ZM, .offset_words = 3 }, - { .mem_type = WMFW_ADSP2_ZM, .offset_words = 4 }, - { .mem_type = WMFW_ADSP2_ZM, .offset_words = 23 }, - { .mem_type = WMFW_ADSP2_ZM, .offset_words = 22 }, - { .mem_type = WMFW_ADSP2_ZM, .offset_words = 21 }, - { .mem_type = WMFW_ADSP2_ZM, .offset_words = 20 }, + { .mem_type = WMFW_ADSP2_ZM, .offset_words = 0, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_ZM, .offset_words = 1, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_ZM, .offset_words = 2, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_ZM, .offset_words = 3, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_ZM, .offset_words = 4, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_ZM, .offset_words = 23, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_ZM, .offset_words = 22, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_ZM, .offset_words = 21, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_ZM, .offset_words = 20, WMDR_PATCH_SHORT }, }; /* Parameterize on choice of packed XM or YM with a range of word offsets */ static const struct bin_test_param packed_x_or_y_and_offset_param_cases[] = { - { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0 }, - { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 4 }, - { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 8 }, - { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 12 }, - - { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0 }, - { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 4 }, - { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 8 }, - { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 12 }, + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 4, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 8, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 12, WMDR_PATCH_SHORT }, + + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 4, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 8, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 12, WMDR_PATCH_SHORT }, +}; + +static const struct bin_test_param packed_x_or_y_and_long_offset_param_cases[] = { + /* Offset < 0xffff in long-offset block type */ + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 4, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 8, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 12, WMDR_PATCH_LONG }, + + /* Offset < 0xffff in long-offset block type */ + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 4, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 8, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 12, WMDR_PATCH_LONG }, + + /* Offset > 0xffff in long-offset block type */ + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0x10000, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0x10004, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0x10008, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0x2f000, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0x2f004, WMDR_PATCH_LONG }, + + /* Offset > 0xffff in long-offset block type */ + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0x10000, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0x10004, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0x10008, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0x2f000, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0x2f004, WMDR_PATCH_LONG }, }; static void x_or_y_or_z_and_offset_param_desc(const struct bin_test_param *param, char *desc) { - snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s@%u", + snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s@%u %s", cs_dsp_mem_region_name(param->mem_type), - param->offset_words); + param->offset_words, + (param->add_patch == cs_dsp_mock_bin_add_patch_off32) ? "offs32" : ""); } KUNIT_ARRAY_PARAM(x_or_y_and_offset, x_or_y_and_offset_param_cases, x_or_y_or_z_and_offset_param_desc); +KUNIT_ARRAY_PARAM(x_or_y_and_long_offset, + x_or_y_and_long_offset_param_cases, + x_or_y_or_z_and_offset_param_desc); + KUNIT_ARRAY_PARAM(z_and_offset, z_and_offset_param_cases, x_or_y_or_z_and_offset_param_desc); @@ -2353,103 +2473,181 @@ KUNIT_ARRAY_PARAM(packed_x_or_y_and_offset, packed_x_or_y_and_offset_param_cases, x_or_y_or_z_and_offset_param_desc); +KUNIT_ARRAY_PARAM(packed_x_or_y_and_long_offset, + packed_x_or_y_and_long_offset_param_cases, + x_or_y_or_z_and_offset_param_desc); + /* Parameterize on choice of packed XM or YM */ static const struct bin_test_param packed_x_or_y_param_cases[] = { - { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0 }, - { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0 }, + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0, WMDR_PATCH_SHORT }, +}; + +static const struct bin_test_param packed_x_or_y_long_param_cases[] = { + { .mem_type = WMFW_HALO_XM_PACKED, .offset_words = 0, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_YM_PACKED, .offset_words = 0, WMDR_PATCH_LONG }, }; static void x_or_y_or_z_param_desc(const struct bin_test_param *param, char *desc) { - snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s", cs_dsp_mem_region_name(param->mem_type)); + snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s %s", + cs_dsp_mem_region_name(param->mem_type), + (param->add_patch == cs_dsp_mock_bin_add_patch_off32) ? "offs32" : ""); } KUNIT_ARRAY_PARAM(packed_x_or_y, packed_x_or_y_param_cases, x_or_y_or_z_param_desc); +KUNIT_ARRAY_PARAM(packed_x_or_y_long, packed_x_or_y_long_param_cases, x_or_y_or_z_param_desc); static const struct bin_test_param offset_param_cases[] = { - { .offset_words = 0 }, - { .offset_words = 1 }, - { .offset_words = 2 }, - { .offset_words = 3 }, - { .offset_words = 4 }, - { .offset_words = 23 }, - { .offset_words = 22 }, - { .offset_words = 21 }, - { .offset_words = 20 }, + { .offset_words = 0, WMDR_PATCH_SHORT }, + { .offset_words = 1, WMDR_PATCH_SHORT }, + { .offset_words = 2, WMDR_PATCH_SHORT }, + { .offset_words = 3, WMDR_PATCH_SHORT }, + { .offset_words = 4, WMDR_PATCH_SHORT }, + { .offset_words = 23, WMDR_PATCH_SHORT }, + { .offset_words = 22, WMDR_PATCH_SHORT }, + { .offset_words = 21, WMDR_PATCH_SHORT }, + { .offset_words = 20, WMDR_PATCH_SHORT }, +}; + +static const struct bin_test_param long_offset_param_cases[] = { + /* Offset < 0xffff in long-offset block type */ + { .offset_words = 0, WMDR_PATCH_LONG }, + { .offset_words = 1, WMDR_PATCH_LONG }, + { .offset_words = 2, WMDR_PATCH_LONG }, + { .offset_words = 3, WMDR_PATCH_LONG }, + { .offset_words = 4, WMDR_PATCH_LONG }, + { .offset_words = 23, WMDR_PATCH_LONG }, + { .offset_words = 22, WMDR_PATCH_LONG }, + { .offset_words = 21, WMDR_PATCH_LONG }, + { .offset_words = 20, WMDR_PATCH_LONG }, + + /* Offset > 0xffff in long-offset block type */ + { .offset_words = 0x10000, WMDR_PATCH_LONG }, + { .offset_words = 0x10001, WMDR_PATCH_LONG }, + { .offset_words = 0x10002, WMDR_PATCH_LONG }, + { .offset_words = 0x10003, WMDR_PATCH_LONG }, + { .offset_words = 0x10004, WMDR_PATCH_LONG }, + { .offset_words = 0x2f000, WMDR_PATCH_LONG }, + { .offset_words = 0x2f001, WMDR_PATCH_LONG }, + { .offset_words = 0x2f002, WMDR_PATCH_LONG }, + { .offset_words = 0x2f003, WMDR_PATCH_LONG }, }; static void offset_param_desc(const struct bin_test_param *param, char *desc) { - snprintf(desc, KUNIT_PARAM_DESC_SIZE, "@%u", param->offset_words); + snprintf(desc, KUNIT_PARAM_DESC_SIZE, "@%u %s", + param->offset_words, + (param->add_patch == cs_dsp_mock_bin_add_patch_off32) ? "offs32" : ""); } KUNIT_ARRAY_PARAM(offset, offset_param_cases, offset_param_desc); +KUNIT_ARRAY_PARAM(long_offset, long_offset_param_cases, offset_param_desc); static const struct bin_test_param alg_param_cases[] = { - { .alg_idx = 0 }, - { .alg_idx = 1 }, - { .alg_idx = 2 }, - { .alg_idx = 3 }, + { .alg_idx = 0, WMDR_PATCH_SHORT }, + { .alg_idx = 1, WMDR_PATCH_SHORT }, + { .alg_idx = 2, WMDR_PATCH_SHORT }, + { .alg_idx = 3, WMDR_PATCH_SHORT }, +}; + +static const struct bin_test_param alg_long_param_cases[] = { + { .alg_idx = 0, WMDR_PATCH_LONG }, + { .alg_idx = 1, WMDR_PATCH_LONG }, + { .alg_idx = 2, WMDR_PATCH_LONG }, + { .alg_idx = 3, WMDR_PATCH_LONG }, }; static void alg_param_desc(const struct bin_test_param *param, char *desc) { WARN_ON(param->alg_idx >= ARRAY_SIZE(bin_test_mock_algs)); - snprintf(desc, KUNIT_PARAM_DESC_SIZE, "alg[%u] (%#x)", - param->alg_idx, bin_test_mock_algs[param->alg_idx].id); + snprintf(desc, KUNIT_PARAM_DESC_SIZE, "alg[%u] (%#x) %s", + param->alg_idx, bin_test_mock_algs[param->alg_idx].id, + (param->add_patch == cs_dsp_mock_bin_add_patch_off32) ? "offs32" : ""); } KUNIT_ARRAY_PARAM(alg, alg_param_cases, alg_param_desc); +KUNIT_ARRAY_PARAM(alg_long, alg_long_param_cases, alg_param_desc); static const struct bin_test_param x_or_y_and_alg_param_cases[] = { - { .mem_type = WMFW_ADSP2_XM, .alg_idx = 0 }, - { .mem_type = WMFW_ADSP2_XM, .alg_idx = 1 }, - { .mem_type = WMFW_ADSP2_XM, .alg_idx = 2 }, - { .mem_type = WMFW_ADSP2_XM, .alg_idx = 3 }, - - { .mem_type = WMFW_ADSP2_YM, .alg_idx = 0 }, - { .mem_type = WMFW_ADSP2_YM, .alg_idx = 1 }, - { .mem_type = WMFW_ADSP2_YM, .alg_idx = 2 }, - { .mem_type = WMFW_ADSP2_YM, .alg_idx = 3 }, + { .mem_type = WMFW_ADSP2_XM, .alg_idx = 0, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_XM, .alg_idx = 1, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_XM, .alg_idx = 2, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_XM, .alg_idx = 3, WMDR_PATCH_SHORT }, + + { .mem_type = WMFW_ADSP2_YM, .alg_idx = 0, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_YM, .alg_idx = 1, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_YM, .alg_idx = 2, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_YM, .alg_idx = 3, WMDR_PATCH_SHORT }, +}; + +static const struct bin_test_param x_or_y_and_alg_long_param_cases[] = { + { .mem_type = WMFW_ADSP2_XM, .alg_idx = 0, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .alg_idx = 1, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .alg_idx = 2, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_XM, .alg_idx = 3, WMDR_PATCH_LONG }, + + { .mem_type = WMFW_ADSP2_YM, .alg_idx = 0, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .alg_idx = 1, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .alg_idx = 2, WMDR_PATCH_LONG }, + { .mem_type = WMFW_ADSP2_YM, .alg_idx = 3, WMDR_PATCH_LONG }, }; static void x_or_y_or_z_and_alg_param_desc(const struct bin_test_param *param, char *desc) { WARN_ON(param->alg_idx >= ARRAY_SIZE(bin_test_mock_algs)); - snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s alg[%u] (%#x)", + snprintf(desc, KUNIT_PARAM_DESC_SIZE, "%s alg[%u] (%#x) %s", cs_dsp_mem_region_name(param->mem_type), - param->alg_idx, bin_test_mock_algs[param->alg_idx].id); + param->alg_idx, bin_test_mock_algs[param->alg_idx].id, + (param->add_patch == cs_dsp_mock_bin_add_patch_off32) ? "offs32" : ""); } KUNIT_ARRAY_PARAM(x_or_y_and_alg, x_or_y_and_alg_param_cases, x_or_y_or_z_and_alg_param_desc); +KUNIT_ARRAY_PARAM(x_or_y_and_alg_long, x_or_y_and_alg_long_param_cases, + x_or_y_or_z_and_alg_param_desc); static const struct bin_test_param z_and_alg_param_cases[] = { - { .mem_type = WMFW_ADSP2_ZM, .alg_idx = 0 }, - { .mem_type = WMFW_ADSP2_ZM, .alg_idx = 1 }, - { .mem_type = WMFW_ADSP2_ZM, .alg_idx = 2 }, - { .mem_type = WMFW_ADSP2_ZM, .alg_idx = 3 }, + { .mem_type = WMFW_ADSP2_ZM, .alg_idx = 0, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_ZM, .alg_idx = 1, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_ZM, .alg_idx = 2, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_ADSP2_ZM, .alg_idx = 3, WMDR_PATCH_SHORT }, }; KUNIT_ARRAY_PARAM(z_and_alg, z_and_alg_param_cases, x_or_y_or_z_and_alg_param_desc); static const struct bin_test_param packed_x_or_y_and_alg_param_cases[] = { - { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 0 }, - { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 1 }, - { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 2 }, - { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 3 }, - - { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 0 }, - { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 1 }, - { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 2 }, - { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 3 }, + { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 0, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 1, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 2, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 3, WMDR_PATCH_SHORT }, + + { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 0, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 1, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 2, WMDR_PATCH_SHORT }, + { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 3, WMDR_PATCH_SHORT }, +}; + +static const struct bin_test_param packed_x_or_y_and_alg_long_param_cases[] = { + { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 0, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 1, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 2, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_XM_PACKED, .alg_idx = 3, WMDR_PATCH_LONG }, + + { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 0, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 1, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 2, WMDR_PATCH_LONG }, + { .mem_type = WMFW_HALO_YM_PACKED, .alg_idx = 3, WMDR_PATCH_LONG }, }; KUNIT_ARRAY_PARAM(packed_x_or_y_and_alg, packed_x_or_y_and_alg_param_cases, x_or_y_or_z_and_alg_param_desc); +KUNIT_ARRAY_PARAM(packed_x_or_y_and_alg_long, packed_x_or_y_and_alg_long_param_cases, + x_or_y_or_z_and_alg_param_desc); + static struct kunit_case cs_dsp_bin_test_cases_halo[] = { /* Unpacked memory */ KUNIT_CASE_PARAM(bin_patch_one_word, x_or_y_and_offset_gen_params), @@ -2505,6 +2703,111 @@ static struct kunit_case cs_dsp_bin_test_cases_halo[] = { { } /* terminator */ }; +static struct kunit_case cs_dsp_bin_test_cases_halo_wmdr3[] = { + /* Unpacked memory */ + KUNIT_CASE_PARAM(bin_patch_one_word, x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_one_multiword, x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_multi_oneword, x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_multi_oneword_unordered, x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_one_word_multiple_mems, offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_one_word_multiple_mems, alg_gen_params), + KUNIT_CASE_PARAM(bin_patch_multi_oneword_sparse_unordered, x_or_y_and_alg_gen_params), + KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs, x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs_unordered, x_or_y_and_offset_gen_params), + + /* Packed memory tests */ + KUNIT_CASE_PARAM(bin_patch_1_packed, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_1_single_trailing, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_2_single_trailing, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_3_single_trailing, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_2_trailing, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_3_trailing, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_single_leading_1_packed, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_2_single_leading_1_packed, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_2_leading_1_packed, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_3_single_leading_1_packed, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_3_leading_1_packed, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_multi_onepacked, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_multi_onepacked_unordered, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_mems, offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_mems, alg_gen_params), + KUNIT_CASE_PARAM(bin_patch_multi_onepacked_sparse_unordered, + packed_x_or_y_and_alg_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_algs, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_algs_unordered, + packed_x_or_y_and_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_mixed_packed_unpacked_random, + packed_x_or_y_gen_params), + + /* Unpacked memory with long-offset blocks */ + KUNIT_CASE_PARAM(bin_patch_one_word, x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_one_multiword, x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_multi_oneword, x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_multi_oneword_unordered, x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_one_word_multiple_mems, long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_one_word_multiple_mems, alg_long_gen_params), + KUNIT_CASE_PARAM(bin_patch_multi_oneword_sparse_unordered, x_or_y_and_alg_long_gen_params), + KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs, x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_one_word_multiple_algs_unordered, + x_or_y_and_long_offset_gen_params), + + /* Packed memory tests with long offset blocks */ + KUNIT_CASE_PARAM(bin_patch_1_packed, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_1_single_trailing, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_2_single_trailing, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_3_single_trailing, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_2_trailing, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_3_trailing, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_single_leading_1_packed, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_2_single_leading_1_packed, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_2_leading_1_packed, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_3_single_leading_1_packed, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_3_leading_1_packed, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_multi_onepacked, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_multi_onepacked_unordered, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_mems, long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_mems, alg_long_gen_params), + KUNIT_CASE_PARAM(bin_patch_multi_onepacked_sparse_unordered, + packed_x_or_y_and_alg_long_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_algs, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_1_packed_multiple_algs_unordered, + packed_x_or_y_and_long_offset_gen_params), + KUNIT_CASE_PARAM(bin_patch_mixed_packed_unpacked_random, + packed_x_or_y_long_gen_params), + + KUNIT_CASE(bin_patch_name_and_info), + + { } /* terminator */ +}; + static struct kunit_case cs_dsp_bin_test_cases_adsp2[] = { /* XM and YM */ KUNIT_CASE_PARAM(bin_patch_one_word, x_or_y_and_offset_gen_params), @@ -2537,20 +2840,31 @@ static struct kunit_suite cs_dsp_bin_test_halo = { .name = "cs_dsp_bin_halo", .init = cs_dsp_bin_test_halo_init, .test_cases = cs_dsp_bin_test_cases_halo, + .attr.speed = KUNIT_SPEED_SLOW, +}; + +static struct kunit_suite cs_dsp_bin_test_halo_wmdr3 = { + .name = "cs_dsp_bin_halo_wmdr_v3", + .init = cs_dsp_bin_test_halo_wmdr3_init, + .test_cases = cs_dsp_bin_test_cases_halo_wmdr3, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_bin_test_adsp2_32bit = { .name = "cs_dsp_bin_adsp2_32bit", .init = cs_dsp_bin_test_adsp2_32bit_init, .test_cases = cs_dsp_bin_test_cases_adsp2, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_bin_test_adsp2_16bit = { .name = "cs_dsp_bin_adsp2_16bit", .init = cs_dsp_bin_test_adsp2_16bit_init, .test_cases = cs_dsp_bin_test_cases_adsp2, + .attr.speed = KUNIT_SPEED_SLOW, }; kunit_test_suites(&cs_dsp_bin_test_halo, + &cs_dsp_bin_test_halo_wmdr3, &cs_dsp_bin_test_adsp2_32bit, &cs_dsp_bin_test_adsp2_16bit); diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c b/drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c index 5dcf62f19faf..f879c5467c98 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_bin_error.c @@ -8,6 +8,7 @@ #include <kunit/device.h> #include <kunit/resource.h> +#include <kunit/static_stub.h> #include <kunit/test.h> #include <linux/build_bug.h> #include <linux/firmware/cirrus/cs_dsp.h> @@ -18,6 +19,8 @@ #include <linux/string.h> #include <linux/vmalloc.h> +#include "../cs_dsp.h" + KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *); KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *); @@ -66,24 +69,24 @@ static void bin_load_with_unknown_blocks(struct kunit *test) cs_dsp_mock_bin_add_raw_block(local->bin_builder, cs_dsp_bin_err_test_mock_algs[0].id, cs_dsp_bin_err_test_mock_algs[0].ver, - 0xf5, 0, + 0xf5, 0, 0, random_data, sizeof(random_data)); cs_dsp_mock_bin_add_raw_block(local->bin_builder, cs_dsp_bin_err_test_mock_algs[0].id, cs_dsp_bin_err_test_mock_algs[0].ver, - 0xf500, 0, + 0xf500, 0, 0, random_data, sizeof(random_data)); cs_dsp_mock_bin_add_raw_block(local->bin_builder, cs_dsp_bin_err_test_mock_algs[0].id, cs_dsp_bin_err_test_mock_algs[0].ver, - 0xc300, 0, + 0xc300, 0, 0, random_data, sizeof(random_data)); /* Add a single payload to be written to DSP memory */ cs_dsp_mock_bin_add_raw_block(local->bin_builder, cs_dsp_bin_err_test_mock_algs[0].id, cs_dsp_bin_err_test_mock_algs[0].ver, - WMFW_ADSP2_YM, 0, + WMFW_ADSP2_YM, 0, 0, payload_data, payload_size_bytes); bin = cs_dsp_mock_bin_get_firmware(local->bin_builder); @@ -277,7 +280,7 @@ static void bin_too_short_for_block_header(struct kunit *test) cs_dsp_mock_bin_add_raw_block(local->bin_builder, cs_dsp_bin_err_test_mock_algs[0].id, cs_dsp_bin_err_test_mock_algs[0].ver, - param->block_type, 0, + param->block_type, 0, 0, NULL, 0); bin = cs_dsp_mock_bin_get_firmware(local->bin_builder); @@ -309,7 +312,7 @@ static void bin_too_short_for_block_payload(struct kunit *test) cs_dsp_mock_bin_add_raw_block(local->bin_builder, cs_dsp_bin_err_test_mock_algs[0].id, cs_dsp_bin_err_test_mock_algs[0].ver, - param->block_type, 0, + param->block_type, 0, 0, payload, sizeof(payload)); bin = cs_dsp_mock_bin_get_firmware(local->bin_builder); @@ -341,7 +344,7 @@ static void bin_block_payload_len_garbage(struct kunit *test) cs_dsp_mock_bin_add_raw_block(local->bin_builder, cs_dsp_bin_err_test_mock_algs[0].id, cs_dsp_bin_err_test_mock_algs[0].ver, - param->block_type, 0, + param->block_type, 0, 0, &payload, sizeof(payload)); bin = cs_dsp_mock_bin_get_firmware(local->bin_builder); @@ -378,13 +381,13 @@ static void bin_block_payload_len_garbage(struct kunit *test) 0); } -static void cs_dsp_bin_err_test_exit(struct kunit *test) +static bool cs_dsp_bin_err_test_can_emit_message_hook(void) { - /* - * Testing error conditions can produce a lot of log output - * from cs_dsp error messages, so rate limit the test cases. - */ - usleep_range(200, 500); +#if defined(DEBUG) + return true; +#else + return false; +#endif } static int cs_dsp_bin_err_test_common_init(struct kunit *test, struct cs_dsp *dsp, @@ -451,7 +454,7 @@ static int cs_dsp_bin_err_test_common_init(struct kunit *test, struct cs_dsp *ds local->bin_builder = cs_dsp_mock_bin_init(priv, 1, - cs_dsp_mock_xm_header_get_fw_version_from_regmap(priv)); + cs_dsp_mock_xm_header_get_fw_version(local->xm_header)); KUNIT_ASSERT_NOT_ERR_OR_NULL(test, local->bin_builder); /* Init cs_dsp */ @@ -474,7 +477,18 @@ static int cs_dsp_bin_err_test_common_init(struct kunit *test, struct cs_dsp *ds return ret; /* Automatically call cs_dsp_remove() when test case ends */ - return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); + ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); + if (ret) + return ret; + + /* + * Testing error conditions can produce a lot of log output + * from cs_dsp error messages, so suppress messages. + */ + kunit_activate_static_stub(test, cs_dsp_can_emit_message, + cs_dsp_bin_err_test_can_emit_message_hook); + + return 0; } static int cs_dsp_bin_err_test_halo_init(struct kunit *test) @@ -534,11 +548,6 @@ static int cs_dsp_bin_err_test_adsp2_16bit_init(struct kunit *test) return cs_dsp_bin_err_test_common_init(test, dsp, 1); } -static struct kunit_case cs_dsp_bin_err_test_cases_halo[] = { - - { } /* terminator */ -}; - static void cs_dsp_bin_err_block_types_desc(const struct cs_dsp_bin_test_param *param, char *desc) { @@ -560,7 +569,7 @@ KUNIT_ARRAY_PARAM(bin_test_block_types, bin_test_block_types_cases, cs_dsp_bin_err_block_types_desc); -static struct kunit_case cs_dsp_bin_err_test_cases_adsp2[] = { +static struct kunit_case cs_dsp_bin_err_test_cases[] = { KUNIT_CASE(bin_load_with_unknown_blocks), KUNIT_CASE(bin_err_wrong_magic), KUNIT_CASE(bin_err_too_short_for_header), @@ -577,22 +586,22 @@ static struct kunit_case cs_dsp_bin_err_test_cases_adsp2[] = { static struct kunit_suite cs_dsp_bin_err_test_halo = { .name = "cs_dsp_bin_err_halo", .init = cs_dsp_bin_err_test_halo_init, - .exit = cs_dsp_bin_err_test_exit, - .test_cases = cs_dsp_bin_err_test_cases_halo, + .test_cases = cs_dsp_bin_err_test_cases, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_bin_err_test_adsp2_32bit = { .name = "cs_dsp_bin_err_adsp2_32bit", .init = cs_dsp_bin_err_test_adsp2_32bit_init, - .exit = cs_dsp_bin_err_test_exit, - .test_cases = cs_dsp_bin_err_test_cases_adsp2, + .test_cases = cs_dsp_bin_err_test_cases, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_bin_err_test_adsp2_16bit = { .name = "cs_dsp_bin_err_adsp2_16bit", .init = cs_dsp_bin_err_test_adsp2_16bit_init, - .exit = cs_dsp_bin_err_test_exit, - .test_cases = cs_dsp_bin_err_test_cases_adsp2, + .test_cases = cs_dsp_bin_err_test_cases, + .attr.speed = KUNIT_SPEED_SLOW, }; kunit_test_suites(&cs_dsp_bin_err_test_halo, diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c b/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c index 8a9b66a3b7d3..e5a389808e5f 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_callbacks.c @@ -600,6 +600,7 @@ KUNIT_ARRAY_PARAM(cs_dsp_callbacks_ops, static const struct cs_dsp_callbacks_test_param cs_dsp_no_callbacks_cases[] = { { .ops = &cs_dsp_callback_test_empty_client_ops, .case_name = "empty ops" }, + { .ops = NULL, .case_name = "NULL ops" }, }; KUNIT_ARRAY_PARAM(cs_dsp_no_callbacks, diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_control_cache.c b/drivers/firmware/cirrus/test/cs_dsp_test_control_cache.c index 83386cc978e3..b03cd7c37f6e 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_control_cache.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_control_cache.c @@ -776,7 +776,6 @@ static void cs_dsp_ctl_cache_init_multiple_offsets(struct kunit *test) "dummyalg", NULL); /* Create controls identical except for offset */ - def.length_bytes = 8; def.offset_dsp_words = 0; def.shortname = "CtlA"; cs_dsp_mock_wmfw_add_coeff_desc(local->wmfw_builder, &def); @@ -3249,30 +3248,35 @@ static struct kunit_suite cs_dsp_ctl_cache_test_halo = { .name = "cs_dsp_ctl_cache_wmfwV3_halo", .init = cs_dsp_ctl_cache_test_halo_init, .test_cases = cs_dsp_ctl_cache_test_cases_v3, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1 = { .name = "cs_dsp_ctl_cache_wmfwV1_adsp2_32bit", .init = cs_dsp_ctl_cache_test_adsp2_32bit_wmfw1_init, .test_cases = cs_dsp_ctl_cache_test_cases_v1, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2 = { .name = "cs_dsp_ctl_cache_wmfwV2_adsp2_32bit", .init = cs_dsp_ctl_cache_test_adsp2_32bit_wmfw2_init, .test_cases = cs_dsp_ctl_cache_test_cases_v2, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1 = { .name = "cs_dsp_ctl_cache_wmfwV1_adsp2_16bit", .init = cs_dsp_ctl_cache_test_adsp2_16bit_wmfw1_init, .test_cases = cs_dsp_ctl_cache_test_cases_v1, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2 = { .name = "cs_dsp_ctl_cache_wmfwV2_adsp2_16bit", .init = cs_dsp_ctl_cache_test_adsp2_16bit_wmfw2_init, .test_cases = cs_dsp_ctl_cache_test_cases_v2, + .attr.speed = KUNIT_SPEED_SLOW, }; kunit_test_suites(&cs_dsp_ctl_cache_test_halo, diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_control_parse.c b/drivers/firmware/cirrus/test/cs_dsp_test_control_parse.c index cb90964740ea..368703767644 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_control_parse.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_control_parse.c @@ -73,6 +73,18 @@ static const struct cs_dsp_mock_coeff_def mock_coeff_template = { .length_bytes = 4, }; +static char *cs_dsp_ctl_alloc_test_string(struct kunit *test, char c, size_t len) +{ + char *str; + + str = kunit_kmalloc(test, len + 1, GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, str); + memset(str, c, len); + str[len] = '\0'; + + return str; +} + /* Algorithm info block without controls should load */ static void cs_dsp_ctl_parse_no_coeffs(struct kunit *test) { @@ -160,12 +172,8 @@ static void cs_dsp_ctl_parse_max_v1_name(struct kunit *test) struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw; - char *name; - name = kunit_kzalloc(test, 256, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, name); - memset(name, 'A', 255); - def.fullname = name; + def.fullname = cs_dsp_ctl_alloc_test_string(test, 'A', 255); cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, cs_dsp_ctl_parse_test_algs[0].id, @@ -252,14 +260,9 @@ static void cs_dsp_ctl_parse_max_short_name(struct kunit *test) struct cs_dsp_test_local *local = priv->local; struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; - char *name; struct firmware *wmfw; - name = kunit_kmalloc(test, 255, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, name); - memset(name, 'A', 255); - - def.shortname = name; + def.shortname = cs_dsp_ctl_alloc_test_string(test, 'A', 255); cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, cs_dsp_ctl_parse_test_algs[0].id, @@ -273,7 +276,7 @@ static void cs_dsp_ctl_parse_max_short_name(struct kunit *test) ctl = list_first_entry_or_null(&priv->dsp->ctl_list, struct cs_dsp_coeff_ctl, list); KUNIT_ASSERT_NOT_NULL(test, ctl); KUNIT_EXPECT_EQ(test, ctl->subname_len, 255); - KUNIT_EXPECT_MEMEQ(test, ctl->subname, name, ctl->subname_len); + KUNIT_EXPECT_MEMEQ(test, ctl->subname, def.shortname, ctl->subname_len); KUNIT_EXPECT_EQ(test, ctl->flags, def.flags); KUNIT_EXPECT_EQ(test, ctl->type, def.type); KUNIT_EXPECT_EQ(test, ctl->len, def.length_bytes); @@ -323,12 +326,8 @@ static void cs_dsp_ctl_parse_with_max_fullname(struct kunit *test) struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw; - char *fullname; - fullname = kunit_kmalloc(test, 255, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fullname); - memset(fullname, 'A', 255); - def.fullname = fullname; + def.fullname = cs_dsp_ctl_alloc_test_string(test, 'A', 255); cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, cs_dsp_ctl_parse_test_algs[0].id, @@ -392,12 +391,8 @@ static void cs_dsp_ctl_parse_with_max_description(struct kunit *test) struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw; - char *description; - description = kunit_kmalloc(test, 65535, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, description); - memset(description, 'A', 65535); - def.description = description; + def.description = cs_dsp_ctl_alloc_test_string(test, 'A', 65535); cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, cs_dsp_ctl_parse_test_algs[0].id, @@ -429,17 +424,9 @@ static void cs_dsp_ctl_parse_with_max_fullname_and_description(struct kunit *tes struct cs_dsp_mock_coeff_def def = mock_coeff_template; struct cs_dsp_coeff_ctl *ctl; struct firmware *wmfw; - char *fullname, *description; - - fullname = kunit_kmalloc(test, 255, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fullname); - memset(fullname, 'A', 255); - def.fullname = fullname; - description = kunit_kmalloc(test, 65535, GFP_KERNEL); - KUNIT_ASSERT_NOT_ERR_OR_NULL(test, description); - memset(description, 'A', 65535); - def.description = description; + def.fullname = cs_dsp_ctl_alloc_test_string(test, 'A', 255); + def.description = cs_dsp_ctl_alloc_test_string(test, 'A', 65535); cs_dsp_mock_wmfw_start_alg_info_block(local->wmfw_builder, cs_dsp_ctl_parse_test_algs[0].id, @@ -1818,30 +1805,35 @@ static struct kunit_suite cs_dsp_ctl_parse_test_halo = { .name = "cs_dsp_ctl_parse_wmfwV3_halo", .init = cs_dsp_ctl_parse_test_halo_init, .test_cases = cs_dsp_ctl_parse_test_cases_v2_v3, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_ctl_parse_test_adsp2_32bit_wmfw1 = { .name = "cs_dsp_ctl_parse_wmfwV1_adsp2_32bit", .init = cs_dsp_ctl_parse_test_adsp2_32bit_wmfw1_init, .test_cases = cs_dsp_ctl_parse_test_cases_v1, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_ctl_parse_test_adsp2_32bit_wmfw2 = { .name = "cs_dsp_ctl_parse_wmfwV2_adsp2_32bit", .init = cs_dsp_ctl_parse_test_adsp2_32bit_wmfw2_init, .test_cases = cs_dsp_ctl_parse_test_cases_v2_v3, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_ctl_parse_test_adsp2_16bit_wmfw1 = { .name = "cs_dsp_ctl_parse_wmfwV1_adsp2_16bit", .init = cs_dsp_ctl_parse_test_adsp2_16bit_wmfw1_init, .test_cases = cs_dsp_ctl_parse_test_cases_v1, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_ctl_parse_test_adsp2_16bit_wmfw2 = { .name = "cs_dsp_ctl_parse_wmfwV2_adsp2_16bit", .init = cs_dsp_ctl_parse_test_adsp2_16bit_wmfw2_init, .test_cases = cs_dsp_ctl_parse_test_cases_v2_v3, + .attr.speed = KUNIT_SPEED_SLOW, }; kunit_test_suites(&cs_dsp_ctl_parse_test_halo, diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_control_rw.c b/drivers/firmware/cirrus/test/cs_dsp_test_control_rw.c index bda00a95d4f9..d800f163b099 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_control_rw.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_control_rw.c @@ -2636,30 +2636,35 @@ static struct kunit_suite cs_dsp_ctl_rw_test_halo = { .name = "cs_dsp_ctl_rw_wmfwV3_halo", .init = cs_dsp_ctl_rw_test_halo_init, .test_cases = cs_dsp_ctl_rw_test_cases_halo, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_ctl_rw_test_adsp2_32bit_wmfw1 = { .name = "cs_dsp_ctl_rw_wmfwV1_adsp2_32bit", .init = cs_dsp_ctl_rw_test_adsp2_32bit_wmfw1_init, .test_cases = cs_dsp_ctl_rw_test_cases_adsp, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_ctl_rw_test_adsp2_32bit_wmfw2 = { .name = "cs_dsp_ctl_rw_wmfwV2_adsp2_32bit", .init = cs_dsp_ctl_rw_test_adsp2_32bit_wmfw2_init, .test_cases = cs_dsp_ctl_rw_test_cases_adsp, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_ctl_rw_test_adsp2_16bit_wmfw1 = { .name = "cs_dsp_ctl_rw_wmfwV1_adsp2_16bit", .init = cs_dsp_ctl_rw_test_adsp2_16bit_wmfw1_init, .test_cases = cs_dsp_ctl_rw_test_cases_adsp, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_ctl_rw_test_adsp2_16bit_wmfw2 = { .name = "cs_dsp_ctl_rw_wmfwV2_adsp2_16bit", .init = cs_dsp_ctl_rw_test_adsp2_16bit_wmfw2_init, .test_cases = cs_dsp_ctl_rw_test_cases_adsp, + .attr.speed = KUNIT_SPEED_SLOW, }; kunit_test_suites(&cs_dsp_ctl_rw_test_halo, diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c b/drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c index 9e997c4ee2d6..1de70e81a868 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_wmfw.c @@ -8,6 +8,7 @@ #include <kunit/device.h> #include <kunit/resource.h> +#include <kunit/static_stub.h> #include <kunit/test.h> #include <linux/build_bug.h> #include <linux/firmware/cirrus/cs_dsp.h> @@ -18,6 +19,8 @@ #include <linux/string.h> #include <linux/vmalloc.h> +#include "../cs_dsp.h" + /* * Test method is: * @@ -1773,6 +1776,15 @@ static void wmfw_load_with_info(struct kunit *test) KUNIT_EXPECT_MEMEQ(test, readback, payload_data, payload_size_bytes); } +static bool cs_dsp_wmfw_test_can_emit_message_hook(void) +{ +#if defined(DEBUG) + return true; +#else + return false; +#endif +} + static int cs_dsp_wmfw_test_common_init(struct kunit *test, struct cs_dsp *dsp, int wmfw_version) { @@ -1853,7 +1865,18 @@ static int cs_dsp_wmfw_test_common_init(struct kunit *test, struct cs_dsp *dsp, return ret; /* Automatically call cs_dsp_remove() when test case ends */ - return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); + ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); + if (ret) + return ret; + + /* + * The large number of test cases will cause an unusually large amount + * of dev_info() messages from cs_dsp, so suppress these. + */ + kunit_activate_static_stub(test, cs_dsp_can_emit_message, + cs_dsp_wmfw_test_can_emit_message_hook); + + return 0; } static int cs_dsp_wmfw_test_halo_init(struct kunit *test) @@ -2164,42 +2187,49 @@ static struct kunit_suite cs_dsp_wmfw_test_halo = { .name = "cs_dsp_wmfwV3_halo", .init = cs_dsp_wmfw_test_halo_init, .test_cases = cs_dsp_wmfw_test_cases_halo, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw0 = { .name = "cs_dsp_wmfwV0_adsp2_32bit", .init = cs_dsp_wmfw_test_adsp2_32bit_wmfw0_init, .test_cases = cs_dsp_wmfw_test_cases_adsp2, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw1 = { .name = "cs_dsp_wmfwV1_adsp2_32bit", .init = cs_dsp_wmfw_test_adsp2_32bit_wmfw1_init, .test_cases = cs_dsp_wmfw_test_cases_adsp2, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_wmfw_test_adsp2_32bit_wmfw2 = { .name = "cs_dsp_wmfwV2_adsp2_32bit", .init = cs_dsp_wmfw_test_adsp2_32bit_wmfw2_init, .test_cases = cs_dsp_wmfw_test_cases_adsp2, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw0 = { .name = "cs_dsp_wmfwV0_adsp2_16bit", .init = cs_dsp_wmfw_test_adsp2_16bit_wmfw0_init, .test_cases = cs_dsp_wmfw_test_cases_adsp2, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw1 = { .name = "cs_dsp_wmfwV1_adsp2_16bit", .init = cs_dsp_wmfw_test_adsp2_16bit_wmfw1_init, .test_cases = cs_dsp_wmfw_test_cases_adsp2, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_wmfw_test_adsp2_16bit_wmfw2 = { .name = "cs_dsp_wmfwV2_adsp2_16bit", .init = cs_dsp_wmfw_test_adsp2_16bit_wmfw2_init, .test_cases = cs_dsp_wmfw_test_cases_adsp2, + .attr.speed = KUNIT_SPEED_SLOW, }; kunit_test_suites(&cs_dsp_wmfw_test_halo, diff --git a/drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c b/drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c index c309843261d7..e7bf5dc474f5 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c +++ b/drivers/firmware/cirrus/test/cs_dsp_test_wmfw_error.c @@ -8,6 +8,7 @@ #include <kunit/device.h> #include <kunit/resource.h> +#include <kunit/static_stub.h> #include <kunit/test.h> #include <linux/build_bug.h> #include <linux/firmware/cirrus/cs_dsp.h> @@ -18,6 +19,8 @@ #include <linux/string.h> #include <linux/vmalloc.h> +#include "../cs_dsp.h" + KUNIT_DEFINE_ACTION_WRAPPER(_put_device_wrapper, put_device, struct device *); KUNIT_DEFINE_ACTION_WRAPPER(_cs_dsp_remove_wrapper, cs_dsp_remove, struct cs_dsp *); @@ -987,13 +990,13 @@ static void wmfw_v2_coeff_description_exceeds_block(struct kunit *test) -EOVERFLOW); } -static void cs_dsp_wmfw_err_test_exit(struct kunit *test) +static bool cs_dsp_wmfw_err_test_can_emit_message_hook(void) { - /* - * Testing error conditions can produce a lot of log output - * from cs_dsp error messages, so rate limit the test cases. - */ - usleep_range(200, 500); +#if defined(DEBUG) + return true; +#else + return false; +#endif } static int cs_dsp_wmfw_err_test_common_init(struct kunit *test, struct cs_dsp *dsp, @@ -1072,7 +1075,18 @@ static int cs_dsp_wmfw_err_test_common_init(struct kunit *test, struct cs_dsp *d return ret; /* Automatically call cs_dsp_remove() when test case ends */ - return kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); + ret = kunit_add_action_or_reset(priv->test, _cs_dsp_remove_wrapper, dsp); + if (ret) + return ret; + + /* + * Testing error conditions can produce a lot of log output + * from cs_dsp error messages, so suppress messages. + */ + kunit_activate_static_stub(test, cs_dsp_can_emit_message, + cs_dsp_wmfw_err_test_can_emit_message_hook); + + return 0; } static int cs_dsp_wmfw_err_test_halo_init(struct kunit *test) @@ -1292,50 +1306,50 @@ static struct kunit_case cs_dsp_wmfw_err_test_cases_v3[] = { static struct kunit_suite cs_dsp_wmfw_err_test_halo = { .name = "cs_dsp_wmfwV3_err_halo", .init = cs_dsp_wmfw_err_test_halo_init, - .exit = cs_dsp_wmfw_err_test_exit, .test_cases = cs_dsp_wmfw_err_test_cases_v3, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_wmfw_err_test_adsp2_32bit_wmfw0 = { .name = "cs_dsp_wmfwV0_err_adsp2_32bit", .init = cs_dsp_wmfw_err_test_adsp2_32bit_wmfw0_init, - .exit = cs_dsp_wmfw_err_test_exit, .test_cases = cs_dsp_wmfw_err_test_cases_v0, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_wmfw_err_test_adsp2_32bit_wmfw1 = { .name = "cs_dsp_wmfwV1_err_adsp2_32bit", .init = cs_dsp_wmfw_err_test_adsp2_32bit_wmfw1_init, - .exit = cs_dsp_wmfw_err_test_exit, .test_cases = cs_dsp_wmfw_err_test_cases_v1, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_wmfw_err_test_adsp2_32bit_wmfw2 = { .name = "cs_dsp_wmfwV2_err_adsp2_32bit", .init = cs_dsp_wmfw_err_test_adsp2_32bit_wmfw2_init, - .exit = cs_dsp_wmfw_err_test_exit, .test_cases = cs_dsp_wmfw_err_test_cases_v2, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_wmfw_err_test_adsp2_16bit_wmfw0 = { .name = "cs_dsp_wmfwV0_err_adsp2_16bit", .init = cs_dsp_wmfw_err_test_adsp2_16bit_wmfw0_init, - .exit = cs_dsp_wmfw_err_test_exit, .test_cases = cs_dsp_wmfw_err_test_cases_v0, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_wmfw_err_test_adsp2_16bit_wmfw1 = { .name = "cs_dsp_wmfwV1_err_adsp2_16bit", .init = cs_dsp_wmfw_err_test_adsp2_16bit_wmfw1_init, - .exit = cs_dsp_wmfw_err_test_exit, .test_cases = cs_dsp_wmfw_err_test_cases_v1, + .attr.speed = KUNIT_SPEED_SLOW, }; static struct kunit_suite cs_dsp_wmfw_err_test_adsp2_16bit_wmfw2 = { .name = "cs_dsp_wmfwV2_err_adsp2_16bit", .init = cs_dsp_wmfw_err_test_adsp2_16bit_wmfw2_init, - .exit = cs_dsp_wmfw_err_test_exit, .test_cases = cs_dsp_wmfw_err_test_cases_v2, + .attr.speed = KUNIT_SPEED_SLOW, }; kunit_test_suites(&cs_dsp_wmfw_err_test_halo, diff --git a/drivers/firmware/cirrus/test/cs_dsp_tests.c b/drivers/firmware/cirrus/test/cs_dsp_tests.c index 7b829a03ca52..288675fdbdc5 100644 --- a/drivers/firmware/cirrus/test/cs_dsp_tests.c +++ b/drivers/firmware/cirrus/test/cs_dsp_tests.c @@ -12,3 +12,4 @@ MODULE_AUTHOR("Richard Fitzgerald <rf@opensource.cirrus.com>"); MODULE_LICENSE("GPL"); MODULE_IMPORT_NS("FW_CS_DSP"); MODULE_IMPORT_NS("FW_CS_DSP_KUNIT_TEST_UTILS"); +MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING"); |
