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(®ion->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(®ion->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(®ion->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(®ion->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(®ion->list, &dsp->alg_regions); 692 break; 693 } 694 } 695 696 out: 697 kfree(alg); 698 return ret; 699 } 700 701 static int wm_adsp_load_coeff(struct wm_adsp *dsp) 702 { 703 LIST_HEAD(buf_list); 704 struct regmap *regmap = dsp->regmap; 705 struct wmfw_coeff_hdr *hdr; 706 struct wmfw_coeff_item *blk; 707 const struct firmware *firmware; 708 const struct wm_adsp_region *mem; 709 struct wm_adsp_alg_region *alg_region; 710 const char *region_name; 711 int ret, pos, blocks, type, offset, reg; 712 char *file; 713 struct wm_adsp_buf *buf; 714 int tmp; 715 716 file = kzalloc(PAGE_SIZE, GFP_KERNEL); 717 if (file == NULL) 718 return -ENOMEM; 719 720 snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.bin", dsp->part, dsp->num, 721 wm_adsp_fw[dsp->fw].file); 722 file[PAGE_SIZE - 1] = '\0'; 723 724 ret = request_firmware(&firmware, file, dsp->dev); 725 if (ret != 0) { 726 adsp_warn(dsp, "Failed to request '%s'\n", file); 727 ret = 0; 728 goto out; 729 } 730 ret = -EINVAL; 731 732 if (sizeof(*hdr) >= firmware->size) { 733 adsp_err(dsp, "%s: file too short, %zu bytes\n", 734 file, firmware->size); 735 goto out_fw; 736 } 737 738 hdr = (void*)&firmware->data[0]; 739 if (memcmp(hdr->magic, "WMDR", 4) != 0) { 740 adsp_err(dsp, "%s: invalid magic\n", file); 741 goto out_fw; 742 } 743 744 switch (be32_to_cpu(hdr->rev) & 0xff) { 745 case 1: 746 break; 747 default: 748 adsp_err(dsp, "%s: Unsupported coefficient file format %d\n", 749 file, be32_to_cpu(hdr->rev) & 0xff); 750 ret = -EINVAL; 751 goto out_fw; 752 } 753 754 adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, 755 (le32_to_cpu(hdr->ver) >> 16) & 0xff, 756 (le32_to_cpu(hdr->ver) >> 8) & 0xff, 757 le32_to_cpu(hdr->ver) & 0xff); 758 759 pos = le32_to_cpu(hdr->len); 760 761 blocks = 0; 762 while (pos < firmware->size && 763 pos - firmware->size > sizeof(*blk)) { 764 blk = (void*)(&firmware->data[pos]); 765 766 type = le16_to_cpu(blk->type); 767 offset = le16_to_cpu(blk->offset); 768 769 adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", 770 file, blocks, le32_to_cpu(blk->id), 771 (le32_to_cpu(blk->ver) >> 16) & 0xff, 772 (le32_to_cpu(blk->ver) >> 8) & 0xff, 773 le32_to_cpu(blk->ver) & 0xff); 774 adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", 775 file, blocks, le32_to_cpu(blk->len), offset, type); 776 777 reg = 0; 778 region_name = "Unknown"; 779 switch (type) { 780 case (WMFW_NAME_TEXT << 8): 781 case (WMFW_INFO_TEXT << 8): 782 break; 783 case (WMFW_ABSOLUTE << 8): 784 region_name = "register"; 785 reg = offset; 786 break; 787 788 case WMFW_ADSP1_DM: 789 case WMFW_ADSP1_ZM: 790 case WMFW_ADSP2_XM: 791 case WMFW_ADSP2_YM: 792 adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", 793 file, blocks, le32_to_cpu(blk->len), 794 type, le32_to_cpu(blk->id)); 795 796 mem = wm_adsp_find_region(dsp, type); 797 if (!mem) { 798 adsp_err(dsp, "No base for region %x\n", type); 799 break; 800 } 801 802 reg = 0; 803 list_for_each_entry(alg_region, 804 &dsp->alg_regions, list) { 805 if (le32_to_cpu(blk->id) == alg_region->alg && 806 type == alg_region->type) { 807 reg = alg_region->base; 808 reg = wm_adsp_region_to_reg(mem, 809 reg); 810 reg += offset; 811 } 812 } 813 814 if (reg == 0) 815 adsp_err(dsp, "No %x for algorithm %x\n", 816 type, le32_to_cpu(blk->id)); 817 break; 818 819 default: 820 adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", 821 file, blocks, type, pos); 822 break; 823 } 824 825 if (reg) { 826 buf = wm_adsp_buf_alloc(blk->data, 827 le32_to_cpu(blk->len), 828 &buf_list); 829 if (!buf) { 830 adsp_err(dsp, "Out of memory\n"); 831 return -ENOMEM; 832 } 833 834 adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", 835 file, blocks, le32_to_cpu(blk->len), 836 reg); 837 ret = regmap_raw_write_async(regmap, reg, buf->buf, 838 le32_to_cpu(blk->len)); 839 if (ret != 0) { 840 adsp_err(dsp, 841 "%s.%d: Failed to write to %x in %s\n", 842 file, blocks, reg, region_name); 843 } 844 } 845 846 tmp = le32_to_cpu(blk->len) % 4; 847 if (tmp) 848 pos += le32_to_cpu(blk->len) + (4 - tmp) + sizeof(*blk); 849 else 850 pos += le32_to_cpu(blk->len) + sizeof(*blk); 851 852 blocks++; 853 } 854 855 ret = regmap_async_complete(regmap); 856 if (ret != 0) 857 adsp_err(dsp, "Failed to complete async write: %d\n", ret); 858 859 if (pos > firmware->size) 860 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", 861 file, blocks, pos - firmware->size); 862 863 out_fw: 864 release_firmware(firmware); 865 wm_adsp_buf_free(&buf_list); 866 out: 867 kfree(file); 868 return 0; 869 } 870 871 int wm_adsp1_init(struct wm_adsp *adsp) 872 { 873 INIT_LIST_HEAD(&adsp->alg_regions); 874 875 return 0; 876 } 877 EXPORT_SYMBOL_GPL(wm_adsp1_init); 878 879 int wm_adsp1_event(struct snd_soc_dapm_widget *w, 880 struct snd_kcontrol *kcontrol, 881 int event) 882 { 883 struct snd_soc_codec *codec = w->codec; 884 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 885 struct wm_adsp *dsp = &dsps[w->shift]; 886 int ret; 887 int val; 888 889 switch (event) { 890 case SND_SOC_DAPM_POST_PMU: 891 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 892 ADSP1_SYS_ENA, ADSP1_SYS_ENA); 893 894 /* 895 * For simplicity set the DSP clock rate to be the 896 * SYSCLK rate rather than making it configurable. 897 */ 898 if(dsp->sysclk_reg) { 899 ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); 900 if (ret != 0) { 901 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", 902 ret); 903 return ret; 904 } 905 906 val = (val & dsp->sysclk_mask) 907 >> dsp->sysclk_shift; 908 909 ret = regmap_update_bits(dsp->regmap, 910 dsp->base + ADSP1_CONTROL_31, 911 ADSP1_CLK_SEL_MASK, val); 912 if (ret != 0) { 913 adsp_err(dsp, "Failed to set clock rate: %d\n", 914 ret); 915 return ret; 916 } 917 } 918 919 ret = wm_adsp_load(dsp); 920 if (ret != 0) 921 goto err; 922 923 ret = wm_adsp_setup_algs(dsp); 924 if (ret != 0) 925 goto err; 926 927 ret = wm_adsp_load_coeff(dsp); 928 if (ret != 0) 929 goto err; 930 931 /* Start the core running */ 932 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 933 ADSP1_CORE_ENA | ADSP1_START, 934 ADSP1_CORE_ENA | ADSP1_START); 935 break; 936 937 case SND_SOC_DAPM_PRE_PMD: 938 /* Halt the core */ 939 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 940 ADSP1_CORE_ENA | ADSP1_START, 0); 941 942 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, 943 ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); 944 945 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 946 ADSP1_SYS_ENA, 0); 947 break; 948 949 default: 950 break; 951 } 952 953 return 0; 954 955 err: 956 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 957 ADSP1_SYS_ENA, 0); 958 return ret; 959 } 960 EXPORT_SYMBOL_GPL(wm_adsp1_event); 961 962 static int wm_adsp2_ena(struct wm_adsp *dsp) 963 { 964 unsigned int val; 965 int ret, count; 966 967 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 968 ADSP2_SYS_ENA, ADSP2_SYS_ENA); 969 if (ret != 0) 970 return ret; 971 972 /* Wait for the RAM to start, should be near instantaneous */ 973 count = 0; 974 do { 975 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, 976 &val); 977 if (ret != 0) 978 return ret; 979 } while (!(val & ADSP2_RAM_RDY) && ++count < 10); 980 981 if (!(val & ADSP2_RAM_RDY)) { 982 adsp_err(dsp, "Failed to start DSP RAM\n"); 983 return -EBUSY; 984 } 985 986 adsp_dbg(dsp, "RAM ready after %d polls\n", count); 987 adsp_info(dsp, "RAM ready after %d polls\n", count); 988 989 return 0; 990 } 991 992 int wm_adsp2_event(struct snd_soc_dapm_widget *w, 993 struct snd_kcontrol *kcontrol, int event) 994 { 995 struct snd_soc_codec *codec = w->codec; 996 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 997 struct wm_adsp *dsp = &dsps[w->shift]; 998 struct wm_adsp_alg_region *alg_region; 999 unsigned int val; 1000 int ret; 1001 1002 switch (event) { 1003 case SND_SOC_DAPM_POST_PMU: 1004 /* 1005 * For simplicity set the DSP clock rate to be the 1006 * SYSCLK rate rather than making it configurable. 1007 */ 1008 ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val); 1009 if (ret != 0) { 1010 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", 1011 ret); 1012 return ret; 1013 } 1014 val = (val & ARIZONA_SYSCLK_FREQ_MASK) 1015 >> ARIZONA_SYSCLK_FREQ_SHIFT; 1016 1017 ret = regmap_update_bits(dsp->regmap, 1018 dsp->base + ADSP2_CLOCKING, 1019 ADSP2_CLK_SEL_MASK, val); 1020 if (ret != 0) { 1021 adsp_err(dsp, "Failed to set clock rate: %d\n", 1022 ret); 1023 return ret; 1024 } 1025 1026 if (dsp->dvfs) { 1027 ret = regmap_read(dsp->regmap, 1028 dsp->base + ADSP2_CLOCKING, &val); 1029 if (ret != 0) { 1030 dev_err(dsp->dev, 1031 "Failed to read clocking: %d\n", ret); 1032 return ret; 1033 } 1034 1035 if ((val & ADSP2_CLK_SEL_MASK) >= 3) { 1036 ret = regulator_enable(dsp->dvfs); 1037 if (ret != 0) { 1038 dev_err(dsp->dev, 1039 "Failed to enable supply: %d\n", 1040 ret); 1041 return ret; 1042 } 1043 1044 ret = regulator_set_voltage(dsp->dvfs, 1045 1800000, 1046 1800000); 1047 if (ret != 0) { 1048 dev_err(dsp->dev, 1049 "Failed to raise supply: %d\n", 1050 ret); 1051 return ret; 1052 } 1053 } 1054 } 1055 1056 ret = wm_adsp2_ena(dsp); 1057 if (ret != 0) 1058 return ret; 1059 1060 ret = wm_adsp_load(dsp); 1061 if (ret != 0) 1062 goto err; 1063 1064 ret = wm_adsp_setup_algs(dsp); 1065 if (ret != 0) 1066 goto err; 1067 1068 ret = wm_adsp_load_coeff(dsp); 1069 if (ret != 0) 1070 goto err; 1071 1072 ret = regmap_update_bits(dsp->regmap, 1073 dsp->base + ADSP2_CONTROL, 1074 ADSP2_CORE_ENA | ADSP2_START, 1075 ADSP2_CORE_ENA | ADSP2_START); 1076 if (ret != 0) 1077 goto err; 1078 1079 dsp->running = true; 1080 break; 1081 1082 case SND_SOC_DAPM_PRE_PMD: 1083 dsp->running = false; 1084 1085 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 1086 ADSP2_SYS_ENA | ADSP2_CORE_ENA | 1087 ADSP2_START, 0); 1088 1089 /* Make sure DMAs are quiesced */ 1090 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); 1091 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); 1092 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); 1093 1094 if (dsp->dvfs) { 1095 ret = regulator_set_voltage(dsp->dvfs, 1200000, 1096 1800000); 1097 if (ret != 0) 1098 dev_warn(dsp->dev, 1099 "Failed to lower supply: %d\n", 1100 ret); 1101 1102 ret = regulator_disable(dsp->dvfs); 1103 if (ret != 0) 1104 dev_err(dsp->dev, 1105 "Failed to enable supply: %d\n", 1106 ret); 1107 } 1108 1109 while (!list_empty(&dsp->alg_regions)) { 1110 alg_region = list_first_entry(&dsp->alg_regions, 1111 struct wm_adsp_alg_region, 1112 list); 1113 list_del(&alg_region->list); 1114 kfree(alg_region); 1115 } 1116 break; 1117 1118 default: 1119 break; 1120 } 1121 1122 return 0; 1123 err: 1124 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 1125 ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); 1126 return ret; 1127 } 1128 EXPORT_SYMBOL_GPL(wm_adsp2_event); 1129 1130 int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) 1131 { 1132 int ret; 1133 1134 /* 1135 * Disable the DSP memory by default when in reset for a small 1136 * power saving. 1137 */ 1138 ret = regmap_update_bits(adsp->regmap, adsp->base + ADSP2_CONTROL, 1139 ADSP2_MEM_ENA, 0); 1140 if (ret != 0) { 1141 adsp_err(adsp, "Failed to clear memory retention: %d\n", ret); 1142 return ret; 1143 } 1144 1145 INIT_LIST_HEAD(&adsp->alg_regions); 1146 1147 if (dvfs) { 1148 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); 1149 if (IS_ERR(adsp->dvfs)) { 1150 ret = PTR_ERR(adsp->dvfs); 1151 dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); 1152 return ret; 1153 } 1154 1155 ret = regulator_enable(adsp->dvfs); 1156 if (ret != 0) { 1157 dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", 1158 ret); 1159 return ret; 1160 } 1161 1162 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); 1163 if (ret != 0) { 1164 dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", 1165 ret); 1166 return ret; 1167 } 1168 1169 ret = regulator_disable(adsp->dvfs); 1170 if (ret != 0) { 1171 dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", 1172 ret); 1173 return ret; 1174 } 1175 } 1176 1177 return 0; 1178 } 1179 EXPORT_SYMBOL_GPL(wm_adsp2_init); 1180