cs_dsp.h (8473B)
1/* SPDX-License-Identifier: GPL-2.0-only */ 2/* 3 * cs_dsp.h -- Cirrus Logic DSP firmware support 4 * 5 * Based on sound/soc/codecs/wm_adsp.h 6 * 7 * Copyright 2012 Wolfson Microelectronics plc 8 * Copyright (C) 2015-2021 Cirrus Logic, Inc. and 9 * Cirrus Logic International Semiconductor Ltd. 10 */ 11#ifndef __CS_DSP_H 12#define __CS_DSP_H 13 14#include <linux/device.h> 15#include <linux/firmware.h> 16#include <linux/list.h> 17#include <linux/regmap.h> 18 19#define CS_ADSP2_REGION_0 BIT(0) 20#define CS_ADSP2_REGION_1 BIT(1) 21#define CS_ADSP2_REGION_2 BIT(2) 22#define CS_ADSP2_REGION_3 BIT(3) 23#define CS_ADSP2_REGION_4 BIT(4) 24#define CS_ADSP2_REGION_5 BIT(5) 25#define CS_ADSP2_REGION_6 BIT(6) 26#define CS_ADSP2_REGION_7 BIT(7) 27#define CS_ADSP2_REGION_8 BIT(8) 28#define CS_ADSP2_REGION_9 BIT(9) 29#define CS_ADSP2_REGION_1_9 (CS_ADSP2_REGION_1 | \ 30 CS_ADSP2_REGION_2 | CS_ADSP2_REGION_3 | \ 31 CS_ADSP2_REGION_4 | CS_ADSP2_REGION_5 | \ 32 CS_ADSP2_REGION_6 | CS_ADSP2_REGION_7 | \ 33 CS_ADSP2_REGION_8 | CS_ADSP2_REGION_9) 34#define CS_ADSP2_REGION_ALL (CS_ADSP2_REGION_0 | CS_ADSP2_REGION_1_9) 35 36#define CS_DSP_DATA_WORD_SIZE 3 37 38#define CS_DSP_ACKED_CTL_TIMEOUT_MS 100 39#define CS_DSP_ACKED_CTL_N_QUICKPOLLS 10 40#define CS_DSP_ACKED_CTL_MIN_VALUE 0 41#define CS_DSP_ACKED_CTL_MAX_VALUE 0xFFFFFF 42 43/** 44 * struct cs_dsp_region - Describes a logical memory region in DSP address space 45 * @type: Memory region type 46 * @base: Address of region 47 */ 48struct cs_dsp_region { 49 int type; 50 unsigned int base; 51}; 52 53/** 54 * struct cs_dsp_alg_region - Describes a logical algorithm region in DSP address space 55 * @list: List node for internal use 56 * @alg: Algorithm id 57 * @ver: Expected algorithm version 58 * @type: Memory region type 59 * @base: Address of region 60 */ 61struct cs_dsp_alg_region { 62 struct list_head list; 63 unsigned int alg; 64 unsigned int ver; 65 int type; 66 unsigned int base; 67}; 68 69/** 70 * struct cs_dsp_coeff_ctl - Describes a coefficient control 71 * @list: List node for internal use 72 * @dsp: DSP instance associated with this control 73 * @cache: Cached value of the control 74 * @fw_name: Name of the firmware 75 * @subname: Name of the control parsed from the WMFW 76 * @subname_len: Length of subname 77 * @offset: Offset of control within alg_region in words 78 * @len: Length of the cached value in bytes 79 * @type: One of the WMFW_CTL_TYPE_ control types defined in wmfw.h 80 * @flags: Bitfield of WMFW_CTL_FLAG_ control flags defined in wmfw.h 81 * @set: Flag indicating the value has been written by the user 82 * @enabled: Flag indicating whether control is enabled 83 * @alg_region: Logical region associated with this control 84 * @priv: For use by the client 85 */ 86struct cs_dsp_coeff_ctl { 87 struct list_head list; 88 struct cs_dsp *dsp; 89 void *cache; 90 const char *fw_name; 91 /* Subname is needed to match with firmware */ 92 const char *subname; 93 unsigned int subname_len; 94 unsigned int offset; 95 size_t len; 96 unsigned int type; 97 unsigned int flags; 98 unsigned int set:1; 99 unsigned int enabled:1; 100 struct cs_dsp_alg_region alg_region; 101 102 void *priv; 103}; 104 105struct cs_dsp_ops; 106struct cs_dsp_client_ops; 107 108/** 109 * struct cs_dsp - Configuration and state of a Cirrus Logic DSP 110 * @name: The name of the DSP instance 111 * @rev: Revision of the DSP 112 * @num: DSP instance number 113 * @type: Type of DSP 114 * @dev: Driver model representation of the device 115 * @regmap: Register map of the device 116 * @ops: Function pointers for internal callbacks 117 * @client_ops: Function pointers for client callbacks 118 * @base: Address of the DSP registers 119 * @base_sysinfo: Address of the sysinfo register (Halo only) 120 * @sysclk_reg: Address of the sysclk register (ADSP1 only) 121 * @sysclk_mask: Mask of frequency bits within sysclk register (ADSP1 only) 122 * @sysclk_shift: Shift of frequency bits within sysclk register (ADSP1 only) 123 * @alg_regions: List of currently loaded algorithm regions 124 * @fw_file_name: Filename of the current firmware 125 * @fw_name: Name of the current firmware 126 * @fw_id: ID of the current firmware, obtained from the wmfw 127 * @fw_id_version: Version of the firmware, obtained from the wmfw 128 * @fw_vendor_id: Vendor of the firmware, obtained from the wmfw 129 * @mem: DSP memory region descriptions 130 * @num_mems: Number of memory regions in this DSP 131 * @fw_ver: Version of the wmfw file format 132 * @booted: Flag indicating DSP has been configured 133 * @running: Flag indicating DSP is executing firmware 134 * @ctl_list: Controls defined within the loaded DSP firmware 135 * @lock_regions: Enable MPU traps on specified memory regions 136 * @pwr_lock: Lock used to serialize accesses 137 * @debugfs_root: Debugfs directory for this DSP instance 138 * @wmfw_file_name: Filename of the currently loaded firmware 139 * @bin_file_name: Filename of the currently loaded coefficients 140 */ 141struct cs_dsp { 142 const char *name; 143 int rev; 144 int num; 145 int type; 146 struct device *dev; 147 struct regmap *regmap; 148 149 const struct cs_dsp_ops *ops; 150 const struct cs_dsp_client_ops *client_ops; 151 152 unsigned int base; 153 unsigned int base_sysinfo; 154 unsigned int sysclk_reg; 155 unsigned int sysclk_mask; 156 unsigned int sysclk_shift; 157 158 struct list_head alg_regions; 159 160 const char *fw_name; 161 unsigned int fw_id; 162 unsigned int fw_id_version; 163 unsigned int fw_vendor_id; 164 165 const struct cs_dsp_region *mem; 166 int num_mems; 167 168 int fw_ver; 169 170 bool booted; 171 bool running; 172 173 struct list_head ctl_list; 174 175 struct mutex pwr_lock; 176 177 unsigned int lock_regions; 178 179#ifdef CONFIG_DEBUG_FS 180 struct dentry *debugfs_root; 181 char *wmfw_file_name; 182 char *bin_file_name; 183#endif 184}; 185 186/** 187 * struct cs_dsp_client_ops - client callbacks 188 * @control_add: Called under the pwr_lock when a control is created 189 * @control_remove: Called under the pwr_lock when a control is destroyed 190 * @pre_run: Called under the pwr_lock by cs_dsp_run() before the core is started 191 * @post_run: Called under the pwr_lock by cs_dsp_run() after the core is started 192 * @post_stop: Called under the pwr_lock by cs_dsp_stop() 193 * @watchdog_expired: Called when a watchdog expiry is detected 194 * 195 * These callbacks give the cs_dsp client an opportunity to respond to events 196 * or to perform actions atomically. 197 */ 198struct cs_dsp_client_ops { 199 int (*control_add)(struct cs_dsp_coeff_ctl *ctl); 200 void (*control_remove)(struct cs_dsp_coeff_ctl *ctl); 201 int (*pre_run)(struct cs_dsp *dsp); 202 int (*post_run)(struct cs_dsp *dsp); 203 void (*post_stop)(struct cs_dsp *dsp); 204 void (*watchdog_expired)(struct cs_dsp *dsp); 205}; 206 207int cs_dsp_adsp1_init(struct cs_dsp *dsp); 208int cs_dsp_adsp2_init(struct cs_dsp *dsp); 209int cs_dsp_halo_init(struct cs_dsp *dsp); 210 211int cs_dsp_adsp1_power_up(struct cs_dsp *dsp, 212 const struct firmware *wmfw_firmware, char *wmfw_filename, 213 const struct firmware *coeff_firmware, char *coeff_filename, 214 const char *fw_name); 215void cs_dsp_adsp1_power_down(struct cs_dsp *dsp); 216int cs_dsp_power_up(struct cs_dsp *dsp, 217 const struct firmware *wmfw_firmware, char *wmfw_filename, 218 const struct firmware *coeff_firmware, char *coeff_filename, 219 const char *fw_name); 220void cs_dsp_power_down(struct cs_dsp *dsp); 221int cs_dsp_run(struct cs_dsp *dsp); 222void cs_dsp_stop(struct cs_dsp *dsp); 223 224void cs_dsp_remove(struct cs_dsp *dsp); 225 226int cs_dsp_set_dspclk(struct cs_dsp *dsp, unsigned int freq); 227void cs_dsp_adsp2_bus_error(struct cs_dsp *dsp); 228void cs_dsp_halo_bus_error(struct cs_dsp *dsp); 229void cs_dsp_halo_wdt_expire(struct cs_dsp *dsp); 230 231void cs_dsp_init_debugfs(struct cs_dsp *dsp, struct dentry *debugfs_root); 232void cs_dsp_cleanup_debugfs(struct cs_dsp *dsp); 233 234int cs_dsp_coeff_write_acked_control(struct cs_dsp_coeff_ctl *ctl, unsigned int event_id); 235int cs_dsp_coeff_write_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off, 236 const void *buf, size_t len); 237int cs_dsp_coeff_read_ctrl(struct cs_dsp_coeff_ctl *ctl, unsigned int off, 238 void *buf, size_t len); 239struct cs_dsp_coeff_ctl *cs_dsp_get_ctl(struct cs_dsp *dsp, const char *name, int type, 240 unsigned int alg); 241 242int cs_dsp_read_raw_data_block(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, 243 unsigned int num_words, __be32 *data); 244int cs_dsp_read_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 *data); 245int cs_dsp_write_data_word(struct cs_dsp *dsp, int mem_type, unsigned int mem_addr, u32 data); 246void cs_dsp_remove_padding(u32 *buf, int nwords); 247 248struct cs_dsp_alg_region *cs_dsp_find_alg_region(struct cs_dsp *dsp, 249 int type, unsigned int id); 250 251const char *cs_dsp_mem_region_name(unsigned int type); 252 253#endif