Lines Matching refs:dsp

286 	bool (*validate_version)(struct cs_dsp *dsp, unsigned int version);
287 unsigned int (*parse_sizes)(struct cs_dsp *dsp,
291 int (*setup_algs)(struct cs_dsp *dsp);
295 void (*show_fw_status)(struct cs_dsp *dsp);
296 void (*stop_watchdog)(struct cs_dsp *dsp);
298 int (*enable_memory)(struct cs_dsp *dsp);
299 void (*disable_memory)(struct cs_dsp *dsp);
300 int (*lock_memory)(struct cs_dsp *dsp, unsigned int lock_regions);
302 int (*enable_core)(struct cs_dsp *dsp);
303 void (*disable_core)(struct cs_dsp *dsp);
305 int (*start_core)(struct cs_dsp *dsp);
306 void (*stop_core)(struct cs_dsp *dsp);
389 static void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, const char *s) in cs_dsp_debugfs_save_wmfwname() argument
393 kfree(dsp->wmfw_file_name); in cs_dsp_debugfs_save_wmfwname()
394 dsp->wmfw_file_name = tmp; in cs_dsp_debugfs_save_wmfwname()
397 static void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, const char *s) in cs_dsp_debugfs_save_binname() argument
401 kfree(dsp->bin_file_name); in cs_dsp_debugfs_save_binname()
402 dsp->bin_file_name = tmp; in cs_dsp_debugfs_save_binname()
405 static void cs_dsp_debugfs_clear(struct cs_dsp *dsp) in cs_dsp_debugfs_clear() argument
407 kfree(dsp->wmfw_file_name); in cs_dsp_debugfs_clear()
408 kfree(dsp->bin_file_name); in cs_dsp_debugfs_clear()
409 dsp->wmfw_file_name = NULL; in cs_dsp_debugfs_clear()
410 dsp->bin_file_name = NULL; in cs_dsp_debugfs_clear()
417 struct cs_dsp *dsp = file->private_data; in cs_dsp_debugfs_wmfw_read() local
420 mutex_lock(&dsp->pwr_lock); in cs_dsp_debugfs_wmfw_read()
422 if (!dsp->wmfw_file_name || !dsp->booted) in cs_dsp_debugfs_wmfw_read()
426 dsp->wmfw_file_name, in cs_dsp_debugfs_wmfw_read()
427 strlen(dsp->wmfw_file_name)); in cs_dsp_debugfs_wmfw_read()
429 mutex_unlock(&dsp->pwr_lock); in cs_dsp_debugfs_wmfw_read()
437 struct cs_dsp *dsp = file->private_data; in cs_dsp_debugfs_bin_read() local
440 mutex_lock(&dsp->pwr_lock); in cs_dsp_debugfs_bin_read()
442 if (!dsp->bin_file_name || !dsp->booted) in cs_dsp_debugfs_bin_read()
446 dsp->bin_file_name, in cs_dsp_debugfs_bin_read()
447 strlen(dsp->bin_file_name)); in cs_dsp_debugfs_bin_read()
449 mutex_unlock(&dsp->pwr_lock); in cs_dsp_debugfs_bin_read()
478 struct cs_dsp *dsp = s->private; in cs_dsp_debugfs_read_controls_show() local
482 list_for_each_entry(ctl, &dsp->ctl_list, list) { in cs_dsp_debugfs_read_controls_show()
506 void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root) in cs_dsp_init_debugfs() argument
511 root = debugfs_create_dir(dsp->name, debugfs_root); in cs_dsp_init_debugfs()
513 debugfs_create_bool("booted", 0444, root, &dsp->booted); in cs_dsp_init_debugfs()
514 debugfs_create_bool("running", 0444, root, &dsp->running); in cs_dsp_init_debugfs()
515 debugfs_create_x32("fw_id", 0444, root, &dsp->fw_id); in cs_dsp_init_debugfs()
516 debugfs_create_x32("fw_version", 0444, root, &dsp->fw_id_version); in cs_dsp_init_debugfs()
520 dsp, &cs_dsp_debugfs_fops[i].fops); in cs_dsp_init_debugfs()
522 debugfs_create_file("controls", 0444, root, dsp, in cs_dsp_init_debugfs()
525 dsp->debugfs_root = root; in cs_dsp_init_debugfs()
533 void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) in cs_dsp_cleanup_debugfs() argument
535 cs_dsp_debugfs_clear(dsp); in cs_dsp_cleanup_debugfs()
536 debugfs_remove_recursive(dsp->debugfs_root); in cs_dsp_cleanup_debugfs()
537 dsp->debugfs_root = ERR_PTR(-ENODEV); in cs_dsp_cleanup_debugfs()
541 void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root) in cs_dsp_init_debugfs() argument
546 void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp) in cs_dsp_cleanup_debugfs() argument
551 static inline void cs_dsp_debugfs_save_wmfwname(struct cs_dsp *dsp, in cs_dsp_debugfs_save_wmfwname() argument
556 static inline void cs_dsp_debugfs_save_binname(struct cs_dsp *dsp, in cs_dsp_debugfs_save_binname() argument
561 static inline void cs_dsp_debugfs_clear(struct cs_dsp *dsp) in cs_dsp_debugfs_clear() argument
566 static const struct cs_dsp_region *cs_dsp_find_region(struct cs_dsp *dsp, in cs_dsp_find_region() argument
571 for (i = 0; i < dsp->num_mems; i++) in cs_dsp_find_region()
572 if (dsp->mem[i].type == type) in cs_dsp_find_region()
573 return &dsp->mem[i]; in cs_dsp_find_region()
613 static void cs_dsp_read_fw_status(struct cs_dsp *dsp, in cs_dsp_read_fw_status() argument
620 ret = regmap_read(dsp->regmap, dsp->base + offs[i], &offs[i]); in cs_dsp_read_fw_status()
622 cs_dsp_err(dsp, "Failed to read SCRATCH%u: %d\n", i, ret); in cs_dsp_read_fw_status()
628 static void cs_dsp_adsp2_show_fw_status(struct cs_dsp *dsp) in cs_dsp_adsp2_show_fw_status() argument
634 cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); in cs_dsp_adsp2_show_fw_status()
636 cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", in cs_dsp_adsp2_show_fw_status()
640 static void cs_dsp_adsp2v2_show_fw_status(struct cs_dsp *dsp) in cs_dsp_adsp2v2_show_fw_status() argument
644 cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); in cs_dsp_adsp2v2_show_fw_status()
646 cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", in cs_dsp_adsp2v2_show_fw_status()
651 static void cs_dsp_halo_show_fw_status(struct cs_dsp *dsp) in cs_dsp_halo_show_fw_status() argument
657 cs_dsp_read_fw_status(dsp, ARRAY_SIZE(offs), offs); in cs_dsp_halo_show_fw_status()
659 cs_dsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", in cs_dsp_halo_show_fw_status()
667 struct cs_dsp *dsp = ctl->dsp; in cs_dsp_coeff_base_reg() local
670 mem = cs_dsp_find_region(dsp, alg_region->type); in cs_dsp_coeff_base_reg()
672 cs_dsp_err(dsp, "No base for region %x\n", in cs_dsp_coeff_base_reg()
677 *reg = dsp->ops->region_to_reg(mem, ctl->alg_region.base + ctl->offset + off); in cs_dsp_coeff_base_reg()
696 struct cs_dsp *dsp = ctl->dsp; in cs_dsp_coeff_write_acked_control() local
701 lockdep_assert_held(&dsp->pwr_lock); in cs_dsp_coeff_write_acked_control()
703 if (!dsp->running) in cs_dsp_coeff_write_acked_control()
710 cs_dsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", in cs_dsp_coeff_write_acked_control()
714 ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); in cs_dsp_coeff_write_acked_control()
716 cs_dsp_err(dsp, "Failed to write %x: %d\n", reg, ret); in cs_dsp_coeff_write_acked_control()
738 ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); in cs_dsp_coeff_write_acked_control()
740 cs_dsp_err(dsp, "Failed to read %x: %d\n", reg, ret); in cs_dsp_coeff_write_acked_control()
745 cs_dsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); in cs_dsp_coeff_write_acked_control()
750 cs_dsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", in cs_dsp_coeff_write_acked_control()
762 struct cs_dsp *dsp = ctl->dsp; in cs_dsp_coeff_write_ctrl_raw() local
775 ret = regmap_raw_write(dsp->regmap, reg, scratch, in cs_dsp_coeff_write_ctrl_raw()
778 cs_dsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", in cs_dsp_coeff_write_ctrl_raw()
783 cs_dsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg); in cs_dsp_coeff_write_ctrl_raw()
809 lockdep_assert_held(&ctl->dsp->pwr_lock); in cs_dsp_coeff_write_ctrl()
827 if (ctl->enabled && ctl->dsp->running) in cs_dsp_coeff_write_ctrl()
851 struct cs_dsp *dsp = ctl->dsp; in cs_dsp_coeff_lock_and_write_ctrl() local
854 lockdep_assert_not_held(&dsp->pwr_lock); in cs_dsp_coeff_lock_and_write_ctrl()
856 mutex_lock(&dsp->pwr_lock); in cs_dsp_coeff_lock_and_write_ctrl()
858 mutex_unlock(&dsp->pwr_lock); in cs_dsp_coeff_lock_and_write_ctrl()
867 struct cs_dsp *dsp = ctl->dsp; in cs_dsp_coeff_read_ctrl_raw() local
880 ret = regmap_raw_read(dsp->regmap, reg, scratch, len); in cs_dsp_coeff_read_ctrl_raw()
882 cs_dsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", in cs_dsp_coeff_read_ctrl_raw()
887 cs_dsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg); in cs_dsp_coeff_read_ctrl_raw()
914 lockdep_assert_held(&ctl->dsp->pwr_lock); in cs_dsp_coeff_read_ctrl()
920 if (ctl->enabled && ctl->dsp->running) in cs_dsp_coeff_read_ctrl()
925 if (!ctl->flags && ctl->enabled && ctl->dsp->running) in cs_dsp_coeff_read_ctrl()
950 struct cs_dsp *dsp = ctl->dsp; in cs_dsp_coeff_lock_and_read_ctrl() local
953 lockdep_assert_not_held(&dsp->pwr_lock); in cs_dsp_coeff_lock_and_read_ctrl()
955 mutex_lock(&dsp->pwr_lock); in cs_dsp_coeff_lock_and_read_ctrl()
957 mutex_unlock(&dsp->pwr_lock); in cs_dsp_coeff_lock_and_read_ctrl()
963 static int cs_dsp_coeff_init_control_caches(struct cs_dsp *dsp) in cs_dsp_coeff_init_control_caches() argument
968 list_for_each_entry(ctl, &dsp->ctl_list, list) { in cs_dsp_coeff_init_control_caches()
989 static int cs_dsp_coeff_sync_controls(struct cs_dsp *dsp) in cs_dsp_coeff_sync_controls() argument
994 list_for_each_entry(ctl, &dsp->ctl_list, list) { in cs_dsp_coeff_sync_controls()
1008 static void cs_dsp_signal_event_controls(struct cs_dsp *dsp, in cs_dsp_signal_event_controls() argument
1014 list_for_each_entry(ctl, &dsp->ctl_list, list) { in cs_dsp_signal_event_controls()
1023 cs_dsp_warn(dsp, in cs_dsp_signal_event_controls()
1036 static int cs_dsp_create_control(struct cs_dsp *dsp, in cs_dsp_create_control() argument
1045 list_for_each_entry(ctl, &dsp->ctl_list, list) { in cs_dsp_create_control()
1046 if (ctl->fw_name == dsp->fw_name && in cs_dsp_create_control()
1063 ctl->fw_name = dsp->fw_name; in cs_dsp_create_control()
1065 if (subname && dsp->wmfw_ver >= 2) { in cs_dsp_create_control()
1075 ctl->dsp = dsp; in cs_dsp_create_control()
1087 list_add(&ctl->list, &dsp->ctl_list); in cs_dsp_create_control()
1089 if (dsp->client_ops->control_add) { in cs_dsp_create_control()
1090 ret = dsp->client_ops->control_add(ctl); in cs_dsp_create_control()
1181 static int cs_dsp_coeff_parse_alg(struct cs_dsp *dsp, in cs_dsp_coeff_parse_alg() argument
1192 switch (dsp->wmfw_ver) { in cs_dsp_coeff_parse_alg()
1236 cs_dsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); in cs_dsp_coeff_parse_alg()
1237 cs_dsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); in cs_dsp_coeff_parse_alg()
1238 cs_dsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); in cs_dsp_coeff_parse_alg()
1243 static int cs_dsp_coeff_parse_coeff(struct cs_dsp *dsp, in cs_dsp_coeff_parse_coeff() argument
1269 switch (dsp->wmfw_ver) { in cs_dsp_coeff_parse_coeff()
1312 cs_dsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); in cs_dsp_coeff_parse_coeff()
1313 cs_dsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); in cs_dsp_coeff_parse_coeff()
1314 cs_dsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); in cs_dsp_coeff_parse_coeff()
1315 cs_dsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); in cs_dsp_coeff_parse_coeff()
1316 cs_dsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); in cs_dsp_coeff_parse_coeff()
1317 cs_dsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); in cs_dsp_coeff_parse_coeff()
1322 static int cs_dsp_check_coeff_flags(struct cs_dsp *dsp, in cs_dsp_check_coeff_flags() argument
1329 cs_dsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", in cs_dsp_check_coeff_flags()
1337 static int cs_dsp_parse_coeff(struct cs_dsp *dsp, in cs_dsp_parse_coeff() argument
1345 pos = cs_dsp_coeff_parse_alg(dsp, region, &alg_blk); in cs_dsp_parse_coeff()
1350 pos = cs_dsp_coeff_parse_coeff(dsp, region, pos, &coeff_blk); in cs_dsp_parse_coeff()
1361 ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, in cs_dsp_parse_coeff()
1371 ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, in cs_dsp_parse_coeff()
1381 ret = cs_dsp_check_coeff_flags(dsp, &coeff_blk, in cs_dsp_parse_coeff()
1390 cs_dsp_err(dsp, "Unknown control type: %d\n", in cs_dsp_parse_coeff()
1398 ret = cs_dsp_create_control(dsp, &alg_region, in cs_dsp_parse_coeff()
1406 cs_dsp_err(dsp, "Failed to create control: %.*s, %d\n", in cs_dsp_parse_coeff()
1413 static unsigned int cs_dsp_adsp1_parse_sizes(struct cs_dsp *dsp, in cs_dsp_adsp1_parse_sizes() argument
1422 cs_dsp_err(dsp, "%s: file truncated\n", file); in cs_dsp_adsp1_parse_sizes()
1426 cs_dsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", file, in cs_dsp_adsp1_parse_sizes()
1433 static unsigned int cs_dsp_adsp2_parse_sizes(struct cs_dsp *dsp, in cs_dsp_adsp2_parse_sizes() argument
1442 cs_dsp_err(dsp, "%s: file truncated\n", file); in cs_dsp_adsp2_parse_sizes()
1446 cs_dsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", file, in cs_dsp_adsp2_parse_sizes()
1453 static bool cs_dsp_validate_version(struct cs_dsp *dsp, unsigned int version) in cs_dsp_validate_version() argument
1457 cs_dsp_warn(dsp, "Deprecated file format %d\n", version); in cs_dsp_validate_version()
1467 static bool cs_dsp_halo_validate_version(struct cs_dsp *dsp, unsigned int version) in cs_dsp_halo_validate_version() argument
1477 static int cs_dsp_load(struct cs_dsp *dsp, const struct firmware *firmware, in cs_dsp_load() argument
1481 struct regmap *regmap = dsp->regmap; in cs_dsp_load()
1506 cs_dsp_err(dsp, "%s: invalid magic\n", file); in cs_dsp_load()
1510 if (!dsp->ops->validate_version(dsp, header->ver)) { in cs_dsp_load()
1511 cs_dsp_err(dsp, "%s: unknown file format %d\n", in cs_dsp_load()
1516 dsp->wmfw_ver = header->ver; in cs_dsp_load()
1518 if (header->core != dsp->type) { in cs_dsp_load()
1519 cs_dsp_err(dsp, "%s: invalid core %d != %d\n", in cs_dsp_load()
1520 file, header->core, dsp->type); in cs_dsp_load()
1525 pos = dsp->ops->parse_sizes(dsp, file, pos, firmware); in cs_dsp_load()
1539 cs_dsp_info(dsp, "%s: format %d timestamp %#llx\n", file, header->ver, in cs_dsp_load()
1565 cs_dsp_info(dsp, "%s: %.*s\n", file, in cs_dsp_load()
1570 ret = cs_dsp_parse_coeff(dsp, region); in cs_dsp_load()
1586 mem = cs_dsp_find_region(dsp, type); in cs_dsp_load()
1588 cs_dsp_err(dsp, "No region of type: %x\n", type); in cs_dsp_load()
1594 reg = dsp->ops->region_to_reg(mem, offset); in cs_dsp_load()
1597 cs_dsp_warn(dsp, in cs_dsp_load()
1603 cs_dsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, in cs_dsp_load()
1612 cs_dsp_err(dsp, "Out of memory\n"); in cs_dsp_load()
1620 cs_dsp_err(dsp, in cs_dsp_load()
1634 cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", in cs_dsp_load()
1637 cs_dsp_debugfs_save_wmfwname(dsp, file); in cs_dsp_load()
1644 cs_dsp_err(dsp, "%s: file content overflows file data\n", file); in cs_dsp_load()
1660 struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type, in cs_dsp_get_ctl() argument
1665 lockdep_assert_held(&dsp->pwr_lock); in cs_dsp_get_ctl()
1667 list_for_each_entry(pos, &dsp->ctl_list, list) { in cs_dsp_get_ctl()
1671 pos->fw_name == dsp->fw_name && in cs_dsp_get_ctl()
1683 static void cs_dsp_ctl_fixup_base(struct cs_dsp *dsp, in cs_dsp_ctl_fixup_base() argument
1688 list_for_each_entry(ctl, &dsp->ctl_list, list) { in cs_dsp_ctl_fixup_base()
1689 if (ctl->fw_name == dsp->fw_name && in cs_dsp_ctl_fixup_base()
1697 static void *cs_dsp_read_algs(struct cs_dsp *dsp, size_t n_algs, in cs_dsp_read_algs() argument
1707 cs_dsp_err(dsp, "No algorithms\n"); in cs_dsp_read_algs()
1712 cs_dsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); in cs_dsp_read_algs()
1717 reg = dsp->ops->region_to_reg(mem, pos + len); in cs_dsp_read_algs()
1719 ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); in cs_dsp_read_algs()
1721 cs_dsp_err(dsp, "Failed to read algorithm list end: %d\n", in cs_dsp_read_algs()
1727 cs_dsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbedead\n", in cs_dsp_read_algs()
1737 reg = dsp->ops->region_to_reg(mem, pos); in cs_dsp_read_algs()
1739 ret = regmap_raw_read(dsp->regmap, reg, alg, len); in cs_dsp_read_algs()
1741 cs_dsp_err(dsp, "Failed to read algorithm list: %d\n", ret); in cs_dsp_read_algs()
1757 struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, in cs_dsp_find_alg_region() argument
1762 lockdep_assert_held(&dsp->pwr_lock); in cs_dsp_find_alg_region()
1764 list_for_each_entry(item, &dsp->alg_regions, list) { in cs_dsp_find_alg_region()
1773 static struct cs_dsp_alg_region *cs_dsp_create_region(struct cs_dsp *dsp, in cs_dsp_create_region() argument
1788 list_add_tail(&item->list, &dsp->alg_regions); in cs_dsp_create_region()
1790 if (dsp->wmfw_ver > 0) in cs_dsp_create_region()
1791 cs_dsp_ctl_fixup_base(dsp, &item->alg_region); in cs_dsp_create_region()
1796 static void cs_dsp_free_alg_regions(struct cs_dsp *dsp) in cs_dsp_free_alg_regions() argument
1800 while (!list_empty(&dsp->alg_regions)) { in cs_dsp_free_alg_regions()
1801 item = list_first_entry(&dsp->alg_regions, in cs_dsp_free_alg_regions()
1809 static void cs_dsp_parse_wmfw_id_header(struct cs_dsp *dsp, in cs_dsp_parse_wmfw_id_header() argument
1812 dsp->fw_id = be32_to_cpu(fw->id); in cs_dsp_parse_wmfw_id_header()
1813 dsp->fw_id_version = be32_to_cpu(fw->ver); in cs_dsp_parse_wmfw_id_header()
1815 cs_dsp_info(dsp, "Firmware: %x v%d.%d.%d, %d algorithms\n", in cs_dsp_parse_wmfw_id_header()
1816 dsp->fw_id, (dsp->fw_id_version & 0xff0000) >> 16, in cs_dsp_parse_wmfw_id_header()
1817 (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, in cs_dsp_parse_wmfw_id_header()
1821 static void cs_dsp_parse_wmfw_v3_id_header(struct cs_dsp *dsp, in cs_dsp_parse_wmfw_v3_id_header() argument
1824 dsp->fw_id = be32_to_cpu(fw->id); in cs_dsp_parse_wmfw_v3_id_header()
1825 dsp->fw_id_version = be32_to_cpu(fw->ver); in cs_dsp_parse_wmfw_v3_id_header()
1826 dsp->fw_vendor_id = be32_to_cpu(fw->vendor_id); in cs_dsp_parse_wmfw_v3_id_header()
1828 cs_dsp_info(dsp, "Firmware: %x vendor: 0x%x v%d.%d.%d, %d algorithms\n", in cs_dsp_parse_wmfw_v3_id_header()
1829 dsp->fw_id, dsp->fw_vendor_id, in cs_dsp_parse_wmfw_v3_id_header()
1830 (dsp->fw_id_version & 0xff0000) >> 16, in cs_dsp_parse_wmfw_v3_id_header()
1831 (dsp->fw_id_version & 0xff00) >> 8, dsp->fw_id_version & 0xff, in cs_dsp_parse_wmfw_v3_id_header()
1835 static int cs_dsp_create_regions(struct cs_dsp *dsp, __be32 id, __be32 ver, in cs_dsp_create_regions() argument
1842 alg_region = cs_dsp_create_region(dsp, type[i], id, ver, base[i]); in cs_dsp_create_regions()
1850 static int cs_dsp_adsp1_setup_algs(struct cs_dsp *dsp) in cs_dsp_adsp1_setup_algs() argument
1860 mem = cs_dsp_find_region(dsp, WMFW_ADSP1_DM); in cs_dsp_adsp1_setup_algs()
1864 ret = regmap_raw_read(dsp->regmap, mem->base, &adsp1_id, in cs_dsp_adsp1_setup_algs()
1867 cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", in cs_dsp_adsp1_setup_algs()
1874 cs_dsp_parse_wmfw_id_header(dsp, &adsp1_id.fw, n_algs); in cs_dsp_adsp1_setup_algs()
1876 alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, in cs_dsp_adsp1_setup_algs()
1882 alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, in cs_dsp_adsp1_setup_algs()
1892 adsp1_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); in cs_dsp_adsp1_setup_algs()
1897 cs_dsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", in cs_dsp_adsp1_setup_algs()
1905 alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_DM, in cs_dsp_adsp1_setup_algs()
1913 if (dsp->wmfw_ver == 0) { in cs_dsp_adsp1_setup_algs()
1918 cs_dsp_create_control(dsp, alg_region, 0, in cs_dsp_adsp1_setup_algs()
1922 cs_dsp_warn(dsp, "Missing length info for region DM with ID %x\n", in cs_dsp_adsp1_setup_algs()
1927 alg_region = cs_dsp_create_region(dsp, WMFW_ADSP1_ZM, in cs_dsp_adsp1_setup_algs()
1935 if (dsp->wmfw_ver == 0) { in cs_dsp_adsp1_setup_algs()
1940 cs_dsp_create_control(dsp, alg_region, 0, in cs_dsp_adsp1_setup_algs()
1944 cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", in cs_dsp_adsp1_setup_algs()
1955 static int cs_dsp_adsp2_setup_algs(struct cs_dsp *dsp) in cs_dsp_adsp2_setup_algs() argument
1965 mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); in cs_dsp_adsp2_setup_algs()
1969 ret = regmap_raw_read(dsp->regmap, mem->base, &adsp2_id, in cs_dsp_adsp2_setup_algs()
1972 cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", in cs_dsp_adsp2_setup_algs()
1979 cs_dsp_parse_wmfw_id_header(dsp, &adsp2_id.fw, n_algs); in cs_dsp_adsp2_setup_algs()
1981 alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, in cs_dsp_adsp2_setup_algs()
1987 alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, in cs_dsp_adsp2_setup_algs()
1993 alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, in cs_dsp_adsp2_setup_algs()
2003 adsp2_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); in cs_dsp_adsp2_setup_algs()
2008 cs_dsp_dbg(dsp, in cs_dsp_adsp2_setup_algs()
2018 alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_XM, in cs_dsp_adsp2_setup_algs()
2026 if (dsp->wmfw_ver == 0) { in cs_dsp_adsp2_setup_algs()
2031 cs_dsp_create_control(dsp, alg_region, 0, in cs_dsp_adsp2_setup_algs()
2035 cs_dsp_warn(dsp, "Missing length info for region XM with ID %x\n", in cs_dsp_adsp2_setup_algs()
2040 alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_YM, in cs_dsp_adsp2_setup_algs()
2048 if (dsp->wmfw_ver == 0) { in cs_dsp_adsp2_setup_algs()
2053 cs_dsp_create_control(dsp, alg_region, 0, in cs_dsp_adsp2_setup_algs()
2057 cs_dsp_warn(dsp, "Missing length info for region YM with ID %x\n", in cs_dsp_adsp2_setup_algs()
2062 alg_region = cs_dsp_create_region(dsp, WMFW_ADSP2_ZM, in cs_dsp_adsp2_setup_algs()
2070 if (dsp->wmfw_ver == 0) { in cs_dsp_adsp2_setup_algs()
2075 cs_dsp_create_control(dsp, alg_region, 0, in cs_dsp_adsp2_setup_algs()
2079 cs_dsp_warn(dsp, "Missing length info for region ZM with ID %x\n", in cs_dsp_adsp2_setup_algs()
2090 static int cs_dsp_halo_create_regions(struct cs_dsp *dsp, __be32 id, __be32 ver, in cs_dsp_halo_create_regions() argument
2099 return cs_dsp_create_regions(dsp, id, ver, ARRAY_SIZE(types), types, bases); in cs_dsp_halo_create_regions()
2102 static int cs_dsp_halo_setup_algs(struct cs_dsp *dsp) in cs_dsp_halo_setup_algs() argument
2111 mem = cs_dsp_find_region(dsp, WMFW_ADSP2_XM); in cs_dsp_halo_setup_algs()
2115 ret = regmap_raw_read(dsp->regmap, mem->base, &halo_id, in cs_dsp_halo_setup_algs()
2118 cs_dsp_err(dsp, "Failed to read algorithm info: %d\n", in cs_dsp_halo_setup_algs()
2125 cs_dsp_parse_wmfw_v3_id_header(dsp, &halo_id.fw, n_algs); in cs_dsp_halo_setup_algs()
2127 ret = cs_dsp_halo_create_regions(dsp, halo_id.fw.id, halo_id.fw.ver, in cs_dsp_halo_setup_algs()
2136 halo_alg = cs_dsp_read_algs(dsp, n_algs, mem, pos, len); in cs_dsp_halo_setup_algs()
2141 cs_dsp_dbg(dsp, in cs_dsp_halo_setup_algs()
2150 ret = cs_dsp_halo_create_regions(dsp, halo_alg[i].alg.id, in cs_dsp_halo_setup_algs()
2163 static int cs_dsp_load_coeff(struct cs_dsp *dsp, const struct firmware *firmware, in cs_dsp_load_coeff() argument
2167 struct regmap *regmap = dsp->regmap; in cs_dsp_load_coeff()
2182 cs_dsp_err(dsp, "%s: coefficient file too short, %zu bytes\n", in cs_dsp_load_coeff()
2189 cs_dsp_err(dsp, "%s: invalid coefficient magic\n", file); in cs_dsp_load_coeff()
2198 cs_dsp_err(dsp, "%s: Unsupported coefficient file format %d\n", in cs_dsp_load_coeff()
2204 cs_dsp_info(dsp, "%s: v%d.%d.%d\n", file, in cs_dsp_load_coeff()
2230 cs_dsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", in cs_dsp_load_coeff()
2235 cs_dsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", in cs_dsp_load_coeff()
2242 cs_dsp_info(dsp, "%s: %.*s\n", dsp->fw_name, in cs_dsp_load_coeff()
2253 if (le32_to_cpu(blk->id) == dsp->fw_id && in cs_dsp_load_coeff()
2256 mem = cs_dsp_find_region(dsp, type); in cs_dsp_load_coeff()
2258 cs_dsp_err(dsp, "No ZM\n"); in cs_dsp_load_coeff()
2261 reg = dsp->ops->region_to_reg(mem, 0); in cs_dsp_load_coeff()
2276 cs_dsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", in cs_dsp_load_coeff()
2281 mem = cs_dsp_find_region(dsp, type); in cs_dsp_load_coeff()
2283 cs_dsp_err(dsp, "No base for region %x\n", type); in cs_dsp_load_coeff()
2287 alg_region = cs_dsp_find_alg_region(dsp, type, in cs_dsp_load_coeff()
2291 cs_dsp_warn(dsp, in cs_dsp_load_coeff()
2301 reg = dsp->ops->region_to_reg(mem, reg); in cs_dsp_load_coeff()
2304 cs_dsp_err(dsp, "No %s for algorithm %x\n", in cs_dsp_load_coeff()
2310 cs_dsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", in cs_dsp_load_coeff()
2320 cs_dsp_err(dsp, "Out of memory\n"); in cs_dsp_load_coeff()
2325 cs_dsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", in cs_dsp_load_coeff()
2331 cs_dsp_err(dsp, in cs_dsp_load_coeff()
2342 cs_dsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", in cs_dsp_load_coeff()
2345 cs_dsp_debugfs_save_binname(dsp, file); in cs_dsp_load_coeff()
2352 cs_dsp_err(dsp, "%s: file content overflows file data\n", file); in cs_dsp_load_coeff()
2357 static int cs_dsp_create_name(struct cs_dsp *dsp) in cs_dsp_create_name() argument
2359 if (!dsp->name) { in cs_dsp_create_name()
2360 dsp->name = devm_kasprintf(dsp->dev, GFP_KERNEL, "DSP%d", in cs_dsp_create_name()
2361 dsp->num); in cs_dsp_create_name()
2362 if (!dsp->name) in cs_dsp_create_name()
2369 static int cs_dsp_common_init(struct cs_dsp *dsp) in cs_dsp_common_init() argument
2373 ret = cs_dsp_create_name(dsp); in cs_dsp_common_init()
2377 INIT_LIST_HEAD(&dsp->alg_regions); in cs_dsp_common_init()
2378 INIT_LIST_HEAD(&dsp->ctl_list); in cs_dsp_common_init()
2380 mutex_init(&dsp->pwr_lock); in cs_dsp_common_init()
2384 dsp->debugfs_root = ERR_PTR(-ENODEV); in cs_dsp_common_init()
2396 int cs_dsp_adsp1_init(struct cs_dsp *dsp) in cs_dsp_adsp1_init() argument
2398 dsp->ops = &cs_dsp_adsp1_ops; in cs_dsp_adsp1_init()
2400 return cs_dsp_common_init(dsp); in cs_dsp_adsp1_init()
2415 int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, in cs_dsp_adsp1_power_up() argument
2423 mutex_lock(&dsp->pwr_lock); in cs_dsp_adsp1_power_up()
2425 dsp->fw_name = fw_name; in cs_dsp_adsp1_power_up()
2427 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, in cs_dsp_adsp1_power_up()
2434 if (dsp->sysclk_reg) { in cs_dsp_adsp1_power_up()
2435 ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); in cs_dsp_adsp1_power_up()
2437 cs_dsp_err(dsp, "Failed to read SYSCLK state: %d\n", ret); in cs_dsp_adsp1_power_up()
2441 val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; in cs_dsp_adsp1_power_up()
2443 ret = regmap_update_bits(dsp->regmap, in cs_dsp_adsp1_power_up()
2444 dsp->base + ADSP1_CONTROL_31, in cs_dsp_adsp1_power_up()
2447 cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); in cs_dsp_adsp1_power_up()
2452 ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); in cs_dsp_adsp1_power_up()
2456 ret = cs_dsp_adsp1_setup_algs(dsp); in cs_dsp_adsp1_power_up()
2460 ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); in cs_dsp_adsp1_power_up()
2465 ret = cs_dsp_coeff_init_control_caches(dsp); in cs_dsp_adsp1_power_up()
2470 ret = cs_dsp_coeff_sync_controls(dsp); in cs_dsp_adsp1_power_up()
2474 dsp->booted = true; in cs_dsp_adsp1_power_up()
2477 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, in cs_dsp_adsp1_power_up()
2481 dsp->running = true; in cs_dsp_adsp1_power_up()
2483 mutex_unlock(&dsp->pwr_lock); in cs_dsp_adsp1_power_up()
2488 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, in cs_dsp_adsp1_power_up()
2491 mutex_unlock(&dsp->pwr_lock); in cs_dsp_adsp1_power_up()
2500 void cs_dsp_adsp1_power_down(struct cs_dsp *dsp) in cs_dsp_adsp1_power_down() argument
2504 mutex_lock(&dsp->pwr_lock); in cs_dsp_adsp1_power_down()
2506 dsp->running = false; in cs_dsp_adsp1_power_down()
2507 dsp->booted = false; in cs_dsp_adsp1_power_down()
2510 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, in cs_dsp_adsp1_power_down()
2513 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, in cs_dsp_adsp1_power_down()
2516 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, in cs_dsp_adsp1_power_down()
2519 list_for_each_entry(ctl, &dsp->ctl_list, list) in cs_dsp_adsp1_power_down()
2522 cs_dsp_free_alg_regions(dsp); in cs_dsp_adsp1_power_down()
2524 mutex_unlock(&dsp->pwr_lock); in cs_dsp_adsp1_power_down()
2528 static int cs_dsp_adsp2v2_enable_core(struct cs_dsp *dsp) in cs_dsp_adsp2v2_enable_core() argument
2535 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val); in cs_dsp_adsp2v2_enable_core()
2546 cs_dsp_err(dsp, "Failed to start DSP RAM\n"); in cs_dsp_adsp2v2_enable_core()
2550 cs_dsp_dbg(dsp, "RAM ready after %d polls\n", count); in cs_dsp_adsp2v2_enable_core()
2555 static int cs_dsp_adsp2_enable_core(struct cs_dsp *dsp) in cs_dsp_adsp2_enable_core() argument
2559 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in cs_dsp_adsp2_enable_core()
2564 return cs_dsp_adsp2v2_enable_core(dsp); in cs_dsp_adsp2_enable_core()
2567 static int cs_dsp_adsp2_lock(struct cs_dsp *dsp, unsigned int lock_regions) in cs_dsp_adsp2_lock() argument
2569 struct regmap *regmap = dsp->regmap; in cs_dsp_adsp2_lock()
2576 lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0; in cs_dsp_adsp2_lock()
2597 static int cs_dsp_adsp2_enable_memory(struct cs_dsp *dsp) in cs_dsp_adsp2_enable_memory() argument
2599 return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in cs_dsp_adsp2_enable_memory()
2603 static void cs_dsp_adsp2_disable_memory(struct cs_dsp *dsp) in cs_dsp_adsp2_disable_memory() argument
2605 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in cs_dsp_adsp2_disable_memory()
2609 static void cs_dsp_adsp2_disable_core(struct cs_dsp *dsp) in cs_dsp_adsp2_disable_core() argument
2611 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); in cs_dsp_adsp2_disable_core()
2612 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); in cs_dsp_adsp2_disable_core()
2613 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); in cs_dsp_adsp2_disable_core()
2615 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in cs_dsp_adsp2_disable_core()
2619 static void cs_dsp_adsp2v2_disable_core(struct cs_dsp *dsp) in cs_dsp_adsp2v2_disable_core() argument
2621 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); in cs_dsp_adsp2v2_disable_core()
2622 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); in cs_dsp_adsp2v2_disable_core()
2623 regmap_write(dsp->regmap, dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); in cs_dsp_adsp2v2_disable_core()
2626 static int cs_dsp_halo_configure_mpu(struct cs_dsp *dsp, unsigned int lock_regions) in cs_dsp_halo_configure_mpu() argument
2629 { dsp->base + HALO_MPU_LOCK_CONFIG, 0x5555 }, in cs_dsp_halo_configure_mpu()
2630 { dsp->base + HALO_MPU_LOCK_CONFIG, 0xAAAA }, in cs_dsp_halo_configure_mpu()
2631 { dsp->base + HALO_MPU_XMEM_ACCESS_0, 0xFFFFFFFF }, in cs_dsp_halo_configure_mpu()
2632 { dsp->base + HALO_MPU_YMEM_ACCESS_0, 0xFFFFFFFF }, in cs_dsp_halo_configure_mpu()
2633 { dsp->base + HALO_MPU_WINDOW_ACCESS_0, lock_regions }, in cs_dsp_halo_configure_mpu()
2634 { dsp->base + HALO_MPU_XREG_ACCESS_0, lock_regions }, in cs_dsp_halo_configure_mpu()
2635 { dsp->base + HALO_MPU_YREG_ACCESS_0, lock_regions }, in cs_dsp_halo_configure_mpu()
2636 { dsp->base + HALO_MPU_XMEM_ACCESS_1, 0xFFFFFFFF }, in cs_dsp_halo_configure_mpu()
2637 { dsp->base + HALO_MPU_YMEM_ACCESS_1, 0xFFFFFFFF }, in cs_dsp_halo_configure_mpu()
2638 { dsp->base + HALO_MPU_WINDOW_ACCESS_1, lock_regions }, in cs_dsp_halo_configure_mpu()
2639 { dsp->base + HALO_MPU_XREG_ACCESS_1, lock_regions }, in cs_dsp_halo_configure_mpu()
2640 { dsp->base + HALO_MPU_YREG_ACCESS_1, lock_regions }, in cs_dsp_halo_configure_mpu()
2641 { dsp->base + HALO_MPU_XMEM_ACCESS_2, 0xFFFFFFFF }, in cs_dsp_halo_configure_mpu()
2642 { dsp->base + HALO_MPU_YMEM_ACCESS_2, 0xFFFFFFFF }, in cs_dsp_halo_configure_mpu()
2643 { dsp->base + HALO_MPU_WINDOW_ACCESS_2, lock_regions }, in cs_dsp_halo_configure_mpu()
2644 { dsp->base + HALO_MPU_XREG_ACCESS_2, lock_regions }, in cs_dsp_halo_configure_mpu()
2645 { dsp->base + HALO_MPU_YREG_ACCESS_2, lock_regions }, in cs_dsp_halo_configure_mpu()
2646 { dsp->base + HALO_MPU_XMEM_ACCESS_3, 0xFFFFFFFF }, in cs_dsp_halo_configure_mpu()
2647 { dsp->base + HALO_MPU_YMEM_ACCESS_3, 0xFFFFFFFF }, in cs_dsp_halo_configure_mpu()
2648 { dsp->base + HALO_MPU_WINDOW_ACCESS_3, lock_regions }, in cs_dsp_halo_configure_mpu()
2649 { dsp->base + HALO_MPU_XREG_ACCESS_3, lock_regions }, in cs_dsp_halo_configure_mpu()
2650 { dsp->base + HALO_MPU_YREG_ACCESS_3, lock_regions }, in cs_dsp_halo_configure_mpu()
2651 { dsp->base + HALO_MPU_LOCK_CONFIG, 0 }, in cs_dsp_halo_configure_mpu()
2654 return regmap_multi_reg_write(dsp->regmap, config, ARRAY_SIZE(config)); in cs_dsp_halo_configure_mpu()
2666 int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq) in cs_dsp_set_dspclk() argument
2670 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CLOCKING, in cs_dsp_set_dspclk()
2674 cs_dsp_err(dsp, "Failed to set clock rate: %d\n", ret); in cs_dsp_set_dspclk()
2680 static void cs_dsp_stop_watchdog(struct cs_dsp *dsp) in cs_dsp_stop_watchdog() argument
2682 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, in cs_dsp_stop_watchdog()
2686 static void cs_dsp_halo_stop_watchdog(struct cs_dsp *dsp) in cs_dsp_halo_stop_watchdog() argument
2688 regmap_update_bits(dsp->regmap, dsp->base + HALO_WDT_CONTROL, in cs_dsp_halo_stop_watchdog()
2709 int cs_dsp_power_up(struct cs_dsp *dsp, in cs_dsp_power_up() argument
2716 mutex_lock(&dsp->pwr_lock); in cs_dsp_power_up()
2718 dsp->fw_name = fw_name; in cs_dsp_power_up()
2720 if (dsp->ops->enable_memory) { in cs_dsp_power_up()
2721 ret = dsp->ops->enable_memory(dsp); in cs_dsp_power_up()
2726 if (dsp->ops->enable_core) { in cs_dsp_power_up()
2727 ret = dsp->ops->enable_core(dsp); in cs_dsp_power_up()
2732 ret = cs_dsp_load(dsp, wmfw_firmware, wmfw_filename); in cs_dsp_power_up()
2736 ret = dsp->ops->setup_algs(dsp); in cs_dsp_power_up()
2740 ret = cs_dsp_load_coeff(dsp, coeff_firmware, coeff_filename); in cs_dsp_power_up()
2745 ret = cs_dsp_coeff_init_control_caches(dsp); in cs_dsp_power_up()
2749 if (dsp->ops->disable_core) in cs_dsp_power_up()
2750 dsp->ops->disable_core(dsp); in cs_dsp_power_up()
2752 dsp->booted = true; in cs_dsp_power_up()
2754 mutex_unlock(&dsp->pwr_lock); in cs_dsp_power_up()
2758 if (dsp->ops->disable_core) in cs_dsp_power_up()
2759 dsp->ops->disable_core(dsp); in cs_dsp_power_up()
2761 if (dsp->ops->disable_memory) in cs_dsp_power_up()
2762 dsp->ops->disable_memory(dsp); in cs_dsp_power_up()
2764 mutex_unlock(&dsp->pwr_lock); in cs_dsp_power_up()
2777 void cs_dsp_power_down(struct cs_dsp *dsp) in cs_dsp_power_down() argument
2781 mutex_lock(&dsp->pwr_lock); in cs_dsp_power_down()
2783 cs_dsp_debugfs_clear(dsp); in cs_dsp_power_down()
2785 dsp->fw_id = 0; in cs_dsp_power_down()
2786 dsp->fw_id_version = 0; in cs_dsp_power_down()
2788 dsp->booted = false; in cs_dsp_power_down()
2790 if (dsp->ops->disable_memory) in cs_dsp_power_down()
2791 dsp->ops->disable_memory(dsp); in cs_dsp_power_down()
2793 list_for_each_entry(ctl, &dsp->ctl_list, list) in cs_dsp_power_down()
2796 cs_dsp_free_alg_regions(dsp); in cs_dsp_power_down()
2798 mutex_unlock(&dsp->pwr_lock); in cs_dsp_power_down()
2800 cs_dsp_dbg(dsp, "Shutdown complete\n"); in cs_dsp_power_down()
2804 static int cs_dsp_adsp2_start_core(struct cs_dsp *dsp) in cs_dsp_adsp2_start_core() argument
2806 return regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in cs_dsp_adsp2_start_core()
2811 static void cs_dsp_adsp2_stop_core(struct cs_dsp *dsp) in cs_dsp_adsp2_stop_core() argument
2813 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in cs_dsp_adsp2_stop_core()
2825 int cs_dsp_run(struct cs_dsp *dsp) in cs_dsp_run() argument
2829 mutex_lock(&dsp->pwr_lock); in cs_dsp_run()
2831 if (!dsp->booted) { in cs_dsp_run()
2836 if (dsp->ops->enable_core) { in cs_dsp_run()
2837 ret = dsp->ops->enable_core(dsp); in cs_dsp_run()
2842 if (dsp->client_ops->pre_run) { in cs_dsp_run()
2843 ret = dsp->client_ops->pre_run(dsp); in cs_dsp_run()
2849 ret = cs_dsp_coeff_sync_controls(dsp); in cs_dsp_run()
2853 if (dsp->ops->lock_memory) { in cs_dsp_run()
2854 ret = dsp->ops->lock_memory(dsp, dsp->lock_regions); in cs_dsp_run()
2856 cs_dsp_err(dsp, "Error configuring MPU: %d\n", ret); in cs_dsp_run()
2861 if (dsp->ops->start_core) { in cs_dsp_run()
2862 ret = dsp->ops->start_core(dsp); in cs_dsp_run()
2867 dsp->running = true; in cs_dsp_run()
2869 if (dsp->client_ops->post_run) { in cs_dsp_run()
2870 ret = dsp->client_ops->post_run(dsp); in cs_dsp_run()
2875 mutex_unlock(&dsp->pwr_lock); in cs_dsp_run()
2880 if (dsp->ops->stop_core) in cs_dsp_run()
2881 dsp->ops->stop_core(dsp); in cs_dsp_run()
2882 if (dsp->ops->disable_core) in cs_dsp_run()
2883 dsp->ops->disable_core(dsp); in cs_dsp_run()
2884 mutex_unlock(&dsp->pwr_lock); in cs_dsp_run()
2896 void cs_dsp_stop(struct cs_dsp *dsp) in cs_dsp_stop() argument
2899 cs_dsp_signal_event_controls(dsp, CS_DSP_FW_EVENT_SHUTDOWN); in cs_dsp_stop()
2901 if (dsp->ops->stop_watchdog) in cs_dsp_stop()
2902 dsp->ops->stop_watchdog(dsp); in cs_dsp_stop()
2905 if (dsp->ops->show_fw_status) in cs_dsp_stop()
2906 dsp->ops->show_fw_status(dsp); in cs_dsp_stop()
2908 mutex_lock(&dsp->pwr_lock); in cs_dsp_stop()
2910 if (dsp->client_ops->pre_stop) in cs_dsp_stop()
2911 dsp->client_ops->pre_stop(dsp); in cs_dsp_stop()
2913 dsp->running = false; in cs_dsp_stop()
2915 if (dsp->ops->stop_core) in cs_dsp_stop()
2916 dsp->ops->stop_core(dsp); in cs_dsp_stop()
2917 if (dsp->ops->disable_core) in cs_dsp_stop()
2918 dsp->ops->disable_core(dsp); in cs_dsp_stop()
2920 if (dsp->client_ops->post_stop) in cs_dsp_stop()
2921 dsp->client_ops->post_stop(dsp); in cs_dsp_stop()
2923 mutex_unlock(&dsp->pwr_lock); in cs_dsp_stop()
2925 cs_dsp_dbg(dsp, "Execution stopped\n"); in cs_dsp_stop()
2929 static int cs_dsp_halo_start_core(struct cs_dsp *dsp) in cs_dsp_halo_start_core() argument
2933 ret = regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, in cs_dsp_halo_start_core()
2939 return regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, in cs_dsp_halo_start_core()
2943 static void cs_dsp_halo_stop_core(struct cs_dsp *dsp) in cs_dsp_halo_stop_core() argument
2945 regmap_update_bits(dsp->regmap, dsp->base + HALO_CCM_CORE_CONTROL, in cs_dsp_halo_stop_core()
2949 regmap_update_bits(dsp->regmap, dsp->base + HALO_CORE_SOFT_RESET, in cs_dsp_halo_stop_core()
2959 int cs_dsp_adsp2_init(struct cs_dsp *dsp) in cs_dsp_adsp2_init() argument
2963 switch (dsp->rev) { in cs_dsp_adsp2_init()
2969 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, in cs_dsp_adsp2_init()
2972 cs_dsp_err(dsp, in cs_dsp_adsp2_init()
2977 dsp->ops = &cs_dsp_adsp2_ops[0]; in cs_dsp_adsp2_init()
2980 dsp->ops = &cs_dsp_adsp2_ops[1]; in cs_dsp_adsp2_init()
2983 dsp->ops = &cs_dsp_adsp2_ops[2]; in cs_dsp_adsp2_init()
2987 return cs_dsp_common_init(dsp); in cs_dsp_adsp2_init()
2997 int cs_dsp_halo_init(struct cs_dsp *dsp) in cs_dsp_halo_init() argument
2999 if (dsp->no_core_startstop) in cs_dsp_halo_init()
3000 dsp->ops = &cs_dsp_halo_ao_ops; in cs_dsp_halo_init()
3002 dsp->ops = &cs_dsp_halo_ops; in cs_dsp_halo_init()
3004 return cs_dsp_common_init(dsp); in cs_dsp_halo_init()
3012 void cs_dsp_remove(struct cs_dsp *dsp) in cs_dsp_remove() argument
3016 while (!list_empty(&dsp->ctl_list)) { in cs_dsp_remove()
3017 ctl = list_first_entry(&dsp->ctl_list, struct cs_dsp_coeff_ctl, list); in cs_dsp_remove()
3019 if (dsp->client_ops->control_remove) in cs_dsp_remove()
3020 dsp->client_ops->control_remove(ctl); in cs_dsp_remove()
3042 int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, in cs_dsp_read_raw_data_block() argument
3045 struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); in cs_dsp_read_raw_data_block()
3049 lockdep_assert_held(&dsp->pwr_lock); in cs_dsp_read_raw_data_block()
3054 reg = dsp->ops->region_to_reg(mem, mem_addr); in cs_dsp_read_raw_data_block()
3056 ret = regmap_raw_read(dsp->regmap, reg, data, in cs_dsp_read_raw_data_block()
3074 int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 *data) in cs_dsp_read_data_word() argument
3079 ret = cs_dsp_read_raw_data_block(dsp, mem_type, mem_addr, 1, &raw); in cs_dsp_read_data_word()
3098 int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data) in cs_dsp_write_data_word() argument
3100 struct cs_dsp_region const *mem = cs_dsp_find_region(dsp, mem_type); in cs_dsp_write_data_word()
3104 lockdep_assert_held(&dsp->pwr_lock); in cs_dsp_write_data_word()
3109 reg = dsp->ops->region_to_reg(mem, mem_addr); in cs_dsp_write_data_word()
3111 return regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); in cs_dsp_write_data_word()
3145 void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp) in cs_dsp_adsp2_bus_error() argument
3148 struct regmap *regmap = dsp->regmap; in cs_dsp_adsp2_bus_error()
3151 mutex_lock(&dsp->pwr_lock); in cs_dsp_adsp2_bus_error()
3153 ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); in cs_dsp_adsp2_bus_error()
3155 cs_dsp_err(dsp, in cs_dsp_adsp2_bus_error()
3161 cs_dsp_err(dsp, "watchdog timeout error\n"); in cs_dsp_adsp2_bus_error()
3162 dsp->ops->stop_watchdog(dsp); in cs_dsp_adsp2_bus_error()
3163 if (dsp->client_ops->watchdog_expired) in cs_dsp_adsp2_bus_error()
3164 dsp->client_ops->watchdog_expired(dsp); in cs_dsp_adsp2_bus_error()
3169 cs_dsp_err(dsp, "bus error: address error\n"); in cs_dsp_adsp2_bus_error()
3171 cs_dsp_err(dsp, "bus error: region lock error\n"); in cs_dsp_adsp2_bus_error()
3173 ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val); in cs_dsp_adsp2_bus_error()
3175 cs_dsp_err(dsp, in cs_dsp_adsp2_bus_error()
3181 cs_dsp_err(dsp, "bus error address = 0x%x\n", in cs_dsp_adsp2_bus_error()
3185 dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR, in cs_dsp_adsp2_bus_error()
3188 cs_dsp_err(dsp, in cs_dsp_adsp2_bus_error()
3194 cs_dsp_err(dsp, "xmem error address = 0x%x\n", in cs_dsp_adsp2_bus_error()
3196 cs_dsp_err(dsp, "pmem error address = 0x%x\n", in cs_dsp_adsp2_bus_error()
3201 regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, in cs_dsp_adsp2_bus_error()
3205 mutex_unlock(&dsp->pwr_lock); in cs_dsp_adsp2_bus_error()
3215 void cs_dsp_halo_bus_error(struct cs_dsp *dsp) in cs_dsp_halo_bus_error() argument
3217 struct regmap *regmap = dsp->regmap; in cs_dsp_halo_bus_error()
3220 { dsp->base + HALO_MPU_XM_VIO_STATUS, 0x0 }, in cs_dsp_halo_bus_error()
3221 { dsp->base + HALO_MPU_YM_VIO_STATUS, 0x0 }, in cs_dsp_halo_bus_error()
3222 { dsp->base + HALO_MPU_PM_VIO_STATUS, 0x0 }, in cs_dsp_halo_bus_error()
3226 mutex_lock(&dsp->pwr_lock); in cs_dsp_halo_bus_error()
3228 ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_1, in cs_dsp_halo_bus_error()
3231 cs_dsp_warn(dsp, "Failed to read AHB DEBUG_1: %d\n", ret); in cs_dsp_halo_bus_error()
3235 cs_dsp_warn(dsp, "AHB: STATUS: 0x%x ADDR: 0x%x\n", in cs_dsp_halo_bus_error()
3240 ret = regmap_read(regmap, dsp->base_sysinfo + HALO_AHBM_WINDOW_DEBUG_0, in cs_dsp_halo_bus_error()
3243 cs_dsp_warn(dsp, "Failed to read AHB DEBUG_0: %d\n", ret); in cs_dsp_halo_bus_error()
3247 cs_dsp_warn(dsp, "AHB: SYS_ADDR: 0x%x\n", *fault); in cs_dsp_halo_bus_error()
3249 ret = regmap_bulk_read(regmap, dsp->base + HALO_MPU_XM_VIO_ADDR, in cs_dsp_halo_bus_error()
3252 cs_dsp_warn(dsp, "Failed to read MPU fault info: %d\n", ret); in cs_dsp_halo_bus_error()
3256 cs_dsp_warn(dsp, "XM: STATUS:0x%x ADDR:0x%x\n", fault[1], fault[0]); in cs_dsp_halo_bus_error()
3257 cs_dsp_warn(dsp, "YM: STATUS:0x%x ADDR:0x%x\n", fault[3], fault[2]); in cs_dsp_halo_bus_error()
3258 cs_dsp_warn(dsp, "PM: STATUS:0x%x ADDR:0x%x\n", fault[5], fault[4]); in cs_dsp_halo_bus_error()
3260 ret = regmap_multi_reg_write(dsp->regmap, clear, ARRAY_SIZE(clear)); in cs_dsp_halo_bus_error()
3262 cs_dsp_warn(dsp, "Failed to clear MPU status: %d\n", ret); in cs_dsp_halo_bus_error()
3265 mutex_unlock(&dsp->pwr_lock); in cs_dsp_halo_bus_error()
3275 void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp) in cs_dsp_halo_wdt_expire() argument
3277 mutex_lock(&dsp->pwr_lock); in cs_dsp_halo_wdt_expire()
3279 cs_dsp_warn(dsp, "WDT Expiry Fault\n"); in cs_dsp_halo_wdt_expire()
3281 dsp->ops->stop_watchdog(dsp); in cs_dsp_halo_wdt_expire()
3282 if (dsp->client_ops->watchdog_expired) in cs_dsp_halo_wdt_expire()
3283 dsp->client_ops->watchdog_expired(dsp); in cs_dsp_halo_wdt_expire()
3285 mutex_unlock(&dsp->pwr_lock); in cs_dsp_halo_wdt_expire()
3489 static void cs_dsp_wseq_clear(struct cs_dsp *dsp, struct cs_dsp_wseq *wseq) in cs_dsp_wseq_clear() argument
3495 devm_kfree(dsp->dev, op); in cs_dsp_wseq_clear()
3499 static int cs_dsp_populate_wseq(struct cs_dsp *dsp, struct cs_dsp_wseq *wseq) in cs_dsp_populate_wseq() argument
3507 cs_dsp_err(dsp, "No control for write sequence\n"); in cs_dsp_populate_wseq()
3517 cs_dsp_err(dsp, "Failed to read %s: %d\n", wseq->ctl->subname, ret); in cs_dsp_populate_wseq()
3526 op = devm_kzalloc(dsp->dev, sizeof(*op), GFP_KERNEL); in cs_dsp_populate_wseq()
3557 cs_dsp_err(dsp, "Unsupported op: %X\n", op->operation); in cs_dsp_populate_wseq()
3558 devm_kfree(dsp->dev, op); in cs_dsp_populate_wseq()
3569 cs_dsp_err(dsp, "%s missing end terminator\n", wseq->ctl->subname); in cs_dsp_populate_wseq()
3587 int cs_dsp_wseq_init(struct cs_dsp *dsp, struct cs_dsp_wseq *wseqs, unsigned int num_wseqs) in cs_dsp_wseq_init() argument
3591 lockdep_assert_held(&dsp->pwr_lock); in cs_dsp_wseq_init()
3594 ret = cs_dsp_populate_wseq(dsp, &wseqs[i]); in cs_dsp_wseq_init()
3596 cs_dsp_wseq_clear(dsp, &wseqs[i]); in cs_dsp_wseq_init()
3637 int cs_dsp_wseq_write(struct cs_dsp *dsp, struct cs_dsp_wseq *wseq, in cs_dsp_wseq_write() argument
3652 cs_dsp_err(dsp, "Missing terminator for %s\n", wseq->ctl->subname); in cs_dsp_wseq_write()
3656 op_new = devm_kzalloc(dsp->dev, sizeof(*op_new), GFP_KERNEL); in cs_dsp_wseq_write()
3683 cs_dsp_err(dsp, "Operation %X not supported\n", op_code); in cs_dsp_wseq_write()
3691 cs_dsp_err(dsp, "Not enough memory in %s for entry\n", wseq->ctl->subname); in cs_dsp_wseq_write()
3714 devm_kfree(dsp->dev, op_new); in cs_dsp_wseq_write()
3735 int cs_dsp_wseq_multi_write(struct cs_dsp *dsp, struct cs_dsp_wseq *wseq, in cs_dsp_wseq_multi_write() argument
3742 ret = cs_dsp_wseq_write(dsp, wseq, reg_seq[i].reg, in cs_dsp_wseq_multi_write()