1 /* 2 * wm_adsp.c -- Wolfson ADSP support 3 * 4 * Copyright 2012 Wolfson Microelectronics plc 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13 #include <linux/module.h> 14 #include <linux/moduleparam.h> 15 #include <linux/init.h> 16 #include <linux/delay.h> 17 #include <linux/firmware.h> 18 #include <linux/list.h> 19 #include <linux/pm.h> 20 #include <linux/pm_runtime.h> 21 #include <linux/regmap.h> 22 #include <linux/regulator/consumer.h> 23 #include <linux/slab.h> 24 #include <linux/vmalloc.h> 25 #include <linux/workqueue.h> 26 #include <linux/debugfs.h> 27 #include <sound/core.h> 28 #include <sound/pcm.h> 29 #include <sound/pcm_params.h> 30 #include <sound/soc.h> 31 #include <sound/jack.h> 32 #include <sound/initval.h> 33 #include <sound/tlv.h> 34 35 #include "wm_adsp.h" 36 37 #define adsp_crit(_dsp, fmt, ...) \ 38 dev_crit(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) 39 #define adsp_err(_dsp, fmt, ...) \ 40 dev_err(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) 41 #define adsp_warn(_dsp, fmt, ...) \ 42 dev_warn(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) 43 #define adsp_info(_dsp, fmt, ...) \ 44 dev_info(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) 45 #define adsp_dbg(_dsp, fmt, ...) \ 46 dev_dbg(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) 47 48 #define ADSP1_CONTROL_1 0x00 49 #define ADSP1_CONTROL_2 0x02 50 #define ADSP1_CONTROL_3 0x03 51 #define ADSP1_CONTROL_4 0x04 52 #define ADSP1_CONTROL_5 0x06 53 #define ADSP1_CONTROL_6 0x07 54 #define ADSP1_CONTROL_7 0x08 55 #define ADSP1_CONTROL_8 0x09 56 #define ADSP1_CONTROL_9 0x0A 57 #define ADSP1_CONTROL_10 0x0B 58 #define ADSP1_CONTROL_11 0x0C 59 #define ADSP1_CONTROL_12 0x0D 60 #define ADSP1_CONTROL_13 0x0F 61 #define ADSP1_CONTROL_14 0x10 62 #define ADSP1_CONTROL_15 0x11 63 #define ADSP1_CONTROL_16 0x12 64 #define ADSP1_CONTROL_17 0x13 65 #define ADSP1_CONTROL_18 0x14 66 #define ADSP1_CONTROL_19 0x16 67 #define ADSP1_CONTROL_20 0x17 68 #define ADSP1_CONTROL_21 0x18 69 #define ADSP1_CONTROL_22 0x1A 70 #define ADSP1_CONTROL_23 0x1B 71 #define ADSP1_CONTROL_24 0x1C 72 #define ADSP1_CONTROL_25 0x1E 73 #define ADSP1_CONTROL_26 0x20 74 #define ADSP1_CONTROL_27 0x21 75 #define ADSP1_CONTROL_28 0x22 76 #define ADSP1_CONTROL_29 0x23 77 #define ADSP1_CONTROL_30 0x24 78 #define ADSP1_CONTROL_31 0x26 79 80 /* 81 * ADSP1 Control 19 82 */ 83 #define ADSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ 84 #define ADSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ 85 #define ADSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ 86 87 88 /* 89 * ADSP1 Control 30 90 */ 91 #define ADSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ 92 #define ADSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ 93 #define ADSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ 94 #define ADSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ 95 #define ADSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ 96 #define ADSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ 97 #define ADSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ 98 #define ADSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ 99 #define ADSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ 100 #define ADSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ 101 #define ADSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ 102 #define ADSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ 103 #define ADSP1_START 0x0001 /* DSP1_START */ 104 #define ADSP1_START_MASK 0x0001 /* DSP1_START */ 105 #define ADSP1_START_SHIFT 0 /* DSP1_START */ 106 #define ADSP1_START_WIDTH 1 /* DSP1_START */ 107 108 /* 109 * ADSP1 Control 31 110 */ 111 #define ADSP1_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ 112 #define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ 113 #define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ 114 115 #define ADSP2_CONTROL 0x0 116 #define ADSP2_CLOCKING 0x1 117 #define ADSP2V2_CLOCKING 0x2 118 #define ADSP2_STATUS1 0x4 119 #define ADSP2_WDMA_CONFIG_1 0x30 120 #define ADSP2_WDMA_CONFIG_2 0x31 121 #define ADSP2V2_WDMA_CONFIG_2 0x32 122 #define ADSP2_RDMA_CONFIG_1 0x34 123 124 #define ADSP2_SCRATCH0 0x40 125 #define ADSP2_SCRATCH1 0x41 126 #define ADSP2_SCRATCH2 0x42 127 #define ADSP2_SCRATCH3 0x43 128 129 #define ADSP2V2_SCRATCH0_1 0x40 130 #define ADSP2V2_SCRATCH2_3 0x42 131 132 /* 133 * ADSP2 Control 134 */ 135 136 #define ADSP2_MEM_ENA 0x0010 /* DSP1_MEM_ENA */ 137 #define ADSP2_MEM_ENA_MASK 0x0010 /* DSP1_MEM_ENA */ 138 #define ADSP2_MEM_ENA_SHIFT 4 /* DSP1_MEM_ENA */ 139 #define ADSP2_MEM_ENA_WIDTH 1 /* DSP1_MEM_ENA */ 140 #define ADSP2_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ 141 #define ADSP2_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ 142 #define ADSP2_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ 143 #define ADSP2_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ 144 #define ADSP2_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ 145 #define ADSP2_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ 146 #define ADSP2_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ 147 #define ADSP2_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ 148 #define ADSP2_START 0x0001 /* DSP1_START */ 149 #define ADSP2_START_MASK 0x0001 /* DSP1_START */ 150 #define ADSP2_START_SHIFT 0 /* DSP1_START */ 151 #define ADSP2_START_WIDTH 1 /* DSP1_START */ 152 153 /* 154 * ADSP2 clocking 155 */ 156 #define ADSP2_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ 157 #define ADSP2_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ 158 #define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ 159 160 /* 161 * ADSP2V2 clocking 162 */ 163 #define ADSP2V2_CLK_SEL_MASK 0x70000 /* CLK_SEL_ENA */ 164 #define ADSP2V2_CLK_SEL_SHIFT 16 /* CLK_SEL_ENA */ 165 #define ADSP2V2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ 166 167 #define ADSP2V2_RATE_MASK 0x7800 /* DSP_RATE */ 168 #define ADSP2V2_RATE_SHIFT 11 /* DSP_RATE */ 169 #define ADSP2V2_RATE_WIDTH 4 /* DSP_RATE */ 170 171 /* 172 * ADSP2 Status 1 173 */ 174 #define ADSP2_RAM_RDY 0x0001 175 #define ADSP2_RAM_RDY_MASK 0x0001 176 #define ADSP2_RAM_RDY_SHIFT 0 177 #define ADSP2_RAM_RDY_WIDTH 1 178 179 /* 180 * ADSP2 Lock support 181 */ 182 #define ADSP2_LOCK_CODE_0 0x5555 183 #define ADSP2_LOCK_CODE_1 0xAAAA 184 185 #define ADSP2_WATCHDOG 0x0A 186 #define ADSP2_BUS_ERR_ADDR 0x52 187 #define ADSP2_REGION_LOCK_STATUS 0x64 188 #define ADSP2_LOCK_REGION_1_LOCK_REGION_0 0x66 189 #define ADSP2_LOCK_REGION_3_LOCK_REGION_2 0x68 190 #define ADSP2_LOCK_REGION_5_LOCK_REGION_4 0x6A 191 #define ADSP2_LOCK_REGION_7_LOCK_REGION_6 0x6C 192 #define ADSP2_LOCK_REGION_9_LOCK_REGION_8 0x6E 193 #define ADSP2_LOCK_REGION_CTRL 0x7A 194 #define ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR 0x7C 195 196 #define ADSP2_REGION_LOCK_ERR_MASK 0x8000 197 #define ADSP2_SLAVE_ERR_MASK 0x4000 198 #define ADSP2_WDT_TIMEOUT_STS_MASK 0x2000 199 #define ADSP2_CTRL_ERR_PAUSE_ENA 0x0002 200 #define ADSP2_CTRL_ERR_EINT 0x0001 201 202 #define ADSP2_BUS_ERR_ADDR_MASK 0x00FFFFFF 203 #define ADSP2_XMEM_ERR_ADDR_MASK 0x0000FFFF 204 #define ADSP2_PMEM_ERR_ADDR_MASK 0x7FFF0000 205 #define ADSP2_PMEM_ERR_ADDR_SHIFT 16 206 #define ADSP2_WDT_ENA_MASK 0xFFFFFFFD 207 208 #define ADSP2_LOCK_REGION_SHIFT 16 209 210 #define ADSP_MAX_STD_CTRL_SIZE 512 211 212 #define WM_ADSP_ACKED_CTL_TIMEOUT_MS 100 213 #define WM_ADSP_ACKED_CTL_N_QUICKPOLLS 10 214 #define WM_ADSP_ACKED_CTL_MIN_VALUE 0 215 #define WM_ADSP_ACKED_CTL_MAX_VALUE 0xFFFFFF 216 217 /* 218 * Event control messages 219 */ 220 #define WM_ADSP_FW_EVENT_SHUTDOWN 0x000001 221 222 struct wm_adsp_buf { 223 struct list_head list; 224 void *buf; 225 }; 226 227 static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len, 228 struct list_head *list) 229 { 230 struct wm_adsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); 231 232 if (buf == NULL) 233 return NULL; 234 235 buf->buf = vmalloc(len); 236 if (!buf->buf) { 237 kfree(buf); 238 return NULL; 239 } 240 memcpy(buf->buf, src, len); 241 242 if (list) 243 list_add_tail(&buf->list, list); 244 245 return buf; 246 } 247 248 static void wm_adsp_buf_free(struct list_head *list) 249 { 250 while (!list_empty(list)) { 251 struct wm_adsp_buf *buf = list_first_entry(list, 252 struct wm_adsp_buf, 253 list); 254 list_del(&buf->list); 255 vfree(buf->buf); 256 kfree(buf); 257 } 258 } 259 260 #define WM_ADSP_FW_MBC_VSS 0 261 #define WM_ADSP_FW_HIFI 1 262 #define WM_ADSP_FW_TX 2 263 #define WM_ADSP_FW_TX_SPK 3 264 #define WM_ADSP_FW_RX 4 265 #define WM_ADSP_FW_RX_ANC 5 266 #define WM_ADSP_FW_CTRL 6 267 #define WM_ADSP_FW_ASR 7 268 #define WM_ADSP_FW_TRACE 8 269 #define WM_ADSP_FW_SPK_PROT 9 270 #define WM_ADSP_FW_MISC 10 271 272 #define WM_ADSP_NUM_FW 11 273 274 static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = { 275 [WM_ADSP_FW_MBC_VSS] = "MBC/VSS", 276 [WM_ADSP_FW_HIFI] = "MasterHiFi", 277 [WM_ADSP_FW_TX] = "Tx", 278 [WM_ADSP_FW_TX_SPK] = "Tx Speaker", 279 [WM_ADSP_FW_RX] = "Rx", 280 [WM_ADSP_FW_RX_ANC] = "Rx ANC", 281 [WM_ADSP_FW_CTRL] = "Voice Ctrl", 282 [WM_ADSP_FW_ASR] = "ASR Assist", 283 [WM_ADSP_FW_TRACE] = "Dbg Trace", 284 [WM_ADSP_FW_SPK_PROT] = "Protection", 285 [WM_ADSP_FW_MISC] = "Misc", 286 }; 287 288 struct wm_adsp_system_config_xm_hdr { 289 __be32 sys_enable; 290 __be32 fw_id; 291 __be32 fw_rev; 292 __be32 boot_status; 293 __be32 watchdog; 294 __be32 dma_buffer_size; 295 __be32 rdma[6]; 296 __be32 wdma[8]; 297 __be32 build_job_name[3]; 298 __be32 build_job_number; 299 }; 300 301 struct wm_adsp_alg_xm_struct { 302 __be32 magic; 303 __be32 smoothing; 304 __be32 threshold; 305 __be32 host_buf_ptr; 306 __be32 start_seq; 307 __be32 high_water_mark; 308 __be32 low_water_mark; 309 __be64 smoothed_power; 310 }; 311 312 struct wm_adsp_buffer { 313 __be32 X_buf_base; /* XM base addr of first X area */ 314 __be32 X_buf_size; /* Size of 1st X area in words */ 315 __be32 X_buf_base2; /* XM base addr of 2nd X area */ 316 __be32 X_buf_brk; /* Total X size in words */ 317 __be32 Y_buf_base; /* YM base addr of Y area */ 318 __be32 wrap; /* Total size X and Y in words */ 319 __be32 high_water_mark; /* Point at which IRQ is asserted */ 320 __be32 irq_count; /* bits 1-31 count IRQ assertions */ 321 __be32 irq_ack; /* acked IRQ count, bit 0 enables IRQ */ 322 __be32 next_write_index; /* word index of next write */ 323 __be32 next_read_index; /* word index of next read */ 324 __be32 error; /* error if any */ 325 __be32 oldest_block_index; /* word index of oldest surviving */ 326 __be32 requested_rewind; /* how many blocks rewind was done */ 327 __be32 reserved_space; /* internal */ 328 __be32 min_free; /* min free space since stream start */ 329 __be32 blocks_written[2]; /* total blocks written (64 bit) */ 330 __be32 words_written[2]; /* total words written (64 bit) */ 331 }; 332 333 struct wm_adsp_compr; 334 335 struct wm_adsp_compr_buf { 336 struct wm_adsp *dsp; 337 struct wm_adsp_compr *compr; 338 339 struct wm_adsp_buffer_region *regions; 340 u32 host_buf_ptr; 341 342 u32 error; 343 u32 irq_count; 344 int read_index; 345 int avail; 346 }; 347 348 struct wm_adsp_compr { 349 struct wm_adsp *dsp; 350 struct wm_adsp_compr_buf *buf; 351 352 struct snd_compr_stream *stream; 353 struct snd_compressed_buffer size; 354 355 u32 *raw_buf; 356 unsigned int copied_total; 357 358 unsigned int sample_rate; 359 }; 360 361 #define WM_ADSP_DATA_WORD_SIZE 3 362 363 #define WM_ADSP_MIN_FRAGMENTS 1 364 #define WM_ADSP_MAX_FRAGMENTS 256 365 #define WM_ADSP_MIN_FRAGMENT_SIZE (64 * WM_ADSP_DATA_WORD_SIZE) 366 #define WM_ADSP_MAX_FRAGMENT_SIZE (4096 * WM_ADSP_DATA_WORD_SIZE) 367 368 #define WM_ADSP_ALG_XM_STRUCT_MAGIC 0x49aec7 369 370 #define HOST_BUFFER_FIELD(field) \ 371 (offsetof(struct wm_adsp_buffer, field) / sizeof(__be32)) 372 373 #define ALG_XM_FIELD(field) \ 374 (offsetof(struct wm_adsp_alg_xm_struct, field) / sizeof(__be32)) 375 376 static int wm_adsp_buffer_init(struct wm_adsp *dsp); 377 static int wm_adsp_buffer_free(struct wm_adsp *dsp); 378 379 struct wm_adsp_buffer_region { 380 unsigned int offset; 381 unsigned int cumulative_size; 382 unsigned int mem_type; 383 unsigned int base_addr; 384 }; 385 386 struct wm_adsp_buffer_region_def { 387 unsigned int mem_type; 388 unsigned int base_offset; 389 unsigned int size_offset; 390 }; 391 392 static const struct wm_adsp_buffer_region_def default_regions[] = { 393 { 394 .mem_type = WMFW_ADSP2_XM, 395 .base_offset = HOST_BUFFER_FIELD(X_buf_base), 396 .size_offset = HOST_BUFFER_FIELD(X_buf_size), 397 }, 398 { 399 .mem_type = WMFW_ADSP2_XM, 400 .base_offset = HOST_BUFFER_FIELD(X_buf_base2), 401 .size_offset = HOST_BUFFER_FIELD(X_buf_brk), 402 }, 403 { 404 .mem_type = WMFW_ADSP2_YM, 405 .base_offset = HOST_BUFFER_FIELD(Y_buf_base), 406 .size_offset = HOST_BUFFER_FIELD(wrap), 407 }, 408 }; 409 410 struct wm_adsp_fw_caps { 411 u32 id; 412 struct snd_codec_desc desc; 413 int num_regions; 414 const struct wm_adsp_buffer_region_def *region_defs; 415 }; 416 417 static const struct wm_adsp_fw_caps ctrl_caps[] = { 418 { 419 .id = SND_AUDIOCODEC_BESPOKE, 420 .desc = { 421 .max_ch = 1, 422 .sample_rates = { 16000 }, 423 .num_sample_rates = 1, 424 .formats = SNDRV_PCM_FMTBIT_S16_LE, 425 }, 426 .num_regions = ARRAY_SIZE(default_regions), 427 .region_defs = default_regions, 428 }, 429 }; 430 431 static const struct wm_adsp_fw_caps trace_caps[] = { 432 { 433 .id = SND_AUDIOCODEC_BESPOKE, 434 .desc = { 435 .max_ch = 8, 436 .sample_rates = { 437 4000, 8000, 11025, 12000, 16000, 22050, 438 24000, 32000, 44100, 48000, 64000, 88200, 439 96000, 176400, 192000 440 }, 441 .num_sample_rates = 15, 442 .formats = SNDRV_PCM_FMTBIT_S16_LE, 443 }, 444 .num_regions = ARRAY_SIZE(default_regions), 445 .region_defs = default_regions, 446 }, 447 }; 448 449 static const struct { 450 const char *file; 451 int compr_direction; 452 int num_caps; 453 const struct wm_adsp_fw_caps *caps; 454 bool voice_trigger; 455 } wm_adsp_fw[WM_ADSP_NUM_FW] = { 456 [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" }, 457 [WM_ADSP_FW_HIFI] = { .file = "hifi" }, 458 [WM_ADSP_FW_TX] = { .file = "tx" }, 459 [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" }, 460 [WM_ADSP_FW_RX] = { .file = "rx" }, 461 [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" }, 462 [WM_ADSP_FW_CTRL] = { 463 .file = "ctrl", 464 .compr_direction = SND_COMPRESS_CAPTURE, 465 .num_caps = ARRAY_SIZE(ctrl_caps), 466 .caps = ctrl_caps, 467 .voice_trigger = true, 468 }, 469 [WM_ADSP_FW_ASR] = { .file = "asr" }, 470 [WM_ADSP_FW_TRACE] = { 471 .file = "trace", 472 .compr_direction = SND_COMPRESS_CAPTURE, 473 .num_caps = ARRAY_SIZE(trace_caps), 474 .caps = trace_caps, 475 }, 476 [WM_ADSP_FW_SPK_PROT] = { .file = "spk-prot" }, 477 [WM_ADSP_FW_MISC] = { .file = "misc" }, 478 }; 479 480 struct wm_coeff_ctl_ops { 481 int (*xget)(struct snd_kcontrol *kcontrol, 482 struct snd_ctl_elem_value *ucontrol); 483 int (*xput)(struct snd_kcontrol *kcontrol, 484 struct snd_ctl_elem_value *ucontrol); 485 int (*xinfo)(struct snd_kcontrol *kcontrol, 486 struct snd_ctl_elem_info *uinfo); 487 }; 488 489 struct wm_coeff_ctl { 490 const char *name; 491 const char *fw_name; 492 struct wm_adsp_alg_region alg_region; 493 struct wm_coeff_ctl_ops ops; 494 struct wm_adsp *dsp; 495 unsigned int enabled:1; 496 struct list_head list; 497 void *cache; 498 unsigned int offset; 499 size_t len; 500 unsigned int set:1; 501 struct soc_bytes_ext bytes_ext; 502 unsigned int flags; 503 unsigned int type; 504 }; 505 506 static const char *wm_adsp_mem_region_name(unsigned int type) 507 { 508 switch (type) { 509 case WMFW_ADSP1_PM: 510 return "PM"; 511 case WMFW_ADSP1_DM: 512 return "DM"; 513 case WMFW_ADSP2_XM: 514 return "XM"; 515 case WMFW_ADSP2_YM: 516 return "YM"; 517 case WMFW_ADSP1_ZM: 518 return "ZM"; 519 default: 520 return NULL; 521 } 522 } 523 524 #ifdef CONFIG_DEBUG_FS 525 static void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, const char *s) 526 { 527 char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); 528 529 kfree(dsp->wmfw_file_name); 530 dsp->wmfw_file_name = tmp; 531 } 532 533 static void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, const char *s) 534 { 535 char *tmp = kasprintf(GFP_KERNEL, "%s\n", s); 536 537 kfree(dsp->bin_file_name); 538 dsp->bin_file_name = tmp; 539 } 540 541 static void wm_adsp_debugfs_clear(struct wm_adsp *dsp) 542 { 543 kfree(dsp->wmfw_file_name); 544 kfree(dsp->bin_file_name); 545 dsp->wmfw_file_name = NULL; 546 dsp->bin_file_name = NULL; 547 } 548 549 static ssize_t wm_adsp_debugfs_wmfw_read(struct file *file, 550 char __user *user_buf, 551 size_t count, loff_t *ppos) 552 { 553 struct wm_adsp *dsp = file->private_data; 554 ssize_t ret; 555 556 mutex_lock(&dsp->pwr_lock); 557 558 if (!dsp->wmfw_file_name || !dsp->booted) 559 ret = 0; 560 else 561 ret = simple_read_from_buffer(user_buf, count, ppos, 562 dsp->wmfw_file_name, 563 strlen(dsp->wmfw_file_name)); 564 565 mutex_unlock(&dsp->pwr_lock); 566 return ret; 567 } 568 569 static ssize_t wm_adsp_debugfs_bin_read(struct file *file, 570 char __user *user_buf, 571 size_t count, loff_t *ppos) 572 { 573 struct wm_adsp *dsp = file->private_data; 574 ssize_t ret; 575 576 mutex_lock(&dsp->pwr_lock); 577 578 if (!dsp->bin_file_name || !dsp->booted) 579 ret = 0; 580 else 581 ret = simple_read_from_buffer(user_buf, count, ppos, 582 dsp->bin_file_name, 583 strlen(dsp->bin_file_name)); 584 585 mutex_unlock(&dsp->pwr_lock); 586 return ret; 587 } 588 589 static const struct { 590 const char *name; 591 const struct file_operations fops; 592 } wm_adsp_debugfs_fops[] = { 593 { 594 .name = "wmfw_file_name", 595 .fops = { 596 .open = simple_open, 597 .read = wm_adsp_debugfs_wmfw_read, 598 }, 599 }, 600 { 601 .name = "bin_file_name", 602 .fops = { 603 .open = simple_open, 604 .read = wm_adsp_debugfs_bin_read, 605 }, 606 }, 607 }; 608 609 static void wm_adsp2_init_debugfs(struct wm_adsp *dsp, 610 struct snd_soc_codec *codec) 611 { 612 struct dentry *root = NULL; 613 char *root_name; 614 int i; 615 616 if (!codec->component.debugfs_root) { 617 adsp_err(dsp, "No codec debugfs root\n"); 618 goto err; 619 } 620 621 root_name = kmalloc(PAGE_SIZE, GFP_KERNEL); 622 if (!root_name) 623 goto err; 624 625 snprintf(root_name, PAGE_SIZE, "dsp%d", dsp->num); 626 root = debugfs_create_dir(root_name, codec->component.debugfs_root); 627 kfree(root_name); 628 629 if (!root) 630 goto err; 631 632 if (!debugfs_create_bool("booted", S_IRUGO, root, &dsp->booted)) 633 goto err; 634 635 if (!debugfs_create_bool("running", S_IRUGO, root, &dsp->running)) 636 goto err; 637 638 if (!debugfs_create_x32("fw_id", S_IRUGO, root, &dsp->fw_id)) 639 goto err; 640 641 if (!debugfs_create_x32("fw_version", S_IRUGO, root, 642 &dsp->fw_id_version)) 643 goto err; 644 645 for (i = 0; i < ARRAY_SIZE(wm_adsp_debugfs_fops); ++i) { 646 if (!debugfs_create_file(wm_adsp_debugfs_fops[i].name, 647 S_IRUGO, root, dsp, 648 &wm_adsp_debugfs_fops[i].fops)) 649 goto err; 650 } 651 652 dsp->debugfs_root = root; 653 return; 654 655 err: 656 debugfs_remove_recursive(root); 657 adsp_err(dsp, "Failed to create debugfs\n"); 658 } 659 660 static void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) 661 { 662 wm_adsp_debugfs_clear(dsp); 663 debugfs_remove_recursive(dsp->debugfs_root); 664 } 665 #else 666 static inline void wm_adsp2_init_debugfs(struct wm_adsp *dsp, 667 struct snd_soc_codec *codec) 668 { 669 } 670 671 static inline void wm_adsp2_cleanup_debugfs(struct wm_adsp *dsp) 672 { 673 } 674 675 static inline void wm_adsp_debugfs_save_wmfwname(struct wm_adsp *dsp, 676 const char *s) 677 { 678 } 679 680 static inline void wm_adsp_debugfs_save_binname(struct wm_adsp *dsp, 681 const char *s) 682 { 683 } 684 685 static inline void wm_adsp_debugfs_clear(struct wm_adsp *dsp) 686 { 687 } 688 #endif 689 690 static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, 691 struct snd_ctl_elem_value *ucontrol) 692 { 693 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 694 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 695 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); 696 697 ucontrol->value.enumerated.item[0] = dsp[e->shift_l].fw; 698 699 return 0; 700 } 701 702 static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, 703 struct snd_ctl_elem_value *ucontrol) 704 { 705 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 706 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 707 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); 708 int ret = 0; 709 710 if (ucontrol->value.enumerated.item[0] == dsp[e->shift_l].fw) 711 return 0; 712 713 if (ucontrol->value.enumerated.item[0] >= WM_ADSP_NUM_FW) 714 return -EINVAL; 715 716 mutex_lock(&dsp[e->shift_l].pwr_lock); 717 718 if (dsp[e->shift_l].booted || dsp[e->shift_l].compr) 719 ret = -EBUSY; 720 else 721 dsp[e->shift_l].fw = ucontrol->value.enumerated.item[0]; 722 723 mutex_unlock(&dsp[e->shift_l].pwr_lock); 724 725 return ret; 726 } 727 728 static const struct soc_enum wm_adsp_fw_enum[] = { 729 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 730 SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 731 SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 732 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 733 SOC_ENUM_SINGLE(0, 4, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 734 SOC_ENUM_SINGLE(0, 5, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 735 SOC_ENUM_SINGLE(0, 6, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 736 }; 737 738 const struct snd_kcontrol_new wm_adsp_fw_controls[] = { 739 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], 740 wm_adsp_fw_get, wm_adsp_fw_put), 741 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], 742 wm_adsp_fw_get, wm_adsp_fw_put), 743 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], 744 wm_adsp_fw_get, wm_adsp_fw_put), 745 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], 746 wm_adsp_fw_get, wm_adsp_fw_put), 747 SOC_ENUM_EXT("DSP5 Firmware", wm_adsp_fw_enum[4], 748 wm_adsp_fw_get, wm_adsp_fw_put), 749 SOC_ENUM_EXT("DSP6 Firmware", wm_adsp_fw_enum[5], 750 wm_adsp_fw_get, wm_adsp_fw_put), 751 SOC_ENUM_EXT("DSP7 Firmware", wm_adsp_fw_enum[6], 752 wm_adsp_fw_get, wm_adsp_fw_put), 753 }; 754 EXPORT_SYMBOL_GPL(wm_adsp_fw_controls); 755 756 static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, 757 int type) 758 { 759 int i; 760 761 for (i = 0; i < dsp->num_mems; i++) 762 if (dsp->mem[i].type == type) 763 return &dsp->mem[i]; 764 765 return NULL; 766 } 767 768 static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *mem, 769 unsigned int offset) 770 { 771 if (WARN_ON(!mem)) 772 return offset; 773 switch (mem->type) { 774 case WMFW_ADSP1_PM: 775 return mem->base + (offset * 3); 776 case WMFW_ADSP1_DM: 777 return mem->base + (offset * 2); 778 case WMFW_ADSP2_XM: 779 return mem->base + (offset * 2); 780 case WMFW_ADSP2_YM: 781 return mem->base + (offset * 2); 782 case WMFW_ADSP1_ZM: 783 return mem->base + (offset * 2); 784 default: 785 WARN(1, "Unknown memory region type"); 786 return offset; 787 } 788 } 789 790 static void wm_adsp2_show_fw_status(struct wm_adsp *dsp) 791 { 792 u16 scratch[4]; 793 int ret; 794 795 ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2_SCRATCH0, 796 scratch, sizeof(scratch)); 797 if (ret) { 798 adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret); 799 return; 800 } 801 802 adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", 803 be16_to_cpu(scratch[0]), 804 be16_to_cpu(scratch[1]), 805 be16_to_cpu(scratch[2]), 806 be16_to_cpu(scratch[3])); 807 } 808 809 static void wm_adsp2v2_show_fw_status(struct wm_adsp *dsp) 810 { 811 u32 scratch[2]; 812 int ret; 813 814 ret = regmap_raw_read(dsp->regmap, dsp->base + ADSP2V2_SCRATCH0_1, 815 scratch, sizeof(scratch)); 816 817 if (ret) { 818 adsp_err(dsp, "Failed to read SCRATCH regs: %d\n", ret); 819 return; 820 } 821 822 scratch[0] = be32_to_cpu(scratch[0]); 823 scratch[1] = be32_to_cpu(scratch[1]); 824 825 adsp_dbg(dsp, "FW SCRATCH 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n", 826 scratch[0] & 0xFFFF, 827 scratch[0] >> 16, 828 scratch[1] & 0xFFFF, 829 scratch[1] >> 16); 830 } 831 832 static inline struct wm_coeff_ctl *bytes_ext_to_ctl(struct soc_bytes_ext *ext) 833 { 834 return container_of(ext, struct wm_coeff_ctl, bytes_ext); 835 } 836 837 static int wm_coeff_base_reg(struct wm_coeff_ctl *ctl, unsigned int *reg) 838 { 839 const struct wm_adsp_alg_region *alg_region = &ctl->alg_region; 840 struct wm_adsp *dsp = ctl->dsp; 841 const struct wm_adsp_region *mem; 842 843 mem = wm_adsp_find_region(dsp, alg_region->type); 844 if (!mem) { 845 adsp_err(dsp, "No base for region %x\n", 846 alg_region->type); 847 return -EINVAL; 848 } 849 850 *reg = wm_adsp_region_to_reg(mem, ctl->alg_region.base + ctl->offset); 851 852 return 0; 853 } 854 855 static int wm_coeff_info(struct snd_kcontrol *kctl, 856 struct snd_ctl_elem_info *uinfo) 857 { 858 struct soc_bytes_ext *bytes_ext = 859 (struct soc_bytes_ext *)kctl->private_value; 860 struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); 861 862 switch (ctl->type) { 863 case WMFW_CTL_TYPE_ACKED: 864 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; 865 uinfo->value.integer.min = WM_ADSP_ACKED_CTL_MIN_VALUE; 866 uinfo->value.integer.max = WM_ADSP_ACKED_CTL_MAX_VALUE; 867 uinfo->value.integer.step = 1; 868 uinfo->count = 1; 869 break; 870 default: 871 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; 872 uinfo->count = ctl->len; 873 break; 874 } 875 876 return 0; 877 } 878 879 static int wm_coeff_write_acked_control(struct wm_coeff_ctl *ctl, 880 unsigned int event_id) 881 { 882 struct wm_adsp *dsp = ctl->dsp; 883 u32 val = cpu_to_be32(event_id); 884 unsigned int reg; 885 int i, ret; 886 887 ret = wm_coeff_base_reg(ctl, ®); 888 if (ret) 889 return ret; 890 891 adsp_dbg(dsp, "Sending 0x%x to acked control alg 0x%x %s:0x%x\n", 892 event_id, ctl->alg_region.alg, 893 wm_adsp_mem_region_name(ctl->alg_region.type), ctl->offset); 894 895 ret = regmap_raw_write(dsp->regmap, reg, &val, sizeof(val)); 896 if (ret) { 897 adsp_err(dsp, "Failed to write %x: %d\n", reg, ret); 898 return ret; 899 } 900 901 /* 902 * Poll for ack, we initially poll at ~1ms intervals for firmwares 903 * that respond quickly, then go to ~10ms polls. A firmware is unlikely 904 * to ack instantly so we do the first 1ms delay before reading the 905 * control to avoid a pointless bus transaction 906 */ 907 for (i = 0; i < WM_ADSP_ACKED_CTL_TIMEOUT_MS;) { 908 switch (i) { 909 case 0 ... WM_ADSP_ACKED_CTL_N_QUICKPOLLS - 1: 910 usleep_range(1000, 2000); 911 i++; 912 break; 913 default: 914 usleep_range(10000, 20000); 915 i += 10; 916 break; 917 } 918 919 ret = regmap_raw_read(dsp->regmap, reg, &val, sizeof(val)); 920 if (ret) { 921 adsp_err(dsp, "Failed to read %x: %d\n", reg, ret); 922 return ret; 923 } 924 925 if (val == 0) { 926 adsp_dbg(dsp, "Acked control ACKED at poll %u\n", i); 927 return 0; 928 } 929 } 930 931 adsp_warn(dsp, "Acked control @0x%x alg:0x%x %s:0x%x timed out\n", 932 reg, ctl->alg_region.alg, 933 wm_adsp_mem_region_name(ctl->alg_region.type), 934 ctl->offset); 935 936 return -ETIMEDOUT; 937 } 938 939 static int wm_coeff_write_control(struct wm_coeff_ctl *ctl, 940 const void *buf, size_t len) 941 { 942 struct wm_adsp *dsp = ctl->dsp; 943 void *scratch; 944 int ret; 945 unsigned int reg; 946 947 ret = wm_coeff_base_reg(ctl, ®); 948 if (ret) 949 return ret; 950 951 scratch = kmemdup(buf, len, GFP_KERNEL | GFP_DMA); 952 if (!scratch) 953 return -ENOMEM; 954 955 ret = regmap_raw_write(dsp->regmap, reg, scratch, 956 len); 957 if (ret) { 958 adsp_err(dsp, "Failed to write %zu bytes to %x: %d\n", 959 len, reg, ret); 960 kfree(scratch); 961 return ret; 962 } 963 adsp_dbg(dsp, "Wrote %zu bytes to %x\n", len, reg); 964 965 kfree(scratch); 966 967 return 0; 968 } 969 970 static int wm_coeff_put(struct snd_kcontrol *kctl, 971 struct snd_ctl_elem_value *ucontrol) 972 { 973 struct soc_bytes_ext *bytes_ext = 974 (struct soc_bytes_ext *)kctl->private_value; 975 struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); 976 char *p = ucontrol->value.bytes.data; 977 int ret = 0; 978 979 mutex_lock(&ctl->dsp->pwr_lock); 980 981 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) 982 ret = -EPERM; 983 else 984 memcpy(ctl->cache, p, ctl->len); 985 986 ctl->set = 1; 987 if (ctl->enabled && ctl->dsp->running) 988 ret = wm_coeff_write_control(ctl, p, ctl->len); 989 990 mutex_unlock(&ctl->dsp->pwr_lock); 991 992 return ret; 993 } 994 995 static int wm_coeff_tlv_put(struct snd_kcontrol *kctl, 996 const unsigned int __user *bytes, unsigned int size) 997 { 998 struct soc_bytes_ext *bytes_ext = 999 (struct soc_bytes_ext *)kctl->private_value; 1000 struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); 1001 int ret = 0; 1002 1003 mutex_lock(&ctl->dsp->pwr_lock); 1004 1005 if (copy_from_user(ctl->cache, bytes, size)) { 1006 ret = -EFAULT; 1007 } else { 1008 ctl->set = 1; 1009 if (ctl->enabled && ctl->dsp->running) 1010 ret = wm_coeff_write_control(ctl, ctl->cache, size); 1011 else if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) 1012 ret = -EPERM; 1013 } 1014 1015 mutex_unlock(&ctl->dsp->pwr_lock); 1016 1017 return ret; 1018 } 1019 1020 static int wm_coeff_put_acked(struct snd_kcontrol *kctl, 1021 struct snd_ctl_elem_value *ucontrol) 1022 { 1023 struct soc_bytes_ext *bytes_ext = 1024 (struct soc_bytes_ext *)kctl->private_value; 1025 struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); 1026 unsigned int val = ucontrol->value.integer.value[0]; 1027 int ret; 1028 1029 if (val == 0) 1030 return 0; /* 0 means no event */ 1031 1032 mutex_lock(&ctl->dsp->pwr_lock); 1033 1034 if (ctl->enabled && ctl->dsp->running) 1035 ret = wm_coeff_write_acked_control(ctl, val); 1036 else 1037 ret = -EPERM; 1038 1039 mutex_unlock(&ctl->dsp->pwr_lock); 1040 1041 return ret; 1042 } 1043 1044 static int wm_coeff_read_control(struct wm_coeff_ctl *ctl, 1045 void *buf, size_t len) 1046 { 1047 struct wm_adsp *dsp = ctl->dsp; 1048 void *scratch; 1049 int ret; 1050 unsigned int reg; 1051 1052 ret = wm_coeff_base_reg(ctl, ®); 1053 if (ret) 1054 return ret; 1055 1056 scratch = kmalloc(len, GFP_KERNEL | GFP_DMA); 1057 if (!scratch) 1058 return -ENOMEM; 1059 1060 ret = regmap_raw_read(dsp->regmap, reg, scratch, len); 1061 if (ret) { 1062 adsp_err(dsp, "Failed to read %zu bytes from %x: %d\n", 1063 len, reg, ret); 1064 kfree(scratch); 1065 return ret; 1066 } 1067 adsp_dbg(dsp, "Read %zu bytes from %x\n", len, reg); 1068 1069 memcpy(buf, scratch, len); 1070 kfree(scratch); 1071 1072 return 0; 1073 } 1074 1075 static int wm_coeff_get(struct snd_kcontrol *kctl, 1076 struct snd_ctl_elem_value *ucontrol) 1077 { 1078 struct soc_bytes_ext *bytes_ext = 1079 (struct soc_bytes_ext *)kctl->private_value; 1080 struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); 1081 char *p = ucontrol->value.bytes.data; 1082 int ret = 0; 1083 1084 mutex_lock(&ctl->dsp->pwr_lock); 1085 1086 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { 1087 if (ctl->enabled && ctl->dsp->running) 1088 ret = wm_coeff_read_control(ctl, p, ctl->len); 1089 else 1090 ret = -EPERM; 1091 } else { 1092 if (!ctl->flags && ctl->enabled && ctl->dsp->running) 1093 ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); 1094 1095 memcpy(p, ctl->cache, ctl->len); 1096 } 1097 1098 mutex_unlock(&ctl->dsp->pwr_lock); 1099 1100 return ret; 1101 } 1102 1103 static int wm_coeff_tlv_get(struct snd_kcontrol *kctl, 1104 unsigned int __user *bytes, unsigned int size) 1105 { 1106 struct soc_bytes_ext *bytes_ext = 1107 (struct soc_bytes_ext *)kctl->private_value; 1108 struct wm_coeff_ctl *ctl = bytes_ext_to_ctl(bytes_ext); 1109 int ret = 0; 1110 1111 mutex_lock(&ctl->dsp->pwr_lock); 1112 1113 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) { 1114 if (ctl->enabled && ctl->dsp->running) 1115 ret = wm_coeff_read_control(ctl, ctl->cache, size); 1116 else 1117 ret = -EPERM; 1118 } else { 1119 if (!ctl->flags && ctl->enabled && ctl->dsp->running) 1120 ret = wm_coeff_read_control(ctl, ctl->cache, size); 1121 } 1122 1123 if (!ret && copy_to_user(bytes, ctl->cache, size)) 1124 ret = -EFAULT; 1125 1126 mutex_unlock(&ctl->dsp->pwr_lock); 1127 1128 return ret; 1129 } 1130 1131 static int wm_coeff_get_acked(struct snd_kcontrol *kcontrol, 1132 struct snd_ctl_elem_value *ucontrol) 1133 { 1134 /* 1135 * Although it's not useful to read an acked control, we must satisfy 1136 * user-side assumptions that all controls are readable and that a 1137 * write of the same value should be filtered out (it's valid to send 1138 * the same event number again to the firmware). We therefore return 0, 1139 * meaning "no event" so valid event numbers will always be a change 1140 */ 1141 ucontrol->value.integer.value[0] = 0; 1142 1143 return 0; 1144 } 1145 1146 struct wmfw_ctl_work { 1147 struct wm_adsp *dsp; 1148 struct wm_coeff_ctl *ctl; 1149 struct work_struct work; 1150 }; 1151 1152 static unsigned int wmfw_convert_flags(unsigned int in, unsigned int len) 1153 { 1154 unsigned int out, rd, wr, vol; 1155 1156 if (len > ADSP_MAX_STD_CTRL_SIZE) { 1157 rd = SNDRV_CTL_ELEM_ACCESS_TLV_READ; 1158 wr = SNDRV_CTL_ELEM_ACCESS_TLV_WRITE; 1159 vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; 1160 1161 out = SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; 1162 } else { 1163 rd = SNDRV_CTL_ELEM_ACCESS_READ; 1164 wr = SNDRV_CTL_ELEM_ACCESS_WRITE; 1165 vol = SNDRV_CTL_ELEM_ACCESS_VOLATILE; 1166 1167 out = 0; 1168 } 1169 1170 if (in) { 1171 if (in & WMFW_CTL_FLAG_READABLE) 1172 out |= rd; 1173 if (in & WMFW_CTL_FLAG_WRITEABLE) 1174 out |= wr; 1175 if (in & WMFW_CTL_FLAG_VOLATILE) 1176 out |= vol; 1177 } else { 1178 out |= rd | wr | vol; 1179 } 1180 1181 return out; 1182 } 1183 1184 static int wmfw_add_ctl(struct wm_adsp *dsp, struct wm_coeff_ctl *ctl) 1185 { 1186 struct snd_kcontrol_new *kcontrol; 1187 int ret; 1188 1189 if (!ctl || !ctl->name) 1190 return -EINVAL; 1191 1192 kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); 1193 if (!kcontrol) 1194 return -ENOMEM; 1195 1196 kcontrol->name = ctl->name; 1197 kcontrol->info = wm_coeff_info; 1198 kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1199 kcontrol->tlv.c = snd_soc_bytes_tlv_callback; 1200 kcontrol->private_value = (unsigned long)&ctl->bytes_ext; 1201 kcontrol->access = wmfw_convert_flags(ctl->flags, ctl->len); 1202 1203 switch (ctl->type) { 1204 case WMFW_CTL_TYPE_ACKED: 1205 kcontrol->get = wm_coeff_get_acked; 1206 kcontrol->put = wm_coeff_put_acked; 1207 break; 1208 default: 1209 kcontrol->get = wm_coeff_get; 1210 kcontrol->put = wm_coeff_put; 1211 1212 ctl->bytes_ext.max = ctl->len; 1213 ctl->bytes_ext.get = wm_coeff_tlv_get; 1214 ctl->bytes_ext.put = wm_coeff_tlv_put; 1215 break; 1216 } 1217 1218 ret = snd_soc_add_codec_controls(dsp->codec, kcontrol, 1); 1219 if (ret < 0) 1220 goto err_kcontrol; 1221 1222 kfree(kcontrol); 1223 1224 return 0; 1225 1226 err_kcontrol: 1227 kfree(kcontrol); 1228 return ret; 1229 } 1230 1231 static int wm_coeff_init_control_caches(struct wm_adsp *dsp) 1232 { 1233 struct wm_coeff_ctl *ctl; 1234 int ret; 1235 1236 list_for_each_entry(ctl, &dsp->ctl_list, list) { 1237 if (!ctl->enabled || ctl->set) 1238 continue; 1239 if (ctl->flags & WMFW_CTL_FLAG_VOLATILE) 1240 continue; 1241 1242 ret = wm_coeff_read_control(ctl, ctl->cache, ctl->len); 1243 if (ret < 0) 1244 return ret; 1245 } 1246 1247 return 0; 1248 } 1249 1250 static int wm_coeff_sync_controls(struct wm_adsp *dsp) 1251 { 1252 struct wm_coeff_ctl *ctl; 1253 int ret; 1254 1255 list_for_each_entry(ctl, &dsp->ctl_list, list) { 1256 if (!ctl->enabled) 1257 continue; 1258 if (ctl->set && !(ctl->flags & WMFW_CTL_FLAG_VOLATILE)) { 1259 ret = wm_coeff_write_control(ctl, ctl->cache, ctl->len); 1260 if (ret < 0) 1261 return ret; 1262 } 1263 } 1264 1265 return 0; 1266 } 1267 1268 static void wm_adsp_signal_event_controls(struct wm_adsp *dsp, 1269 unsigned int event) 1270 { 1271 struct wm_coeff_ctl *ctl; 1272 int ret; 1273 1274 list_for_each_entry(ctl, &dsp->ctl_list, list) { 1275 if (ctl->type != WMFW_CTL_TYPE_HOSTEVENT) 1276 continue; 1277 1278 if (!ctl->enabled) 1279 continue; 1280 1281 ret = wm_coeff_write_acked_control(ctl, event); 1282 if (ret) 1283 adsp_warn(dsp, 1284 "Failed to send 0x%x event to alg 0x%x (%d)\n", 1285 event, ctl->alg_region.alg, ret); 1286 } 1287 } 1288 1289 static void wm_adsp_ctl_work(struct work_struct *work) 1290 { 1291 struct wmfw_ctl_work *ctl_work = container_of(work, 1292 struct wmfw_ctl_work, 1293 work); 1294 1295 wmfw_add_ctl(ctl_work->dsp, ctl_work->ctl); 1296 kfree(ctl_work); 1297 } 1298 1299 static void wm_adsp_free_ctl_blk(struct wm_coeff_ctl *ctl) 1300 { 1301 kfree(ctl->cache); 1302 kfree(ctl->name); 1303 kfree(ctl); 1304 } 1305 1306 static int wm_adsp_create_control(struct wm_adsp *dsp, 1307 const struct wm_adsp_alg_region *alg_region, 1308 unsigned int offset, unsigned int len, 1309 const char *subname, unsigned int subname_len, 1310 unsigned int flags, unsigned int type) 1311 { 1312 struct wm_coeff_ctl *ctl; 1313 struct wmfw_ctl_work *ctl_work; 1314 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN]; 1315 const char *region_name; 1316 int ret; 1317 1318 region_name = wm_adsp_mem_region_name(alg_region->type); 1319 if (!region_name) { 1320 adsp_err(dsp, "Unknown region type: %d\n", alg_region->type); 1321 return -EINVAL; 1322 } 1323 1324 switch (dsp->fw_ver) { 1325 case 0: 1326 case 1: 1327 snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, "DSP%d %s %x", 1328 dsp->num, region_name, alg_region->alg); 1329 break; 1330 default: 1331 ret = snprintf(name, SNDRV_CTL_ELEM_ID_NAME_MAXLEN, 1332 "DSP%d%c %.12s %x", dsp->num, *region_name, 1333 wm_adsp_fw_text[dsp->fw], alg_region->alg); 1334 1335 /* Truncate the subname from the start if it is too long */ 1336 if (subname) { 1337 int avail = SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret - 2; 1338 int skip = 0; 1339 1340 if (subname_len > avail) 1341 skip = subname_len - avail; 1342 1343 snprintf(name + ret, 1344 SNDRV_CTL_ELEM_ID_NAME_MAXLEN - ret, " %.*s", 1345 subname_len - skip, subname + skip); 1346 } 1347 break; 1348 } 1349 1350 list_for_each_entry(ctl, &dsp->ctl_list, list) { 1351 if (!strcmp(ctl->name, name)) { 1352 if (!ctl->enabled) 1353 ctl->enabled = 1; 1354 return 0; 1355 } 1356 } 1357 1358 ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); 1359 if (!ctl) 1360 return -ENOMEM; 1361 ctl->fw_name = wm_adsp_fw_text[dsp->fw]; 1362 ctl->alg_region = *alg_region; 1363 ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL); 1364 if (!ctl->name) { 1365 ret = -ENOMEM; 1366 goto err_ctl; 1367 } 1368 ctl->enabled = 1; 1369 ctl->set = 0; 1370 ctl->ops.xget = wm_coeff_get; 1371 ctl->ops.xput = wm_coeff_put; 1372 ctl->dsp = dsp; 1373 1374 ctl->flags = flags; 1375 ctl->type = type; 1376 ctl->offset = offset; 1377 ctl->len = len; 1378 ctl->cache = kzalloc(ctl->len, GFP_KERNEL); 1379 if (!ctl->cache) { 1380 ret = -ENOMEM; 1381 goto err_ctl_name; 1382 } 1383 1384 list_add(&ctl->list, &dsp->ctl_list); 1385 1386 if (flags & WMFW_CTL_FLAG_SYS) 1387 return 0; 1388 1389 ctl_work = kzalloc(sizeof(*ctl_work), GFP_KERNEL); 1390 if (!ctl_work) { 1391 ret = -ENOMEM; 1392 goto err_ctl_cache; 1393 } 1394 1395 ctl_work->dsp = dsp; 1396 ctl_work->ctl = ctl; 1397 INIT_WORK(&ctl_work->work, wm_adsp_ctl_work); 1398 schedule_work(&ctl_work->work); 1399 1400 return 0; 1401 1402 err_ctl_cache: 1403 kfree(ctl->cache); 1404 err_ctl_name: 1405 kfree(ctl->name); 1406 err_ctl: 1407 kfree(ctl); 1408 1409 return ret; 1410 } 1411 1412 struct wm_coeff_parsed_alg { 1413 int id; 1414 const u8 *name; 1415 int name_len; 1416 int ncoeff; 1417 }; 1418 1419 struct wm_coeff_parsed_coeff { 1420 int offset; 1421 int mem_type; 1422 const u8 *name; 1423 int name_len; 1424 int ctl_type; 1425 int flags; 1426 int len; 1427 }; 1428 1429 static int wm_coeff_parse_string(int bytes, const u8 **pos, const u8 **str) 1430 { 1431 int length; 1432 1433 switch (bytes) { 1434 case 1: 1435 length = **pos; 1436 break; 1437 case 2: 1438 length = le16_to_cpu(*((__le16 *)*pos)); 1439 break; 1440 default: 1441 return 0; 1442 } 1443 1444 if (str) 1445 *str = *pos + bytes; 1446 1447 *pos += ((length + bytes) + 3) & ~0x03; 1448 1449 return length; 1450 } 1451 1452 static int wm_coeff_parse_int(int bytes, const u8 **pos) 1453 { 1454 int val = 0; 1455 1456 switch (bytes) { 1457 case 2: 1458 val = le16_to_cpu(*((__le16 *)*pos)); 1459 break; 1460 case 4: 1461 val = le32_to_cpu(*((__le32 *)*pos)); 1462 break; 1463 default: 1464 break; 1465 } 1466 1467 *pos += bytes; 1468 1469 return val; 1470 } 1471 1472 static inline void wm_coeff_parse_alg(struct wm_adsp *dsp, const u8 **data, 1473 struct wm_coeff_parsed_alg *blk) 1474 { 1475 const struct wmfw_adsp_alg_data *raw; 1476 1477 switch (dsp->fw_ver) { 1478 case 0: 1479 case 1: 1480 raw = (const struct wmfw_adsp_alg_data *)*data; 1481 *data = raw->data; 1482 1483 blk->id = le32_to_cpu(raw->id); 1484 blk->name = raw->name; 1485 blk->name_len = strlen(raw->name); 1486 blk->ncoeff = le32_to_cpu(raw->ncoeff); 1487 break; 1488 default: 1489 blk->id = wm_coeff_parse_int(sizeof(raw->id), data); 1490 blk->name_len = wm_coeff_parse_string(sizeof(u8), data, 1491 &blk->name); 1492 wm_coeff_parse_string(sizeof(u16), data, NULL); 1493 blk->ncoeff = wm_coeff_parse_int(sizeof(raw->ncoeff), data); 1494 break; 1495 } 1496 1497 adsp_dbg(dsp, "Algorithm ID: %#x\n", blk->id); 1498 adsp_dbg(dsp, "Algorithm name: %.*s\n", blk->name_len, blk->name); 1499 adsp_dbg(dsp, "# of coefficient descriptors: %#x\n", blk->ncoeff); 1500 } 1501 1502 static inline void wm_coeff_parse_coeff(struct wm_adsp *dsp, const u8 **data, 1503 struct wm_coeff_parsed_coeff *blk) 1504 { 1505 const struct wmfw_adsp_coeff_data *raw; 1506 const u8 *tmp; 1507 int length; 1508 1509 switch (dsp->fw_ver) { 1510 case 0: 1511 case 1: 1512 raw = (const struct wmfw_adsp_coeff_data *)*data; 1513 *data = *data + sizeof(raw->hdr) + le32_to_cpu(raw->hdr.size); 1514 1515 blk->offset = le16_to_cpu(raw->hdr.offset); 1516 blk->mem_type = le16_to_cpu(raw->hdr.type); 1517 blk->name = raw->name; 1518 blk->name_len = strlen(raw->name); 1519 blk->ctl_type = le16_to_cpu(raw->ctl_type); 1520 blk->flags = le16_to_cpu(raw->flags); 1521 blk->len = le32_to_cpu(raw->len); 1522 break; 1523 default: 1524 tmp = *data; 1525 blk->offset = wm_coeff_parse_int(sizeof(raw->hdr.offset), &tmp); 1526 blk->mem_type = wm_coeff_parse_int(sizeof(raw->hdr.type), &tmp); 1527 length = wm_coeff_parse_int(sizeof(raw->hdr.size), &tmp); 1528 blk->name_len = wm_coeff_parse_string(sizeof(u8), &tmp, 1529 &blk->name); 1530 wm_coeff_parse_string(sizeof(u8), &tmp, NULL); 1531 wm_coeff_parse_string(sizeof(u16), &tmp, NULL); 1532 blk->ctl_type = wm_coeff_parse_int(sizeof(raw->ctl_type), &tmp); 1533 blk->flags = wm_coeff_parse_int(sizeof(raw->flags), &tmp); 1534 blk->len = wm_coeff_parse_int(sizeof(raw->len), &tmp); 1535 1536 *data = *data + sizeof(raw->hdr) + length; 1537 break; 1538 } 1539 1540 adsp_dbg(dsp, "\tCoefficient type: %#x\n", blk->mem_type); 1541 adsp_dbg(dsp, "\tCoefficient offset: %#x\n", blk->offset); 1542 adsp_dbg(dsp, "\tCoefficient name: %.*s\n", blk->name_len, blk->name); 1543 adsp_dbg(dsp, "\tCoefficient flags: %#x\n", blk->flags); 1544 adsp_dbg(dsp, "\tALSA control type: %#x\n", blk->ctl_type); 1545 adsp_dbg(dsp, "\tALSA control len: %#x\n", blk->len); 1546 } 1547 1548 static int wm_adsp_check_coeff_flags(struct wm_adsp *dsp, 1549 const struct wm_coeff_parsed_coeff *coeff_blk, 1550 unsigned int f_required, 1551 unsigned int f_illegal) 1552 { 1553 if ((coeff_blk->flags & f_illegal) || 1554 ((coeff_blk->flags & f_required) != f_required)) { 1555 adsp_err(dsp, "Illegal flags 0x%x for control type 0x%x\n", 1556 coeff_blk->flags, coeff_blk->ctl_type); 1557 return -EINVAL; 1558 } 1559 1560 return 0; 1561 } 1562 1563 static int wm_adsp_parse_coeff(struct wm_adsp *dsp, 1564 const struct wmfw_region *region) 1565 { 1566 struct wm_adsp_alg_region alg_region = {}; 1567 struct wm_coeff_parsed_alg alg_blk; 1568 struct wm_coeff_parsed_coeff coeff_blk; 1569 const u8 *data = region->data; 1570 int i, ret; 1571 1572 wm_coeff_parse_alg(dsp, &data, &alg_blk); 1573 for (i = 0; i < alg_blk.ncoeff; i++) { 1574 wm_coeff_parse_coeff(dsp, &data, &coeff_blk); 1575 1576 switch (coeff_blk.ctl_type) { 1577 case SNDRV_CTL_ELEM_TYPE_BYTES: 1578 break; 1579 case WMFW_CTL_TYPE_ACKED: 1580 if (coeff_blk.flags & WMFW_CTL_FLAG_SYS) 1581 continue; /* ignore */ 1582 1583 ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, 1584 WMFW_CTL_FLAG_VOLATILE | 1585 WMFW_CTL_FLAG_WRITEABLE | 1586 WMFW_CTL_FLAG_READABLE, 1587 0); 1588 if (ret) 1589 return -EINVAL; 1590 break; 1591 case WMFW_CTL_TYPE_HOSTEVENT: 1592 ret = wm_adsp_check_coeff_flags(dsp, &coeff_blk, 1593 WMFW_CTL_FLAG_SYS | 1594 WMFW_CTL_FLAG_VOLATILE | 1595 WMFW_CTL_FLAG_WRITEABLE | 1596 WMFW_CTL_FLAG_READABLE, 1597 0); 1598 if (ret) 1599 return -EINVAL; 1600 break; 1601 default: 1602 adsp_err(dsp, "Unknown control type: %d\n", 1603 coeff_blk.ctl_type); 1604 return -EINVAL; 1605 } 1606 1607 alg_region.type = coeff_blk.mem_type; 1608 alg_region.alg = alg_blk.id; 1609 1610 ret = wm_adsp_create_control(dsp, &alg_region, 1611 coeff_blk.offset, 1612 coeff_blk.len, 1613 coeff_blk.name, 1614 coeff_blk.name_len, 1615 coeff_blk.flags, 1616 coeff_blk.ctl_type); 1617 if (ret < 0) 1618 adsp_err(dsp, "Failed to create control: %.*s, %d\n", 1619 coeff_blk.name_len, coeff_blk.name, ret); 1620 } 1621 1622 return 0; 1623 } 1624 1625 static int wm_adsp_load(struct wm_adsp *dsp) 1626 { 1627 LIST_HEAD(buf_list); 1628 const struct firmware *firmware; 1629 struct regmap *regmap = dsp->regmap; 1630 unsigned int pos = 0; 1631 const struct wmfw_header *header; 1632 const struct wmfw_adsp1_sizes *adsp1_sizes; 1633 const struct wmfw_adsp2_sizes *adsp2_sizes; 1634 const struct wmfw_footer *footer; 1635 const struct wmfw_region *region; 1636 const struct wm_adsp_region *mem; 1637 const char *region_name; 1638 char *file, *text = NULL; 1639 struct wm_adsp_buf *buf; 1640 unsigned int reg; 1641 int regions = 0; 1642 int ret, offset, type, sizes; 1643 1644 file = kzalloc(PAGE_SIZE, GFP_KERNEL); 1645 if (file == NULL) 1646 return -ENOMEM; 1647 1648 snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.wmfw", dsp->part, dsp->num, 1649 wm_adsp_fw[dsp->fw].file); 1650 file[PAGE_SIZE - 1] = '\0'; 1651 1652 ret = request_firmware(&firmware, file, dsp->dev); 1653 if (ret != 0) { 1654 adsp_err(dsp, "Failed to request '%s'\n", file); 1655 goto out; 1656 } 1657 ret = -EINVAL; 1658 1659 pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); 1660 if (pos >= firmware->size) { 1661 adsp_err(dsp, "%s: file too short, %zu bytes\n", 1662 file, firmware->size); 1663 goto out_fw; 1664 } 1665 1666 header = (void *)&firmware->data[0]; 1667 1668 if (memcmp(&header->magic[0], "WMFW", 4) != 0) { 1669 adsp_err(dsp, "%s: invalid magic\n", file); 1670 goto out_fw; 1671 } 1672 1673 switch (header->ver) { 1674 case 0: 1675 adsp_warn(dsp, "%s: Depreciated file format %d\n", 1676 file, header->ver); 1677 break; 1678 case 1: 1679 case 2: 1680 break; 1681 default: 1682 adsp_err(dsp, "%s: unknown file format %d\n", 1683 file, header->ver); 1684 goto out_fw; 1685 } 1686 1687 adsp_info(dsp, "Firmware version: %d\n", header->ver); 1688 dsp->fw_ver = header->ver; 1689 1690 if (header->core != dsp->type) { 1691 adsp_err(dsp, "%s: invalid core %d != %d\n", 1692 file, header->core, dsp->type); 1693 goto out_fw; 1694 } 1695 1696 switch (dsp->type) { 1697 case WMFW_ADSP1: 1698 pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); 1699 adsp1_sizes = (void *)&(header[1]); 1700 footer = (void *)&(adsp1_sizes[1]); 1701 sizes = sizeof(*adsp1_sizes); 1702 1703 adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", 1704 file, le32_to_cpu(adsp1_sizes->dm), 1705 le32_to_cpu(adsp1_sizes->pm), 1706 le32_to_cpu(adsp1_sizes->zm)); 1707 break; 1708 1709 case WMFW_ADSP2: 1710 pos = sizeof(*header) + sizeof(*adsp2_sizes) + sizeof(*footer); 1711 adsp2_sizes = (void *)&(header[1]); 1712 footer = (void *)&(adsp2_sizes[1]); 1713 sizes = sizeof(*adsp2_sizes); 1714 1715 adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", 1716 file, le32_to_cpu(adsp2_sizes->xm), 1717 le32_to_cpu(adsp2_sizes->ym), 1718 le32_to_cpu(adsp2_sizes->pm), 1719 le32_to_cpu(adsp2_sizes->zm)); 1720 break; 1721 1722 default: 1723 WARN(1, "Unknown DSP type"); 1724 goto out_fw; 1725 } 1726 1727 if (le32_to_cpu(header->len) != sizeof(*header) + 1728 sizes + sizeof(*footer)) { 1729 adsp_err(dsp, "%s: unexpected header length %d\n", 1730 file, le32_to_cpu(header->len)); 1731 goto out_fw; 1732 } 1733 1734 adsp_dbg(dsp, "%s: timestamp %llu\n", file, 1735 le64_to_cpu(footer->timestamp)); 1736 1737 while (pos < firmware->size && 1738 pos - firmware->size > sizeof(*region)) { 1739 region = (void *)&(firmware->data[pos]); 1740 region_name = "Unknown"; 1741 reg = 0; 1742 text = NULL; 1743 offset = le32_to_cpu(region->offset) & 0xffffff; 1744 type = be32_to_cpu(region->type) & 0xff; 1745 mem = wm_adsp_find_region(dsp, type); 1746 1747 switch (type) { 1748 case WMFW_NAME_TEXT: 1749 region_name = "Firmware name"; 1750 text = kzalloc(le32_to_cpu(region->len) + 1, 1751 GFP_KERNEL); 1752 break; 1753 case WMFW_ALGORITHM_DATA: 1754 region_name = "Algorithm"; 1755 ret = wm_adsp_parse_coeff(dsp, region); 1756 if (ret != 0) 1757 goto out_fw; 1758 break; 1759 case WMFW_INFO_TEXT: 1760 region_name = "Information"; 1761 text = kzalloc(le32_to_cpu(region->len) + 1, 1762 GFP_KERNEL); 1763 break; 1764 case WMFW_ABSOLUTE: 1765 region_name = "Absolute"; 1766 reg = offset; 1767 break; 1768 case WMFW_ADSP1_PM: 1769 case WMFW_ADSP1_DM: 1770 case WMFW_ADSP2_XM: 1771 case WMFW_ADSP2_YM: 1772 case WMFW_ADSP1_ZM: 1773 region_name = wm_adsp_mem_region_name(type); 1774 reg = wm_adsp_region_to_reg(mem, offset); 1775 break; 1776 default: 1777 adsp_warn(dsp, 1778 "%s.%d: Unknown region type %x at %d(%x)\n", 1779 file, regions, type, pos, pos); 1780 break; 1781 } 1782 1783 adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, 1784 regions, le32_to_cpu(region->len), offset, 1785 region_name); 1786 1787 if ((pos + le32_to_cpu(region->len) + sizeof(*region)) > 1788 firmware->size) { 1789 adsp_err(dsp, 1790 "%s.%d: %s region len %d bytes exceeds file length %zu\n", 1791 file, regions, region_name, 1792 le32_to_cpu(region->len), firmware->size); 1793 ret = -EINVAL; 1794 goto out_fw; 1795 } 1796 1797 if (text) { 1798 memcpy(text, region->data, le32_to_cpu(region->len)); 1799 adsp_info(dsp, "%s: %s\n", file, text); 1800 kfree(text); 1801 text = NULL; 1802 } 1803 1804 if (reg) { 1805 buf = wm_adsp_buf_alloc(region->data, 1806 le32_to_cpu(region->len), 1807 &buf_list); 1808 if (!buf) { 1809 adsp_err(dsp, "Out of memory\n"); 1810 ret = -ENOMEM; 1811 goto out_fw; 1812 } 1813 1814 ret = regmap_raw_write_async(regmap, reg, buf->buf, 1815 le32_to_cpu(region->len)); 1816 if (ret != 0) { 1817 adsp_err(dsp, 1818 "%s.%d: Failed to write %d bytes at %d in %s: %d\n", 1819 file, regions, 1820 le32_to_cpu(region->len), offset, 1821 region_name, ret); 1822 goto out_fw; 1823 } 1824 } 1825 1826 pos += le32_to_cpu(region->len) + sizeof(*region); 1827 regions++; 1828 } 1829 1830 ret = regmap_async_complete(regmap); 1831 if (ret != 0) { 1832 adsp_err(dsp, "Failed to complete async write: %d\n", ret); 1833 goto out_fw; 1834 } 1835 1836 if (pos > firmware->size) 1837 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", 1838 file, regions, pos - firmware->size); 1839 1840 wm_adsp_debugfs_save_wmfwname(dsp, file); 1841 1842 out_fw: 1843 regmap_async_complete(regmap); 1844 wm_adsp_buf_free(&buf_list); 1845 release_firmware(firmware); 1846 kfree(text); 1847 out: 1848 kfree(file); 1849 1850 return ret; 1851 } 1852 1853 static void wm_adsp_ctl_fixup_base(struct wm_adsp *dsp, 1854 const struct wm_adsp_alg_region *alg_region) 1855 { 1856 struct wm_coeff_ctl *ctl; 1857 1858 list_for_each_entry(ctl, &dsp->ctl_list, list) { 1859 if (ctl->fw_name == wm_adsp_fw_text[dsp->fw] && 1860 alg_region->alg == ctl->alg_region.alg && 1861 alg_region->type == ctl->alg_region.type) { 1862 ctl->alg_region.base = alg_region->base; 1863 } 1864 } 1865 } 1866 1867 static void *wm_adsp_read_algs(struct wm_adsp *dsp, size_t n_algs, 1868 unsigned int pos, unsigned int len) 1869 { 1870 void *alg; 1871 int ret; 1872 __be32 val; 1873 1874 if (n_algs == 0) { 1875 adsp_err(dsp, "No algorithms\n"); 1876 return ERR_PTR(-EINVAL); 1877 } 1878 1879 if (n_algs > 1024) { 1880 adsp_err(dsp, "Algorithm count %zx excessive\n", n_algs); 1881 return ERR_PTR(-EINVAL); 1882 } 1883 1884 /* Read the terminator first to validate the length */ 1885 ret = regmap_raw_read(dsp->regmap, pos + len, &val, sizeof(val)); 1886 if (ret != 0) { 1887 adsp_err(dsp, "Failed to read algorithm list end: %d\n", 1888 ret); 1889 return ERR_PTR(ret); 1890 } 1891 1892 if (be32_to_cpu(val) != 0xbedead) 1893 adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbeadead\n", 1894 pos + len, be32_to_cpu(val)); 1895 1896 alg = kzalloc(len * 2, GFP_KERNEL | GFP_DMA); 1897 if (!alg) 1898 return ERR_PTR(-ENOMEM); 1899 1900 ret = regmap_raw_read(dsp->regmap, pos, alg, len * 2); 1901 if (ret != 0) { 1902 adsp_err(dsp, "Failed to read algorithm list: %d\n", ret); 1903 kfree(alg); 1904 return ERR_PTR(ret); 1905 } 1906 1907 return alg; 1908 } 1909 1910 static struct wm_adsp_alg_region * 1911 wm_adsp_find_alg_region(struct wm_adsp *dsp, int type, unsigned int id) 1912 { 1913 struct wm_adsp_alg_region *alg_region; 1914 1915 list_for_each_entry(alg_region, &dsp->alg_regions, list) { 1916 if (id == alg_region->alg && type == alg_region->type) 1917 return alg_region; 1918 } 1919 1920 return NULL; 1921 } 1922 1923 static struct wm_adsp_alg_region *wm_adsp_create_region(struct wm_adsp *dsp, 1924 int type, __be32 id, 1925 __be32 base) 1926 { 1927 struct wm_adsp_alg_region *alg_region; 1928 1929 alg_region = kzalloc(sizeof(*alg_region), GFP_KERNEL); 1930 if (!alg_region) 1931 return ERR_PTR(-ENOMEM); 1932 1933 alg_region->type = type; 1934 alg_region->alg = be32_to_cpu(id); 1935 alg_region->base = be32_to_cpu(base); 1936 1937 list_add_tail(&alg_region->list, &dsp->alg_regions); 1938 1939 if (dsp->fw_ver > 0) 1940 wm_adsp_ctl_fixup_base(dsp, alg_region); 1941 1942 return alg_region; 1943 } 1944 1945 static void wm_adsp_free_alg_regions(struct wm_adsp *dsp) 1946 { 1947 struct wm_adsp_alg_region *alg_region; 1948 1949 while (!list_empty(&dsp->alg_regions)) { 1950 alg_region = list_first_entry(&dsp->alg_regions, 1951 struct wm_adsp_alg_region, 1952 list); 1953 list_del(&alg_region->list); 1954 kfree(alg_region); 1955 } 1956 } 1957 1958 static int wm_adsp1_setup_algs(struct wm_adsp *dsp) 1959 { 1960 struct wmfw_adsp1_id_hdr adsp1_id; 1961 struct wmfw_adsp1_alg_hdr *adsp1_alg; 1962 struct wm_adsp_alg_region *alg_region; 1963 const struct wm_adsp_region *mem; 1964 unsigned int pos, len; 1965 size_t n_algs; 1966 int i, ret; 1967 1968 mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM); 1969 if (WARN_ON(!mem)) 1970 return -EINVAL; 1971 1972 ret = regmap_raw_read(dsp->regmap, mem->base, &adsp1_id, 1973 sizeof(adsp1_id)); 1974 if (ret != 0) { 1975 adsp_err(dsp, "Failed to read algorithm info: %d\n", 1976 ret); 1977 return ret; 1978 } 1979 1980 n_algs = be32_to_cpu(adsp1_id.n_algs); 1981 dsp->fw_id = be32_to_cpu(adsp1_id.fw.id); 1982 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", 1983 dsp->fw_id, 1984 (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16, 1985 (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8, 1986 be32_to_cpu(adsp1_id.fw.ver) & 0xff, 1987 n_algs); 1988 1989 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, 1990 adsp1_id.fw.id, adsp1_id.zm); 1991 if (IS_ERR(alg_region)) 1992 return PTR_ERR(alg_region); 1993 1994 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, 1995 adsp1_id.fw.id, adsp1_id.dm); 1996 if (IS_ERR(alg_region)) 1997 return PTR_ERR(alg_region); 1998 1999 pos = sizeof(adsp1_id) / 2; 2000 len = (sizeof(*adsp1_alg) * n_algs) / 2; 2001 2002 adsp1_alg = wm_adsp_read_algs(dsp, n_algs, mem->base + pos, len); 2003 if (IS_ERR(adsp1_alg)) 2004 return PTR_ERR(adsp1_alg); 2005 2006 for (i = 0; i < n_algs; i++) { 2007 adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", 2008 i, be32_to_cpu(adsp1_alg[i].alg.id), 2009 (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, 2010 (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, 2011 be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, 2012 be32_to_cpu(adsp1_alg[i].dm), 2013 be32_to_cpu(adsp1_alg[i].zm)); 2014 2015 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_DM, 2016 adsp1_alg[i].alg.id, 2017 adsp1_alg[i].dm); 2018 if (IS_ERR(alg_region)) { 2019 ret = PTR_ERR(alg_region); 2020 goto out; 2021 } 2022 if (dsp->fw_ver == 0) { 2023 if (i + 1 < n_algs) { 2024 len = be32_to_cpu(adsp1_alg[i + 1].dm); 2025 len -= be32_to_cpu(adsp1_alg[i].dm); 2026 len *= 4; 2027 wm_adsp_create_control(dsp, alg_region, 0, 2028 len, NULL, 0, 0, 2029 SNDRV_CTL_ELEM_TYPE_BYTES); 2030 } else { 2031 adsp_warn(dsp, "Missing length info for region DM with ID %x\n", 2032 be32_to_cpu(adsp1_alg[i].alg.id)); 2033 } 2034 } 2035 2036 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP1_ZM, 2037 adsp1_alg[i].alg.id, 2038 adsp1_alg[i].zm); 2039 if (IS_ERR(alg_region)) { 2040 ret = PTR_ERR(alg_region); 2041 goto out; 2042 } 2043 if (dsp->fw_ver == 0) { 2044 if (i + 1 < n_algs) { 2045 len = be32_to_cpu(adsp1_alg[i + 1].zm); 2046 len -= be32_to_cpu(adsp1_alg[i].zm); 2047 len *= 4; 2048 wm_adsp_create_control(dsp, alg_region, 0, 2049 len, NULL, 0, 0, 2050 SNDRV_CTL_ELEM_TYPE_BYTES); 2051 } else { 2052 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", 2053 be32_to_cpu(adsp1_alg[i].alg.id)); 2054 } 2055 } 2056 } 2057 2058 out: 2059 kfree(adsp1_alg); 2060 return ret; 2061 } 2062 2063 static int wm_adsp2_setup_algs(struct wm_adsp *dsp) 2064 { 2065 struct wmfw_adsp2_id_hdr adsp2_id; 2066 struct wmfw_adsp2_alg_hdr *adsp2_alg; 2067 struct wm_adsp_alg_region *alg_region; 2068 const struct wm_adsp_region *mem; 2069 unsigned int pos, len; 2070 size_t n_algs; 2071 int i, ret; 2072 2073 mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); 2074 if (WARN_ON(!mem)) 2075 return -EINVAL; 2076 2077 ret = regmap_raw_read(dsp->regmap, mem->base, &adsp2_id, 2078 sizeof(adsp2_id)); 2079 if (ret != 0) { 2080 adsp_err(dsp, "Failed to read algorithm info: %d\n", 2081 ret); 2082 return ret; 2083 } 2084 2085 n_algs = be32_to_cpu(adsp2_id.n_algs); 2086 dsp->fw_id = be32_to_cpu(adsp2_id.fw.id); 2087 dsp->fw_id_version = be32_to_cpu(adsp2_id.fw.ver); 2088 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", 2089 dsp->fw_id, 2090 (dsp->fw_id_version & 0xff0000) >> 16, 2091 (dsp->fw_id_version & 0xff00) >> 8, 2092 dsp->fw_id_version & 0xff, 2093 n_algs); 2094 2095 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, 2096 adsp2_id.fw.id, adsp2_id.xm); 2097 if (IS_ERR(alg_region)) 2098 return PTR_ERR(alg_region); 2099 2100 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, 2101 adsp2_id.fw.id, adsp2_id.ym); 2102 if (IS_ERR(alg_region)) 2103 return PTR_ERR(alg_region); 2104 2105 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, 2106 adsp2_id.fw.id, adsp2_id.zm); 2107 if (IS_ERR(alg_region)) 2108 return PTR_ERR(alg_region); 2109 2110 pos = sizeof(adsp2_id) / 2; 2111 len = (sizeof(*adsp2_alg) * n_algs) / 2; 2112 2113 adsp2_alg = wm_adsp_read_algs(dsp, n_algs, mem->base + pos, len); 2114 if (IS_ERR(adsp2_alg)) 2115 return PTR_ERR(adsp2_alg); 2116 2117 for (i = 0; i < n_algs; i++) { 2118 adsp_info(dsp, 2119 "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", 2120 i, be32_to_cpu(adsp2_alg[i].alg.id), 2121 (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, 2122 (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, 2123 be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, 2124 be32_to_cpu(adsp2_alg[i].xm), 2125 be32_to_cpu(adsp2_alg[i].ym), 2126 be32_to_cpu(adsp2_alg[i].zm)); 2127 2128 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_XM, 2129 adsp2_alg[i].alg.id, 2130 adsp2_alg[i].xm); 2131 if (IS_ERR(alg_region)) { 2132 ret = PTR_ERR(alg_region); 2133 goto out; 2134 } 2135 if (dsp->fw_ver == 0) { 2136 if (i + 1 < n_algs) { 2137 len = be32_to_cpu(adsp2_alg[i + 1].xm); 2138 len -= be32_to_cpu(adsp2_alg[i].xm); 2139 len *= 4; 2140 wm_adsp_create_control(dsp, alg_region, 0, 2141 len, NULL, 0, 0, 2142 SNDRV_CTL_ELEM_TYPE_BYTES); 2143 } else { 2144 adsp_warn(dsp, "Missing length info for region XM with ID %x\n", 2145 be32_to_cpu(adsp2_alg[i].alg.id)); 2146 } 2147 } 2148 2149 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_YM, 2150 adsp2_alg[i].alg.id, 2151 adsp2_alg[i].ym); 2152 if (IS_ERR(alg_region)) { 2153 ret = PTR_ERR(alg_region); 2154 goto out; 2155 } 2156 if (dsp->fw_ver == 0) { 2157 if (i + 1 < n_algs) { 2158 len = be32_to_cpu(adsp2_alg[i + 1].ym); 2159 len -= be32_to_cpu(adsp2_alg[i].ym); 2160 len *= 4; 2161 wm_adsp_create_control(dsp, alg_region, 0, 2162 len, NULL, 0, 0, 2163 SNDRV_CTL_ELEM_TYPE_BYTES); 2164 } else { 2165 adsp_warn(dsp, "Missing length info for region YM with ID %x\n", 2166 be32_to_cpu(adsp2_alg[i].alg.id)); 2167 } 2168 } 2169 2170 alg_region = wm_adsp_create_region(dsp, WMFW_ADSP2_ZM, 2171 adsp2_alg[i].alg.id, 2172 adsp2_alg[i].zm); 2173 if (IS_ERR(alg_region)) { 2174 ret = PTR_ERR(alg_region); 2175 goto out; 2176 } 2177 if (dsp->fw_ver == 0) { 2178 if (i + 1 < n_algs) { 2179 len = be32_to_cpu(adsp2_alg[i + 1].zm); 2180 len -= be32_to_cpu(adsp2_alg[i].zm); 2181 len *= 4; 2182 wm_adsp_create_control(dsp, alg_region, 0, 2183 len, NULL, 0, 0, 2184 SNDRV_CTL_ELEM_TYPE_BYTES); 2185 } else { 2186 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", 2187 be32_to_cpu(adsp2_alg[i].alg.id)); 2188 } 2189 } 2190 } 2191 2192 out: 2193 kfree(adsp2_alg); 2194 return ret; 2195 } 2196 2197 static int wm_adsp_load_coeff(struct wm_adsp *dsp) 2198 { 2199 LIST_HEAD(buf_list); 2200 struct regmap *regmap = dsp->regmap; 2201 struct wmfw_coeff_hdr *hdr; 2202 struct wmfw_coeff_item *blk; 2203 const struct firmware *firmware; 2204 const struct wm_adsp_region *mem; 2205 struct wm_adsp_alg_region *alg_region; 2206 const char *region_name; 2207 int ret, pos, blocks, type, offset, reg; 2208 char *file; 2209 struct wm_adsp_buf *buf; 2210 2211 file = kzalloc(PAGE_SIZE, GFP_KERNEL); 2212 if (file == NULL) 2213 return -ENOMEM; 2214 2215 snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.bin", dsp->part, dsp->num, 2216 wm_adsp_fw[dsp->fw].file); 2217 file[PAGE_SIZE - 1] = '\0'; 2218 2219 ret = request_firmware(&firmware, file, dsp->dev); 2220 if (ret != 0) { 2221 adsp_warn(dsp, "Failed to request '%s'\n", file); 2222 ret = 0; 2223 goto out; 2224 } 2225 ret = -EINVAL; 2226 2227 if (sizeof(*hdr) >= firmware->size) { 2228 adsp_err(dsp, "%s: file too short, %zu bytes\n", 2229 file, firmware->size); 2230 goto out_fw; 2231 } 2232 2233 hdr = (void *)&firmware->data[0]; 2234 if (memcmp(hdr->magic, "WMDR", 4) != 0) { 2235 adsp_err(dsp, "%s: invalid magic\n", file); 2236 goto out_fw; 2237 } 2238 2239 switch (be32_to_cpu(hdr->rev) & 0xff) { 2240 case 1: 2241 break; 2242 default: 2243 adsp_err(dsp, "%s: Unsupported coefficient file format %d\n", 2244 file, be32_to_cpu(hdr->rev) & 0xff); 2245 ret = -EINVAL; 2246 goto out_fw; 2247 } 2248 2249 adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, 2250 (le32_to_cpu(hdr->ver) >> 16) & 0xff, 2251 (le32_to_cpu(hdr->ver) >> 8) & 0xff, 2252 le32_to_cpu(hdr->ver) & 0xff); 2253 2254 pos = le32_to_cpu(hdr->len); 2255 2256 blocks = 0; 2257 while (pos < firmware->size && 2258 pos - firmware->size > sizeof(*blk)) { 2259 blk = (void *)(&firmware->data[pos]); 2260 2261 type = le16_to_cpu(blk->type); 2262 offset = le16_to_cpu(blk->offset); 2263 2264 adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", 2265 file, blocks, le32_to_cpu(blk->id), 2266 (le32_to_cpu(blk->ver) >> 16) & 0xff, 2267 (le32_to_cpu(blk->ver) >> 8) & 0xff, 2268 le32_to_cpu(blk->ver) & 0xff); 2269 adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", 2270 file, blocks, le32_to_cpu(blk->len), offset, type); 2271 2272 reg = 0; 2273 region_name = "Unknown"; 2274 switch (type) { 2275 case (WMFW_NAME_TEXT << 8): 2276 case (WMFW_INFO_TEXT << 8): 2277 break; 2278 case (WMFW_ABSOLUTE << 8): 2279 /* 2280 * Old files may use this for global 2281 * coefficients. 2282 */ 2283 if (le32_to_cpu(blk->id) == dsp->fw_id && 2284 offset == 0) { 2285 region_name = "global coefficients"; 2286 mem = wm_adsp_find_region(dsp, type); 2287 if (!mem) { 2288 adsp_err(dsp, "No ZM\n"); 2289 break; 2290 } 2291 reg = wm_adsp_region_to_reg(mem, 0); 2292 2293 } else { 2294 region_name = "register"; 2295 reg = offset; 2296 } 2297 break; 2298 2299 case WMFW_ADSP1_DM: 2300 case WMFW_ADSP1_ZM: 2301 case WMFW_ADSP2_XM: 2302 case WMFW_ADSP2_YM: 2303 adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", 2304 file, blocks, le32_to_cpu(blk->len), 2305 type, le32_to_cpu(blk->id)); 2306 2307 mem = wm_adsp_find_region(dsp, type); 2308 if (!mem) { 2309 adsp_err(dsp, "No base for region %x\n", type); 2310 break; 2311 } 2312 2313 alg_region = wm_adsp_find_alg_region(dsp, type, 2314 le32_to_cpu(blk->id)); 2315 if (alg_region) { 2316 reg = alg_region->base; 2317 reg = wm_adsp_region_to_reg(mem, reg); 2318 reg += offset; 2319 } else { 2320 adsp_err(dsp, "No %x for algorithm %x\n", 2321 type, le32_to_cpu(blk->id)); 2322 } 2323 break; 2324 2325 default: 2326 adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", 2327 file, blocks, type, pos); 2328 break; 2329 } 2330 2331 if (reg) { 2332 if ((pos + le32_to_cpu(blk->len) + sizeof(*blk)) > 2333 firmware->size) { 2334 adsp_err(dsp, 2335 "%s.%d: %s region len %d bytes exceeds file length %zu\n", 2336 file, blocks, region_name, 2337 le32_to_cpu(blk->len), 2338 firmware->size); 2339 ret = -EINVAL; 2340 goto out_fw; 2341 } 2342 2343 buf = wm_adsp_buf_alloc(blk->data, 2344 le32_to_cpu(blk->len), 2345 &buf_list); 2346 if (!buf) { 2347 adsp_err(dsp, "Out of memory\n"); 2348 ret = -ENOMEM; 2349 goto out_fw; 2350 } 2351 2352 adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", 2353 file, blocks, le32_to_cpu(blk->len), 2354 reg); 2355 ret = regmap_raw_write_async(regmap, reg, buf->buf, 2356 le32_to_cpu(blk->len)); 2357 if (ret != 0) { 2358 adsp_err(dsp, 2359 "%s.%d: Failed to write to %x in %s: %d\n", 2360 file, blocks, reg, region_name, ret); 2361 } 2362 } 2363 2364 pos += (le32_to_cpu(blk->len) + sizeof(*blk) + 3) & ~0x03; 2365 blocks++; 2366 } 2367 2368 ret = regmap_async_complete(regmap); 2369 if (ret != 0) 2370 adsp_err(dsp, "Failed to complete async write: %d\n", ret); 2371 2372 if (pos > firmware->size) 2373 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", 2374 file, blocks, pos - firmware->size); 2375 2376 wm_adsp_debugfs_save_binname(dsp, file); 2377 2378 out_fw: 2379 regmap_async_complete(regmap); 2380 release_firmware(firmware); 2381 wm_adsp_buf_free(&buf_list); 2382 out: 2383 kfree(file); 2384 return ret; 2385 } 2386 2387 int wm_adsp1_init(struct wm_adsp *dsp) 2388 { 2389 INIT_LIST_HEAD(&dsp->alg_regions); 2390 2391 mutex_init(&dsp->pwr_lock); 2392 2393 return 0; 2394 } 2395 EXPORT_SYMBOL_GPL(wm_adsp1_init); 2396 2397 int wm_adsp1_event(struct snd_soc_dapm_widget *w, 2398 struct snd_kcontrol *kcontrol, 2399 int event) 2400 { 2401 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 2402 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 2403 struct wm_adsp *dsp = &dsps[w->shift]; 2404 struct wm_coeff_ctl *ctl; 2405 int ret; 2406 unsigned int val; 2407 2408 dsp->codec = codec; 2409 2410 mutex_lock(&dsp->pwr_lock); 2411 2412 switch (event) { 2413 case SND_SOC_DAPM_POST_PMU: 2414 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2415 ADSP1_SYS_ENA, ADSP1_SYS_ENA); 2416 2417 /* 2418 * For simplicity set the DSP clock rate to be the 2419 * SYSCLK rate rather than making it configurable. 2420 */ 2421 if (dsp->sysclk_reg) { 2422 ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); 2423 if (ret != 0) { 2424 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", 2425 ret); 2426 goto err_mutex; 2427 } 2428 2429 val = (val & dsp->sysclk_mask) >> dsp->sysclk_shift; 2430 2431 ret = regmap_update_bits(dsp->regmap, 2432 dsp->base + ADSP1_CONTROL_31, 2433 ADSP1_CLK_SEL_MASK, val); 2434 if (ret != 0) { 2435 adsp_err(dsp, "Failed to set clock rate: %d\n", 2436 ret); 2437 goto err_mutex; 2438 } 2439 } 2440 2441 ret = wm_adsp_load(dsp); 2442 if (ret != 0) 2443 goto err_ena; 2444 2445 ret = wm_adsp1_setup_algs(dsp); 2446 if (ret != 0) 2447 goto err_ena; 2448 2449 ret = wm_adsp_load_coeff(dsp); 2450 if (ret != 0) 2451 goto err_ena; 2452 2453 /* Initialize caches for enabled and unset controls */ 2454 ret = wm_coeff_init_control_caches(dsp); 2455 if (ret != 0) 2456 goto err_ena; 2457 2458 /* Sync set controls */ 2459 ret = wm_coeff_sync_controls(dsp); 2460 if (ret != 0) 2461 goto err_ena; 2462 2463 dsp->booted = true; 2464 2465 /* Start the core running */ 2466 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2467 ADSP1_CORE_ENA | ADSP1_START, 2468 ADSP1_CORE_ENA | ADSP1_START); 2469 2470 dsp->running = true; 2471 break; 2472 2473 case SND_SOC_DAPM_PRE_PMD: 2474 dsp->running = false; 2475 dsp->booted = false; 2476 2477 /* Halt the core */ 2478 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2479 ADSP1_CORE_ENA | ADSP1_START, 0); 2480 2481 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, 2482 ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); 2483 2484 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2485 ADSP1_SYS_ENA, 0); 2486 2487 list_for_each_entry(ctl, &dsp->ctl_list, list) 2488 ctl->enabled = 0; 2489 2490 2491 wm_adsp_free_alg_regions(dsp); 2492 break; 2493 2494 default: 2495 break; 2496 } 2497 2498 mutex_unlock(&dsp->pwr_lock); 2499 2500 return 0; 2501 2502 err_ena: 2503 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 2504 ADSP1_SYS_ENA, 0); 2505 err_mutex: 2506 mutex_unlock(&dsp->pwr_lock); 2507 2508 return ret; 2509 } 2510 EXPORT_SYMBOL_GPL(wm_adsp1_event); 2511 2512 static int wm_adsp2_ena(struct wm_adsp *dsp) 2513 { 2514 unsigned int val; 2515 int ret, count; 2516 2517 switch (dsp->rev) { 2518 case 0: 2519 ret = regmap_update_bits_async(dsp->regmap, 2520 dsp->base + ADSP2_CONTROL, 2521 ADSP2_SYS_ENA, ADSP2_SYS_ENA); 2522 if (ret != 0) 2523 return ret; 2524 break; 2525 default: 2526 break; 2527 } 2528 2529 /* Wait for the RAM to start, should be near instantaneous */ 2530 for (count = 0; count < 10; ++count) { 2531 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, &val); 2532 if (ret != 0) 2533 return ret; 2534 2535 if (val & ADSP2_RAM_RDY) 2536 break; 2537 2538 usleep_range(250, 500); 2539 } 2540 2541 if (!(val & ADSP2_RAM_RDY)) { 2542 adsp_err(dsp, "Failed to start DSP RAM\n"); 2543 return -EBUSY; 2544 } 2545 2546 adsp_dbg(dsp, "RAM ready after %d polls\n", count); 2547 2548 return 0; 2549 } 2550 2551 static void wm_adsp2_boot_work(struct work_struct *work) 2552 { 2553 struct wm_adsp *dsp = container_of(work, 2554 struct wm_adsp, 2555 boot_work); 2556 int ret; 2557 2558 mutex_lock(&dsp->pwr_lock); 2559 2560 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2561 ADSP2_MEM_ENA, ADSP2_MEM_ENA); 2562 if (ret != 0) 2563 goto err_mutex; 2564 2565 ret = wm_adsp2_ena(dsp); 2566 if (ret != 0) 2567 goto err_mem; 2568 2569 ret = wm_adsp_load(dsp); 2570 if (ret != 0) 2571 goto err_ena; 2572 2573 ret = wm_adsp2_setup_algs(dsp); 2574 if (ret != 0) 2575 goto err_ena; 2576 2577 ret = wm_adsp_load_coeff(dsp); 2578 if (ret != 0) 2579 goto err_ena; 2580 2581 /* Initialize caches for enabled and unset controls */ 2582 ret = wm_coeff_init_control_caches(dsp); 2583 if (ret != 0) 2584 goto err_ena; 2585 2586 switch (dsp->rev) { 2587 case 0: 2588 /* Turn DSP back off until we are ready to run */ 2589 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2590 ADSP2_SYS_ENA, 0); 2591 if (ret != 0) 2592 goto err_ena; 2593 break; 2594 default: 2595 break; 2596 } 2597 2598 dsp->booted = true; 2599 2600 mutex_unlock(&dsp->pwr_lock); 2601 2602 return; 2603 2604 err_ena: 2605 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2606 ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); 2607 err_mem: 2608 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2609 ADSP2_MEM_ENA, 0); 2610 err_mutex: 2611 mutex_unlock(&dsp->pwr_lock); 2612 } 2613 2614 static void wm_adsp2_set_dspclk(struct wm_adsp *dsp, unsigned int freq) 2615 { 2616 int ret; 2617 2618 switch (dsp->rev) { 2619 case 0: 2620 ret = regmap_update_bits_async(dsp->regmap, 2621 dsp->base + ADSP2_CLOCKING, 2622 ADSP2_CLK_SEL_MASK, 2623 freq << ADSP2_CLK_SEL_SHIFT); 2624 if (ret) { 2625 adsp_err(dsp, "Failed to set clock rate: %d\n", ret); 2626 return; 2627 } 2628 break; 2629 default: 2630 /* clock is handled by parent codec driver */ 2631 break; 2632 } 2633 } 2634 2635 int wm_adsp2_preloader_get(struct snd_kcontrol *kcontrol, 2636 struct snd_ctl_elem_value *ucontrol) 2637 { 2638 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 2639 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); 2640 2641 ucontrol->value.integer.value[0] = dsp->preloaded; 2642 2643 return 0; 2644 } 2645 EXPORT_SYMBOL_GPL(wm_adsp2_preloader_get); 2646 2647 int wm_adsp2_preloader_put(struct snd_kcontrol *kcontrol, 2648 struct snd_ctl_elem_value *ucontrol) 2649 { 2650 struct snd_soc_codec *codec = snd_soc_kcontrol_codec(kcontrol); 2651 struct wm_adsp *dsp = snd_soc_codec_get_drvdata(codec); 2652 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 2653 struct soc_mixer_control *mc = 2654 (struct soc_mixer_control *)kcontrol->private_value; 2655 char preload[32]; 2656 2657 snprintf(preload, ARRAY_SIZE(preload), "DSP%d Preload", mc->shift); 2658 2659 dsp->preloaded = ucontrol->value.integer.value[0]; 2660 2661 if (ucontrol->value.integer.value[0]) 2662 snd_soc_dapm_force_enable_pin(dapm, preload); 2663 else 2664 snd_soc_dapm_disable_pin(dapm, preload); 2665 2666 snd_soc_dapm_sync(dapm); 2667 2668 return 0; 2669 } 2670 EXPORT_SYMBOL_GPL(wm_adsp2_preloader_put); 2671 2672 static void wm_adsp_stop_watchdog(struct wm_adsp *dsp) 2673 { 2674 switch (dsp->rev) { 2675 case 0: 2676 case 1: 2677 return; 2678 default: 2679 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_WATCHDOG, 2680 ADSP2_WDT_ENA_MASK, 0); 2681 } 2682 } 2683 2684 int wm_adsp2_early_event(struct snd_soc_dapm_widget *w, 2685 struct snd_kcontrol *kcontrol, int event, 2686 unsigned int freq) 2687 { 2688 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 2689 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 2690 struct wm_adsp *dsp = &dsps[w->shift]; 2691 struct wm_coeff_ctl *ctl; 2692 2693 switch (event) { 2694 case SND_SOC_DAPM_PRE_PMU: 2695 wm_adsp2_set_dspclk(dsp, freq); 2696 queue_work(system_unbound_wq, &dsp->boot_work); 2697 break; 2698 case SND_SOC_DAPM_PRE_PMD: 2699 mutex_lock(&dsp->pwr_lock); 2700 2701 wm_adsp_debugfs_clear(dsp); 2702 2703 dsp->fw_id = 0; 2704 dsp->fw_id_version = 0; 2705 2706 dsp->booted = false; 2707 2708 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2709 ADSP2_MEM_ENA, 0); 2710 2711 list_for_each_entry(ctl, &dsp->ctl_list, list) 2712 ctl->enabled = 0; 2713 2714 wm_adsp_free_alg_regions(dsp); 2715 2716 mutex_unlock(&dsp->pwr_lock); 2717 2718 adsp_dbg(dsp, "Shutdown complete\n"); 2719 break; 2720 default: 2721 break; 2722 } 2723 2724 return 0; 2725 } 2726 EXPORT_SYMBOL_GPL(wm_adsp2_early_event); 2727 2728 int wm_adsp2_event(struct snd_soc_dapm_widget *w, 2729 struct snd_kcontrol *kcontrol, int event) 2730 { 2731 struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm); 2732 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 2733 struct wm_adsp *dsp = &dsps[w->shift]; 2734 int ret; 2735 2736 switch (event) { 2737 case SND_SOC_DAPM_POST_PMU: 2738 flush_work(&dsp->boot_work); 2739 2740 mutex_lock(&dsp->pwr_lock); 2741 2742 if (!dsp->booted) { 2743 ret = -EIO; 2744 goto err; 2745 } 2746 2747 ret = wm_adsp2_ena(dsp); 2748 if (ret != 0) 2749 goto err; 2750 2751 /* Sync set controls */ 2752 ret = wm_coeff_sync_controls(dsp); 2753 if (ret != 0) 2754 goto err; 2755 2756 wm_adsp2_lock(dsp, dsp->lock_regions); 2757 2758 ret = regmap_update_bits(dsp->regmap, 2759 dsp->base + ADSP2_CONTROL, 2760 ADSP2_CORE_ENA | ADSP2_START, 2761 ADSP2_CORE_ENA | ADSP2_START); 2762 if (ret != 0) 2763 goto err; 2764 2765 if (wm_adsp_fw[dsp->fw].num_caps != 0) { 2766 ret = wm_adsp_buffer_init(dsp); 2767 if (ret < 0) 2768 goto err; 2769 } 2770 2771 dsp->running = true; 2772 2773 mutex_unlock(&dsp->pwr_lock); 2774 2775 break; 2776 2777 case SND_SOC_DAPM_PRE_PMD: 2778 /* Tell the firmware to cleanup */ 2779 wm_adsp_signal_event_controls(dsp, WM_ADSP_FW_EVENT_SHUTDOWN); 2780 2781 wm_adsp_stop_watchdog(dsp); 2782 2783 /* Log firmware state, it can be useful for analysis */ 2784 switch (dsp->rev) { 2785 case 0: 2786 wm_adsp2_show_fw_status(dsp); 2787 break; 2788 default: 2789 wm_adsp2v2_show_fw_status(dsp); 2790 break; 2791 } 2792 2793 mutex_lock(&dsp->pwr_lock); 2794 2795 dsp->running = false; 2796 2797 regmap_update_bits(dsp->regmap, 2798 dsp->base + ADSP2_CONTROL, 2799 ADSP2_CORE_ENA | ADSP2_START, 0); 2800 2801 /* Make sure DMAs are quiesced */ 2802 switch (dsp->rev) { 2803 case 0: 2804 regmap_write(dsp->regmap, 2805 dsp->base + ADSP2_RDMA_CONFIG_1, 0); 2806 regmap_write(dsp->regmap, 2807 dsp->base + ADSP2_WDMA_CONFIG_1, 0); 2808 regmap_write(dsp->regmap, 2809 dsp->base + ADSP2_WDMA_CONFIG_2, 0); 2810 2811 regmap_update_bits(dsp->regmap, 2812 dsp->base + ADSP2_CONTROL, 2813 ADSP2_SYS_ENA, 0); 2814 break; 2815 default: 2816 regmap_write(dsp->regmap, 2817 dsp->base + ADSP2_RDMA_CONFIG_1, 0); 2818 regmap_write(dsp->regmap, 2819 dsp->base + ADSP2_WDMA_CONFIG_1, 0); 2820 regmap_write(dsp->regmap, 2821 dsp->base + ADSP2V2_WDMA_CONFIG_2, 0); 2822 break; 2823 } 2824 2825 if (wm_adsp_fw[dsp->fw].num_caps != 0) 2826 wm_adsp_buffer_free(dsp); 2827 2828 mutex_unlock(&dsp->pwr_lock); 2829 2830 adsp_dbg(dsp, "Execution stopped\n"); 2831 break; 2832 2833 default: 2834 break; 2835 } 2836 2837 return 0; 2838 err: 2839 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2840 ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); 2841 mutex_unlock(&dsp->pwr_lock); 2842 return ret; 2843 } 2844 EXPORT_SYMBOL_GPL(wm_adsp2_event); 2845 2846 int wm_adsp2_codec_probe(struct wm_adsp *dsp, struct snd_soc_codec *codec) 2847 { 2848 struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec); 2849 char preload[32]; 2850 2851 snprintf(preload, ARRAY_SIZE(preload), "DSP%d Preload", dsp->num); 2852 snd_soc_dapm_disable_pin(dapm, preload); 2853 2854 wm_adsp2_init_debugfs(dsp, codec); 2855 2856 dsp->codec = codec; 2857 2858 return snd_soc_add_codec_controls(codec, 2859 &wm_adsp_fw_controls[dsp->num - 1], 2860 1); 2861 } 2862 EXPORT_SYMBOL_GPL(wm_adsp2_codec_probe); 2863 2864 int wm_adsp2_codec_remove(struct wm_adsp *dsp, struct snd_soc_codec *codec) 2865 { 2866 wm_adsp2_cleanup_debugfs(dsp); 2867 2868 return 0; 2869 } 2870 EXPORT_SYMBOL_GPL(wm_adsp2_codec_remove); 2871 2872 int wm_adsp2_init(struct wm_adsp *dsp) 2873 { 2874 int ret; 2875 2876 switch (dsp->rev) { 2877 case 0: 2878 /* 2879 * Disable the DSP memory by default when in reset for a small 2880 * power saving. 2881 */ 2882 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 2883 ADSP2_MEM_ENA, 0); 2884 if (ret) { 2885 adsp_err(dsp, 2886 "Failed to clear memory retention: %d\n", ret); 2887 return ret; 2888 } 2889 break; 2890 default: 2891 break; 2892 } 2893 2894 INIT_LIST_HEAD(&dsp->alg_regions); 2895 INIT_LIST_HEAD(&dsp->ctl_list); 2896 INIT_WORK(&dsp->boot_work, wm_adsp2_boot_work); 2897 2898 mutex_init(&dsp->pwr_lock); 2899 2900 return 0; 2901 } 2902 EXPORT_SYMBOL_GPL(wm_adsp2_init); 2903 2904 void wm_adsp2_remove(struct wm_adsp *dsp) 2905 { 2906 struct wm_coeff_ctl *ctl; 2907 2908 while (!list_empty(&dsp->ctl_list)) { 2909 ctl = list_first_entry(&dsp->ctl_list, struct wm_coeff_ctl, 2910 list); 2911 list_del(&ctl->list); 2912 wm_adsp_free_ctl_blk(ctl); 2913 } 2914 } 2915 EXPORT_SYMBOL_GPL(wm_adsp2_remove); 2916 2917 static inline int wm_adsp_compr_attached(struct wm_adsp_compr *compr) 2918 { 2919 return compr->buf != NULL; 2920 } 2921 2922 static int wm_adsp_compr_attach(struct wm_adsp_compr *compr) 2923 { 2924 /* 2925 * Note this will be more complex once each DSP can support multiple 2926 * streams 2927 */ 2928 if (!compr->dsp->buffer) 2929 return -EINVAL; 2930 2931 compr->buf = compr->dsp->buffer; 2932 compr->buf->compr = compr; 2933 2934 return 0; 2935 } 2936 2937 static void wm_adsp_compr_detach(struct wm_adsp_compr *compr) 2938 { 2939 if (!compr) 2940 return; 2941 2942 /* Wake the poll so it can see buffer is no longer attached */ 2943 if (compr->stream) 2944 snd_compr_fragment_elapsed(compr->stream); 2945 2946 if (wm_adsp_compr_attached(compr)) { 2947 compr->buf->compr = NULL; 2948 compr->buf = NULL; 2949 } 2950 } 2951 2952 int wm_adsp_compr_open(struct wm_adsp *dsp, struct snd_compr_stream *stream) 2953 { 2954 struct wm_adsp_compr *compr; 2955 int ret = 0; 2956 2957 mutex_lock(&dsp->pwr_lock); 2958 2959 if (wm_adsp_fw[dsp->fw].num_caps == 0) { 2960 adsp_err(dsp, "Firmware does not support compressed API\n"); 2961 ret = -ENXIO; 2962 goto out; 2963 } 2964 2965 if (wm_adsp_fw[dsp->fw].compr_direction != stream->direction) { 2966 adsp_err(dsp, "Firmware does not support stream direction\n"); 2967 ret = -EINVAL; 2968 goto out; 2969 } 2970 2971 if (dsp->compr) { 2972 /* It is expect this limitation will be removed in future */ 2973 adsp_err(dsp, "Only a single stream supported per DSP\n"); 2974 ret = -EBUSY; 2975 goto out; 2976 } 2977 2978 compr = kzalloc(sizeof(*compr), GFP_KERNEL); 2979 if (!compr) { 2980 ret = -ENOMEM; 2981 goto out; 2982 } 2983 2984 compr->dsp = dsp; 2985 compr->stream = stream; 2986 2987 dsp->compr = compr; 2988 2989 stream->runtime->private_data = compr; 2990 2991 out: 2992 mutex_unlock(&dsp->pwr_lock); 2993 2994 return ret; 2995 } 2996 EXPORT_SYMBOL_GPL(wm_adsp_compr_open); 2997 2998 int wm_adsp_compr_free(struct snd_compr_stream *stream) 2999 { 3000 struct wm_adsp_compr *compr = stream->runtime->private_data; 3001 struct wm_adsp *dsp = compr->dsp; 3002 3003 mutex_lock(&dsp->pwr_lock); 3004 3005 wm_adsp_compr_detach(compr); 3006 dsp->compr = NULL; 3007 3008 kfree(compr->raw_buf); 3009 kfree(compr); 3010 3011 mutex_unlock(&dsp->pwr_lock); 3012 3013 return 0; 3014 } 3015 EXPORT_SYMBOL_GPL(wm_adsp_compr_free); 3016 3017 static int wm_adsp_compr_check_params(struct snd_compr_stream *stream, 3018 struct snd_compr_params *params) 3019 { 3020 struct wm_adsp_compr *compr = stream->runtime->private_data; 3021 struct wm_adsp *dsp = compr->dsp; 3022 const struct wm_adsp_fw_caps *caps; 3023 const struct snd_codec_desc *desc; 3024 int i, j; 3025 3026 if (params->buffer.fragment_size < WM_ADSP_MIN_FRAGMENT_SIZE || 3027 params->buffer.fragment_size > WM_ADSP_MAX_FRAGMENT_SIZE || 3028 params->buffer.fragments < WM_ADSP_MIN_FRAGMENTS || 3029 params->buffer.fragments > WM_ADSP_MAX_FRAGMENTS || 3030 params->buffer.fragment_size % WM_ADSP_DATA_WORD_SIZE) { 3031 adsp_err(dsp, "Invalid buffer fragsize=%d fragments=%d\n", 3032 params->buffer.fragment_size, 3033 params->buffer.fragments); 3034 3035 return -EINVAL; 3036 } 3037 3038 for (i = 0; i < wm_adsp_fw[dsp->fw].num_caps; i++) { 3039 caps = &wm_adsp_fw[dsp->fw].caps[i]; 3040 desc = &caps->desc; 3041 3042 if (caps->id != params->codec.id) 3043 continue; 3044 3045 if (stream->direction == SND_COMPRESS_PLAYBACK) { 3046 if (desc->max_ch < params->codec.ch_out) 3047 continue; 3048 } else { 3049 if (desc->max_ch < params->codec.ch_in) 3050 continue; 3051 } 3052 3053 if (!(desc->formats & (1 << params->codec.format))) 3054 continue; 3055 3056 for (j = 0; j < desc->num_sample_rates; ++j) 3057 if (desc->sample_rates[j] == params->codec.sample_rate) 3058 return 0; 3059 } 3060 3061 adsp_err(dsp, "Invalid params id=%u ch=%u,%u rate=%u fmt=%u\n", 3062 params->codec.id, params->codec.ch_in, params->codec.ch_out, 3063 params->codec.sample_rate, params->codec.format); 3064 return -EINVAL; 3065 } 3066 3067 static inline unsigned int wm_adsp_compr_frag_words(struct wm_adsp_compr *compr) 3068 { 3069 return compr->size.fragment_size / WM_ADSP_DATA_WORD_SIZE; 3070 } 3071 3072 int wm_adsp_compr_set_params(struct snd_compr_stream *stream, 3073 struct snd_compr_params *params) 3074 { 3075 struct wm_adsp_compr *compr = stream->runtime->private_data; 3076 unsigned int size; 3077 int ret; 3078 3079 ret = wm_adsp_compr_check_params(stream, params); 3080 if (ret) 3081 return ret; 3082 3083 compr->size = params->buffer; 3084 3085 adsp_dbg(compr->dsp, "fragment_size=%d fragments=%d\n", 3086 compr->size.fragment_size, compr->size.fragments); 3087 3088 size = wm_adsp_compr_frag_words(compr) * sizeof(*compr->raw_buf); 3089 compr->raw_buf = kmalloc(size, GFP_DMA | GFP_KERNEL); 3090 if (!compr->raw_buf) 3091 return -ENOMEM; 3092 3093 compr->sample_rate = params->codec.sample_rate; 3094 3095 return 0; 3096 } 3097 EXPORT_SYMBOL_GPL(wm_adsp_compr_set_params); 3098 3099 int wm_adsp_compr_get_caps(struct snd_compr_stream *stream, 3100 struct snd_compr_caps *caps) 3101 { 3102 struct wm_adsp_compr *compr = stream->runtime->private_data; 3103 int fw = compr->dsp->fw; 3104 int i; 3105 3106 if (wm_adsp_fw[fw].caps) { 3107 for (i = 0; i < wm_adsp_fw[fw].num_caps; i++) 3108 caps->codecs[i] = wm_adsp_fw[fw].caps[i].id; 3109 3110 caps->num_codecs = i; 3111 caps->direction = wm_adsp_fw[fw].compr_direction; 3112 3113 caps->min_fragment_size = WM_ADSP_MIN_FRAGMENT_SIZE; 3114 caps->max_fragment_size = WM_ADSP_MAX_FRAGMENT_SIZE; 3115 caps->min_fragments = WM_ADSP_MIN_FRAGMENTS; 3116 caps->max_fragments = WM_ADSP_MAX_FRAGMENTS; 3117 } 3118 3119 return 0; 3120 } 3121 EXPORT_SYMBOL_GPL(wm_adsp_compr_get_caps); 3122 3123 static int wm_adsp_read_data_block(struct wm_adsp *dsp, int mem_type, 3124 unsigned int mem_addr, 3125 unsigned int num_words, u32 *data) 3126 { 3127 struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); 3128 unsigned int i, reg; 3129 int ret; 3130 3131 if (!mem) 3132 return -EINVAL; 3133 3134 reg = wm_adsp_region_to_reg(mem, mem_addr); 3135 3136 ret = regmap_raw_read(dsp->regmap, reg, data, 3137 sizeof(*data) * num_words); 3138 if (ret < 0) 3139 return ret; 3140 3141 for (i = 0; i < num_words; ++i) 3142 data[i] = be32_to_cpu(data[i]) & 0x00ffffffu; 3143 3144 return 0; 3145 } 3146 3147 static inline int wm_adsp_read_data_word(struct wm_adsp *dsp, int mem_type, 3148 unsigned int mem_addr, u32 *data) 3149 { 3150 return wm_adsp_read_data_block(dsp, mem_type, mem_addr, 1, data); 3151 } 3152 3153 static int wm_adsp_write_data_word(struct wm_adsp *dsp, int mem_type, 3154 unsigned int mem_addr, u32 data) 3155 { 3156 struct wm_adsp_region const *mem = wm_adsp_find_region(dsp, mem_type); 3157 unsigned int reg; 3158 3159 if (!mem) 3160 return -EINVAL; 3161 3162 reg = wm_adsp_region_to_reg(mem, mem_addr); 3163 3164 data = cpu_to_be32(data & 0x00ffffffu); 3165 3166 return regmap_raw_write(dsp->regmap, reg, &data, sizeof(data)); 3167 } 3168 3169 static inline int wm_adsp_buffer_read(struct wm_adsp_compr_buf *buf, 3170 unsigned int field_offset, u32 *data) 3171 { 3172 return wm_adsp_read_data_word(buf->dsp, WMFW_ADSP2_XM, 3173 buf->host_buf_ptr + field_offset, data); 3174 } 3175 3176 static inline int wm_adsp_buffer_write(struct wm_adsp_compr_buf *buf, 3177 unsigned int field_offset, u32 data) 3178 { 3179 return wm_adsp_write_data_word(buf->dsp, WMFW_ADSP2_XM, 3180 buf->host_buf_ptr + field_offset, data); 3181 } 3182 3183 static int wm_adsp_buffer_locate(struct wm_adsp_compr_buf *buf) 3184 { 3185 struct wm_adsp_alg_region *alg_region; 3186 struct wm_adsp *dsp = buf->dsp; 3187 u32 xmalg, addr, magic; 3188 int i, ret; 3189 3190 alg_region = wm_adsp_find_alg_region(dsp, WMFW_ADSP2_XM, dsp->fw_id); 3191 xmalg = sizeof(struct wm_adsp_system_config_xm_hdr) / sizeof(__be32); 3192 3193 addr = alg_region->base + xmalg + ALG_XM_FIELD(magic); 3194 ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, &magic); 3195 if (ret < 0) 3196 return ret; 3197 3198 if (magic != WM_ADSP_ALG_XM_STRUCT_MAGIC) 3199 return -EINVAL; 3200 3201 addr = alg_region->base + xmalg + ALG_XM_FIELD(host_buf_ptr); 3202 for (i = 0; i < 5; ++i) { 3203 ret = wm_adsp_read_data_word(dsp, WMFW_ADSP2_XM, addr, 3204 &buf->host_buf_ptr); 3205 if (ret < 0) 3206 return ret; 3207 3208 if (buf->host_buf_ptr) 3209 break; 3210 3211 usleep_range(1000, 2000); 3212 } 3213 3214 if (!buf->host_buf_ptr) 3215 return -EIO; 3216 3217 adsp_dbg(dsp, "host_buf_ptr=%x\n", buf->host_buf_ptr); 3218 3219 return 0; 3220 } 3221 3222 static int wm_adsp_buffer_populate(struct wm_adsp_compr_buf *buf) 3223 { 3224 const struct wm_adsp_fw_caps *caps = wm_adsp_fw[buf->dsp->fw].caps; 3225 struct wm_adsp_buffer_region *region; 3226 u32 offset = 0; 3227 int i, ret; 3228 3229 for (i = 0; i < caps->num_regions; ++i) { 3230 region = &buf->regions[i]; 3231 3232 region->offset = offset; 3233 region->mem_type = caps->region_defs[i].mem_type; 3234 3235 ret = wm_adsp_buffer_read(buf, caps->region_defs[i].base_offset, 3236 ®ion->base_addr); 3237 if (ret < 0) 3238 return ret; 3239 3240 ret = wm_adsp_buffer_read(buf, caps->region_defs[i].size_offset, 3241 &offset); 3242 if (ret < 0) 3243 return ret; 3244 3245 region->cumulative_size = offset; 3246 3247 adsp_dbg(buf->dsp, 3248 "region=%d type=%d base=%04x off=%04x size=%04x\n", 3249 i, region->mem_type, region->base_addr, 3250 region->offset, region->cumulative_size); 3251 } 3252 3253 return 0; 3254 } 3255 3256 static int wm_adsp_buffer_init(struct wm_adsp *dsp) 3257 { 3258 struct wm_adsp_compr_buf *buf; 3259 int ret; 3260 3261 buf = kzalloc(sizeof(*buf), GFP_KERNEL); 3262 if (!buf) 3263 return -ENOMEM; 3264 3265 buf->dsp = dsp; 3266 buf->read_index = -1; 3267 buf->irq_count = 0xFFFFFFFF; 3268 3269 ret = wm_adsp_buffer_locate(buf); 3270 if (ret < 0) { 3271 adsp_err(dsp, "Failed to acquire host buffer: %d\n", ret); 3272 goto err_buffer; 3273 } 3274 3275 buf->regions = kcalloc(wm_adsp_fw[dsp->fw].caps->num_regions, 3276 sizeof(*buf->regions), GFP_KERNEL); 3277 if (!buf->regions) { 3278 ret = -ENOMEM; 3279 goto err_buffer; 3280 } 3281 3282 ret = wm_adsp_buffer_populate(buf); 3283 if (ret < 0) { 3284 adsp_err(dsp, "Failed to populate host buffer: %d\n", ret); 3285 goto err_regions; 3286 } 3287 3288 dsp->buffer = buf; 3289 3290 return 0; 3291 3292 err_regions: 3293 kfree(buf->regions); 3294 err_buffer: 3295 kfree(buf); 3296 return ret; 3297 } 3298 3299 static int wm_adsp_buffer_free(struct wm_adsp *dsp) 3300 { 3301 if (dsp->buffer) { 3302 wm_adsp_compr_detach(dsp->buffer->compr); 3303 3304 kfree(dsp->buffer->regions); 3305 kfree(dsp->buffer); 3306 3307 dsp->buffer = NULL; 3308 } 3309 3310 return 0; 3311 } 3312 3313 int wm_adsp_compr_trigger(struct snd_compr_stream *stream, int cmd) 3314 { 3315 struct wm_adsp_compr *compr = stream->runtime->private_data; 3316 struct wm_adsp *dsp = compr->dsp; 3317 int ret = 0; 3318 3319 adsp_dbg(dsp, "Trigger: %d\n", cmd); 3320 3321 mutex_lock(&dsp->pwr_lock); 3322 3323 switch (cmd) { 3324 case SNDRV_PCM_TRIGGER_START: 3325 if (wm_adsp_compr_attached(compr)) 3326 break; 3327 3328 ret = wm_adsp_compr_attach(compr); 3329 if (ret < 0) { 3330 adsp_err(dsp, "Failed to link buffer and stream: %d\n", 3331 ret); 3332 break; 3333 } 3334 3335 /* Trigger the IRQ at one fragment of data */ 3336 ret = wm_adsp_buffer_write(compr->buf, 3337 HOST_BUFFER_FIELD(high_water_mark), 3338 wm_adsp_compr_frag_words(compr)); 3339 if (ret < 0) { 3340 adsp_err(dsp, "Failed to set high water mark: %d\n", 3341 ret); 3342 break; 3343 } 3344 break; 3345 case SNDRV_PCM_TRIGGER_STOP: 3346 break; 3347 default: 3348 ret = -EINVAL; 3349 break; 3350 } 3351 3352 mutex_unlock(&dsp->pwr_lock); 3353 3354 return ret; 3355 } 3356 EXPORT_SYMBOL_GPL(wm_adsp_compr_trigger); 3357 3358 static inline int wm_adsp_buffer_size(struct wm_adsp_compr_buf *buf) 3359 { 3360 int last_region = wm_adsp_fw[buf->dsp->fw].caps->num_regions - 1; 3361 3362 return buf->regions[last_region].cumulative_size; 3363 } 3364 3365 static int wm_adsp_buffer_update_avail(struct wm_adsp_compr_buf *buf) 3366 { 3367 u32 next_read_index, next_write_index; 3368 int write_index, read_index, avail; 3369 int ret; 3370 3371 /* Only sync read index if we haven't already read a valid index */ 3372 if (buf->read_index < 0) { 3373 ret = wm_adsp_buffer_read(buf, 3374 HOST_BUFFER_FIELD(next_read_index), 3375 &next_read_index); 3376 if (ret < 0) 3377 return ret; 3378 3379 read_index = sign_extend32(next_read_index, 23); 3380 3381 if (read_index < 0) { 3382 adsp_dbg(buf->dsp, "Avail check on unstarted stream\n"); 3383 return 0; 3384 } 3385 3386 buf->read_index = read_index; 3387 } 3388 3389 ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(next_write_index), 3390 &next_write_index); 3391 if (ret < 0) 3392 return ret; 3393 3394 write_index = sign_extend32(next_write_index, 23); 3395 3396 avail = write_index - buf->read_index; 3397 if (avail < 0) 3398 avail += wm_adsp_buffer_size(buf); 3399 3400 adsp_dbg(buf->dsp, "readindex=0x%x, writeindex=0x%x, avail=%d\n", 3401 buf->read_index, write_index, avail * WM_ADSP_DATA_WORD_SIZE); 3402 3403 buf->avail = avail; 3404 3405 return 0; 3406 } 3407 3408 static int wm_adsp_buffer_get_error(struct wm_adsp_compr_buf *buf) 3409 { 3410 int ret; 3411 3412 ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(error), &buf->error); 3413 if (ret < 0) { 3414 adsp_err(buf->dsp, "Failed to check buffer error: %d\n", ret); 3415 return ret; 3416 } 3417 if (buf->error != 0) { 3418 adsp_err(buf->dsp, "Buffer error occurred: %d\n", buf->error); 3419 return -EIO; 3420 } 3421 3422 return 0; 3423 } 3424 3425 int wm_adsp_compr_handle_irq(struct wm_adsp *dsp) 3426 { 3427 struct wm_adsp_compr_buf *buf; 3428 struct wm_adsp_compr *compr; 3429 int ret = 0; 3430 3431 mutex_lock(&dsp->pwr_lock); 3432 3433 buf = dsp->buffer; 3434 compr = dsp->compr; 3435 3436 if (!buf) { 3437 ret = -ENODEV; 3438 goto out; 3439 } 3440 3441 adsp_dbg(dsp, "Handling buffer IRQ\n"); 3442 3443 ret = wm_adsp_buffer_get_error(buf); 3444 if (ret < 0) 3445 goto out_notify; /* Wake poll to report error */ 3446 3447 ret = wm_adsp_buffer_read(buf, HOST_BUFFER_FIELD(irq_count), 3448 &buf->irq_count); 3449 if (ret < 0) { 3450 adsp_err(dsp, "Failed to get irq_count: %d\n", ret); 3451 goto out; 3452 } 3453 3454 ret = wm_adsp_buffer_update_avail(buf); 3455 if (ret < 0) { 3456 adsp_err(dsp, "Error reading avail: %d\n", ret); 3457 goto out; 3458 } 3459 3460 if (wm_adsp_fw[dsp->fw].voice_trigger && buf->irq_count == 2) 3461 ret = WM_ADSP_COMPR_VOICE_TRIGGER; 3462 3463 out_notify: 3464 if (compr && compr->stream) 3465 snd_compr_fragment_elapsed(compr->stream); 3466 3467 out: 3468 mutex_unlock(&dsp->pwr_lock); 3469 3470 return ret; 3471 } 3472 EXPORT_SYMBOL_GPL(wm_adsp_compr_handle_irq); 3473 3474 static int wm_adsp_buffer_reenable_irq(struct wm_adsp_compr_buf *buf) 3475 { 3476 if (buf->irq_count & 0x01) 3477 return 0; 3478 3479 adsp_dbg(buf->dsp, "Enable IRQ(0x%x) for next fragment\n", 3480 buf->irq_count); 3481 3482 buf->irq_count |= 0x01; 3483 3484 return wm_adsp_buffer_write(buf, HOST_BUFFER_FIELD(irq_ack), 3485 buf->irq_count); 3486 } 3487 3488 int wm_adsp_compr_pointer(struct snd_compr_stream *stream, 3489 struct snd_compr_tstamp *tstamp) 3490 { 3491 struct wm_adsp_compr *compr = stream->runtime->private_data; 3492 struct wm_adsp *dsp = compr->dsp; 3493 struct wm_adsp_compr_buf *buf; 3494 int ret = 0; 3495 3496 adsp_dbg(dsp, "Pointer request\n"); 3497 3498 mutex_lock(&dsp->pwr_lock); 3499 3500 buf = compr->buf; 3501 3502 if (!compr->buf || compr->buf->error) { 3503 snd_compr_stop_error(stream, SNDRV_PCM_STATE_XRUN); 3504 ret = -EIO; 3505 goto out; 3506 } 3507 3508 if (buf->avail < wm_adsp_compr_frag_words(compr)) { 3509 ret = wm_adsp_buffer_update_avail(buf); 3510 if (ret < 0) { 3511 adsp_err(dsp, "Error reading avail: %d\n", ret); 3512 goto out; 3513 } 3514 3515 /* 3516 * If we really have less than 1 fragment available tell the 3517 * DSP to inform us once a whole fragment is available. 3518 */ 3519 if (buf->avail < wm_adsp_compr_frag_words(compr)) { 3520 ret = wm_adsp_buffer_get_error(buf); 3521 if (ret < 0) { 3522 if (compr->buf->error) 3523 snd_compr_stop_error(stream, 3524 SNDRV_PCM_STATE_XRUN); 3525 goto out; 3526 } 3527 3528 ret = wm_adsp_buffer_reenable_irq(buf); 3529 if (ret < 0) { 3530 adsp_err(dsp, 3531 "Failed to re-enable buffer IRQ: %d\n", 3532 ret); 3533 goto out; 3534 } 3535 } 3536 } 3537 3538 tstamp->copied_total = compr->copied_total; 3539 tstamp->copied_total += buf->avail * WM_ADSP_DATA_WORD_SIZE; 3540 tstamp->sampling_rate = compr->sample_rate; 3541 3542 out: 3543 mutex_unlock(&dsp->pwr_lock); 3544 3545 return ret; 3546 } 3547 EXPORT_SYMBOL_GPL(wm_adsp_compr_pointer); 3548 3549 static int wm_adsp_buffer_capture_block(struct wm_adsp_compr *compr, int target) 3550 { 3551 struct wm_adsp_compr_buf *buf = compr->buf; 3552 u8 *pack_in = (u8 *)compr->raw_buf; 3553 u8 *pack_out = (u8 *)compr->raw_buf; 3554 unsigned int adsp_addr; 3555 int mem_type, nwords, max_read; 3556 int i, j, ret; 3557 3558 /* Calculate read parameters */ 3559 for (i = 0; i < wm_adsp_fw[buf->dsp->fw].caps->num_regions; ++i) 3560 if (buf->read_index < buf->regions[i].cumulative_size) 3561 break; 3562 3563 if (i == wm_adsp_fw[buf->dsp->fw].caps->num_regions) 3564 return -EINVAL; 3565 3566 mem_type = buf->regions[i].mem_type; 3567 adsp_addr = buf->regions[i].base_addr + 3568 (buf->read_index - buf->regions[i].offset); 3569 3570 max_read = wm_adsp_compr_frag_words(compr); 3571 nwords = buf->regions[i].cumulative_size - buf->read_index; 3572 3573 if (nwords > target) 3574 nwords = target; 3575 if (nwords > buf->avail) 3576 nwords = buf->avail; 3577 if (nwords > max_read) 3578 nwords = max_read; 3579 if (!nwords) 3580 return 0; 3581 3582 /* Read data from DSP */ 3583 ret = wm_adsp_read_data_block(buf->dsp, mem_type, adsp_addr, 3584 nwords, compr->raw_buf); 3585 if (ret < 0) 3586 return ret; 3587 3588 /* Remove the padding bytes from the data read from the DSP */ 3589 for (i = 0; i < nwords; i++) { 3590 for (j = 0; j < WM_ADSP_DATA_WORD_SIZE; j++) 3591 *pack_out++ = *pack_in++; 3592 3593 pack_in += sizeof(*(compr->raw_buf)) - WM_ADSP_DATA_WORD_SIZE; 3594 } 3595 3596 /* update read index to account for words read */ 3597 buf->read_index += nwords; 3598 if (buf->read_index == wm_adsp_buffer_size(buf)) 3599 buf->read_index = 0; 3600 3601 ret = wm_adsp_buffer_write(buf, HOST_BUFFER_FIELD(next_read_index), 3602 buf->read_index); 3603 if (ret < 0) 3604 return ret; 3605 3606 /* update avail to account for words read */ 3607 buf->avail -= nwords; 3608 3609 return nwords; 3610 } 3611 3612 static int wm_adsp_compr_read(struct wm_adsp_compr *compr, 3613 char __user *buf, size_t count) 3614 { 3615 struct wm_adsp *dsp = compr->dsp; 3616 int ntotal = 0; 3617 int nwords, nbytes; 3618 3619 adsp_dbg(dsp, "Requested read of %zu bytes\n", count); 3620 3621 if (!compr->buf || compr->buf->error) { 3622 snd_compr_stop_error(compr->stream, SNDRV_PCM_STATE_XRUN); 3623 return -EIO; 3624 } 3625 3626 count /= WM_ADSP_DATA_WORD_SIZE; 3627 3628 do { 3629 nwords = wm_adsp_buffer_capture_block(compr, count); 3630 if (nwords < 0) { 3631 adsp_err(dsp, "Failed to capture block: %d\n", nwords); 3632 return nwords; 3633 } 3634 3635 nbytes = nwords * WM_ADSP_DATA_WORD_SIZE; 3636 3637 adsp_dbg(dsp, "Read %d bytes\n", nbytes); 3638 3639 if (copy_to_user(buf + ntotal, compr->raw_buf, nbytes)) { 3640 adsp_err(dsp, "Failed to copy data to user: %d, %d\n", 3641 ntotal, nbytes); 3642 return -EFAULT; 3643 } 3644 3645 count -= nwords; 3646 ntotal += nbytes; 3647 } while (nwords > 0 && count > 0); 3648 3649 compr->copied_total += ntotal; 3650 3651 return ntotal; 3652 } 3653 3654 int wm_adsp_compr_copy(struct snd_compr_stream *stream, char __user *buf, 3655 size_t count) 3656 { 3657 struct wm_adsp_compr *compr = stream->runtime->private_data; 3658 struct wm_adsp *dsp = compr->dsp; 3659 int ret; 3660 3661 mutex_lock(&dsp->pwr_lock); 3662 3663 if (stream->direction == SND_COMPRESS_CAPTURE) 3664 ret = wm_adsp_compr_read(compr, buf, count); 3665 else 3666 ret = -ENOTSUPP; 3667 3668 mutex_unlock(&dsp->pwr_lock); 3669 3670 return ret; 3671 } 3672 EXPORT_SYMBOL_GPL(wm_adsp_compr_copy); 3673 3674 int wm_adsp2_lock(struct wm_adsp *dsp, unsigned int lock_regions) 3675 { 3676 struct regmap *regmap = dsp->regmap; 3677 unsigned int code0, code1, lock_reg; 3678 3679 if (!(lock_regions & WM_ADSP2_REGION_ALL)) 3680 return 0; 3681 3682 lock_regions &= WM_ADSP2_REGION_ALL; 3683 lock_reg = dsp->base + ADSP2_LOCK_REGION_1_LOCK_REGION_0; 3684 3685 while (lock_regions) { 3686 code0 = code1 = 0; 3687 if (lock_regions & BIT(0)) { 3688 code0 = ADSP2_LOCK_CODE_0; 3689 code1 = ADSP2_LOCK_CODE_1; 3690 } 3691 if (lock_regions & BIT(1)) { 3692 code0 |= ADSP2_LOCK_CODE_0 << ADSP2_LOCK_REGION_SHIFT; 3693 code1 |= ADSP2_LOCK_CODE_1 << ADSP2_LOCK_REGION_SHIFT; 3694 } 3695 regmap_write(regmap, lock_reg, code0); 3696 regmap_write(regmap, lock_reg, code1); 3697 lock_regions >>= 2; 3698 lock_reg += 2; 3699 } 3700 3701 return 0; 3702 } 3703 EXPORT_SYMBOL_GPL(wm_adsp2_lock); 3704 3705 irqreturn_t wm_adsp2_bus_error(struct wm_adsp *dsp) 3706 { 3707 unsigned int val; 3708 struct regmap *regmap = dsp->regmap; 3709 int ret = 0; 3710 3711 ret = regmap_read(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, &val); 3712 if (ret) { 3713 adsp_err(dsp, 3714 "Failed to read Region Lock Ctrl register: %d\n", ret); 3715 return IRQ_HANDLED; 3716 } 3717 3718 if (val & ADSP2_WDT_TIMEOUT_STS_MASK) { 3719 adsp_err(dsp, "watchdog timeout error\n"); 3720 wm_adsp_stop_watchdog(dsp); 3721 } 3722 3723 if (val & (ADSP2_SLAVE_ERR_MASK | ADSP2_REGION_LOCK_ERR_MASK)) { 3724 if (val & ADSP2_SLAVE_ERR_MASK) 3725 adsp_err(dsp, "bus error: slave error\n"); 3726 else 3727 adsp_err(dsp, "bus error: region lock error\n"); 3728 3729 ret = regmap_read(regmap, dsp->base + ADSP2_BUS_ERR_ADDR, &val); 3730 if (ret) { 3731 adsp_err(dsp, 3732 "Failed to read Bus Err Addr register: %d\n", 3733 ret); 3734 return IRQ_HANDLED; 3735 } 3736 3737 adsp_err(dsp, "bus error address = 0x%x\n", 3738 val & ADSP2_BUS_ERR_ADDR_MASK); 3739 3740 ret = regmap_read(regmap, 3741 dsp->base + ADSP2_PMEM_ERR_ADDR_XMEM_ERR_ADDR, 3742 &val); 3743 if (ret) { 3744 adsp_err(dsp, 3745 "Failed to read Pmem Xmem Err Addr register: %d\n", 3746 ret); 3747 return IRQ_HANDLED; 3748 } 3749 3750 adsp_err(dsp, "xmem error address = 0x%x\n", 3751 val & ADSP2_XMEM_ERR_ADDR_MASK); 3752 adsp_err(dsp, "pmem error address = 0x%x\n", 3753 (val & ADSP2_PMEM_ERR_ADDR_MASK) >> 3754 ADSP2_PMEM_ERR_ADDR_SHIFT); 3755 } 3756 3757 regmap_update_bits(regmap, dsp->base + ADSP2_LOCK_REGION_CTRL, 3758 ADSP2_CTRL_ERR_EINT, ADSP2_CTRL_ERR_EINT); 3759 3760 return IRQ_HANDLED; 3761 } 3762 EXPORT_SYMBOL_GPL(wm_adsp2_bus_error); 3763 3764 MODULE_LICENSE("GPL v2"); 3765