Lines Matching full: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", \
419 __be32 buf1_size; /* Size of buf1 area in DSP words */
421 __be32 buf1_buf2_size; /* Size of buf1+buf2 in DSP words */
423 __be32 buf_total_size; /* Size of buf1+buf2+buf3 in DSP words */
442 struct wm_adsp *dsp; member
459 struct wm_adsp *dsp; member
493 static int wm_adsp_buffer_init(struct wm_adsp *dsp);
494 static int wm_adsp_buffer_free(struct wm_adsp *dsp);
606 struct wm_adsp *dsp; member
643 static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) in wm_adsp_debugfs_save_wmfwname() argument
647 kfree(dsp->wmfw_file_name); in wm_adsp_debugfs_save_wmfwname()
648 dsp->wmfw_file_name = tmp; in wm_adsp_debugfs_save_wmfwname()
651 static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) in wm_adsp_debugfs_save_binname() argument
655 kfree(dsp->bin_file_name); in wm_adsp_debugfs_save_binname()
656 dsp->bin_file_name = tmp; in wm_adsp_debugfs_save_binname()
659 static void wm_adsp_debugfs_clear(struct wm_adsp *dsp) in wm_adsp_debugfs_clear() argument
661 kfree(dsp->wmfw_file_name); in wm_adsp_debugfs_clear()
662 kfree(dsp->bin_file_name); in wm_adsp_debugfs_clear()
663 dsp->wmfw_file_name = NULL; in wm_adsp_debugfs_clear()
664 dsp->bin_file_name = NULL; in wm_adsp_debugfs_clear()
671 struct wm_adsp *dsp = file->private_data; in wm_adsp_debugfs_wmfw_read() local
674 mutex_lock(&dsp->pwr_lock); in wm_adsp_debugfs_wmfw_read()
676 if (!dsp->wmfw_file_name || !dsp->booted) in wm_adsp_debugfs_wmfw_read()
680 dsp->wmfw_file_name, in wm_adsp_debugfs_wmfw_read()
681 strlen(dsp->wmfw_file_name)); in wm_adsp_debugfs_wmfw_read()
683 mutex_unlock(&dsp->pwr_lock); in wm_adsp_debugfs_wmfw_read()
691 struct wm_adsp *dsp = file->private_data; in wm_adsp_debugfs_bin_read() local
694 mutex_lock(&dsp->pwr_lock); in wm_adsp_debugfs_bin_read()
696 if (!dsp->bin_file_name || !dsp->booted) in wm_adsp_debugfs_bin_read()
700 dsp->bin_file_name, in wm_adsp_debugfs_bin_read()
701 strlen(dsp->bin_file_name)); in wm_adsp_debugfs_bin_read()
703 mutex_unlock(&dsp->pwr_lock); in wm_adsp_debugfs_bin_read()
727 static void wm_adsp2_init_debugfs(struct wm_adsp *dsp, in wm_adsp2_init_debugfs() argument
733 root = debugfs_create_dir(dsp->name, component->debugfs_root); in wm_adsp2_init_debugfs()
735 debugfs_create_bool("booted", 0444, root, &dsp->booted); in wm_adsp2_init_debugfs()
736 debugfs_create_bool("running", 0444, root, &dsp->running); in wm_adsp2_init_debugfs()
737 debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id); in wm_adsp2_init_debugfs()
738 debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version); in wm_adsp2_init_debugfs()
742 dsp, &wm_adsp_debugfs_fops[i].fops); in wm_adsp2_init_debugfs()
744 dsp->debugfs_root = root; in wm_adsp2_init_debugfs()
747 static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) in wm_adsp2_cleanup_debugfs() argument
749 wm_adsp_debugfs_clear(dsp); in wm_adsp2_cleanup_debugfs()
750 debugfs_remove_recursive(dsp->debugfs_root); in wm_adsp2_cleanup_debugfs()
751 dsp->debugfs_root = NULL; in wm_adsp2_cleanup_debugfs()
754 static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp, in wm_adsp2_init_debugfs() argument
759 static inline void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) in wm_adsp2_cleanup_debugfs() argument
763 static inline void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, in wm_adsp_debugfs_save_wmfwname() argument
768 static inline void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, in wm_adsp_debugfs_save_binname() argument
773 static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp) in wm_adsp_debugfs_clear() argument
783 struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); in wm_adsp_fw_get() local
785 ucontrol->value.enumerated.item[0] = dsp[e->shift_l].fw; in wm_adsp_fw_get()
796 struct wm_adsp *dsp = snd_soc_component_get_drvdata(component); in wm_adsp_fw_put() local
799 if (ucontrol->value.enumerated.item[0] == dsp[e->shift_l].fw) in wm_adsp_fw_put()
805 mutex_lock(&dsp[e->shift_l].pwr_lock); in wm_adsp_fw_put()
807 if (dsp[e->shift_l].booted || !list_empty(&dsp[e->shift_l].compr_list)) in wm_adsp_fw_put()
810 dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0]; in wm_adsp_fw_put()
812 mutex_unlock(&dsp[e->shift_l].pwr_lock); in wm_adsp_fw_put()
829 static const struct wm_adsp_region *wm_adsp_find_region(struct wm_adsp *dsp, in wm_adsp_find_region() argument
834 for (i = 0; i < dsp->num_mems; i++) in wm_adsp_find_region()
835 if (dsp->mem[i].type == type) in wm_adsp_find_region()
836 return &dsp->mem[i]; in wm_adsp_find_region()
876 static void wm_adsp_read_fw_status(struct wm_adsp *dsp, in wm_adsp_read_fw_status() argument
883 ret = regmap_read(dsp->regmap, dsp->base + offs[i], &offs[i]); in wm_adsp_read_fw_status()
885 adsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); in wm_adsp_read_fw_status()
891 static void wm_adsp2_show_fw_status(struct wm_adsp *dsp) in wm_adsp2_show_fw_status() argument
897 wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); in wm_adsp2_show_fw_status()
899 adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", in wm_adsp2_show_fw_status()
903 static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp) in wm_adsp2v2_show_fw_status() argument
907 wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); in wm_adsp2v2_show_fw_status()
909 adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", in wm_adsp2v2_show_fw_status()
914 static void wm_halo_show_fw_status(struct wm_adsp *dsp) in wm_halo_show_fw_status() argument
920 wm_adsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); in wm_halo_show_fw_status()
922 adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", in wm_halo_show_fw_status()
934 struct wm_adsp *dsp = ctl->dsp; in wm_coeff_base_reg() local
937 mem = wm_adsp_find_region(dsp, alg_region->type); in wm_coeff_base_reg()
939 adsp_err(dsp, "No base for region %x\n", in wm_coeff_base_reg()
944 *reg = dsp->ops->region_to_reg(mem, ctl->alg_region.base + ctl->offset); in wm_coeff_base_reg()
976 struct wm_adsp *dsp = ctl->dsp; in wm_coeff_write_acked_control() local
985 adsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", in wm_coeff_write_acked_control()
989 ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); in wm_coeff_write_acked_control()
991 adsp_err(dsp, "Failed to write %x: %d\n", reg, ret); in wm_coeff_write_acked_control()
1013 ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); in wm_coeff_write_acked_control()
1015 adsp_err(dsp, "Failed to read %x: %d\n", reg, ret); in wm_coeff_write_acked_control()
1020 adsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); in wm_coeff_write_acked_control()
1025 adsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", in wm_coeff_write_acked_control()
1036 struct wm_adsp *dsp = ctl->dsp; in wm_coeff_write_ctrl_raw() local
1049 ret = regmap_raw_write(dsp->regmap, reg, scratch, in wm_coeff_write_ctrl_raw()
1052 adsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", in wm_coeff_write_ctrl_raw()
1057 adsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg); in wm_coeff_write_ctrl_raw()
1075 if (ctl->enabled && ctl->dsp->running) in wm_coeff_write_ctrl()
1090 mutex_lock(&ctl->dsp->pwr_lock); in wm_coeff_put()
1092 mutex_unlock(&ctl->dsp->pwr_lock); in wm_coeff_put()
1105 mutex_lock(&ctl->dsp->pwr_lock); in wm_coeff_tlv_put()
1112 mutex_unlock(&ctl->dsp->pwr_lock); in wm_coeff_tlv_put()
1129 mutex_lock(&ctl->dsp->pwr_lock); in wm_coeff_put_acked()
1131 if (ctl->enabled && ctl->dsp->running) in wm_coeff_put_acked()
1136 mutex_unlock(&ctl->dsp->pwr_lock); in wm_coeff_put_acked()
1144 struct wm_adsp *dsp = ctl->dsp; in wm_coeff_read_ctrl_raw() local
1157 ret = regmap_raw_read(dsp->regmap, reg, scratch, len); in wm_coeff_read_ctrl_raw()
1159 adsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", in wm_coeff_read_ctrl_raw()
1164 adsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg); in wm_coeff_read_ctrl_raw()
1177 if (ctl->enabled && ctl->dsp->running) in wm_coeff_read_ctrl()
1182 if (!ctl->flags && ctl->enabled && ctl->dsp->running) in wm_coeff_read_ctrl()
1201 mutex_lock(&ctl->dsp->pwr_lock); in wm_coeff_get()
1203 mutex_unlock(&ctl->dsp->pwr_lock); in wm_coeff_get()
1216 mutex_lock(&ctl->dsp->pwr_lock); in wm_coeff_tlv_get()
1223 mutex_unlock(&ctl->dsp->pwr_lock); in wm_coeff_tlv_get()
1244 struct wm_adsp *dsp; member
1280 static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) in wmfw_add_ctl() argument
1316 ret = snd_soc_add_component_controls(dsp->component, kcontrol, 1); in wmfw_add_ctl()
1329 static int wm_coeff_init_control_caches(struct wm_adsp *dsp) in wm_coeff_init_control_caches() argument
1334 list_for_each_entry(ctl, &dsp->ctl_list, list) { in wm_coeff_init_control_caches()
1341 * For readable controls populate the cache from the DSP memory. in wm_coeff_init_control_caches()
1355 static int wm_coeff_sync_controls(struct wm_adsp *dsp) in wm_coeff_sync_controls() argument
1360 list_for_each_entry(ctl, &dsp->ctl_list, list) { in wm_coeff_sync_controls()
1374 static void wm_adsp_signal_event_controls(struct wm_adsp *dsp, in wm_adsp_signal_event_controls() argument
1380 list_for_each_entry(ctl, &dsp->ctl_list, list) { in wm_adsp_signal_event_controls()
1389 adsp_warn(dsp, in wm_adsp_signal_event_controls()
1401 wmfw_add_ctl(ctl_work->dsp, ctl_work->ctl); in wm_adsp_ctl_work()
1413 static int wm_adsp_create_control(struct wm_adsp *dsp, in wm_adsp_create_control() argument
1427 adsp_err(dsp, "Unknown region type: %d\n", alg_region->type); in wm_adsp_create_control()
1431 switch (dsp->fw_ver) { in wm_adsp_create_control()
1435 dsp->name, region_name, alg_region->alg); in wm_adsp_create_control()
1440 "%s%c %.12s %x", dsp->name, *region_name, in wm_adsp_create_control()
1441 wm_adsp_fw_text[dsp->fw], alg_region->alg); in wm_adsp_create_control()
1445 "%s %.12s %x", dsp->name, in wm_adsp_create_control()
1446 wm_adsp_fw_text[dsp->fw], alg_region->alg); in wm_adsp_create_control()
1454 if (dsp->component->name_prefix) in wm_adsp_create_control()
1455 avail -= strlen(dsp->component->name_prefix) + 1; in wm_adsp_create_control()
1465 list_for_each_entry(ctl, &dsp->ctl_list, list) { in wm_adsp_create_control()
1476 ctl->fw_name = wm_adsp_fw_text[dsp->fw]; in wm_adsp_create_control()
1494 ctl->dsp = dsp; in wm_adsp_create_control()
1506 list_add(&ctl->list, &dsp->ctl_list); in wm_adsp_create_control()
1517 ctl_work->dsp = dsp; in wm_adsp_create_control()
1597 static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, in wm_coeff_parse_alg() argument
1602 switch (dsp->fw_ver) { in wm_coeff_parse_alg()
1622 adsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); in wm_coeff_parse_alg()
1623 adsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); in wm_coeff_parse_alg()
1624 adsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); in wm_coeff_parse_alg()
1627 static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, in wm_coeff_parse_coeff() argument
1634 switch (dsp->fw_ver) { in wm_coeff_parse_coeff()
1667 adsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); in wm_coeff_parse_coeff()
1668 adsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); in wm_coeff_parse_coeff()
1669 adsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); in wm_coeff_parse_coeff()
1670 adsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); in wm_coeff_parse_coeff()
1671 adsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); in wm_coeff_parse_coeff()
1672 adsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); in wm_coeff_parse_coeff()
1675 static int wm_adsp_check_coeff_flags(struct wm_adsp *dsp, in wm_adsp_check_coeff_flags() argument
1682 adsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", in wm_adsp_check_coeff_flags()
1690 static int wm_adsp_parse_coeff(struct wm_adsp *dsp, in wm_adsp_parse_coeff() argument
1699 wm_coeff_parse_alg(dsp, &data, &alg_blk); in wm_adsp_parse_coeff()
1701 wm_coeff_parse_coeff(dsp, &data, &coeff_blk); in wm_adsp_parse_coeff()
1710 ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, in wm_adsp_parse_coeff()
1719 ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, in wm_adsp_parse_coeff()
1729 ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, in wm_adsp_parse_coeff()
1738 adsp_err(dsp, "Unknown control type: %d\n", in wm_adsp_parse_coeff()
1746 ret = wm_adsp_create_control(dsp, &alg_region, in wm_adsp_parse_coeff()
1754 adsp_err(dsp, "Failed to create control: %.*s, %d\n", in wm_adsp_parse_coeff()
1761 static unsigned int wm_adsp1_parse_sizes(struct wm_adsp *dsp, in wm_adsp1_parse_sizes() argument
1770 adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, in wm_adsp1_parse_sizes()
1777 static unsigned int wm_adsp2_parse_sizes(struct wm_adsp *dsp, in wm_adsp2_parse_sizes() argument
1786 adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, in wm_adsp2_parse_sizes()
1793 static bool wm_adsp_validate_version(struct wm_adsp *dsp, unsigned int version) in wm_adsp_validate_version() argument
1797 adsp_warn(dsp, "Deprecated file format %d\n", version); in wm_adsp_validate_version()
1807 static bool wm_halo_validate_version(struct wm_adsp *dsp, unsigned int version) in wm_halo_validate_version() argument
1817 static int wm_adsp_load(struct wm_adsp *dsp) in wm_adsp_load() argument
1821 struct regmap *regmap = dsp->regmap; in wm_adsp_load()
1839 snprintf(file, PAGE_SIZE, "%s-%s-%s.wmfw", dsp->part, dsp->fwf_name, in wm_adsp_load()
1840 wm_adsp_fw[dsp->fw].file); in wm_adsp_load()
1843 ret = request_firmware(&firmware, file, dsp->dev); in wm_adsp_load()
1845 adsp_err(dsp, "Failed to request '%s'\n", file); in wm_adsp_load()
1852 adsp_err(dsp, "%s: file too short, %zu bytes\n", in wm_adsp_load()
1860 adsp_err(dsp, "%s: invalid magic\n", file); in wm_adsp_load()
1864 if (!dsp->ops->validate_version(dsp, header->ver)) { in wm_adsp_load()
1865 adsp_err(dsp, "%s: unknown file format %d\n", in wm_adsp_load()
1870 adsp_info(dsp, "Firmware version: %d\n", header->ver); in wm_adsp_load()
1871 dsp->fw_ver = header->ver; in wm_adsp_load()
1873 if (header->core != dsp->type) { in wm_adsp_load()
1874 adsp_err(dsp, "%s: invalid core %d != %d\n", in wm_adsp_load()
1875 file, header->core, dsp->type); in wm_adsp_load()
1880 pos = dsp->ops->parse_sizes(dsp, file, pos, firmware); in wm_adsp_load()
1886 adsp_err(dsp, "%s: unexpected header length %d\n", in wm_adsp_load()
1891 adsp_dbg(dsp, "%s: timestamp %llu\n", file, in wm_adsp_load()
1911 ret = wm_adsp_parse_coeff(dsp, region); in wm_adsp_load()
1932 mem = wm_adsp_find_region(dsp, type); in wm_adsp_load()
1934 adsp_err(dsp, "No region of type: %x\n", type); in wm_adsp_load()
1940 reg = dsp->ops->region_to_reg(mem, offset); in wm_adsp_load()
1943 adsp_warn(dsp, in wm_adsp_load()
1949 adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, in wm_adsp_load()
1955 adsp_err(dsp, in wm_adsp_load()
1965 adsp_info(dsp, "%s: %s\n", file, text); in wm_adsp_load()
1975 adsp_err(dsp, "Out of memory\n"); in wm_adsp_load()
1983 adsp_err(dsp, in wm_adsp_load()
1998 adsp_err(dsp, "Failed to complete async write: %d\n", ret); in wm_adsp_load()
2003 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", in wm_adsp_load()
2006 wm_adsp_debugfs_save_wmfwname(dsp, file); in wm_adsp_load()
2023 static struct wm_coeff_ctl *wm_adsp_get_ctl(struct wm_adsp *dsp, in wm_adsp_get_ctl() argument
2028 const char *fw_txt = wm_adsp_fw_text[dsp->fw]; in wm_adsp_get_ctl()
2030 list_for_each_entry(pos, &dsp->ctl_list, list) { in wm_adsp_get_ctl()
2045 int wm_adsp_write_ctl(struct wm_adsp *dsp, const char *name, int type, in wm_adsp_write_ctl() argument
2053 ctl = wm_adsp_get_ctl(dsp, name, type, alg); in wm_adsp_write_ctl()
2067 if (dsp->component->name_prefix) in wm_adsp_write_ctl()
2069 dsp->component->name_prefix, ctl->name); in wm_adsp_write_ctl()
2074 kcontrol = snd_soc_card_get_kcontrol(dsp->component->card, ctl_name); in wm_adsp_write_ctl()
2076 adsp_err(dsp, "Can't find kcontrol %s\n", ctl_name); in wm_adsp_write_ctl()
2080 snd_ctl_notify(dsp->component->card->snd_card, in wm_adsp_write_ctl()
2087 int wm_adsp_read_ctl(struct wm_adsp *dsp, const char *name, int type, in wm_adsp_read_ctl() argument
2092 ctl = wm_adsp_get_ctl(dsp, name, type, alg); in wm_adsp_read_ctl()
2103 static void wm_adsp_ctl_fixup_base(struct wm_adsp *dsp, in wm_adsp_ctl_fixup_base() argument
2108 list_for_each_entry(ctl, &dsp->ctl_list, list) { in wm_adsp_ctl_fixup_base()
2109 if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && in wm_adsp_ctl_fixup_base()
2117 static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs, in wm_adsp_read_algs() argument
2127 adsp_err(dsp, "No algorithms\n"); in wm_adsp_read_algs()
2132 adsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); in wm_adsp_read_algs()
2137 reg = dsp->ops->region_to_reg(mem, pos + len); in wm_adsp_read_algs()
2139 ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); in wm_adsp_read_algs()
2141 adsp_err(dsp, "Failed to read algorithm list end: %d\n", in wm_adsp_read_algs()
2147 adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", in wm_adsp_read_algs()
2150 /* Convert length from DSP words to bytes */ in wm_adsp_read_algs()
2157 reg = dsp->ops->region_to_reg(mem, pos); in wm_adsp_read_algs()
2159 ret = regmap_raw_read(dsp->regmap, reg, alg, len); in wm_adsp_read_algs()
2161 adsp_err(dsp, "Failed to read algorithm list: %d\n", ret); in wm_adsp_read_algs()
2170 wm_adsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id) in wm_adsp_find_alg_region() argument
2174 list_for_each_entry(alg_region, &dsp->alg_regions, list) { in wm_adsp_find_alg_region()
2182 static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp, in wm_adsp_create_region() argument
2196 list_add_tail(&alg_region->list, &dsp->alg_regions); in wm_adsp_create_region()
2198 if (dsp->fw_ver > 0) in wm_adsp_create_region()
2199 wm_adsp_ctl_fixup_base(dsp, alg_region); in wm_adsp_create_region()
2204 static void wm_adsp_free_alg_regions(struct wm_adsp *dsp) in wm_adsp_free_alg_regions() argument
2208 while (!list_empty(&dsp->alg_regions)) { in wm_adsp_free_alg_regions()
2209 alg_region = list_first_entry(&dsp->alg_regions, in wm_adsp_free_alg_regions()
2217 static void wmfw_parse_id_header(struct wm_adsp *dsp, in wmfw_parse_id_header() argument
2220 dsp->fw_id = be32_to_cpu(fw->id); in wmfw_parse_id_header()
2221 dsp->fw_id_version = be32_to_cpu(fw->ver); in wmfw_parse_id_header()
2223 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %d algorithms\n", in wmfw_parse_id_header()
2224 dsp->fw_id, (dsp->fw_id_version & 0xff0000) >> 16, in wmfw_parse_id_header()
2225 (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, in wmfw_parse_id_header()
2229 static void wmfw_v3_parse_id_header(struct wm_adsp *dsp, in wmfw_v3_parse_id_header() argument
2232 dsp->fw_id = be32_to_cpu(fw->id); in wmfw_v3_parse_id_header()
2233 dsp->fw_id_version = be32_to_cpu(fw->ver); in wmfw_v3_parse_id_header()
2234 dsp->fw_vendor_id = be32_to_cpu(fw->vendor_id); in wmfw_v3_parse_id_header()
2236 adsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %d algorithms\n", in wmfw_v3_parse_id_header()
2237 dsp->fw_id, dsp->fw_vendor_id, in wmfw_v3_parse_id_header()
2238 (dsp->fw_id_version & 0xff0000) >> 16, in wmfw_v3_parse_id_header()
2239 (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, in wmfw_v3_parse_id_header()
2243 static int wm_adsp_create_regions(struct wm_adsp *dsp, __be32 id, int nregions, in wm_adsp_create_regions() argument
2250 alg_region = wm_adsp_create_region(dsp, type[i], id, base[i]); in wm_adsp_create_regions()
2258 static int wm_adsp1_setup_algs(struct wm_adsp *dsp) in wm_adsp1_setup_algs() argument
2268 mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM); in wm_adsp1_setup_algs()
2272 ret = regmap_raw_read(dsp->regmap, mem->base, &adsp1_id, in wm_adsp1_setup_algs()
2275 adsp_err(dsp, "Failed to read algorithm info: %d\n", in wm_adsp1_setup_algs()
2282 wmfw_parse_id_header(dsp, &adsp1_id.fw, n_algs); in wm_adsp1_setup_algs()
2284 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, in wm_adsp1_setup_algs()
2289 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, in wm_adsp1_setup_algs()
2294 /* Calculate offset and length in DSP words */ in wm_adsp1_setup_algs()
2298 adsp1_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len); in wm_adsp1_setup_algs()
2303 adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", in wm_adsp1_setup_algs()
2311 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, in wm_adsp1_setup_algs()
2318 if (dsp->fw_ver == 0) { in wm_adsp1_setup_algs()
2323 wm_adsp_create_control(dsp, alg_region, 0, in wm_adsp1_setup_algs()
2327 adsp_warn(dsp, "Missing length info for region DM with ID %x\n", in wm_adsp1_setup_algs()
2332 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, in wm_adsp1_setup_algs()
2339 if (dsp->fw_ver == 0) { in wm_adsp1_setup_algs()
2344 wm_adsp_create_control(dsp, alg_region, 0, in wm_adsp1_setup_algs()
2348 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", in wm_adsp1_setup_algs()
2359 static int wm_adsp2_setup_algs(struct wm_adsp *dsp) in wm_adsp2_setup_algs() argument
2369 mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); in wm_adsp2_setup_algs()
2373 ret = regmap_raw_read(dsp->regmap, mem->base, &adsp2_id, in wm_adsp2_setup_algs()
2376 adsp_err(dsp, "Failed to read algorithm info: %d\n", in wm_adsp2_setup_algs()
2383 wmfw_parse_id_header(dsp, &adsp2_id.fw, n_algs); in wm_adsp2_setup_algs()
2385 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, in wm_adsp2_setup_algs()
2390 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, in wm_adsp2_setup_algs()
2395 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, in wm_adsp2_setup_algs()
2400 /* Calculate offset and length in DSP words */ in wm_adsp2_setup_algs()
2404 adsp2_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len); in wm_adsp2_setup_algs()
2409 adsp_info(dsp, in wm_adsp2_setup_algs()
2419 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, in wm_adsp2_setup_algs()
2426 if (dsp->fw_ver == 0) { in wm_adsp2_setup_algs()
2431 wm_adsp_create_control(dsp, alg_region, 0, in wm_adsp2_setup_algs()
2435 adsp_warn(dsp, "Missing length info for region XM with ID %x\n", in wm_adsp2_setup_algs()
2440 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, in wm_adsp2_setup_algs()
2447 if (dsp->fw_ver == 0) { in wm_adsp2_setup_algs()
2452 wm_adsp_create_control(dsp, alg_region, 0, in wm_adsp2_setup_algs()
2456 adsp_warn(dsp, "Missing length info for region YM with ID %x\n", in wm_adsp2_setup_algs()
2461 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, in wm_adsp2_setup_algs()
2468 if (dsp->fw_ver == 0) { in wm_adsp2_setup_algs()
2473 wm_adsp_create_control(dsp, alg_region, 0, in wm_adsp2_setup_algs()
2477 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", in wm_adsp2_setup_algs()
2488 static int wm_halo_create_regions(struct wm_adsp *dsp, __be32 id, in wm_halo_create_regions() argument
2497 return wm_adsp_create_regions(dsp, id, ARRAY_SIZE(types), types, bases); in wm_halo_create_regions()
2500 static int wm_halo_setup_algs(struct wm_adsp *dsp) in wm_halo_setup_algs() argument
2509 mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); in wm_halo_setup_algs()
2513 ret = regmap_raw_read(dsp->regmap, mem->base, &halo_id, in wm_halo_setup_algs()
2516 adsp_err(dsp, "Failed to read algorithm info: %d\n", in wm_halo_setup_algs()
2523 wmfw_v3_parse_id_header(dsp, &halo_id.fw, n_algs); in wm_halo_setup_algs()
2525 ret = wm_halo_create_regions(dsp, halo_id.fw.id, in wm_halo_setup_algs()
2530 /* Calculate offset and length in DSP words */ in wm_halo_setup_algs()
2534 halo_alg = wm_adsp_read_algs(dsp, n_algs, mem, pos, len); in wm_halo_setup_algs()
2539 adsp_info(dsp, in wm_halo_setup_algs()
2548 ret = wm_halo_create_regions(dsp, halo_alg[i].alg.id, in wm_halo_setup_algs()
2560 static int wm_adsp_load_coeff(struct wm_adsp *dsp) in wm_adsp_load_coeff() argument
2563 struct regmap *regmap = dsp->regmap; in wm_adsp_load_coeff()
2578 snprintf(file, PAGE_SIZE, "%s-%s-%s.bin", dsp->part, dsp->fwf_name, in wm_adsp_load_coeff()
2579 wm_adsp_fw[dsp->fw].file); in wm_adsp_load_coeff()
2582 ret = request_firmware(&firmware, file, dsp->dev); in wm_adsp_load_coeff()
2584 adsp_warn(dsp, "Failed to request '%s'\n", file); in wm_adsp_load_coeff()
2591 adsp_err(dsp, "%s: file too short, %zu bytes\n", in wm_adsp_load_coeff()
2598 adsp_err(dsp, "%s: invalid magic\n", file); in wm_adsp_load_coeff()
2606 adsp_err(dsp, "%s: Unsupported coefficient file format %d\n", in wm_adsp_load_coeff()
2612 adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, in wm_adsp_load_coeff()
2627 adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", in wm_adsp_load_coeff()
2632 adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", in wm_adsp_load_coeff()
2647 if (le32_to_cpu(blk->id) == dsp->fw_id && in wm_adsp_load_coeff()
2650 mem = wm_adsp_find_region(dsp, type); in wm_adsp_load_coeff()
2652 adsp_err(dsp, "No ZM\n"); in wm_adsp_load_coeff()
2655 reg = dsp->ops->region_to_reg(mem, 0); in wm_adsp_load_coeff()
2670 adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", in wm_adsp_load_coeff()
2674 mem = wm_adsp_find_region(dsp, type); in wm_adsp_load_coeff()
2676 adsp_err(dsp, "No base for region %x\n", type); in wm_adsp_load_coeff()
2680 alg_region = wm_adsp_find_alg_region(dsp, type, in wm_adsp_load_coeff()
2684 reg = dsp->ops->region_to_reg(mem, reg); in wm_adsp_load_coeff()
2687 adsp_err(dsp, "No %x for algorithm %x\n", in wm_adsp_load_coeff()
2693 adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", in wm_adsp_load_coeff()
2701 adsp_err(dsp, in wm_adsp_load_coeff()
2714 adsp_err(dsp, "Out of memory\n"); in wm_adsp_load_coeff()
2719 adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", in wm_adsp_load_coeff()
2725 adsp_err(dsp, in wm_adsp_load_coeff()
2737 adsp_err(dsp, "Failed to complete async write: %d\n", ret); in wm_adsp_load_coeff()
2740 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", in wm_adsp_load_coeff()
2743 wm_adsp_debugfs_save_binname(dsp, file); in wm_adsp_load_coeff()
2754 static int wm_adsp_create_name(struct wm_adsp *dsp) in wm_adsp_create_name() argument
2758 if (!dsp->name) { in wm_adsp_create_name()
2759 dsp->name = devm_kasprintf(dsp->dev, GFP_KERNEL, "DSP%d", in wm_adsp_create_name()
2760 dsp->num); in wm_adsp_create_name()
2761 if (!dsp->name) in wm_adsp_create_name()
2765 if (!dsp->fwf_name) { in wm_adsp_create_name()
2766 p = devm_kstrdup(dsp->dev, dsp->name, GFP_KERNEL); in wm_adsp_create_name()
2770 dsp->fwf_name = p; in wm_adsp_create_name()
2778 static int wm_adsp_common_init(struct wm_adsp *dsp) in wm_adsp_common_init() argument
2782 ret = wm_adsp_create_name(dsp); in wm_adsp_common_init()
2786 INIT_LIST_HEAD(&dsp->alg_regions); in wm_adsp_common_init()
2787 INIT_LIST_HEAD(&dsp->ctl_list); in wm_adsp_common_init()
2788 INIT_LIST_HEAD(&dsp->compr_list); in wm_adsp_common_init()
2789 INIT_LIST_HEAD(&dsp->buffer_list); in wm_adsp_common_init()
2791 mutex_init(&dsp->pwr_lock); in wm_adsp_common_init()
2796 int wm_adsp1_init(struct wm_adsp *dsp) in wm_adsp1_init() argument
2798 dsp->ops = &wm_adsp1_ops; in wm_adsp1_init()
2800 return wm_adsp_common_init(dsp); in wm_adsp1_init()
2810 struct wm_adsp *dsp = &dsps[w->shift]; in wm_adsp1_event() local
2815 dsp->component = component; in wm_adsp1_event()
2817 mutex_lock(&dsp->pwr_lock); in wm_adsp1_event()
2821 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, in wm_adsp1_event()
2825 * For simplicity set the DSP clock rate to be the in wm_adsp1_event()
2828 if (dsp->sysclk_reg) { in wm_adsp1_event()
2829 ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); in wm_adsp1_event()
2831 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", in wm_adsp1_event()
2836 val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; in wm_adsp1_event()
2838 ret = regmap_update_bits(dsp->regmap, in wm_adsp1_event()
2839 dsp->base + ADSP1_CONTROL_31, in wm_adsp1_event()
2842 adsp_err(dsp, "Failed to set clock rate: %d\n", in wm_adsp1_event()
2848 ret = wm_adsp_load(dsp); in wm_adsp1_event()
2852 ret = wm_adsp1_setup_algs(dsp); in wm_adsp1_event()
2856 ret = wm_adsp_load_coeff(dsp); in wm_adsp1_event()
2861 ret = wm_coeff_init_control_caches(dsp); in wm_adsp1_event()
2866 ret = wm_coeff_sync_controls(dsp); in wm_adsp1_event()
2870 dsp->booted = true; in wm_adsp1_event()
2873 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, in wm_adsp1_event()
2877 dsp->running = true; in wm_adsp1_event()
2881 dsp->running = false; in wm_adsp1_event()
2882 dsp->booted = false; in wm_adsp1_event()
2885 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, in wm_adsp1_event()
2888 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, in wm_adsp1_event()
2891 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, in wm_adsp1_event()
2894 list_for_each_entry(ctl, &dsp->ctl_list, list) in wm_adsp1_event()
2898 wm_adsp_free_alg_regions(dsp); in wm_adsp1_event()
2905 mutex_unlock(&dsp->pwr_lock); in wm_adsp1_event()
2910 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, in wm_adsp1_event()
2913 mutex_unlock(&dsp->pwr_lock); in wm_adsp1_event()
2919 static int wm_adsp2v2_enable_core(struct wm_adsp *dsp) in wm_adsp2v2_enable_core() argument
2926 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val); in wm_adsp2v2_enable_core()
2937 adsp_err(dsp, "Failed to start DSP RAM\n"); in wm_adsp2v2_enable_core()
2941 adsp_dbg(dsp, "RAM ready after %d polls\n", count); in wm_adsp2v2_enable_core()
2946 static int wm_adsp2_enable_core(struct wm_adsp *dsp) in wm_adsp2_enable_core() argument
2950 ret = regmap_update_bits_async(dsp->regmap, dsp->base + ADSP2_CONTROL, in wm_adsp2_enable_core()
2955 return wm_adsp2v2_enable_core(dsp); in wm_adsp2_enable_core()
2958 static int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) in wm_adsp2_lock() argument
2960 struct regmap *regmap = dsp->regmap; in wm_adsp2_lock()
2967 lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0; in wm_adsp2_lock()
2988 static int wm_adsp2_enable_memory(struct wm_adsp *dsp) in wm_adsp2_enable_memory() argument
2990 return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in wm_adsp2_enable_memory()
2994 static void wm_adsp2_disable_memory(struct wm_adsp *dsp) in wm_adsp2_disable_memory() argument
2996 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in wm_adsp2_disable_memory()
3000 static void wm_adsp2_disable_core(struct wm_adsp *dsp) in wm_adsp2_disable_core() argument
3002 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); in wm_adsp2_disable_core()
3003 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); in wm_adsp2_disable_core()
3004 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); in wm_adsp2_disable_core()
3006 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in wm_adsp2_disable_core()
3010 static void wm_adsp2v2_disable_core(struct wm_adsp *dsp) in wm_adsp2v2_disable_core() argument
3012 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); in wm_adsp2v2_disable_core()
3013 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); in wm_adsp2v2_disable_core()
3014 regmap_write(dsp->regmap, dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); in wm_adsp2v2_disable_core()
3019 struct wm_adsp *dsp = container_of(work, in wm_adsp_boot_work() local
3024 mutex_lock(&dsp->pwr_lock); in wm_adsp_boot_work()
3026 if (dsp->ops->enable_memory) { in wm_adsp_boot_work()
3027 ret = dsp->ops->enable_memory(dsp); in wm_adsp_boot_work()
3032 if (dsp->ops->enable_core) { in wm_adsp_boot_work()
3033 ret = dsp->ops->enable_core(dsp); in wm_adsp_boot_work()
3038 ret = wm_adsp_load(dsp); in wm_adsp_boot_work()
3042 ret = dsp->ops->setup_algs(dsp); in wm_adsp_boot_work()
3046 ret = wm_adsp_load_coeff(dsp); in wm_adsp_boot_work()
3051 ret = wm_coeff_init_control_caches(dsp); in wm_adsp_boot_work()
3055 if (dsp->ops->disable_core) in wm_adsp_boot_work()
3056 dsp->ops->disable_core(dsp); in wm_adsp_boot_work()
3058 dsp->booted = true; in wm_adsp_boot_work()
3060 mutex_unlock(&dsp->pwr_lock); in wm_adsp_boot_work()
3065 if (dsp->ops->disable_core) in wm_adsp_boot_work()
3066 dsp->ops->disable_core(dsp); in wm_adsp_boot_work()
3068 if (dsp->ops->disable_memory) in wm_adsp_boot_work()
3069 dsp->ops->disable_memory(dsp); in wm_adsp_boot_work()
3071 mutex_unlock(&dsp->pwr_lock); in wm_adsp_boot_work()
3074 static int wm_halo_configure_mpu(struct wm_adsp *dsp, unsigned int lock_regions) in wm_halo_configure_mpu() argument
3077 { dsp->base + HALO_MPU_LOCK_CONFIG, 0x5555 }, in wm_halo_configure_mpu()
3078 { dsp->base + HALO_MPU_LOCK_CONFIG, 0xAAAA }, in wm_halo_configure_mpu()
3079 { dsp->base + HALO_MPU_XMEM_ACCESS_0, 0xFFFFFFFF }, in wm_halo_configure_mpu()
3080 { dsp->base + HALO_MPU_YMEM_ACCESS_0, 0xFFFFFFFF }, in wm_halo_configure_mpu()
3081 { dsp->base + HALO_MPU_WINDOW_ACCESS_0, lock_regions }, in wm_halo_configure_mpu()
3082 { dsp->base + HALO_MPU_XREG_ACCESS_0, lock_regions }, in wm_halo_configure_mpu()
3083 { dsp->base + HALO_MPU_YREG_ACCESS_0, lock_regions }, in wm_halo_configure_mpu()
3084 { dsp->base + HALO_MPU_XMEM_ACCESS_1, 0xFFFFFFFF }, in wm_halo_configure_mpu()
3085 { dsp->base + HALO_MPU_YMEM_ACCESS_1, 0xFFFFFFFF }, in wm_halo_configure_mpu()
3086 { dsp->base + HALO_MPU_WINDOW_ACCESS_1, lock_regions }, in wm_halo_configure_mpu()
3087 { dsp->base + HALO_MPU_XREG_ACCESS_1, lock_regions }, in wm_halo_configure_mpu()
3088 { dsp->base + HALO_MPU_YREG_ACCESS_1, lock_regions }, in wm_halo_configure_mpu()
3089 { dsp->base + HALO_MPU_XMEM_ACCESS_2, 0xFFFFFFFF }, in wm_halo_configure_mpu()
3090 { dsp->base + HALO_MPU_YMEM_ACCESS_2, 0xFFFFFFFF }, in wm_halo_configure_mpu()
3091 { dsp->base + HALO_MPU_WINDOW_ACCESS_2, lock_regions }, in wm_halo_configure_mpu()
3092 { dsp->base + HALO_MPU_XREG_ACCESS_2, lock_regions }, in wm_halo_configure_mpu()
3093 { dsp->base + HALO_MPU_YREG_ACCESS_2, lock_regions }, in wm_halo_configure_mpu()
3094 { dsp->base + HALO_MPU_XMEM_ACCESS_3, 0xFFFFFFFF }, in wm_halo_configure_mpu()
3095 { dsp->base + HALO_MPU_YMEM_ACCESS_3, 0xFFFFFFFF }, in wm_halo_configure_mpu()
3096 { dsp->base + HALO_MPU_WINDOW_ACCESS_3, lock_regions }, in wm_halo_configure_mpu()
3097 { dsp->base + HALO_MPU_XREG_ACCESS_3, lock_regions }, in wm_halo_configure_mpu()
3098 { dsp->base + HALO_MPU_YREG_ACCESS_3, lock_regions }, in wm_halo_configure_mpu()
3099 { dsp->base + HALO_MPU_LOCK_CONFIG, 0 }, in wm_halo_configure_mpu()
3102 return regmap_multi_reg_write(dsp->regmap, config, ARRAY_SIZE(config)); in wm_halo_configure_mpu()
3109 struct wm_adsp *dsp = &dsps[w->shift]; in wm_adsp2_set_dspclk() local
3112 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CLOCKING, in wm_adsp2_set_dspclk()
3116 adsp_err(dsp, "Failed to set clock rate: %d\n", ret); in wm_adsp2_set_dspclk()
3129 struct wm_adsp *dsp = &dsps[mc->shift - 1]; in wm_adsp2_preloader_get() local
3131 ucontrol->value.integer.value[0] = dsp->preloaded; in wm_adsp2_preloader_get()
3145 struct wm_adsp *dsp = &dsps[mc->shift - 1]; in wm_adsp2_preloader_put() local
3148 snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->name); in wm_adsp2_preloader_put()
3150 dsp->preloaded = ucontrol->value.integer.value[0]; in wm_adsp2_preloader_put()
3159 flush_work(&dsp->boot_work); in wm_adsp2_preloader_put()
3165 static void wm_adsp_stop_watchdog(struct wm_adsp *dsp) in wm_adsp_stop_watchdog() argument
3167 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, in wm_adsp_stop_watchdog()
3171 static void wm_halo_stop_watchdog(struct wm_adsp *dsp) in wm_halo_stop_watchdog() argument
3173 regmap_update_bits(dsp->regmap, dsp->base + HALO_WDT_CONTROL, in wm_halo_stop_watchdog()
3182 struct wm_adsp *dsp = &dsps[w->shift]; in wm_adsp_early_event() local
3187 queue_work(system_unbound_wq, &dsp->boot_work); in wm_adsp_early_event()
3190 mutex_lock(&dsp->pwr_lock); in wm_adsp_early_event()
3192 wm_adsp_debugfs_clear(dsp); in wm_adsp_early_event()
3194 dsp->fw_id = 0; in wm_adsp_early_event()
3195 dsp->fw_id_version = 0; in wm_adsp_early_event()
3197 dsp->booted = false; in wm_adsp_early_event()
3199 if (dsp->ops->disable_memory) in wm_adsp_early_event()
3200 dsp->ops->disable_memory(dsp); in wm_adsp_early_event()
3202 list_for_each_entry(ctl, &dsp->ctl_list, list) in wm_adsp_early_event()
3205 wm_adsp_free_alg_regions(dsp); in wm_adsp_early_event()
3207 mutex_unlock(&dsp->pwr_lock); in wm_adsp_early_event()
3209 adsp_dbg(dsp, "Shutdown complete\n"); in wm_adsp_early_event()
3219 static int wm_adsp2_start_core(struct wm_adsp *dsp) in wm_adsp2_start_core() argument
3221 return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in wm_adsp2_start_core()
3226 static void wm_adsp2_stop_core(struct wm_adsp *dsp) in wm_adsp2_stop_core() argument
3228 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in wm_adsp2_stop_core()
3237 struct wm_adsp *dsp = &dsps[w->shift]; in wm_adsp_event() local
3242 flush_work(&dsp->boot_work); in wm_adsp_event()
3244 mutex_lock(&dsp->pwr_lock); in wm_adsp_event()
3246 if (!dsp->booted) { in wm_adsp_event()
3251 if (dsp->ops->enable_core) { in wm_adsp_event()
3252 ret = dsp->ops->enable_core(dsp); in wm_adsp_event()
3258 ret = wm_coeff_sync_controls(dsp); in wm_adsp_event()
3262 if (dsp->ops->lock_memory) { in wm_adsp_event()
3263 ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); in wm_adsp_event()
3265 adsp_err(dsp, "Error configuring MPU: %d\n", in wm_adsp_event()
3271 if (dsp->ops->start_core) { in wm_adsp_event()
3272 ret = dsp->ops->start_core(dsp); in wm_adsp_event()
3277 if (wm_adsp_fw[dsp->fw].num_caps != 0) { in wm_adsp_event()
3278 ret = wm_adsp_buffer_init(dsp); in wm_adsp_event()
3283 dsp->running = true; in wm_adsp_event()
3285 mutex_unlock(&dsp->pwr_lock); in wm_adsp_event()
3290 wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN); in wm_adsp_event()
3292 if (dsp->ops->stop_watchdog) in wm_adsp_event()
3293 dsp->ops->stop_watchdog(dsp); in wm_adsp_event()
3296 if (dsp->ops->show_fw_status) in wm_adsp_event()
3297 dsp->ops->show_fw_status(dsp); in wm_adsp_event()
3299 mutex_lock(&dsp->pwr_lock); in wm_adsp_event()
3301 dsp->running = false; in wm_adsp_event()
3303 if (dsp->ops->stop_core) in wm_adsp_event()
3304 dsp->ops->stop_core(dsp); in wm_adsp_event()
3305 if (dsp->ops->disable_core) in wm_adsp_event()
3306 dsp->ops->disable_core(dsp); in wm_adsp_event()
3308 if (wm_adsp_fw[dsp->fw].num_caps != 0) in wm_adsp_event()
3309 wm_adsp_buffer_free(dsp); in wm_adsp_event()
3311 dsp->fatal_error = false; in wm_adsp_event()
3313 mutex_unlock(&dsp->pwr_lock); in wm_adsp_event()
3315 adsp_dbg(dsp, "Execution stopped\n"); in wm_adsp_event()
3324 if (dsp->ops->stop_core) in wm_adsp_event()
3325 dsp->ops->stop_core(dsp); in wm_adsp_event()
3326 if (dsp->ops->disable_core) in wm_adsp_event()
3327 dsp->ops->disable_core(dsp); in wm_adsp_event()
3328 mutex_unlock(&dsp->pwr_lock); in wm_adsp_event()
3333 static int wm_halo_start_core(struct wm_adsp *dsp) in wm_halo_start_core() argument
3335 return regmap_update_bits(dsp->regmap, in wm_halo_start_core()
3336 dsp->base + HALO_CCM_CORE_CONTROL, in wm_halo_start_core()
3341 static void wm_halo_stop_core(struct wm_adsp *dsp) in wm_halo_stop_core() argument
3343 regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, in wm_halo_stop_core()
3347 regmap_update_bits(dsp->regmap, dsp->base + HALO_CORE_SOFT_RESET, in wm_halo_stop_core()
3351 int wm_adsp2_component_probe(struct wm_adsp *dsp, struct snd_soc_component *component) in wm_adsp2_component_probe() argument
3355 snprintf(preload, ARRAY_SIZE(preload), "%s Preload", dsp->name); in wm_adsp2_component_probe()
3358 wm_adsp2_init_debugfs(dsp, component); in wm_adsp2_component_probe()
3360 dsp->component = component; in wm_adsp2_component_probe()
3366 int wm_adsp2_component_remove(struct wm_adsp *dsp, struct snd_soc_component *component) in wm_adsp2_component_remove() argument
3368 wm_adsp2_cleanup_debugfs(dsp); in wm_adsp2_component_remove()
3374 int wm_adsp2_init(struct wm_adsp *dsp) in wm_adsp2_init() argument
3378 ret = wm_adsp_common_init(dsp); in wm_adsp2_init()
3382 switch (dsp->rev) { in wm_adsp2_init()
3385 * Disable the DSP memory by default when in reset for a small in wm_adsp2_init()
3388 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in wm_adsp2_init()
3391 adsp_err(dsp, in wm_adsp2_init()
3396 dsp->ops = &wm_adsp2_ops[0]; in wm_adsp2_init()
3399 dsp->ops = &wm_adsp2_ops[1]; in wm_adsp2_init()
3402 dsp->ops = &wm_adsp2_ops[2]; in wm_adsp2_init()
3406 INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); in wm_adsp2_init()
3412 int wm_halo_init(struct wm_adsp *dsp) in wm_halo_init() argument
3416 ret = wm_adsp_common_init(dsp); in wm_halo_init()
3420 dsp->ops = &wm_halo_ops; in wm_halo_init()
3422 INIT_WORK(&dsp->boot_work, wm_adsp_boot_work); in wm_halo_init()
3428 void wm_adsp2_remove(struct wm_adsp *dsp) in wm_adsp2_remove() argument
3432 while (!list_empty(&dsp->ctl_list)) { in wm_adsp2_remove()
3433 ctl = list_first_entry(&dsp->ctl_list, struct wm_coeff_ctl, in wm_adsp2_remove()
3450 if (compr->dsp->fatal_error) in wm_adsp_compr_attach()
3453 list_for_each_entry(tmp, &compr->dsp->buffer_list, list) { in wm_adsp_compr_attach()
3484 int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) in wm_adsp_compr_open() argument
3490 mutex_lock(&dsp->pwr_lock); in wm_adsp_compr_open()
3492 if (wm_adsp_fw[dsp->fw].num_caps == 0) { in wm_adsp_compr_open()
3493 adsp_err(dsp, "%s: Firmware does not support compressed API\n", in wm_adsp_compr_open()
3499 if (wm_adsp_fw[dsp->fw].compr_direction != stream->direction) { in wm_adsp_compr_open()
3500 adsp_err(dsp, "%s: Firmware does not support stream direction\n", in wm_adsp_compr_open()
3506 list_for_each_entry(tmp, &dsp->compr_list, list) { in wm_adsp_compr_open()
3508 adsp_err(dsp, "%s: Only a single stream supported per dai\n", in wm_adsp_compr_open()
3521 compr->dsp = dsp; in wm_adsp_compr_open()
3525 list_add_tail(&compr->list, &dsp->compr_list); in wm_adsp_compr_open()
3530 mutex_unlock(&dsp->pwr_lock); in wm_adsp_compr_open()
3540 struct wm_adsp *dsp = compr->dsp; in wm_adsp_compr_free() local
3542 mutex_lock(&dsp->pwr_lock); in wm_adsp_compr_free()
3550 mutex_unlock(&dsp->pwr_lock); in wm_adsp_compr_free()
3560 struct wm_adsp *dsp = compr->dsp; in wm_adsp_compr_check_params() local
3577 for (i = 0; i < wm_adsp_fw[dsp->fw].num_caps; i++) { in wm_adsp_compr_check_params()
3578 caps = &wm_adsp_fw[dsp->fw].caps[i]; in wm_adsp_compr_check_params()
3644 int fw = compr->dsp->fw; in wm_adsp_compr_get_caps()
3664 static int wm_adsp_read_raw_data_block(struct wm_adsp *dsp, int mem_type, in wm_adsp_read_raw_data_block() argument
3668 struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); in wm_adsp_read_raw_data_block()
3675 reg = dsp->ops->region_to_reg(mem, mem_addr); in wm_adsp_read_raw_data_block()
3677 ret = regmap_raw_read(dsp->regmap, reg, data, in wm_adsp_read_raw_data_block()
3685 static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, in wm_adsp_read_data_word() argument
3691 ret = wm_adsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); in wm_adsp_read_data_word()
3700 static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, in wm_adsp_write_data_word() argument
3703 struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); in wm_adsp_write_data_word()
3710 reg = dsp->ops->region_to_reg(mem, mem_addr); in wm_adsp_write_data_word()
3712 return regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); in wm_adsp_write_data_word()
3718 return wm_adsp_read_data_word(buf->dsp, buf->host_buf_mem_type, in wm_adsp_buffer_read()
3725 return wm_adsp_write_data_word(buf->dsp, buf->host_buf_mem_type, in wm_adsp_buffer_write()
3736 * DSP words from the register map have pad bytes and the data bytes in wm_adsp_remove_padding()
3750 const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps; in wm_adsp_buffer_populate()
3794 static struct wm_adsp_compr_buf *wm_adsp_buffer_alloc(struct wm_adsp *dsp) in wm_adsp_buffer_alloc() argument
3802 buf->dsp = dsp; in wm_adsp_buffer_alloc()
3806 list_add_tail(&buf->list, &dsp->buffer_list); in wm_adsp_buffer_alloc()
3811 static int wm_adsp_buffer_parse_legacy(struct wm_adsp *dsp) in wm_adsp_buffer_parse_legacy() argument
3818 alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); in wm_adsp_buffer_parse_legacy()
3820 adsp_err(dsp, "No algorithm region found\n"); in wm_adsp_buffer_parse_legacy()
3824 buf = wm_adsp_buffer_alloc(dsp); in wm_adsp_buffer_parse_legacy()
3828 xmalg = dsp->ops->sys_config_size / sizeof(__be32); in wm_adsp_buffer_parse_legacy()
3831 ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); in wm_adsp_buffer_parse_legacy()
3840 ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, in wm_adsp_buffer_parse_legacy()
3878 ret = regmap_raw_read(ctl->dsp->regmap, reg, &bufp, sizeof(bufp)); in wm_adsp_buffer_parse_coeff()
3889 adsp_err(ctl->dsp, "Failed to acquire host buffer\n"); in wm_adsp_buffer_parse_coeff()
3893 buf = wm_adsp_buffer_alloc(ctl->dsp); in wm_adsp_buffer_parse_coeff()
3913 ret = regmap_raw_read(ctl->dsp->regmap, reg, &coeff_v1, in wm_adsp_buffer_parse_coeff()
3922 adsp_err(ctl->dsp, in wm_adsp_buffer_parse_coeff()
3930 buf->name = kasprintf(GFP_KERNEL, "%s-dsp-%s", ctl->dsp->part, in wm_adsp_buffer_parse_coeff()
3939 static int wm_adsp_buffer_init(struct wm_adsp *dsp) in wm_adsp_buffer_init() argument
3944 list_for_each_entry(ctl, &dsp->ctl_list, list) { in wm_adsp_buffer_init()
3953 adsp_err(dsp, "Failed to parse coeff: %d\n", ret); in wm_adsp_buffer_init()
3961 if (list_empty(&dsp->buffer_list)) { in wm_adsp_buffer_init()
3963 ret = wm_adsp_buffer_parse_legacy(dsp); in wm_adsp_buffer_init()
3965 adsp_err(dsp, "Failed to parse legacy: %d\n", ret); in wm_adsp_buffer_init()
3973 wm_adsp_buffer_free(dsp); in wm_adsp_buffer_init()
3977 static int wm_adsp_buffer_free(struct wm_adsp *dsp) in wm_adsp_buffer_free() argument
3981 list_for_each_entry_safe(buf, tmp, &dsp->buffer_list, list) { in wm_adsp_buffer_free()
4014 struct wm_adsp *dsp = compr->dsp; in wm_adsp_compr_trigger() local
4019 mutex_lock(&dsp->pwr_lock); in wm_adsp_compr_trigger()
4055 mutex_unlock(&dsp->pwr_lock); in wm_adsp_compr_trigger()
4063 int last_region = wm_adsp_fw[buf->dsp->fw].caps->num_regions - 1; in wm_adsp_buffer_size()
4111 int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) in wm_adsp_compr_handle_irq() argument
4117 mutex_lock(&dsp->pwr_lock); in wm_adsp_compr_handle_irq()
4119 if (list_empty(&dsp->buffer_list)) { in wm_adsp_compr_handle_irq()
4124 adsp_dbg(dsp, "Handling buffer IRQ\n"); in wm_adsp_compr_handle_irq()
4126 list_for_each_entry(buf, &dsp->buffer_list, list) { in wm_adsp_compr_handle_irq()
4146 if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2) in wm_adsp_compr_handle_irq()
4155 mutex_unlock(&dsp->pwr_lock); in wm_adsp_compr_handle_irq()
4179 struct wm_adsp *dsp = compr->dsp; in wm_adsp_compr_pointer() local
4185 mutex_lock(&dsp->pwr_lock); in wm_adsp_compr_pointer()
4189 if (dsp->fatal_error || !buf || buf->error) { in wm_adsp_compr_pointer()
4204 * DSP to inform us once a whole fragment is available. in wm_adsp_compr_pointer()
4229 mutex_unlock(&dsp->pwr_lock); in wm_adsp_compr_pointer()
4243 for (i = 0; i < wm_adsp_fw[buf->dsp->fw].caps->num_regions; ++i) in wm_adsp_buffer_capture_block()
4247 if (i == wm_adsp_fw[buf->dsp->fw].caps->num_regions) in wm_adsp_buffer_capture_block()
4266 /* Read data from DSP */ in wm_adsp_buffer_capture_block()
4267 ret = wm_adsp_read_raw_data_block(buf->dsp, mem_type, adsp_addr, in wm_adsp_buffer_capture_block()
4293 struct wm_adsp *dsp = compr->dsp; in wm_adsp_compr_read() local
4299 if (dsp->fatal_error || !compr->buf || compr->buf->error) { in wm_adsp_compr_read()
4338 struct wm_adsp *dsp = compr->dsp; in wm_adsp_compr_copy() local
4341 mutex_lock(&dsp->pwr_lock); in wm_adsp_compr_copy()
4348 mutex_unlock(&dsp->pwr_lock); in wm_adsp_compr_copy()
4354 static void wm_adsp_fatal_error(struct wm_adsp *dsp) in wm_adsp_fatal_error() argument
4358 dsp->fatal_error = true; in wm_adsp_fatal_error()
4360 list_for_each_entry(compr, &dsp->compr_list, list) { in wm_adsp_fatal_error()
4368 struct wm_adsp *dsp = (struct wm_adsp *)data; in wm_adsp2_bus_error() local
4370 struct regmap *regmap = dsp->regmap; in wm_adsp2_bus_error()
4373 mutex_lock(&dsp->pwr_lock); in wm_adsp2_bus_error()
4375 ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); in wm_adsp2_bus_error()
4377 adsp_err(dsp, in wm_adsp2_bus_error()
4383 adsp_err(dsp, "watchdog timeout error\n"); in wm_adsp2_bus_error()
4384 dsp->ops->stop_watchdog(dsp); in wm_adsp2_bus_error()
4385 wm_adsp_fatal_error(dsp); in wm_adsp2_bus_error()
4390 adsp_err(dsp, "bus error: address error\n"); in wm_adsp2_bus_error()
4392 adsp_err(dsp, "bus error: region lock error\n"); in wm_adsp2_bus_error()
4394 ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val); in wm_adsp2_bus_error()
4396 adsp_err(dsp, in wm_adsp2_bus_error()
4402 adsp_err(dsp, "bus error address = 0x%x\n", in wm_adsp2_bus_error()
4406 dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR, in wm_adsp2_bus_error()
4409 adsp_err(dsp, in wm_adsp2_bus_error()
4415 adsp_err(dsp, "xmem error address = 0x%x\n", in wm_adsp2_bus_error()
4417 adsp_err(dsp, "pmem error address = 0x%x\n", in wm_adsp2_bus_error()
4422 regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, in wm_adsp2_bus_error()
4426 mutex_unlock(&dsp->pwr_lock); in wm_adsp2_bus_error()
4434 struct wm_adsp *dsp = (struct wm_adsp *)data; in wm_halo_bus_error() local
4435 struct regmap *regmap = dsp->regmap; in wm_halo_bus_error()
4438 { dsp->base + HALO_MPU_XM_VIO_STATUS, 0x0 }, in wm_halo_bus_error()
4439 { dsp->base + HALO_MPU_YM_VIO_STATUS, 0x0 }, in wm_halo_bus_error()
4440 { dsp->base + HALO_MPU_PM_VIO_STATUS, 0x0 }, in wm_halo_bus_error()
4444 mutex_lock(&dsp->pwr_lock); in wm_halo_bus_error()
4446 ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_1, in wm_halo_bus_error()
4449 adsp_warn(dsp, "Failed to read AHB DEBUG_1: %d\n", ret); in wm_halo_bus_error()
4453 adsp_warn(dsp, "AHB: STATUS: 0x%x ADDR: 0x%x\n", in wm_halo_bus_error()
4458 ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_0, in wm_halo_bus_error()
4461 adsp_warn(dsp, "Failed to read AHB DEBUG_0: %d\n", ret); in wm_halo_bus_error()
4465 adsp_warn(dsp, "AHB: SYS_ADDR: 0x%x\n", *fault); in wm_halo_bus_error()
4467 ret = regmap_bulk_read(regmap, dsp->base + HALO_MPU_XM_VIO_ADDR, in wm_halo_bus_error()
4470 adsp_warn(dsp, "Failed to read MPU fault info: %d\n", ret); in wm_halo_bus_error()
4474 adsp_warn(dsp, "XM: STATUS:0x%x ADDR:0x%x\n", fault[1], fault[0]); in wm_halo_bus_error()
4475 adsp_warn(dsp, "YM: STATUS:0x%x ADDR:0x%x\n", fault[3], fault[2]); in wm_halo_bus_error()
4476 adsp_warn(dsp, "PM: STATUS:0x%x ADDR:0x%x\n", fault[5], fault[4]); in wm_halo_bus_error()
4478 ret = regmap_multi_reg_write(dsp->regmap, clear, ARRAY_SIZE(clear)); in wm_halo_bus_error()
4480 adsp_warn(dsp, "Failed to clear MPU status: %d\n", ret); in wm_halo_bus_error()
4483 mutex_unlock(&dsp->pwr_lock); in wm_halo_bus_error()
4491 struct wm_adsp *dsp = data; in wm_halo_wdt_expire() local
4493 mutex_lock(&dsp->pwr_lock); in wm_halo_wdt_expire()
4495 adsp_warn(dsp, "WDT Expiry Fault\n"); in wm_halo_wdt_expire()
4496 dsp->ops->stop_watchdog(dsp); in wm_halo_wdt_expire()
4497 wm_adsp_fatal_error(dsp); in wm_halo_wdt_expire()
4499 mutex_unlock(&dsp->pwr_lock); in wm_halo_wdt_expire()