Merge branch 'next/kvm' into mips-for-linux-next
[pandora-kernel.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                                 ret = -ENOMEM;
832                                 goto out_fw;
833                         }
834
835                         adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n",
836                                  file, blocks, le32_to_cpu(blk->len),
837                                  reg);
838                         ret = regmap_raw_write_async(regmap, reg, buf->buf,
839                                                      le32_to_cpu(blk->len));
840                         if (ret != 0) {
841                                 adsp_err(dsp,
842                                         "%s.%d: Failed to write to %x in %s\n",
843                                         file, blocks, reg, region_name);
844                         }
845                 }
846
847                 tmp = le32_to_cpu(blk->len) % 4;
848                 if (tmp)
849                         pos += le32_to_cpu(blk->len) + (4 - tmp) + sizeof(*blk);
850                 else
851                         pos += le32_to_cpu(blk->len) + sizeof(*blk);
852
853                 blocks++;
854         }
855
856         ret = regmap_async_complete(regmap);
857         if (ret != 0)
858                 adsp_err(dsp, "Failed to complete async write: %d\n", ret);
859
860         if (pos > firmware->size)
861                 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n",
862                           file, blocks, pos - firmware->size);
863
864 out_fw:
865         release_firmware(firmware);
866         wm_adsp_buf_free(&buf_list);
867 out:
868         kfree(file);
869         return ret;
870 }
871
872 int wm_adsp1_init(struct wm_adsp *adsp)
873 {
874         INIT_LIST_HEAD(&adsp->alg_regions);
875
876         return 0;
877 }
878 EXPORT_SYMBOL_GPL(wm_adsp1_init);
879
880 int wm_adsp1_event(struct snd_soc_dapm_widget *w,
881                    struct snd_kcontrol *kcontrol,
882                    int event)
883 {
884         struct snd_soc_codec *codec = w->codec;
885         struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
886         struct wm_adsp *dsp = &dsps[w->shift];
887         int ret;
888         int val;
889
890         switch (event) {
891         case SND_SOC_DAPM_POST_PMU:
892                 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
893                                    ADSP1_SYS_ENA, ADSP1_SYS_ENA);
894
895                 /*
896                  * For simplicity set the DSP clock rate to be the
897                  * SYSCLK rate rather than making it configurable.
898                  */
899                 if(dsp->sysclk_reg) {
900                         ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val);
901                         if (ret != 0) {
902                                 adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
903                                 ret);
904                                 return ret;
905                         }
906
907                         val = (val & dsp->sysclk_mask)
908                                 >> dsp->sysclk_shift;
909
910                         ret = regmap_update_bits(dsp->regmap,
911                                                  dsp->base + ADSP1_CONTROL_31,
912                                                  ADSP1_CLK_SEL_MASK, val);
913                         if (ret != 0) {
914                                 adsp_err(dsp, "Failed to set clock rate: %d\n",
915                                          ret);
916                                 return ret;
917                         }
918                 }
919
920                 ret = wm_adsp_load(dsp);
921                 if (ret != 0)
922                         goto err;
923
924                 ret = wm_adsp_setup_algs(dsp);
925                 if (ret != 0)
926                         goto err;
927
928                 ret = wm_adsp_load_coeff(dsp);
929                 if (ret != 0)
930                         goto err;
931
932                 /* Start the core running */
933                 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
934                                    ADSP1_CORE_ENA | ADSP1_START,
935                                    ADSP1_CORE_ENA | ADSP1_START);
936                 break;
937
938         case SND_SOC_DAPM_PRE_PMD:
939                 /* Halt the core */
940                 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
941                                    ADSP1_CORE_ENA | ADSP1_START, 0);
942
943                 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19,
944                                    ADSP1_WDMA_BUFFER_LENGTH_MASK, 0);
945
946                 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
947                                    ADSP1_SYS_ENA, 0);
948                 break;
949
950         default:
951                 break;
952         }
953
954         return 0;
955
956 err:
957         regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30,
958                            ADSP1_SYS_ENA, 0);
959         return ret;
960 }
961 EXPORT_SYMBOL_GPL(wm_adsp1_event);
962
963 static int wm_adsp2_ena(struct wm_adsp *dsp)
964 {
965         unsigned int val;
966         int ret, count;
967
968         ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
969                                  ADSP2_SYS_ENA, ADSP2_SYS_ENA);
970         if (ret != 0)
971                 return ret;
972
973         /* Wait for the RAM to start, should be near instantaneous */
974         count = 0;
975         do {
976                 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1,
977                                   &val);
978                 if (ret != 0)
979                         return ret;
980         } while (!(val & ADSP2_RAM_RDY) && ++count < 10);
981
982         if (!(val & ADSP2_RAM_RDY)) {
983                 adsp_err(dsp, "Failed to start DSP RAM\n");
984                 return -EBUSY;
985         }
986
987         adsp_dbg(dsp, "RAM ready after %d polls\n", count);
988         adsp_info(dsp, "RAM ready after %d polls\n", count);
989
990         return 0;
991 }
992
993 int wm_adsp2_event(struct snd_soc_dapm_widget *w,
994                    struct snd_kcontrol *kcontrol, int event)
995 {
996         struct snd_soc_codec *codec = w->codec;
997         struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec);
998         struct wm_adsp *dsp = &dsps[w->shift];
999         struct wm_adsp_alg_region *alg_region;
1000         unsigned int val;
1001         int ret;
1002
1003         switch (event) {
1004         case SND_SOC_DAPM_POST_PMU:
1005                 /*
1006                  * For simplicity set the DSP clock rate to be the
1007                  * SYSCLK rate rather than making it configurable.
1008                  */
1009                 ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val);
1010                 if (ret != 0) {
1011                         adsp_err(dsp, "Failed to read SYSCLK state: %d\n",
1012                                  ret);
1013                         return ret;
1014                 }
1015                 val = (val & ARIZONA_SYSCLK_FREQ_MASK)
1016                         >> ARIZONA_SYSCLK_FREQ_SHIFT;
1017
1018                 ret = regmap_update_bits(dsp->regmap,
1019                                          dsp->base + ADSP2_CLOCKING,
1020                                          ADSP2_CLK_SEL_MASK, val);
1021                 if (ret != 0) {
1022                         adsp_err(dsp, "Failed to set clock rate: %d\n",
1023                                  ret);
1024                         return ret;
1025                 }
1026
1027                 if (dsp->dvfs) {
1028                         ret = regmap_read(dsp->regmap,
1029                                           dsp->base + ADSP2_CLOCKING, &val);
1030                         if (ret != 0) {
1031                                 dev_err(dsp->dev,
1032                                         "Failed to read clocking: %d\n", ret);
1033                                 return ret;
1034                         }
1035
1036                         if ((val & ADSP2_CLK_SEL_MASK) >= 3) {
1037                                 ret = regulator_enable(dsp->dvfs);
1038                                 if (ret != 0) {
1039                                         dev_err(dsp->dev,
1040                                                 "Failed to enable supply: %d\n",
1041                                                 ret);
1042                                         return ret;
1043                                 }
1044
1045                                 ret = regulator_set_voltage(dsp->dvfs,
1046                                                             1800000,
1047                                                             1800000);
1048                                 if (ret != 0) {
1049                                         dev_err(dsp->dev,
1050                                                 "Failed to raise supply: %d\n",
1051                                                 ret);
1052                                         return ret;
1053                                 }
1054                         }
1055                 }
1056
1057                 ret = wm_adsp2_ena(dsp);
1058                 if (ret != 0)
1059                         return ret;
1060
1061                 ret = wm_adsp_load(dsp);
1062                 if (ret != 0)
1063                         goto err;
1064
1065                 ret = wm_adsp_setup_algs(dsp);
1066                 if (ret != 0)
1067                         goto err;
1068
1069                 ret = wm_adsp_load_coeff(dsp);
1070                 if (ret != 0)
1071                         goto err;
1072
1073                 ret = regmap_update_bits(dsp->regmap,
1074                                          dsp->base + ADSP2_CONTROL,
1075                                          ADSP2_CORE_ENA | ADSP2_START,
1076                                          ADSP2_CORE_ENA | ADSP2_START);
1077                 if (ret != 0)
1078                         goto err;
1079
1080                 dsp->running = true;
1081                 break;
1082
1083         case SND_SOC_DAPM_PRE_PMD:
1084                 dsp->running = false;
1085
1086                 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
1087                                    ADSP2_SYS_ENA | ADSP2_CORE_ENA |
1088                                    ADSP2_START, 0);
1089
1090                 /* Make sure DMAs are quiesced */
1091                 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0);
1092                 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0);
1093                 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0);
1094
1095                 if (dsp->dvfs) {
1096                         ret = regulator_set_voltage(dsp->dvfs, 1200000,
1097                                                     1800000);
1098                         if (ret != 0)
1099                                 dev_warn(dsp->dev,
1100                                          "Failed to lower supply: %d\n",
1101                                          ret);
1102
1103                         ret = regulator_disable(dsp->dvfs);
1104                         if (ret != 0)
1105                                 dev_err(dsp->dev,
1106                                         "Failed to enable supply: %d\n",
1107                                         ret);
1108                 }
1109
1110                 while (!list_empty(&dsp->alg_regions)) {
1111                         alg_region = list_first_entry(&dsp->alg_regions,
1112                                                       struct wm_adsp_alg_region,
1113                                                       list);
1114                         list_del(&alg_region->list);
1115                         kfree(alg_region);
1116                 }
1117                 break;
1118
1119         default:
1120                 break;
1121         }
1122
1123         return 0;
1124 err:
1125         regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL,
1126                            ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0);
1127         return ret;
1128 }
1129 EXPORT_SYMBOL_GPL(wm_adsp2_event);
1130
1131 int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs)
1132 {
1133         int ret;
1134
1135         /*
1136          * Disable the DSP memory by default when in reset for a small
1137          * power saving.
1138          */
1139         ret = regmap_update_bits(adsp->regmap, adsp->base + ADSP2_CONTROL,
1140                                  ADSP2_MEM_ENA, 0);
1141         if (ret != 0) {
1142                 adsp_err(adsp, "Failed to clear memory retention: %d\n", ret);
1143                 return ret;
1144         }
1145
1146         INIT_LIST_HEAD(&adsp->alg_regions);
1147
1148         if (dvfs) {
1149                 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD");
1150                 if (IS_ERR(adsp->dvfs)) {
1151                         ret = PTR_ERR(adsp->dvfs);
1152                         dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret);
1153                         return ret;
1154                 }
1155
1156                 ret = regulator_enable(adsp->dvfs);
1157                 if (ret != 0) {
1158                         dev_err(adsp->dev, "Failed to enable DCVDD: %d\n",
1159                                 ret);
1160                         return ret;
1161                 }
1162
1163                 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000);
1164                 if (ret != 0) {
1165                         dev_err(adsp->dev, "Failed to initialise DVFS: %d\n",
1166                                 ret);
1167                         return ret;
1168                 }
1169
1170                 ret = regulator_disable(adsp->dvfs);
1171                 if (ret != 0) {
1172                         dev_err(adsp->dev, "Failed to disable DCVDD: %d\n",
1173                                 ret);
1174                         return ret;
1175                 }
1176         }
1177
1178         return 0;
1179 }
1180 EXPORT_SYMBOL_GPL(wm_adsp2_init);