Lines Matching refs:dsp

47 	adsp_err(_obj->dsp, "%s: " fmt, _obj->name ? _obj->name : "legacy", \
50 adsp_dbg(_obj->dsp, "%s: " fmt, _obj->name ? _obj->name : "legacy", \
441 struct wm_adsp *dsp;
458 struct wm_adsp *dsp;
492 static int wm_adsp_buffer_init(struct wm_adsp *dsp);
493 static int wm_adsp_buffer_free(struct wm_adsp *dsp);
613 struct wm_adsp *dsp;
650 static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s)
654 kfree(dsp->wmfw_file_name);
655 dsp->wmfw_file_name = tmp;
658 static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s)
662 kfree(dsp->bin_file_name);
663 dsp->bin_file_name = tmp;
666 static void wm_adsp_debugfs_clear(struct wm_adsp *dsp)
668 kfree(dsp->wmfw_file_name);
669 kfree(dsp->bin_file_name);
670 dsp->wmfw_file_name = NULL;
671 dsp->bin_file_name = NULL;
678 struct wm_adsp *dsp = file->private_data;
681 mutex_lock(&dsp->pwr_lock);
683 if (!dsp->wmfw_file_name || !dsp->booted)
687 dsp->wmfw_file_name,
688 strlen(dsp->wmfw_file_name));
690 mutex_unlock(&dsp->pwr_lock);
698 struct wm_adsp *dsp = file->private_data;
701 mutex_lock(&dsp->pwr_lock);
703 if (!dsp->bin_file_name || !dsp->booted)
707 dsp->bin_file_name,
708 strlen(dsp->bin_file_name));
710 mutex_unlock(&dsp->pwr_lock);
734 static void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
740 root = debugfs_create_dir(dsp->name, component->debugfs_root);
742 debugfs_create_bool("booted", 0444, root, &dsp->booted);
743 debugfs_create_bool("running", 0444, root, &dsp->running);
744 debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id);
745 debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version);
749 dsp, &wm_adsp_debugfs_fops[i].fops);
751 dsp->debugfs_root = root;
754 static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp)
756 wm_adsp_debugfs_clear(dsp);
757 debugfs_remove_recursive(dsp->debugfs_root);
760 static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp,
765 static inline void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp)
769 static inline void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp,
774 static inline void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp,
779 static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp)
789 struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
791 ucontrol->value.enumerated.item[0] = dsp[e->shift_l].fw;
802 struct wm_adsp *dsp = snd_soc_component_get_drvdata(component);
805 if (ucontrol->value.enumerated.item[0] == dsp[e->shift_l].fw)
811 mutex_lock(&dsp[e->shift_l].pwr_lock);
813 if (dsp[e->shift_l].booted || !list_empty(&dsp[e->shift_l].compr_list))
816 dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0];
818 mutex_unlock(&dsp[e->shift_l].pwr_lock);
835 static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp,
840 for (i = 0; i < dsp->num_mems; i++)
841 if (dsp->mem[i].type == type)
842 return &dsp->mem[i];
882 static void wm_adsp_read_fw_status(struct wm_adsp *dsp,
889 ret = regmap_read(dsp->regmap, dsp->base + offs[i], &offs[i]);
891 adsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret);
897 static void wm_adsp2_show_fw_status(struct wm_adsp *dsp)
903 wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs);
905 adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
909 static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp)
913 wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs);
915 adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
920 static void wm_halo_show_fw_status(struct wm_adsp *dsp)
926 wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs);
928 adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
940 struct wm_adsp *dsp = ctl->dsp;
943 mem = wm_adsp_find_region(dsp, alg_region->type);
945 adsp_err(dsp, "No base for region %x\n",
950 *reg = dsp->ops->region_to_reg(mem, ctl->alg_region.base + ctl->offset);
982 struct wm_adsp *dsp = ctl->dsp;
991 adsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n",
995 ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val));
997 adsp_err(dsp, "Failed to write %x: %d\n", reg, ret);
1019 ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val));
1021 adsp_err(dsp, "Failed to read %x: %d\n", reg, ret);
1026 adsp_dbg(dsp, "Acked control ACKED at poll %u\n", i);
1031 adsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n",
1042 struct wm_adsp *dsp = ctl->dsp;
1055 ret = regmap_raw_write(dsp->regmap, reg, scratch,
1058 adsp_err(dsp, "Failed to write %zu bytes to %x: %d\n",
1063 adsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg);
1081 if (ctl->enabled && ctl->dsp->running)
1096 mutex_lock(&ctl->dsp->pwr_lock);
1098 mutex_unlock(&ctl->dsp->pwr_lock);
1111 mutex_lock(&ctl->dsp->pwr_lock);
1118 mutex_unlock(&ctl->dsp->pwr_lock);
1135 mutex_lock(&ctl->dsp->pwr_lock);
1137 if (ctl->enabled && ctl->dsp->running)
1142 mutex_unlock(&ctl->dsp->pwr_lock);
1150 struct wm_adsp *dsp = ctl->dsp;
1163 ret = regmap_raw_read(dsp->regmap, reg, scratch, len);
1165 adsp_err(dsp, "Failed to read %zu bytes from %x: %d\n",
1170 adsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg);
1183 if (ctl->enabled && ctl->dsp->running)
1188 if (!ctl->flags && ctl->enabled && ctl->dsp->running)
1207 mutex_lock(&ctl->dsp->pwr_lock);
1209 mutex_unlock(&ctl->dsp->pwr_lock);
1222 mutex_lock(&ctl->dsp->pwr_lock);
1229 mutex_unlock(&ctl->dsp->pwr_lock);
1250 struct wm_adsp *dsp;
1286 static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl)
1322 ret = snd_soc_add_component_controls(dsp->component, kcontrol, 1);
1335 static int wm_coeff_init_control_caches(struct wm_adsp *dsp)
1340 list_for_each_entry(ctl, &dsp->ctl_list, list) {
1361 static int wm_coeff_sync_controls(struct wm_adsp *dsp)
1366 list_for_each_entry(ctl, &dsp->ctl_list, list) {
1380 static void wm_adsp_signal_event_controls(struct wm_adsp *dsp,
1386 list_for_each_entry(ctl, &dsp->ctl_list, list) {
1395 adsp_warn(dsp,
1407 wmfw_add_ctl(ctl_work->dsp, ctl_work->ctl);
1419 static int wm_adsp_create_control(struct wm_adsp *dsp,
1433 adsp_err(dsp, "Unknown region type: %d\n", alg_region->type);
1437 switch (dsp->fw_ver) {
1441 dsp->name, region_name, alg_region->alg);
1446 "%s%c %.12s %x", dsp->name, *region_name,
1447 wm_adsp_fw_text[dsp->fw], alg_region->alg);
1451 "%s %.12s %x", dsp->name,
1452 wm_adsp_fw_text[dsp->fw], alg_region->alg);
1460 if (dsp->component->name_prefix)
1461 avail -= strlen(dsp->component->name_prefix) + 1;
1471 list_for_each_entry(ctl, &dsp->ctl_list, list) {
1482 ctl->fw_name = wm_adsp_fw_text[dsp->fw];
1502 ctl->dsp = dsp;
1514 list_add(&ctl->list, &dsp->ctl_list);
1525 ctl_work->dsp = dsp;
1605 static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data,
1610 switch (dsp->fw_ver) {
1630 adsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id);
1631 adsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name);
1632 adsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff);
1635 static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data,
1642 switch (dsp->fw_ver) {
1673 adsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type);
1674 adsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset);
1675 adsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name);
1676 adsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags);
1677 adsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type);
1678 adsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len);
1681 static int wm_adsp_check_coeff_flags(struct wm_adsp *dsp,
1688 adsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n",
1696 static int wm_adsp_parse_coeff(struct wm_adsp *dsp,
1705 wm_coeff_parse_alg(dsp, &data, &alg_blk);
1707 wm_coeff_parse_coeff(dsp, &data, &coeff_blk);
1716 ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk,
1725 ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk,
1735 ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk,
1744 adsp_err(dsp, "Unknown control type: %d\n",
1752 ret = wm_adsp_create_control(dsp, &alg_region,
1760 adsp_err(dsp, "Failed to create control: %.*s, %d\n",
1767 static unsigned int wm_adsp1_parse_sizes(struct wm_adsp *dsp,
1776 adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file,
1783 static unsigned int wm_adsp2_parse_sizes(struct wm_adsp *dsp,
1792 adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file,
1799 static bool wm_adsp_validate_version(struct wm_adsp *dsp, unsigned int version)
1803 adsp_warn(dsp, "Deprecated file format %d\n", version);
1813 static bool wm_halo_validate_version(struct wm_adsp *dsp, unsigned int version)
1823 static int wm_adsp_load(struct wm_adsp *dsp)
1827 struct regmap *regmap = dsp->regmap;
1845 snprintf(file, PAGE_SIZE, "%s-%s-%s.wmfw", dsp->part, dsp->fwf_name,
1846 wm_adsp_fw[dsp->fw].file);
1849 ret = request_firmware(&firmware, file, dsp->dev);
1851 adsp_err(dsp, "Failed to request '%s'\n", file);
1858 adsp_err(dsp, "%s: file too short, %zu bytes\n",
1866 adsp_err(dsp, "%s: invalid magic\n", file);
1870 if (!dsp->ops->validate_version(dsp, header->ver)) {
1871 adsp_err(dsp, "%s: unknown file format %d\n",
1876 adsp_info(dsp, "Firmware version: %d\n", header->ver);
1877 dsp->fw_ver = header->ver;
1879 if (header->core != dsp->type) {
1880 adsp_err(dsp, "%s: invalid core %d != %d\n",
1881 file, header->core, dsp->type);
1886 pos = dsp->ops->parse_sizes(dsp, file, pos, firmware);
1892 adsp_err(dsp, "%s: unexpected header length %d\n",
1897 adsp_dbg(dsp, "%s: timestamp %llu\n", file,
1917 ret = wm_adsp_parse_coeff(dsp, region);
1938 mem = wm_adsp_find_region(dsp, type);
1940 adsp_err(dsp, "No region of type: %x\n", type);
1946 reg = dsp->ops->region_to_reg(mem, offset);
1949 adsp_warn(dsp,
1955 adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file,
1961 adsp_err(dsp,
1971 adsp_info(dsp, "%s: %s\n", file, text);
1981 adsp_err(dsp, "Out of memory\n");
1989 adsp_err(dsp,
2004 adsp_err(dsp, "Failed to complete async write: %d\n", ret);
2009 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
2012 wm_adsp_debugfs_save_wmfwname(dsp, file);
2029 static struct wm_coeff_ctl *wm_adsp_get_ctl(struct wm_adsp *dsp,
2034 const char *fw_txt = wm_adsp_fw_text[dsp->fw];
2036 list_for_each_entry(pos, &dsp->ctl_list, list) {
2052 int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type,
2060 ctl = wm_adsp_get_ctl(dsp, name, type, alg);
2074 if (dsp->component->name_prefix)
2076 dsp->component->name_prefix, ctl->name);
2081 kcontrol = snd_soc_card_get_kcontrol(dsp->component->card, ctl_name);
2083 adsp_err(dsp, "Can't find kcontrol %s\n", ctl_name);
2087 snd_ctl_notify(dsp->component->card->snd_card,
2094 int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type,
2099 ctl = wm_adsp_get_ctl(dsp, name, type, alg);
2110 static void wm_adsp_ctl_fixup_base(struct wm_adsp *dsp,
2115 list_for_each_entry(ctl, &dsp->ctl_list, list) {
2116 if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] &&
2124 static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs,
2134 adsp_err(dsp, "No algorithms\n");
2139 adsp_err(dsp, "Algorithm count %zx excessive\n", n_algs);
2144 reg = dsp->ops->region_to_reg(mem, pos + len);
2146 ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val));
2148 adsp_err(dsp, "Failed to read algorithm list end: %d\n",
2154 adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n",
2164 reg = dsp->ops->region_to_reg(mem, pos);
2166 ret = regmap_raw_read(dsp->regmap, reg, alg, len);
2168 adsp_err(dsp, "Failed to read algorithm list: %d\n", ret);
2177 wm_adsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id)
2181 list_for_each_entry(alg_region, &dsp->alg_regions, list) {
2189 static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp,
2203 list_add_tail(&alg_region->list, &dsp->alg_regions);
2205 if (dsp->fw_ver > 0)
2206 wm_adsp_ctl_fixup_base(dsp, alg_region);
2211 static void wm_adsp_free_alg_regions(struct wm_adsp *dsp)
2215 while (!list_empty(&dsp->alg_regions)) {
2216 alg_region = list_first_entry(&dsp->alg_regions,
2224 static void wmfw_parse_id_header(struct wm_adsp *dsp,
2227 dsp->fw_id = be32_to_cpu(fw->id);
2228 dsp->fw_id_version = be32_to_cpu(fw->ver);
2230 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %d algorithms\n",
2231 dsp->fw_id, (dsp->fw_id_version & 0xff0000) >> 16,
2232 (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff,
2236 static void wmfw_v3_parse_id_header(struct wm_adsp *dsp,
2239 dsp->fw_id = be32_to_cpu(fw->id);
2240 dsp->fw_id_version = be32_to_cpu(fw->ver);
2241 dsp->fw_vendor_id = be32_to_cpu(fw->vendor_id);
2243 adsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %d algorithms\n",
2244 dsp->fw_id, dsp->fw_vendor_id,
2245 (dsp->fw_id_version & 0xff0000) >> 16,
2246 (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff,
2250 static int wm_adsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions,
2257 alg_region = wm_adsp_create_region(dsp, type[i], id, base[i]);
2265 static int wm_adsp1_setup_algs(struct wm_adsp *dsp)
2275 mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM);
2279 ret = regmap_raw_read(dsp->regmap, mem->base, &adsp1_id,
2282 adsp_err(dsp, "Failed to read algorithm info: %d\n",
2289 wmfw_parse_id_header(dsp, &adsp1_id.fw, n_algs);
2291 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM,
2296 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM,
2305 adsp1_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len);
2310 adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n",
2318 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM,
2325 if (dsp->fw_ver == 0) {
2330 wm_adsp_create_control(dsp, alg_region, 0,
2334 adsp_warn(dsp, "Missing length info for region DM with ID %x\n",
2339 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM,
2346 if (dsp->fw_ver == 0) {
2351 wm_adsp_create_control(dsp, alg_region, 0,
2355 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
2366 static int wm_adsp2_setup_algs(struct wm_adsp *dsp)
2376 mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM);
2380 ret = regmap_raw_read(dsp->regmap, mem->base, &adsp2_id,
2383 adsp_err(dsp, "Failed to read algorithm info: %d\n",
2390 wmfw_parse_id_header(dsp, &adsp2_id.fw, n_algs);
2392 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM,
2397 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM,
2402 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM,
2411 adsp2_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len);
2416 adsp_info(dsp,
2426 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM,
2433 if (dsp->fw_ver == 0) {
2438 wm_adsp_create_control(dsp, alg_region, 0,
2442 adsp_warn(dsp, "Missing length info for region XM with ID %x\n",
2447 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM,
2454 if (dsp->fw_ver == 0) {
2459 wm_adsp_create_control(dsp, alg_region, 0,
2463 adsp_warn(dsp, "Missing length info for region YM with ID %x\n",
2468 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM,
2475 if (dsp->fw_ver == 0) {
2480 wm_adsp_create_control(dsp, alg_region, 0,
2484 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n",
2495 static int wm_halo_create_regions(struct wm_adsp *dsp, __be32 id,
2504 return wm_adsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases);
2507 static int wm_halo_setup_algs(struct wm_adsp *dsp)
2516 mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM);
2520 ret = regmap_raw_read(dsp->regmap, mem->base, &halo_id,
2523 adsp_err(dsp, "Failed to read algorithm info: %d\n",
2530 wmfw_v3_parse_id_header(dsp, &halo_id.fw, n_algs);
2532 ret = wm_halo_create_regions(dsp, halo_id.fw.id,
2541 halo_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len);
2546 adsp_info(dsp,
2555 ret = wm_halo_create_regions(dsp, halo_alg[i].alg.id,
2567 static int wm_adsp_load_coeff(struct wm_adsp *dsp)
2570 struct regmap *regmap = dsp->regmap;
2585 snprintf(file, PAGE_SIZE, "%s-%s-%s.bin", dsp->part, dsp->fwf_name,
2586 wm_adsp_fw[dsp->fw].file);
2589 ret = request_firmware(&firmware, file, dsp->dev);
2591 adsp_warn(dsp, "Failed to request '%s'\n", file);
2598 adsp_err(dsp, "%s: file too short, %zu bytes\n",
2605 adsp_err(dsp, "%s: invalid magic\n", file);
2613 adsp_err(dsp, "%s: Unsupported coefficient file format %d\n",
2619 adsp_dbg(dsp, "%s: v%d.%d.%d\n", file,
2634 adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n",
2639 adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n",
2654 if (le32_to_cpu(blk->id) == dsp->fw_id &&
2657 mem = wm_adsp_find_region(dsp, type);
2659 adsp_err(dsp, "No ZM\n");
2662 reg = dsp->ops->region_to_reg(mem, 0);
2677 adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n",
2681 mem = wm_adsp_find_region(dsp, type);
2683 adsp_err(dsp, "No base for region %x\n", type);
2687 alg_region = wm_adsp_find_alg_region(dsp, type,
2691 reg = dsp->ops->region_to_reg(mem, reg);
2694 adsp_err(dsp, "No %x for algorithm %x\n",
2700 adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n",
2708 adsp_err(dsp,
2721 adsp_err(dsp, "Out of memory\n");
2726 adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n",
2732 adsp_err(dsp,
2744 adsp_err(dsp, "Failed to complete async write: %d\n", ret);
2747 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
2750 wm_adsp_debugfs_save_binname(dsp, file);
2761 static int wm_adsp_create_name(struct wm_adsp *dsp)
2765 if (!dsp->name) {
2766 dsp->name = devm_kasprintf(dsp->dev, GFP_KERNEL, "DSP%d",
2767 dsp->num);
2768 if (!dsp->name)
2772 if (!dsp->fwf_name) {
2773 p = devm_kstrdup(dsp->dev, dsp->name, GFP_KERNEL);
2777 dsp->fwf_name = p;
2785 static int wm_adsp_common_init(struct wm_adsp *dsp)
2789 ret = wm_adsp_create_name(dsp);
2793 INIT_LIST_HEAD(&dsp->alg_regions);
2794 INIT_LIST_HEAD(&dsp->ctl_list);
2795 INIT_LIST_HEAD(&dsp->compr_list);
2796 INIT_LIST_HEAD(&dsp->buffer_list);
2798 mutex_init(&dsp->pwr_lock);
2803 int wm_adsp1_init(struct wm_adsp *dsp)
2805 dsp->ops = &wm_adsp1_ops;
2807 return wm_adsp_common_init(dsp);
2817 struct wm_adsp *dsp = &dsps[w->shift];
2822 dsp->component = component;
2824 mutex_lock(&dsp->pwr_lock);
2828 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
2835 if (dsp->sysclk_reg) {
2836 ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val);
2838 adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
2843 val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift;
2845 ret = regmap_update_bits(dsp->regmap,
2846 dsp->base + ADSP1_CONTROL_31,
2849 adsp_err(dsp, "Failed to set clock rate: %d\n",
2855 ret = wm_adsp_load(dsp);
2859 ret = wm_adsp1_setup_algs(dsp);
2863 ret = wm_adsp_load_coeff(dsp);
2868 ret = wm_coeff_init_control_caches(dsp);
2873 ret = wm_coeff_sync_controls(dsp);
2877 dsp->booted = true;
2880 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
2884 dsp->running = true;
2888 dsp->running = false;
2889 dsp->booted = false;
2892 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
2895 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19,
2898 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
2901 list_for_each_entry(ctl, &dsp->ctl_list, list)
2905 wm_adsp_free_alg_regions(dsp);
2912 mutex_unlock(&dsp->pwr_lock);
2917 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
2920 mutex_unlock(&dsp->pwr_lock);
2926 static int wm_adsp2v2_enable_core(struct wm_adsp *dsp)
2933 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val);
2944 adsp_err(dsp, "Failed to start DSP RAM\n");
2948 adsp_dbg(dsp, "RAM ready after %d polls\n", count);
2953 static int wm_adsp2_enable_core(struct wm_adsp *dsp)
2957 ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL,
2962 return wm_adsp2v2_enable_core(dsp);
2965 static int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions)
2967 struct regmap *regmap = dsp->regmap;
2974 lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0;
2995 static int wm_adsp2_enable_memory(struct wm_adsp *dsp)
2997 return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
3001 static void wm_adsp2_disable_memory(struct wm_adsp *dsp)
3003 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
3007 static void wm_adsp2_disable_core(struct wm_adsp *dsp)
3009 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0);
3010 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0);
3011 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0);
3013 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
3017 static void wm_adsp2v2_disable_core(struct wm_adsp *dsp)
3019 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0);
3020 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0);
3021 regmap_write(dsp->regmap, dsp->base + ADSP2V2_WDMA_CONFIG_2, 0);
3026 struct wm_adsp *dsp = container_of(work,
3031 mutex_lock(&dsp->pwr_lock);
3033 if (dsp->ops->enable_memory) {
3034 ret = dsp->ops->enable_memory(dsp);
3039 if (dsp->ops->enable_core) {
3040 ret = dsp->ops->enable_core(dsp);
3045 ret = wm_adsp_load(dsp);
3049 ret = dsp->ops->setup_algs(dsp);
3053 ret = wm_adsp_load_coeff(dsp);
3058 ret = wm_coeff_init_control_caches(dsp);
3062 if (dsp->ops->disable_core)
3063 dsp->ops->disable_core(dsp);
3065 dsp->booted = true;
3067 mutex_unlock(&dsp->pwr_lock);
3072 if (dsp->ops->disable_core)
3073 dsp->ops->disable_core(dsp);
3075 if (dsp->ops->disable_memory)
3076 dsp->ops->disable_memory(dsp);
3078 mutex_unlock(&dsp->pwr_lock);
3081 static int wm_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regions)
3084 { dsp->base + HALO_MPU_LOCK_CONFIG, 0x5555 },
3085 { dsp->base + HALO_MPU_LOCK_CONFIG, 0xAAAA },
3086 { dsp->base + HALO_MPU_XMEM_ACCESS_0, 0xFFFFFFFF },
3087 { dsp->base + HALO_MPU_YMEM_ACCESS_0, 0xFFFFFFFF },
3088 { dsp->base + HALO_MPU_WINDOW_ACCESS_0, lock_regions },
3089 { dsp->base + HALO_MPU_XREG_ACCESS_0, lock_regions },
3090 { dsp->base + HALO_MPU_YREG_ACCESS_0, lock_regions },
3091 { dsp->base + HALO_MPU_XMEM_ACCESS_1, 0xFFFFFFFF },
3092 { dsp->base + HALO_MPU_YMEM_ACCESS_1, 0xFFFFFFFF },
3093 { dsp->base + HALO_MPU_WINDOW_ACCESS_1, lock_regions },
3094 { dsp->base + HALO_MPU_XREG_ACCESS_1, lock_regions },
3095 { dsp->base + HALO_MPU_YREG_ACCESS_1, lock_regions },
3096 { dsp->base + HALO_MPU_XMEM_ACCESS_2, 0xFFFFFFFF },
3097 { dsp->base + HALO_MPU_YMEM_ACCESS_2, 0xFFFFFFFF },
3098 { dsp->base + HALO_MPU_WINDOW_ACCESS_2, lock_regions },
3099 { dsp->base + HALO_MPU_XREG_ACCESS_2, lock_regions },
3100 { dsp->base + HALO_MPU_YREG_ACCESS_2, lock_regions },
3101 { dsp->base + HALO_MPU_XMEM_ACCESS_3, 0xFFFFFFFF },
3102 { dsp->base + HALO_MPU_YMEM_ACCESS_3, 0xFFFFFFFF },
3103 { dsp->base + HALO_MPU_WINDOW_ACCESS_3, lock_regions },
3104 { dsp->base + HALO_MPU_XREG_ACCESS_3, lock_regions },
3105 { dsp->base + HALO_MPU_YREG_ACCESS_3, lock_regions },
3106 { dsp->base + HALO_MPU_LOCK_CONFIG, 0 },
3109 return regmap_multi_reg_write(dsp->regmap, config, ARRAY_SIZE(config));
3116 struct wm_adsp *dsp = &dsps[w->shift];
3119 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CLOCKING,
3123 adsp_err(dsp, "Failed to set clock rate: %d\n", ret);
3136 struct wm_adsp *dsp = &dsps[mc->shift - 1];
3138 ucontrol->value.integer.value[0] = dsp->preloaded;
3152 struct wm_adsp *dsp = &dsps[mc->shift - 1];
3155 snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->name);
3157 dsp->preloaded = ucontrol->value.integer.value[0];
3166 flush_work(&dsp->boot_work);
3172 static void wm_adsp_stop_watchdog(struct wm_adsp *dsp)
3174 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG,
3178 static void wm_halo_stop_watchdog(struct wm_adsp *dsp)
3180 regmap_update_bits(dsp->regmap, dsp->base + HALO_WDT_CONTROL,
3189 struct wm_adsp *dsp = &dsps[w->shift];
3194 queue_work(system_unbound_wq, &dsp->boot_work);
3197 mutex_lock(&dsp->pwr_lock);
3199 wm_adsp_debugfs_clear(dsp);
3201 dsp->fw_id = 0;
3202 dsp->fw_id_version = 0;
3204 dsp->booted = false;
3206 if (dsp->ops->disable_memory)
3207 dsp->ops->disable_memory(dsp);
3209 list_for_each_entry(ctl, &dsp->ctl_list, list)
3212 wm_adsp_free_alg_regions(dsp);
3214 mutex_unlock(&dsp->pwr_lock);
3216 adsp_dbg(dsp, "Shutdown complete\n");
3226 static int wm_adsp2_start_core(struct wm_adsp *dsp)
3228 return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
3233 static void wm_adsp2_stop_core(struct wm_adsp *dsp)
3235 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
3244 struct wm_adsp *dsp = &dsps[w->shift];
3249 flush_work(&dsp->boot_work);
3251 mutex_lock(&dsp->pwr_lock);
3253 if (!dsp->booted) {
3258 if (dsp->ops->enable_core) {
3259 ret = dsp->ops->enable_core(dsp);
3265 ret = wm_coeff_sync_controls(dsp);
3269 if (dsp->ops->lock_memory) {
3270 ret = dsp->ops->lock_memory(dsp, dsp->lock_regions);
3272 adsp_err(dsp, "Error configuring MPU: %d\n",
3278 if (dsp->ops->start_core) {
3279 ret = dsp->ops->start_core(dsp);
3284 if (wm_adsp_fw[dsp->fw].num_caps != 0) {
3285 ret = wm_adsp_buffer_init(dsp);
3290 dsp->running = true;
3292 mutex_unlock(&dsp->pwr_lock);
3297 wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN);
3299 if (dsp->ops->stop_watchdog)
3300 dsp->ops->stop_watchdog(dsp);
3303 if (dsp->ops->show_fw_status)
3304 dsp->ops->show_fw_status(dsp);
3306 mutex_lock(&dsp->pwr_lock);
3308 dsp->running = false;
3310 if (dsp->ops->stop_core)
3311 dsp->ops->stop_core(dsp);
3312 if (dsp->ops->disable_core)
3313 dsp->ops->disable_core(dsp);
3315 if (wm_adsp_fw[dsp->fw].num_caps != 0)
3316 wm_adsp_buffer_free(dsp);
3318 dsp->fatal_error = false;
3320 mutex_unlock(&dsp->pwr_lock);
3322 adsp_dbg(dsp, "Execution stopped\n");
3331 if (dsp->ops->stop_core)
3332 dsp->ops->stop_core(dsp);
3333 if (dsp->ops->disable_core)
3334 dsp->ops->disable_core(dsp);
3335 mutex_unlock(&dsp->pwr_lock);
3340 static int wm_halo_start_core(struct wm_adsp *dsp)
3342 return regmap_update_bits(dsp->regmap,
3343 dsp->base + HALO_CCM_CORE_CONTROL,
3347 static void wm_halo_stop_core(struct wm_adsp *dsp)
3349 regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL,
3353 regmap_update_bits(dsp->regmap, dsp->base + HALO_CORE_SOFT_RESET,
3357 int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component)
3361 snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->name);
3364 wm_adsp2_init_debugfs(dsp, component);
3366 dsp->component = component;
3372 int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component)
3374 wm_adsp2_cleanup_debugfs(dsp);
3380 int wm_adsp2_init(struct wm_adsp *dsp)
3384 ret = wm_adsp_common_init(dsp);
3388 switch (dsp->rev) {
3394 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
3397 adsp_err(dsp,
3402 dsp->ops = &wm_adsp2_ops[0];
3405 dsp->ops = &wm_adsp2_ops[1];
3408 dsp->ops = &wm_adsp2_ops[2];
3412 INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
3418 int wm_halo_init(struct wm_adsp *dsp)
3422 ret = wm_adsp_common_init(dsp);
3426 dsp->ops = &wm_halo_ops;
3428 INIT_WORK(&dsp->boot_work, wm_adsp_boot_work);
3434 void wm_adsp2_remove(struct wm_adsp *dsp)
3438 while (!list_empty(&dsp->ctl_list)) {
3439 ctl = list_first_entry(&dsp->ctl_list, struct wm_coeff_ctl,
3456 if (compr->dsp->fatal_error)
3459 list_for_each_entry(tmp, &compr->dsp->buffer_list, list) {
3490 int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream)
3496 mutex_lock(&dsp->pwr_lock);
3498 if (wm_adsp_fw[dsp->fw].num_caps == 0) {
3499 adsp_err(dsp, "%s: Firmware does not support compressed API\n",
3505 if (wm_adsp_fw[dsp->fw].compr_direction != stream->direction) {
3506 adsp_err(dsp, "%s: Firmware does not support stream direction\n",
3512 list_for_each_entry(tmp, &dsp->compr_list, list) {
3514 adsp_err(dsp, "%s: Only a single stream supported per dai\n",
3527 compr->dsp = dsp;
3531 list_add_tail(&compr->list, &dsp->compr_list);
3536 mutex_unlock(&dsp->pwr_lock);
3546 struct wm_adsp *dsp = compr->dsp;
3548 mutex_lock(&dsp->pwr_lock);
3556 mutex_unlock(&dsp->pwr_lock);
3566 struct wm_adsp *dsp = compr->dsp;
3583 for (i = 0; i < wm_adsp_fw[dsp->fw].num_caps; i++) {
3584 caps = &wm_adsp_fw[dsp->fw].caps[i];
3650 int fw = compr->dsp->fw;
3670 static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type,
3674 struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type);
3681 reg = dsp->ops->region_to_reg(mem, mem_addr);
3683 ret = regmap_raw_read(dsp->regmap, reg, data,
3694 static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type,
3697 return wm_adsp_read_data_block(dsp, mem_type, mem_addr, 1, data);
3700 static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type,
3703 struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type);
3709 reg = dsp->ops->region_to_reg(mem, mem_addr);
3713 return regmap_raw_write(dsp->regmap, reg, &data, sizeof(data));
3719 return wm_adsp_read_data_word(buf->dsp, buf->host_buf_mem_type,
3726 return wm_adsp_write_data_word(buf->dsp, buf->host_buf_mem_type,
3747 const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps;
3795 static struct wm_adsp_compr_buf *wm_adsp_buffer_alloc(struct wm_adsp *dsp)
3803 buf->dsp = dsp;
3807 list_add_tail(&buf->list, &dsp->buffer_list);
3812 static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp)
3819 alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id);
3821 adsp_err(dsp, "No algorithm region found\n");
3825 buf = wm_adsp_buffer_alloc(dsp);
3829 xmalg = dsp->ops->sys_config_size / sizeof(__be32);
3832 ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic);
3841 ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr,
3878 ret = regmap_raw_read(ctl->dsp->regmap, reg, &val, sizeof(val));
3889 adsp_err(ctl->dsp, "Failed to acquire host buffer\n");
3893 buf = wm_adsp_buffer_alloc(ctl->dsp);
3913 ret = regmap_raw_read(ctl->dsp->regmap, reg, &coeff_v1,
3923 adsp_err(ctl->dsp,
3936 buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part,
3945 static int wm_adsp_buffer_init(struct wm_adsp *dsp)
3950 list_for_each_entry(ctl, &dsp->ctl_list, list) {
3959 adsp_err(dsp, "Failed to parse coeff: %d\n", ret);
3967 if (list_empty(&dsp->buffer_list)) {
3969 ret = wm_adsp_buffer_parse_legacy(dsp);
3971 adsp_err(dsp, "Failed to parse legacy: %d\n", ret);
3979 wm_adsp_buffer_free(dsp);
3983 static int wm_adsp_buffer_free(struct wm_adsp *dsp)
3987 list_for_each_entry_safe(buf, tmp, &dsp->buffer_list, list) {
4020 struct wm_adsp *dsp = compr->dsp;
4025 mutex_lock(&dsp->pwr_lock);
4061 mutex_unlock(&dsp->pwr_lock);
4069 int last_region = wm_adsp_fw[buf->dsp->fw].caps->num_regions - 1;
4117 int wm_adsp_compr_handle_irq(struct wm_adsp *dsp)
4123 mutex_lock(&dsp->pwr_lock);
4125 if (list_empty(&dsp->buffer_list)) {
4130 adsp_dbg(dsp, "Handling buffer IRQ\n");
4132 list_for_each_entry(buf, &dsp->buffer_list, list) {
4152 if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2)
4161 mutex_unlock(&dsp->pwr_lock);
4185 struct wm_adsp *dsp = compr->dsp;
4191 mutex_lock(&dsp->pwr_lock);
4195 if (dsp->fatal_error || !buf || buf->error) {
4235 mutex_unlock(&dsp->pwr_lock);
4249 for (i = 0; i < wm_adsp_fw[buf->dsp->fw].caps->num_regions; ++i)
4253 if (i == wm_adsp_fw[buf->dsp->fw].caps->num_regions)
4273 ret = wm_adsp_read_data_block(buf->dsp, mem_type, adsp_addr,
4299 struct wm_adsp *dsp = compr->dsp;
4305 if (dsp->fatal_error || !compr->buf || compr->buf->error) {
4344 struct wm_adsp *dsp = compr->dsp;
4347 mutex_lock(&dsp->pwr_lock);
4354 mutex_unlock(&dsp->pwr_lock);
4360 static void wm_adsp_fatal_error(struct wm_adsp *dsp)
4364 dsp->fatal_error = true;
4366 list_for_each_entry(compr, &dsp->compr_list, list) {
4374 struct wm_adsp *dsp = (struct wm_adsp *)data;
4376 struct regmap *regmap = dsp->regmap;
4379 mutex_lock(&dsp->pwr_lock);
4381 ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val);
4383 adsp_err(dsp,
4389 adsp_err(dsp, "watchdog timeout error\n");
4390 dsp->ops->stop_watchdog(dsp);
4391 wm_adsp_fatal_error(dsp);
4396 adsp_err(dsp, "bus error: address error\n");
4398 adsp_err(dsp, "bus error: region lock error\n");
4400 ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val);
4402 adsp_err(dsp,
4408 adsp_err(dsp, "bus error address = 0x%x\n",
4412 dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR,
4415 adsp_err(dsp,
4421 adsp_err(dsp, "xmem error address = 0x%x\n",
4423 adsp_err(dsp, "pmem error address = 0x%x\n",
4428 regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL,
4432 mutex_unlock(&dsp->pwr_lock);
4440 struct wm_adsp *dsp = (struct wm_adsp *)data;
4441 struct regmap *regmap = dsp->regmap;
4444 { dsp->base + HALO_MPU_XM_VIO_STATUS, 0x0 },
4445 { dsp->base + HALO_MPU_YM_VIO_STATUS, 0x0 },
4446 { dsp->base + HALO_MPU_PM_VIO_STATUS, 0x0 },
4450 mutex_lock(&dsp->pwr_lock);
4452 ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_1,
4455 adsp_warn(dsp, "Failed to read AHB DEBUG_1: %d\n", ret);
4459 adsp_warn(dsp, "AHB: STATUS: 0x%x ADDR: 0x%x\n",
4464 ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_0,
4467 adsp_warn(dsp, "Failed to read AHB DEBUG_0: %d\n", ret);
4471 adsp_warn(dsp, "AHB: SYS_ADDR: 0x%x\n", *fault);
4473 ret = regmap_bulk_read(regmap, dsp->base + HALO_MPU_XM_VIO_ADDR,
4476 adsp_warn(dsp, "Failed to read MPU fault info: %d\n", ret);
4480 adsp_warn(dsp, "XM: STATUS:0x%x ADDR:0x%x\n", fault[1], fault[0]);
4481 adsp_warn(dsp, "YM: STATUS:0x%x ADDR:0x%x\n", fault[3], fault[2]);
4482 adsp_warn(dsp, "PM: STATUS:0x%x ADDR:0x%x\n", fault[5], fault[4]);
4484 ret = regmap_multi_reg_write(dsp->regmap, clear, ARRAY_SIZE(clear));
4486 adsp_warn(dsp, "Failed to clear MPU status: %d\n", ret);
4489 mutex_unlock(&dsp->pwr_lock);
4497 struct wm_adsp *dsp = data;
4499 mutex_lock(&dsp->pwr_lock);
4501 adsp_warn(dsp, "WDT Expiry Fault\n");
4502 dsp->ops->stop_watchdog(dsp);
4503 wm_adsp_fatal_error(dsp);
4505 mutex_unlock(&dsp->pwr_lock);