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