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