ASoC: core: Merge Samsung fixes to avoid trivial context conflict
[cascardo/linux.git] / sound / soc / codecs / wm_adsp.c
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 <sound/core.h>
25 #include <sound/pcm.h>
26 #include <sound/pcm_params.h>
27 #include <sound/soc.h>
28 #include <sound/jack.h>
29 #include <sound/initval.h>
30 #include <sound/tlv.h>
31
32 #include <linux/mfd/arizona/registers.h>
33
34 #include "wm_adsp.h"
35
36 #define adsp_crit(_dsp, fmt, ...) \
37         dev_crit(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
38 #define adsp_err(_dsp, fmt, ...) \
39         dev_err(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
40 #define adsp_warn(_dsp, fmt, ...) \
41         dev_warn(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
42 #define adsp_info(_dsp, fmt, ...) \
43         dev_info(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
44 #define adsp_dbg(_dsp, fmt, ...) \
45         dev_dbg(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__)
46
47 #define ADSP1_CONTROL_1                   0x00
48 #define ADSP1_CONTROL_2                   0x02
49 #define ADSP1_CONTROL_3                   0x03
50 #define ADSP1_CONTROL_4                   0x04
51 #define ADSP1_CONTROL_5                   0x06
52 #define ADSP1_CONTROL_6                   0x07
53 #define ADSP1_CONTROL_7                   0x08
54 #define ADSP1_CONTROL_8                   0x09
55 #define ADSP1_CONTROL_9                   0x0A
56 #define ADSP1_CONTROL_10                  0x0B
57 #define ADSP1_CONTROL_11                  0x0C
58 #define ADSP1_CONTROL_12                  0x0D
59 #define ADSP1_CONTROL_13                  0x0F
60 #define ADSP1_CONTROL_14                  0x10
61 #define ADSP1_CONTROL_15                  0x11
62 #define ADSP1_CONTROL_16                  0x12
63 #define ADSP1_CONTROL_17                  0x13
64 #define ADSP1_CONTROL_18                  0x14
65 #define ADSP1_CONTROL_19                  0x16
66 #define ADSP1_CONTROL_20                  0x17
67 #define ADSP1_CONTROL_21                  0x18
68 #define ADSP1_CONTROL_22                  0x1A
69 #define ADSP1_CONTROL_23                  0x1B
70 #define ADSP1_CONTROL_24                  0x1C
71 #define ADSP1_CONTROL_25                  0x1E
72 #define ADSP1_CONTROL_26                  0x20
73 #define ADSP1_CONTROL_27                  0x21
74 #define ADSP1_CONTROL_28                  0x22
75 #define ADSP1_CONTROL_29                  0x23
76 #define ADSP1_CONTROL_30                  0x24
77 #define ADSP1_CONTROL_31                  0x26
78
79 /*
80  * ADSP1 Control 19
81  */
82 #define ADSP1_WDMA_BUFFER_LENGTH_MASK     0x00FF  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
83 #define ADSP1_WDMA_BUFFER_LENGTH_SHIFT         0  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
84 #define ADSP1_WDMA_BUFFER_LENGTH_WIDTH         8  /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */
85
86
87 /*
88  * ADSP1 Control 30
89  */
90 #define ADSP1_DBG_CLK_ENA                 0x0008  /* DSP1_DBG_CLK_ENA */
91 #define ADSP1_DBG_CLK_ENA_MASK            0x0008  /* DSP1_DBG_CLK_ENA */
92 #define ADSP1_DBG_CLK_ENA_SHIFT                3  /* DSP1_DBG_CLK_ENA */
93 #define ADSP1_DBG_CLK_ENA_WIDTH                1  /* DSP1_DBG_CLK_ENA */
94 #define ADSP1_SYS_ENA                     0x0004  /* DSP1_SYS_ENA */
95 #define ADSP1_SYS_ENA_MASK                0x0004  /* DSP1_SYS_ENA */
96 #define ADSP1_SYS_ENA_SHIFT                    2  /* DSP1_SYS_ENA */
97 #define ADSP1_SYS_ENA_WIDTH                    1  /* DSP1_SYS_ENA */
98 #define ADSP1_CORE_ENA                    0x0002  /* DSP1_CORE_ENA */
99 #define ADSP1_CORE_ENA_MASK               0x0002  /* DSP1_CORE_ENA */
100 #define ADSP1_CORE_ENA_SHIFT                   1  /* DSP1_CORE_ENA */
101 #define ADSP1_CORE_ENA_WIDTH                   1  /* DSP1_CORE_ENA */
102 #define ADSP1_START                       0x0001  /* DSP1_START */
103 #define ADSP1_START_MASK                  0x0001  /* DSP1_START */
104 #define ADSP1_START_SHIFT                      0  /* DSP1_START */
105 #define ADSP1_START_WIDTH                      1  /* DSP1_START */
106
107 /*
108  * ADSP1 Control 31
109  */
110 #define ADSP1_CLK_SEL_MASK                0x0007  /* CLK_SEL_ENA */
111 #define ADSP1_CLK_SEL_SHIFT                    0  /* CLK_SEL_ENA */
112 #define ADSP1_CLK_SEL_WIDTH                    3  /* CLK_SEL_ENA */
113
114 #define ADSP2_CONTROL        0x0
115 #define ADSP2_CLOCKING       0x1
116 #define ADSP2_STATUS1        0x4
117 #define ADSP2_WDMA_CONFIG_1 0x30
118 #define ADSP2_WDMA_CONFIG_2 0x31
119 #define ADSP2_RDMA_CONFIG_1 0x34
120
121 /*
122  * ADSP2 Control
123  */
124
125 #define ADSP2_MEM_ENA                     0x0010  /* DSP1_MEM_ENA */
126 #define ADSP2_MEM_ENA_MASK                0x0010  /* DSP1_MEM_ENA */
127 #define ADSP2_MEM_ENA_SHIFT                    4  /* DSP1_MEM_ENA */
128 #define ADSP2_MEM_ENA_WIDTH                    1  /* DSP1_MEM_ENA */
129 #define ADSP2_SYS_ENA                     0x0004  /* DSP1_SYS_ENA */
130 #define ADSP2_SYS_ENA_MASK                0x0004  /* DSP1_SYS_ENA */
131 #define ADSP2_SYS_ENA_SHIFT                    2  /* DSP1_SYS_ENA */
132 #define ADSP2_SYS_ENA_WIDTH                    1  /* DSP1_SYS_ENA */
133 #define ADSP2_CORE_ENA                    0x0002  /* DSP1_CORE_ENA */
134 #define ADSP2_CORE_ENA_MASK               0x0002  /* DSP1_CORE_ENA */
135 #define ADSP2_CORE_ENA_SHIFT                   1  /* DSP1_CORE_ENA */
136 #define ADSP2_CORE_ENA_WIDTH                   1  /* DSP1_CORE_ENA */
137 #define ADSP2_START                       0x0001  /* DSP1_START */
138 #define ADSP2_START_MASK                  0x0001  /* DSP1_START */
139 #define ADSP2_START_SHIFT                      0  /* DSP1_START */
140 #define ADSP2_START_WIDTH                      1  /* DSP1_START */
141
142 /*
143  * ADSP2 clocking
144  */
145 #define ADSP2_CLK_SEL_MASK                0x0007  /* CLK_SEL_ENA */
146 #define ADSP2_CLK_SEL_SHIFT                    0  /* CLK_SEL_ENA */
147 #define ADSP2_CLK_SEL_WIDTH                    3  /* CLK_SEL_ENA */
148
149 /*
150  * ADSP2 Status 1
151  */
152 #define ADSP2_RAM_RDY                     0x0001
153 #define ADSP2_RAM_RDY_MASK                0x0001
154 #define ADSP2_RAM_RDY_SHIFT                    0
155 #define ADSP2_RAM_RDY_WIDTH                    1
156
157 struct wm_adsp_buf {
158         struct list_head list;
159         void *buf;
160 };
161
162 static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len,
163                                              struct list_head *list)
164 {
165         struct wm_adsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL);
166
167         if (buf == NULL)
168                 return NULL;
169
170         buf->buf = kmemdup(src, len, GFP_KERNEL | GFP_DMA);
171         if (!buf->buf) {
172                 kfree(buf);
173                 return NULL;
174         }
175
176         if (list)
177                 list_add_tail(&buf->list, list);
178
179         return buf;
180 }
181
182 static void wm_adsp_buf_free(struct list_head *list)
183 {
184         while (!list_empty(list)) {
185                 struct wm_adsp_buf *buf = list_first_entry(list,
186                                                            struct wm_adsp_buf,
187                                                            list);
188                 list_del(&buf->list);
189                 kfree(buf->buf);
190                 kfree(buf);
191         }
192 }
193
194 #define WM_ADSP_NUM_FW 4
195
196 static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = {
197         "MBC/VSS", "Tx", "Tx Speaker", "Rx ANC"
198 };
199
200 static struct {
201         const char *file;
202 } wm_adsp_fw[WM_ADSP_NUM_FW] = {
203         { .file = "mbc-vss" },
204         { .file = "tx" },
205         { .file = "tx-spk" },
206         { .file = "rx-anc" },
207 };
208
209 static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol,
210                           struct snd_ctl_elem_value *ucontrol)
211 {
212         struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
213         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
214         struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec);
215
216         ucontrol->value.integer.value[0] = adsp[e->shift_l].fw;
217
218         return 0;
219 }
220
221 static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol,
222                           struct snd_ctl_elem_value *ucontrol)
223 {
224         struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
225         struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
226         struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec);
227
228         if (ucontrol->value.integer.value[0] == adsp[e->shift_l].fw)
229                 return 0;
230
231         if (ucontrol->value.integer.value[0] >= WM_ADSP_NUM_FW)
232                 return -EINVAL;
233
234         if (adsp[e->shift_l].running)
235                 return -EBUSY;
236
237         adsp[e->shift_l].fw = ucontrol->value.integer.value[0];
238
239         return 0;
240 }
241
242 static const struct soc_enum wm_adsp_fw_enum[] = {
243         SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
244         SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
245         SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
246         SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text),
247 };
248
249 const struct snd_kcontrol_new wm_adsp_fw_controls[] = {
250         SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0],
251                      wm_adsp_fw_get, wm_adsp_fw_put),
252         SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1],
253                      wm_adsp_fw_get, wm_adsp_fw_put),
254         SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2],
255                      wm_adsp_fw_get, wm_adsp_fw_put),
256         SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3],
257                      wm_adsp_fw_get, wm_adsp_fw_put),
258 };
259 EXPORT_SYMBOL_GPL(wm_adsp_fw_controls);
260
261 static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp,
262                                                         int type)
263 {
264         int i;
265
266         for (i = 0; i < dsp->num_mems; i++)
267                 if (dsp->mem[i].type == type)
268                         return &dsp->mem[i];
269
270         return NULL;
271 }
272
273 static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *region,
274                                           unsigned int offset)
275 {
276         switch (region->type) {
277         case WMFW_ADSP1_PM:
278                 return region->base + (offset * 3);
279         case WMFW_ADSP1_DM:
280                 return region->base + (offset * 2);
281         case WMFW_ADSP2_XM:
282                 return region->base + (offset * 2);
283         case WMFW_ADSP2_YM:
284                 return region->base + (offset * 2);
285         case WMFW_ADSP1_ZM:
286                 return region->base + (offset * 2);
287         default:
288                 WARN_ON(NULL != "Unknown memory region type");
289                 return offset;
290         }
291 }
292
293 static int wm_adsp_load(struct wm_adsp *dsp)
294 {
295         LIST_HEAD(buf_list);
296         const struct firmware *firmware;
297         struct regmap *regmap = dsp->regmap;
298         unsigned int pos = 0;
299         const struct wmfw_header *header;
300         const struct wmfw_adsp1_sizes *adsp1_sizes;
301         const struct wmfw_adsp2_sizes *adsp2_sizes;
302         const struct wmfw_footer *footer;
303         const struct wmfw_region *region;
304         const struct wm_adsp_region *mem;
305         const char *region_name;
306         char *file, *text;
307         struct wm_adsp_buf *buf;
308         unsigned int reg;
309         int regions = 0;
310         int ret, offset, type, sizes;
311
312         file = kzalloc(PAGE_SIZE, GFP_KERNEL);
313         if (file == NULL)
314                 return -ENOMEM;
315
316         snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.wmfw", dsp->part, dsp->num,
317                  wm_adsp_fw[dsp->fw].file);
318         file[PAGE_SIZE - 1] = '\0';
319
320         ret = request_firmware(&firmware, file, dsp->dev);
321         if (ret != 0) {
322                 adsp_err(dsp, "Failed to request '%s'\n", file);
323                 goto out;
324         }
325         ret = -EINVAL;
326
327         pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);
328         if (pos >= firmware->size) {
329                 adsp_err(dsp, "%s: file too short, %zu bytes\n",
330                          file, firmware->size);
331                 goto out_fw;
332         }
333
334         header = (void*)&firmware->data[0];
335
336         if (memcmp(&header->magic[0], "WMFW", 4) != 0) {
337                 adsp_err(dsp, "%s: invalid magic\n", file);
338                 goto out_fw;
339         }
340
341         if (header->ver != 0) {
342                 adsp_err(dsp, "%s: unknown file format %d\n",
343                          file, header->ver);
344                 goto out_fw;
345         }
346
347         if (header->core != dsp->type) {
348                 adsp_err(dsp, "%s: invalid core %d != %d\n",
349                          file, header->core, dsp->type);
350                 goto out_fw;
351         }
352
353         switch (dsp->type) {
354         case WMFW_ADSP1:
355                 pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer);
356                 adsp1_sizes = (void *)&(header[1]);
357                 footer = (void *)&(adsp1_sizes[1]);
358                 sizes = sizeof(*adsp1_sizes);
359
360                 adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n",
361                          file, le32_to_cpu(adsp1_sizes->dm),
362                          le32_to_cpu(adsp1_sizes->pm),
363                          le32_to_cpu(adsp1_sizes->zm));
364                 break;
365
366         case WMFW_ADSP2:
367                 pos = sizeof(*header) + sizeof(*adsp2_sizes) + sizeof(*footer);
368                 adsp2_sizes = (void *)&(header[1]);
369                 footer = (void *)&(adsp2_sizes[1]);
370                 sizes = sizeof(*adsp2_sizes);
371
372                 adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n",
373                          file, le32_to_cpu(adsp2_sizes->xm),
374                          le32_to_cpu(adsp2_sizes->ym),
375                          le32_to_cpu(adsp2_sizes->pm),
376                          le32_to_cpu(adsp2_sizes->zm));
377                 break;
378
379         default:
380                 BUG_ON(NULL == "Unknown DSP type");
381                 goto out_fw;
382         }
383
384         if (le32_to_cpu(header->len) != sizeof(*header) +
385             sizes + sizeof(*footer)) {
386                 adsp_err(dsp, "%s: unexpected header length %d\n",
387                          file, le32_to_cpu(header->len));
388                 goto out_fw;
389         }
390
391         adsp_dbg(dsp, "%s: timestamp %llu\n", file,
392                  le64_to_cpu(footer->timestamp));
393
394         while (pos < firmware->size &&
395                pos - firmware->size > sizeof(*region)) {
396                 region = (void *)&(firmware->data[pos]);
397                 region_name = "Unknown";
398                 reg = 0;
399                 text = NULL;
400                 offset = le32_to_cpu(region->offset) & 0xffffff;
401                 type = be32_to_cpu(region->type) & 0xff;
402                 mem = wm_adsp_find_region(dsp, type);
403                 
404                 switch (type) {
405                 case WMFW_NAME_TEXT:
406                         region_name = "Firmware name";
407                         text = kzalloc(le32_to_cpu(region->len) + 1,
408                                        GFP_KERNEL);
409                         break;
410                 case WMFW_INFO_TEXT:
411                         region_name = "Information";
412                         text = kzalloc(le32_to_cpu(region->len) + 1,
413                                        GFP_KERNEL);
414                         break;
415                 case WMFW_ABSOLUTE:
416                         region_name = "Absolute";
417                         reg = offset;
418                         break;
419                 case WMFW_ADSP1_PM:
420                         BUG_ON(!mem);
421                         region_name = "PM";
422                         reg = wm_adsp_region_to_reg(mem, offset);
423                         break;
424                 case WMFW_ADSP1_DM:
425                         BUG_ON(!mem);
426                         region_name = "DM";
427                         reg = wm_adsp_region_to_reg(mem, offset);
428                         break;
429                 case WMFW_ADSP2_XM:
430                         BUG_ON(!mem);
431                         region_name = "XM";
432                         reg = wm_adsp_region_to_reg(mem, offset);
433                         break;
434                 case WMFW_ADSP2_YM:
435                         BUG_ON(!mem);
436                         region_name = "YM";
437                         reg = wm_adsp_region_to_reg(mem, offset);
438                         break;
439                 case WMFW_ADSP1_ZM:
440                         BUG_ON(!mem);
441                         region_name = "ZM";
442                         reg = wm_adsp_region_to_reg(mem, offset);
443                         break;
444                 default:
445                         adsp_warn(dsp,
446                                   "%s.%d: Unknown region type %x at %d(%x)\n",
447                                   file, regions, type, pos, pos);
448                         break;
449                 }
450
451                 adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file,
452                          regions, le32_to_cpu(region->len), offset,
453                          region_name);
454
455                 if (text) {
456                         memcpy(text, region->data, le32_to_cpu(region->len));
457                         adsp_info(dsp, "%s: %s\n", file, text);
458                         kfree(text);
459                 }
460
461                 if (reg) {
462                         buf = wm_adsp_buf_alloc(region->data,
463                                                 le32_to_cpu(region->len),
464                                                 &buf_list);
465                         if (!buf) {
466                                 adsp_err(dsp, "Out of memory\n");
467                                 return -ENOMEM;
468                         }
469
470                         ret = regmap_raw_write_async(regmap, reg, buf->buf,
471                                                      le32_to_cpu(region->len));
472                         if (ret != 0) {
473                                 adsp_err(dsp,
474                                         "%s.%d: Failed to write %d bytes at %d in %s: %d\n",
475                                         file, regions,
476                                         le32_to_cpu(region->len), offset,
477                                         region_name, ret);
478                                 goto out_fw;
479                         }
480                 }
481
482                 pos += le32_to_cpu(region->len) + sizeof(*region);
483                 regions++;
484         }
485
486         ret = regmap_async_complete(regmap);
487         if (ret != 0) {
488                 adsp_err(dsp, "Failed to complete async write: %d\n", ret);
489                 goto out_fw;
490         }
491
492         if (pos > firmware->size)
493                 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
494                           file, regions, pos - firmware->size);
495
496 out_fw:
497         regmap_async_complete(regmap);
498         wm_adsp_buf_free(&buf_list);
499         release_firmware(firmware);
500 out:
501         kfree(file);
502
503         return ret;
504 }
505
506 static int wm_adsp_setup_algs(struct wm_adsp *dsp)
507 {
508         struct regmap *regmap = dsp->regmap;
509         struct wmfw_adsp1_id_hdr adsp1_id;
510         struct wmfw_adsp2_id_hdr adsp2_id;
511         struct wmfw_adsp1_alg_hdr *adsp1_alg;
512         struct wmfw_adsp2_alg_hdr *adsp2_alg;
513         void *alg, *buf;
514         struct wm_adsp_alg_region *region;
515         const struct wm_adsp_region *mem;
516         unsigned int pos, term;
517         size_t algs, buf_size;
518         __be32 val;
519         int i, ret;
520
521         switch (dsp->type) {
522         case WMFW_ADSP1:
523                 mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM);
524                 break;
525         case WMFW_ADSP2:
526                 mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM);
527                 break;
528         default:
529                 mem = NULL;
530                 break;
531         }
532
533         if (mem == NULL) {
534                 BUG_ON(mem != NULL);
535                 return -EINVAL;
536         }
537
538         switch (dsp->type) {
539         case WMFW_ADSP1:
540                 ret = regmap_raw_read(regmap, mem->base, &adsp1_id,
541                                       sizeof(adsp1_id));
542                 if (ret != 0) {
543                         adsp_err(dsp, "Failed to read algorithm info: %d\n",
544                                  ret);
545                         return ret;
546                 }
547
548                 buf = &adsp1_id;
549                 buf_size = sizeof(adsp1_id);
550
551                 algs = be32_to_cpu(adsp1_id.algs);
552                 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n",
553                           be32_to_cpu(adsp1_id.fw.id),
554                           (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16,
555                           (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8,
556                           be32_to_cpu(adsp1_id.fw.ver) & 0xff,
557                           algs);
558
559                 pos = sizeof(adsp1_id) / 2;
560                 term = pos + ((sizeof(*adsp1_alg) * algs) / 2);
561                 break;
562
563         case WMFW_ADSP2:
564                 ret = regmap_raw_read(regmap, mem->base, &adsp2_id,
565                                       sizeof(adsp2_id));
566                 if (ret != 0) {
567                         adsp_err(dsp, "Failed to read algorithm info: %d\n",
568                                  ret);
569                         return ret;
570                 }
571
572                 buf = &adsp2_id;
573                 buf_size = sizeof(adsp2_id);
574
575                 algs = be32_to_cpu(adsp2_id.algs);
576                 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n",
577                           be32_to_cpu(adsp2_id.fw.id),
578                           (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16,
579                           (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8,
580                           be32_to_cpu(adsp2_id.fw.ver) & 0xff,
581                           algs);
582
583                 pos = sizeof(adsp2_id) / 2;
584                 term = pos + ((sizeof(*adsp2_alg) * algs) / 2);
585                 break;
586
587         default:
588                 BUG_ON(NULL == "Unknown DSP type");
589                 return -EINVAL;
590         }
591
592         if (algs == 0) {
593                 adsp_err(dsp, "No algorithms\n");
594                 return -EINVAL;
595         }
596
597         if (algs > 1024) {
598                 adsp_err(dsp, "Algorithm count %zx excessive\n", algs);
599                 print_hex_dump_bytes(dev_name(dsp->dev), DUMP_PREFIX_OFFSET,
600                                      buf, buf_size);
601                 return -EINVAL;
602         }
603
604         /* Read the terminator first to validate the length */
605         ret = regmap_raw_read(regmap, mem->base + term, &val, sizeof(val));
606         if (ret != 0) {
607                 adsp_err(dsp, "Failed to read algorithm list end: %d\n",
608                         ret);
609                 return ret;
610         }
611
612         if (be32_to_cpu(val) != 0xbedead)
613                 adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbeadead\n",
614                           term, be32_to_cpu(val));
615
616         alg = kzalloc((term - pos) * 2, GFP_KERNEL | GFP_DMA);
617         if (!alg)
618                 return -ENOMEM;
619
620         ret = regmap_raw_read(regmap, mem->base + pos, alg, (term - pos) * 2);
621         if (ret != 0) {
622                 adsp_err(dsp, "Failed to read algorithm list: %d\n",
623                         ret);
624                 goto out;
625         }
626
627         adsp1_alg = alg;
628         adsp2_alg = alg;
629
630         for (i = 0; i < algs; i++) {
631                 switch (dsp->type) {
632                 case WMFW_ADSP1:
633                         adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n",
634                                   i, be32_to_cpu(adsp1_alg[i].alg.id),
635                                   (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16,
636                                   (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8,
637                                   be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff,
638                                   be32_to_cpu(adsp1_alg[i].dm),
639                                   be32_to_cpu(adsp1_alg[i].zm));
640
641                         region = kzalloc(sizeof(*region), GFP_KERNEL);
642                         if (!region)
643                                 return -ENOMEM;
644                         region->type = WMFW_ADSP1_DM;
645                         region->alg = be32_to_cpu(adsp1_alg[i].alg.id);
646                         region->base = be32_to_cpu(adsp1_alg[i].dm);
647                         list_add_tail(&region->list, &dsp->alg_regions);
648
649                         region = kzalloc(sizeof(*region), GFP_KERNEL);
650                         if (!region)
651                                 return -ENOMEM;
652                         region->type = WMFW_ADSP1_ZM;
653                         region->alg = be32_to_cpu(adsp1_alg[i].alg.id);
654                         region->base = be32_to_cpu(adsp1_alg[i].zm);
655                         list_add_tail(&region->list, &dsp->alg_regions);
656                         break;
657
658                 case WMFW_ADSP2:
659                         adsp_info(dsp,
660                                   "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n",
661                                   i, be32_to_cpu(adsp2_alg[i].alg.id),
662                                   (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16,
663                                   (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8,
664                                   be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff,
665                                   be32_to_cpu(adsp2_alg[i].xm),
666                                   be32_to_cpu(adsp2_alg[i].ym),
667                                   be32_to_cpu(adsp2_alg[i].zm));
668
669                         region = kzalloc(sizeof(*region), GFP_KERNEL);
670                         if (!region)
671                                 return -ENOMEM;
672                         region->type = WMFW_ADSP2_XM;
673                         region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
674                         region->base = be32_to_cpu(adsp2_alg[i].xm);
675                         list_add_tail(&region->list, &dsp->alg_regions);
676
677                         region = kzalloc(sizeof(*region), GFP_KERNEL);
678                         if (!region)
679                                 return -ENOMEM;
680                         region->type = WMFW_ADSP2_YM;
681                         region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
682                         region->base = be32_to_cpu(adsp2_alg[i].ym);
683                         list_add_tail(&region->list, &dsp->alg_regions);
684
685                         region = kzalloc(sizeof(*region), GFP_KERNEL);
686                         if (!region)
687                                 return -ENOMEM;
688                         region->type = WMFW_ADSP2_ZM;
689                         region->alg = be32_to_cpu(adsp2_alg[i].alg.id);
690                         region->base = be32_to_cpu(adsp2_alg[i].zm);
691                         list_add_tail(&region->list, &dsp->alg_regions);
692                         break;
693                 }
694         }
695
696 out:
697         kfree(alg);
698         return ret;
699 }
700
701 static int wm_adsp_load_coeff(struct wm_adsp *dsp)
702 {
703         LIST_HEAD(buf_list);
704         struct regmap *regmap = dsp->regmap;
705         struct wmfw_coeff_hdr *hdr;
706         struct wmfw_coeff_item *blk;
707         const struct firmware *firmware;
708         const struct wm_adsp_region *mem;
709         struct wm_adsp_alg_region *alg_region;
710         const char *region_name;
711         int ret, pos, blocks, type, offset, reg;
712         char *file;
713         struct wm_adsp_buf *buf;
714         int tmp;
715
716         file = kzalloc(PAGE_SIZE, GFP_KERNEL);
717         if (file == NULL)
718                 return -ENOMEM;
719
720         snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.bin", dsp->part, dsp->num,
721                  wm_adsp_fw[dsp->fw].file);
722         file[PAGE_SIZE - 1] = '\0';
723
724         ret = request_firmware(&firmware, file, dsp->dev);
725         if (ret != 0) {
726                 adsp_warn(dsp, "Failed to request '%s'\n", file);
727                 ret = 0;
728                 goto out;
729         }
730         ret = -EINVAL;
731
732         if (sizeof(*hdr) >= firmware->size) {
733                 adsp_err(dsp, "%s: file too short, %zu bytes\n",
734                         file, firmware->size);
735                 goto out_fw;
736         }
737
738         hdr = (void*)&firmware->data[0];
739         if (memcmp(hdr->magic, "WMDR", 4) != 0) {
740                 adsp_err(dsp, "%s: invalid magic\n", file);
741                 goto out_fw;
742         }
743
744         switch (be32_to_cpu(hdr->rev) & 0xff) {
745         case 1:
746                 break;
747         default:
748                 adsp_err(dsp, "%s: Unsupported coefficient file format %d\n",
749                          file, be32_to_cpu(hdr->rev) & 0xff);
750                 ret = -EINVAL;
751                 goto out_fw;
752         }
753
754         adsp_dbg(dsp, "%s: v%d.%d.%d\n", file,
755                 (le32_to_cpu(hdr->ver) >> 16) & 0xff,
756                 (le32_to_cpu(hdr->ver) >>  8) & 0xff,
757                 le32_to_cpu(hdr->ver) & 0xff);
758
759         pos = le32_to_cpu(hdr->len);
760
761         blocks = 0;
762         while (pos < firmware->size &&
763                pos - firmware->size > sizeof(*blk)) {
764                 blk = (void*)(&firmware->data[pos]);
765
766                 type = le16_to_cpu(blk->type);
767                 offset = le16_to_cpu(blk->offset);
768
769                 adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n",
770                          file, blocks, le32_to_cpu(blk->id),
771                          (le32_to_cpu(blk->ver) >> 16) & 0xff,
772                          (le32_to_cpu(blk->ver) >>  8) & 0xff,
773                          le32_to_cpu(blk->ver) & 0xff);
774                 adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n",
775                          file, blocks, le32_to_cpu(blk->len), offset, type);
776
777                 reg = 0;
778                 region_name = "Unknown";
779                 switch (type) {
780                 case (WMFW_NAME_TEXT << 8):
781                 case (WMFW_INFO_TEXT << 8):
782                         break;
783                 case (WMFW_ABSOLUTE << 8):
784                         region_name = "register";
785                         reg = offset;
786                         break;
787
788                 case WMFW_ADSP1_DM:
789                 case WMFW_ADSP1_ZM:
790                 case WMFW_ADSP2_XM:
791                 case WMFW_ADSP2_YM:
792                         adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n",
793                                  file, blocks, le32_to_cpu(blk->len),
794                                  type, le32_to_cpu(blk->id));
795
796                         mem = wm_adsp_find_region(dsp, type);
797                         if (!mem) {
798                                 adsp_err(dsp, "No base for region %x\n", type);
799                                 break;
800                         }
801
802                         reg = 0;
803                         list_for_each_entry(alg_region,
804                                             &dsp->alg_regions, list) {
805                                 if (le32_to_cpu(blk->id) == alg_region->alg &&
806                                     type == alg_region->type) {
807                                         reg = alg_region->base;
808                                         reg = wm_adsp_region_to_reg(mem,
809                                                                     reg);
810                                         reg += offset;
811                                 }
812                         }
813
814                         if (reg == 0)
815                                 adsp_err(dsp, "No %x for algorithm %x\n",
816                                          type, le32_to_cpu(blk->id));
817                         break;
818
819                 default:
820                         adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n",
821                                  file, blocks, type, pos);
822                         break;
823                 }
824
825                 if (reg) {
826                         buf = wm_adsp_buf_alloc(blk->data,
827                                                 le32_to_cpu(blk->len),
828                                                 &buf_list);
829                         if (!buf) {
830                                 adsp_err(dsp, "Out of memory\n");
831                                 return -ENOMEM;
832                         }
833
834                         adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n",
835                                  file, blocks, le32_to_cpu(blk->len),
836                                  reg);
837                         ret = regmap_raw_write_async(regmap, reg, buf->buf,
838                                                      le32_to_cpu(blk->len));
839                         if (ret != 0) {
840                                 adsp_err(dsp,
841                                         "%s.%d: Failed to write to %x in %s\n",
842                                         file, blocks, reg, region_name);
843                         }
844                 }
845
846                 tmp = le32_to_cpu(blk->len) % 4;
847                 if (tmp)
848                         pos += le32_to_cpu(blk->len) + (4 - tmp) + sizeof(*blk);
849                 else
850                         pos += le32_to_cpu(blk->len) + sizeof(*blk);
851
852                 blocks++;
853         }
854
855         ret = regmap_async_complete(regmap);
856         if (ret != 0)
857                 adsp_err(dsp, "Failed to complete async write: %d\n", ret);
858
859         if (pos > firmware->size)
860                 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
861                           file, blocks, pos - firmware->size);
862
863 out_fw:
864         release_firmware(firmware);
865         wm_adsp_buf_free(&buf_list);
866 out:
867         kfree(file);
868         return 0;
869 }
870
871 int wm_adsp1_init(struct wm_adsp *adsp)
872 {
873         INIT_LIST_HEAD(&adsp->alg_regions);
874
875         return 0;
876 }
877 EXPORT_SYMBOL_GPL(wm_adsp1_init);
878
879 int wm_adsp1_event(struct snd_soc_dapm_widget *w,
880                    struct snd_kcontrol *kcontrol,
881                    int event)
882 {
883         struct snd_soc_codec *codec = w->codec;
884         struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
885         struct wm_adsp *dsp = &dsps[w->shift];
886         int ret;
887         int val;
888
889         switch (event) {
890         case SND_SOC_DAPM_POST_PMU:
891                 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
892                                    ADSP1_SYS_ENA, ADSP1_SYS_ENA);
893
894                 /*
895                  * For simplicity set the DSP clock rate to be the
896                  * SYSCLK rate rather than making it configurable.
897                  */
898                 if(dsp->sysclk_reg) {
899                         ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val);
900                         if (ret != 0) {
901                                 adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
902                                 ret);
903                                 return ret;
904                         }
905
906                         val = (val & dsp->sysclk_mask)
907                                 >> dsp->sysclk_shift;
908
909                         ret = regmap_update_bits(dsp->regmap,
910                                                  dsp->base + ADSP1_CONTROL_31,
911                                                  ADSP1_CLK_SEL_MASK, val);
912                         if (ret != 0) {
913                                 adsp_err(dsp, "Failed to set clock rate: %d\n",
914                                          ret);
915                                 return ret;
916                         }
917                 }
918
919                 ret = wm_adsp_load(dsp);
920                 if (ret != 0)
921                         goto err;
922
923                 ret = wm_adsp_setup_algs(dsp);
924                 if (ret != 0)
925                         goto err;
926
927                 ret = wm_adsp_load_coeff(dsp);
928                 if (ret != 0)
929                         goto err;
930
931                 /* Start the core running */
932                 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
933                                    ADSP1_CORE_ENA | ADSP1_START,
934                                    ADSP1_CORE_ENA | ADSP1_START);
935                 break;
936
937         case SND_SOC_DAPM_PRE_PMD:
938                 /* Halt the core */
939                 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
940                                    ADSP1_CORE_ENA | ADSP1_START, 0);
941
942                 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19,
943                                    ADSP1_WDMA_BUFFER_LENGTH_MASK, 0);
944
945                 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
946                                    ADSP1_SYS_ENA, 0);
947                 break;
948
949         default:
950                 break;
951         }
952
953         return 0;
954
955 err:
956         regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
957                            ADSP1_SYS_ENA, 0);
958         return ret;
959 }
960 EXPORT_SYMBOL_GPL(wm_adsp1_event);
961
962 static int wm_adsp2_ena(struct wm_adsp *dsp)
963 {
964         unsigned int val;
965         int ret, count;
966
967         ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
968                                  ADSP2_SYS_ENA, ADSP2_SYS_ENA);
969         if (ret != 0)
970                 return ret;
971
972         /* Wait for the RAM to start, should be near instantaneous */
973         count = 0;
974         do {
975                 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1,
976                                   &val);
977                 if (ret != 0)
978                         return ret;
979         } while (!(val & ADSP2_RAM_RDY) && ++count < 10);
980
981         if (!(val & ADSP2_RAM_RDY)) {
982                 adsp_err(dsp, "Failed to start DSP RAM\n");
983                 return -EBUSY;
984         }
985
986         adsp_dbg(dsp, "RAM ready after %d polls\n", count);
987         adsp_info(dsp, "RAM ready after %d polls\n", count);
988
989         return 0;
990 }
991
992 int wm_adsp2_event(struct snd_soc_dapm_widget *w,
993                    struct snd_kcontrol *kcontrol, int event)
994 {
995         struct snd_soc_codec *codec = w->codec;
996         struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
997         struct wm_adsp *dsp = &dsps[w->shift];
998         struct wm_adsp_alg_region *alg_region;
999         unsigned int val;
1000         int ret;
1001
1002         switch (event) {
1003         case SND_SOC_DAPM_POST_PMU:
1004                 /*
1005                  * For simplicity set the DSP clock rate to be the
1006                  * SYSCLK rate rather than making it configurable.
1007                  */
1008                 ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
1009                 if (ret != 0) {
1010                         adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
1011                                  ret);
1012                         return ret;
1013                 }
1014                 val = (val & ARIZONA_SYSCLK_FREQ_MASK)
1015                         >> ARIZONA_SYSCLK_FREQ_SHIFT;
1016
1017                 ret = regmap_update_bits(dsp->regmap,
1018                                          dsp->base + ADSP2_CLOCKING,
1019                                          ADSP2_CLK_SEL_MASK, val);
1020                 if (ret != 0) {
1021                         adsp_err(dsp, "Failed to set clock rate: %d\n",
1022                                  ret);
1023                         return ret;
1024                 }
1025
1026                 if (dsp->dvfs) {
1027                         ret = regmap_read(dsp->regmap,
1028                                           dsp->base + ADSP2_CLOCKING, &val);
1029                         if (ret != 0) {
1030                                 dev_err(dsp->dev,
1031                                         "Failed to read clocking: %d\n", ret);
1032                                 return ret;
1033                         }
1034
1035                         if ((val & ADSP2_CLK_SEL_MASK) >= 3) {
1036                                 ret = regulator_enable(dsp->dvfs);
1037                                 if (ret != 0) {
1038                                         dev_err(dsp->dev,
1039                                                 "Failed to enable supply: %d\n",
1040                                                 ret);
1041                                         return ret;
1042                                 }
1043
1044                                 ret = regulator_set_voltage(dsp->dvfs,
1045                                                             1800000,
1046                                                             1800000);
1047                                 if (ret != 0) {
1048                                         dev_err(dsp->dev,
1049                                                 "Failed to raise supply: %d\n",
1050                                                 ret);
1051                                         return ret;
1052                                 }
1053                         }
1054                 }
1055
1056                 ret = wm_adsp2_ena(dsp);
1057                 if (ret != 0)
1058                         return ret;
1059
1060                 ret = wm_adsp_load(dsp);
1061                 if (ret != 0)
1062                         goto err;
1063
1064                 ret = wm_adsp_setup_algs(dsp);
1065                 if (ret != 0)
1066                         goto err;
1067
1068                 ret = wm_adsp_load_coeff(dsp);
1069                 if (ret != 0)
1070                         goto err;
1071
1072                 ret = regmap_update_bits(dsp->regmap,
1073                                          dsp->base + ADSP2_CONTROL,
1074                                          ADSP2_CORE_ENA | ADSP2_START,
1075                                          ADSP2_CORE_ENA | ADSP2_START);
1076                 if (ret != 0)
1077                         goto err;
1078
1079                 dsp->running = true;
1080                 break;
1081
1082         case SND_SOC_DAPM_PRE_PMD:
1083                 dsp->running = false;
1084
1085                 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
1086                                    ADSP2_SYS_ENA | ADSP2_CORE_ENA |
1087                                    ADSP2_START, 0);
1088
1089                 /* Make sure DMAs are quiesced */
1090                 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0);
1091                 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0);
1092                 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0);
1093
1094                 if (dsp->dvfs) {
1095                         ret = regulator_set_voltage(dsp->dvfs, 1200000,
1096                                                     1800000);
1097                         if (ret != 0)
1098                                 dev_warn(dsp->dev,
1099                                          "Failed to lower supply: %d\n",
1100                                          ret);
1101
1102                         ret = regulator_disable(dsp->dvfs);
1103                         if (ret != 0)
1104                                 dev_err(dsp->dev,
1105                                         "Failed to enable supply: %d\n",
1106                                         ret);
1107                 }
1108
1109                 while (!list_empty(&dsp->alg_regions)) {
1110                         alg_region = list_first_entry(&dsp->alg_regions,
1111                                                       struct wm_adsp_alg_region,
1112                                                       list);
1113                         list_del(&alg_region->list);
1114                         kfree(alg_region);
1115                 }
1116                 break;
1117
1118         default:
1119                 break;
1120         }
1121
1122         return 0;
1123 err:
1124         regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
1125                            ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
1126         return ret;
1127 }
1128 EXPORT_SYMBOL_GPL(wm_adsp2_event);
1129
1130 int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
1131 {
1132         int ret;
1133
1134         /*
1135          * Disable the DSP memory by default when in reset for a small
1136          * power saving.
1137          */
1138         ret = regmap_update_bits(adsp->regmap, adsp->base + ADSP2_CONTROL,
1139                                  ADSP2_MEM_ENA, 0);
1140         if (ret != 0) {
1141                 adsp_err(adsp, "Failed to clear memory retention: %d\n", ret);
1142                 return ret;
1143         }
1144
1145         INIT_LIST_HEAD(&adsp->alg_regions);
1146
1147         if (dvfs) {
1148                 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
1149                 if (IS_ERR(adsp->dvfs)) {
1150                         ret = PTR_ERR(adsp->dvfs);
1151                         dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret);
1152                         return ret;
1153                 }
1154
1155                 ret = regulator_enable(adsp->dvfs);
1156                 if (ret != 0) {
1157                         dev_err(adsp->dev, "Failed to enable DCVDD: %d\n",
1158                                 ret);
1159                         return ret;
1160                 }
1161
1162                 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000);
1163                 if (ret != 0) {
1164                         dev_err(adsp->dev, "Failed to initialise DVFS: %d\n",
1165                                 ret);
1166                         return ret;
1167                 }
1168
1169                 ret = regulator_disable(adsp->dvfs);
1170                 if (ret != 0) {
1171                         dev_err(adsp->dev, "Failed to disable DCVDD: %d\n",
1172                                 ret);
1173                         return ret;
1174                 }
1175         }
1176
1177         return 0;
1178 }
1179 EXPORT_SYMBOL_GPL(wm_adsp2_init);