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