1 /* 2 * wm_adsp.c -- Wolfson ADSP support 3 * 4 * Copyright 2012 Wolfson Microelectronics plc 5 * 6 * Author: Mark Brown <broonie@opensource.wolfsonmicro.com> 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 */ 12 13 #include <linux/module.h> 14 #include <linux/moduleparam.h> 15 #include <linux/init.h> 16 #include <linux/delay.h> 17 #include <linux/firmware.h> 18 #include <linux/list.h> 19 #include <linux/pm.h> 20 #include <linux/pm_runtime.h> 21 #include <linux/regmap.h> 22 #include <linux/regulator/consumer.h> 23 #include <linux/slab.h> 24 #include <linux/workqueue.h> 25 #include <sound/core.h> 26 #include <sound/pcm.h> 27 #include <sound/pcm_params.h> 28 #include <sound/soc.h> 29 #include <sound/jack.h> 30 #include <sound/initval.h> 31 #include <sound/tlv.h> 32 33 #include <linux/mfd/arizona/registers.h> 34 35 #include "arizona.h" 36 #include "wm_adsp.h" 37 38 #define adsp_crit(_dsp, fmt, ...) \ 39 dev_crit(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) 40 #define adsp_err(_dsp, fmt, ...) \ 41 dev_err(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) 42 #define adsp_warn(_dsp, fmt, ...) \ 43 dev_warn(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) 44 #define adsp_info(_dsp, fmt, ...) \ 45 dev_info(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) 46 #define adsp_dbg(_dsp, fmt, ...) \ 47 dev_dbg(_dsp->dev, "DSP%d: " fmt, _dsp->num, ##__VA_ARGS__) 48 49 #define ADSP1_CONTROL_1 0x00 50 #define ADSP1_CONTROL_2 0x02 51 #define ADSP1_CONTROL_3 0x03 52 #define ADSP1_CONTROL_4 0x04 53 #define ADSP1_CONTROL_5 0x06 54 #define ADSP1_CONTROL_6 0x07 55 #define ADSP1_CONTROL_7 0x08 56 #define ADSP1_CONTROL_8 0x09 57 #define ADSP1_CONTROL_9 0x0A 58 #define ADSP1_CONTROL_10 0x0B 59 #define ADSP1_CONTROL_11 0x0C 60 #define ADSP1_CONTROL_12 0x0D 61 #define ADSP1_CONTROL_13 0x0F 62 #define ADSP1_CONTROL_14 0x10 63 #define ADSP1_CONTROL_15 0x11 64 #define ADSP1_CONTROL_16 0x12 65 #define ADSP1_CONTROL_17 0x13 66 #define ADSP1_CONTROL_18 0x14 67 #define ADSP1_CONTROL_19 0x16 68 #define ADSP1_CONTROL_20 0x17 69 #define ADSP1_CONTROL_21 0x18 70 #define ADSP1_CONTROL_22 0x1A 71 #define ADSP1_CONTROL_23 0x1B 72 #define ADSP1_CONTROL_24 0x1C 73 #define ADSP1_CONTROL_25 0x1E 74 #define ADSP1_CONTROL_26 0x20 75 #define ADSP1_CONTROL_27 0x21 76 #define ADSP1_CONTROL_28 0x22 77 #define ADSP1_CONTROL_29 0x23 78 #define ADSP1_CONTROL_30 0x24 79 #define ADSP1_CONTROL_31 0x26 80 81 /* 82 * ADSP1 Control 19 83 */ 84 #define ADSP1_WDMA_BUFFER_LENGTH_MASK 0x00FF /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ 85 #define ADSP1_WDMA_BUFFER_LENGTH_SHIFT 0 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ 86 #define ADSP1_WDMA_BUFFER_LENGTH_WIDTH 8 /* DSP1_WDMA_BUFFER_LENGTH - [7:0] */ 87 88 89 /* 90 * ADSP1 Control 30 91 */ 92 #define ADSP1_DBG_CLK_ENA 0x0008 /* DSP1_DBG_CLK_ENA */ 93 #define ADSP1_DBG_CLK_ENA_MASK 0x0008 /* DSP1_DBG_CLK_ENA */ 94 #define ADSP1_DBG_CLK_ENA_SHIFT 3 /* DSP1_DBG_CLK_ENA */ 95 #define ADSP1_DBG_CLK_ENA_WIDTH 1 /* DSP1_DBG_CLK_ENA */ 96 #define ADSP1_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ 97 #define ADSP1_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ 98 #define ADSP1_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ 99 #define ADSP1_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ 100 #define ADSP1_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ 101 #define ADSP1_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ 102 #define ADSP1_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ 103 #define ADSP1_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ 104 #define ADSP1_START 0x0001 /* DSP1_START */ 105 #define ADSP1_START_MASK 0x0001 /* DSP1_START */ 106 #define ADSP1_START_SHIFT 0 /* DSP1_START */ 107 #define ADSP1_START_WIDTH 1 /* DSP1_START */ 108 109 /* 110 * ADSP1 Control 31 111 */ 112 #define ADSP1_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ 113 #define ADSP1_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ 114 #define ADSP1_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ 115 116 #define ADSP2_CONTROL 0x0 117 #define ADSP2_CLOCKING 0x1 118 #define ADSP2_STATUS1 0x4 119 #define ADSP2_WDMA_CONFIG_1 0x30 120 #define ADSP2_WDMA_CONFIG_2 0x31 121 #define ADSP2_RDMA_CONFIG_1 0x34 122 123 /* 124 * ADSP2 Control 125 */ 126 127 #define ADSP2_MEM_ENA 0x0010 /* DSP1_MEM_ENA */ 128 #define ADSP2_MEM_ENA_MASK 0x0010 /* DSP1_MEM_ENA */ 129 #define ADSP2_MEM_ENA_SHIFT 4 /* DSP1_MEM_ENA */ 130 #define ADSP2_MEM_ENA_WIDTH 1 /* DSP1_MEM_ENA */ 131 #define ADSP2_SYS_ENA 0x0004 /* DSP1_SYS_ENA */ 132 #define ADSP2_SYS_ENA_MASK 0x0004 /* DSP1_SYS_ENA */ 133 #define ADSP2_SYS_ENA_SHIFT 2 /* DSP1_SYS_ENA */ 134 #define ADSP2_SYS_ENA_WIDTH 1 /* DSP1_SYS_ENA */ 135 #define ADSP2_CORE_ENA 0x0002 /* DSP1_CORE_ENA */ 136 #define ADSP2_CORE_ENA_MASK 0x0002 /* DSP1_CORE_ENA */ 137 #define ADSP2_CORE_ENA_SHIFT 1 /* DSP1_CORE_ENA */ 138 #define ADSP2_CORE_ENA_WIDTH 1 /* DSP1_CORE_ENA */ 139 #define ADSP2_START 0x0001 /* DSP1_START */ 140 #define ADSP2_START_MASK 0x0001 /* DSP1_START */ 141 #define ADSP2_START_SHIFT 0 /* DSP1_START */ 142 #define ADSP2_START_WIDTH 1 /* DSP1_START */ 143 144 /* 145 * ADSP2 clocking 146 */ 147 #define ADSP2_CLK_SEL_MASK 0x0007 /* CLK_SEL_ENA */ 148 #define ADSP2_CLK_SEL_SHIFT 0 /* CLK_SEL_ENA */ 149 #define ADSP2_CLK_SEL_WIDTH 3 /* CLK_SEL_ENA */ 150 151 /* 152 * ADSP2 Status 1 153 */ 154 #define ADSP2_RAM_RDY 0x0001 155 #define ADSP2_RAM_RDY_MASK 0x0001 156 #define ADSP2_RAM_RDY_SHIFT 0 157 #define ADSP2_RAM_RDY_WIDTH 1 158 159 struct wm_adsp_buf { 160 struct list_head list; 161 void *buf; 162 }; 163 164 static struct wm_adsp_buf *wm_adsp_buf_alloc(const void *src, size_t len, 165 struct list_head *list) 166 { 167 struct wm_adsp_buf *buf = kzalloc(sizeof(*buf), GFP_KERNEL); 168 169 if (buf == NULL) 170 return NULL; 171 172 buf->buf = kmemdup(src, len, GFP_KERNEL | GFP_DMA); 173 if (!buf->buf) { 174 kfree(buf); 175 return NULL; 176 } 177 178 if (list) 179 list_add_tail(&buf->list, list); 180 181 return buf; 182 } 183 184 static void wm_adsp_buf_free(struct list_head *list) 185 { 186 while (!list_empty(list)) { 187 struct wm_adsp_buf *buf = list_first_entry(list, 188 struct wm_adsp_buf, 189 list); 190 list_del(&buf->list); 191 kfree(buf->buf); 192 kfree(buf); 193 } 194 } 195 196 #define WM_ADSP_NUM_FW 4 197 198 #define WM_ADSP_FW_MBC_VSS 0 199 #define WM_ADSP_FW_TX 1 200 #define WM_ADSP_FW_TX_SPK 2 201 #define WM_ADSP_FW_RX_ANC 3 202 203 static const char *wm_adsp_fw_text[WM_ADSP_NUM_FW] = { 204 [WM_ADSP_FW_MBC_VSS] = "MBC/VSS", 205 [WM_ADSP_FW_TX] = "Tx", 206 [WM_ADSP_FW_TX_SPK] = "Tx Speaker", 207 [WM_ADSP_FW_RX_ANC] = "Rx ANC", 208 }; 209 210 static struct { 211 const char *file; 212 } wm_adsp_fw[WM_ADSP_NUM_FW] = { 213 [WM_ADSP_FW_MBC_VSS] = { .file = "mbc-vss" }, 214 [WM_ADSP_FW_TX] = { .file = "tx" }, 215 [WM_ADSP_FW_TX_SPK] = { .file = "tx-spk" }, 216 [WM_ADSP_FW_RX_ANC] = { .file = "rx-anc" }, 217 }; 218 219 struct wm_coeff_ctl_ops { 220 int (*xget)(struct snd_kcontrol *kcontrol, 221 struct snd_ctl_elem_value *ucontrol); 222 int (*xput)(struct snd_kcontrol *kcontrol, 223 struct snd_ctl_elem_value *ucontrol); 224 int (*xinfo)(struct snd_kcontrol *kcontrol, 225 struct snd_ctl_elem_info *uinfo); 226 }; 227 228 struct wm_coeff_ctl { 229 const char *name; 230 struct wm_adsp_alg_region region; 231 struct wm_coeff_ctl_ops ops; 232 struct wm_adsp *adsp; 233 void *private; 234 unsigned int enabled:1; 235 struct list_head list; 236 void *cache; 237 size_t len; 238 unsigned int set:1; 239 struct snd_kcontrol *kcontrol; 240 }; 241 242 static int wm_adsp_fw_get(struct snd_kcontrol *kcontrol, 243 struct snd_ctl_elem_value *ucontrol) 244 { 245 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 246 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 247 struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec); 248 249 ucontrol->value.integer.value[0] = adsp[e->shift_l].fw; 250 251 return 0; 252 } 253 254 static int wm_adsp_fw_put(struct snd_kcontrol *kcontrol, 255 struct snd_ctl_elem_value *ucontrol) 256 { 257 struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol); 258 struct soc_enum *e = (struct soc_enum *)kcontrol->private_value; 259 struct wm_adsp *adsp = snd_soc_codec_get_drvdata(codec); 260 261 if (ucontrol->value.integer.value[0] == adsp[e->shift_l].fw) 262 return 0; 263 264 if (ucontrol->value.integer.value[0] >= WM_ADSP_NUM_FW) 265 return -EINVAL; 266 267 if (adsp[e->shift_l].running) 268 return -EBUSY; 269 270 adsp[e->shift_l].fw = ucontrol->value.integer.value[0]; 271 272 return 0; 273 } 274 275 static const struct soc_enum wm_adsp_fw_enum[] = { 276 SOC_ENUM_SINGLE(0, 0, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 277 SOC_ENUM_SINGLE(0, 1, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 278 SOC_ENUM_SINGLE(0, 2, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 279 SOC_ENUM_SINGLE(0, 3, ARRAY_SIZE(wm_adsp_fw_text), wm_adsp_fw_text), 280 }; 281 282 const struct snd_kcontrol_new wm_adsp1_fw_controls[] = { 283 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], 284 wm_adsp_fw_get, wm_adsp_fw_put), 285 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], 286 wm_adsp_fw_get, wm_adsp_fw_put), 287 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], 288 wm_adsp_fw_get, wm_adsp_fw_put), 289 }; 290 EXPORT_SYMBOL_GPL(wm_adsp1_fw_controls); 291 292 #if IS_ENABLED(CONFIG_SND_SOC_ARIZONA) 293 static const struct soc_enum wm_adsp2_rate_enum[] = { 294 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP1_CONTROL_1, 295 ARIZONA_DSP1_RATE_SHIFT, 0xf, 296 ARIZONA_RATE_ENUM_SIZE, 297 arizona_rate_text, arizona_rate_val), 298 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP2_CONTROL_1, 299 ARIZONA_DSP1_RATE_SHIFT, 0xf, 300 ARIZONA_RATE_ENUM_SIZE, 301 arizona_rate_text, arizona_rate_val), 302 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP3_CONTROL_1, 303 ARIZONA_DSP1_RATE_SHIFT, 0xf, 304 ARIZONA_RATE_ENUM_SIZE, 305 arizona_rate_text, arizona_rate_val), 306 SOC_VALUE_ENUM_SINGLE(ARIZONA_DSP4_CONTROL_1, 307 ARIZONA_DSP1_RATE_SHIFT, 0xf, 308 ARIZONA_RATE_ENUM_SIZE, 309 arizona_rate_text, arizona_rate_val), 310 }; 311 312 const struct snd_kcontrol_new wm_adsp2_fw_controls[] = { 313 SOC_ENUM_EXT("DSP1 Firmware", wm_adsp_fw_enum[0], 314 wm_adsp_fw_get, wm_adsp_fw_put), 315 SOC_ENUM("DSP1 Rate", wm_adsp2_rate_enum[0]), 316 SOC_ENUM_EXT("DSP2 Firmware", wm_adsp_fw_enum[1], 317 wm_adsp_fw_get, wm_adsp_fw_put), 318 SOC_ENUM("DSP2 Rate", wm_adsp2_rate_enum[1]), 319 SOC_ENUM_EXT("DSP3 Firmware", wm_adsp_fw_enum[2], 320 wm_adsp_fw_get, wm_adsp_fw_put), 321 SOC_ENUM("DSP3 Rate", wm_adsp2_rate_enum[2]), 322 SOC_ENUM_EXT("DSP4 Firmware", wm_adsp_fw_enum[3], 323 wm_adsp_fw_get, wm_adsp_fw_put), 324 SOC_ENUM("DSP4 Rate", wm_adsp2_rate_enum[3]), 325 }; 326 EXPORT_SYMBOL_GPL(wm_adsp2_fw_controls); 327 #endif 328 329 static struct wm_adsp_region const *wm_adsp_find_region(struct wm_adsp *dsp, 330 int type) 331 { 332 int i; 333 334 for (i = 0; i < dsp->num_mems; i++) 335 if (dsp->mem[i].type == type) 336 return &dsp->mem[i]; 337 338 return NULL; 339 } 340 341 static unsigned int wm_adsp_region_to_reg(struct wm_adsp_region const *region, 342 unsigned int offset) 343 { 344 switch (region->type) { 345 case WMFW_ADSP1_PM: 346 return region->base + (offset * 3); 347 case WMFW_ADSP1_DM: 348 return region->base + (offset * 2); 349 case WMFW_ADSP2_XM: 350 return region->base + (offset * 2); 351 case WMFW_ADSP2_YM: 352 return region->base + (offset * 2); 353 case WMFW_ADSP1_ZM: 354 return region->base + (offset * 2); 355 default: 356 WARN_ON(NULL != "Unknown memory region type"); 357 return offset; 358 } 359 } 360 361 static int wm_coeff_info(struct snd_kcontrol *kcontrol, 362 struct snd_ctl_elem_info *uinfo) 363 { 364 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 365 366 uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES; 367 uinfo->count = ctl->len; 368 return 0; 369 } 370 371 static int wm_coeff_write_control(struct snd_kcontrol *kcontrol, 372 const void *buf, size_t len) 373 { 374 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 375 struct wm_adsp_alg_region *region = &ctl->region; 376 const struct wm_adsp_region *mem; 377 struct wm_adsp *adsp = ctl->adsp; 378 void *scratch; 379 int ret; 380 unsigned int reg; 381 382 mem = wm_adsp_find_region(adsp, region->type); 383 if (!mem) { 384 adsp_err(adsp, "No base for region %x\n", 385 region->type); 386 return -EINVAL; 387 } 388 389 reg = ctl->region.base; 390 reg = wm_adsp_region_to_reg(mem, reg); 391 392 scratch = kmemdup(buf, ctl->len, GFP_KERNEL | GFP_DMA); 393 if (!scratch) 394 return -ENOMEM; 395 396 ret = regmap_raw_write(adsp->regmap, reg, scratch, 397 ctl->len); 398 if (ret) { 399 adsp_err(adsp, "Failed to write %zu bytes to %x\n", 400 ctl->len, reg); 401 kfree(scratch); 402 return ret; 403 } 404 405 kfree(scratch); 406 407 return 0; 408 } 409 410 static int wm_coeff_put(struct snd_kcontrol *kcontrol, 411 struct snd_ctl_elem_value *ucontrol) 412 { 413 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 414 char *p = ucontrol->value.bytes.data; 415 416 memcpy(ctl->cache, p, ctl->len); 417 418 if (!ctl->enabled) { 419 ctl->set = 1; 420 return 0; 421 } 422 423 return wm_coeff_write_control(kcontrol, p, ctl->len); 424 } 425 426 static int wm_coeff_read_control(struct snd_kcontrol *kcontrol, 427 void *buf, size_t len) 428 { 429 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 430 struct wm_adsp_alg_region *region = &ctl->region; 431 const struct wm_adsp_region *mem; 432 struct wm_adsp *adsp = ctl->adsp; 433 void *scratch; 434 int ret; 435 unsigned int reg; 436 437 mem = wm_adsp_find_region(adsp, region->type); 438 if (!mem) { 439 adsp_err(adsp, "No base for region %x\n", 440 region->type); 441 return -EINVAL; 442 } 443 444 reg = ctl->region.base; 445 reg = wm_adsp_region_to_reg(mem, reg); 446 447 scratch = kmalloc(ctl->len, GFP_KERNEL | GFP_DMA); 448 if (!scratch) 449 return -ENOMEM; 450 451 ret = regmap_raw_read(adsp->regmap, reg, scratch, ctl->len); 452 if (ret) { 453 adsp_err(adsp, "Failed to read %zu bytes from %x\n", 454 ctl->len, reg); 455 kfree(scratch); 456 return ret; 457 } 458 459 memcpy(buf, scratch, ctl->len); 460 kfree(scratch); 461 462 return 0; 463 } 464 465 static int wm_coeff_get(struct snd_kcontrol *kcontrol, 466 struct snd_ctl_elem_value *ucontrol) 467 { 468 struct wm_coeff_ctl *ctl = (struct wm_coeff_ctl *)kcontrol->private_value; 469 char *p = ucontrol->value.bytes.data; 470 471 memcpy(p, ctl->cache, ctl->len); 472 return 0; 473 } 474 475 struct wmfw_ctl_work { 476 struct wm_adsp *adsp; 477 struct wm_coeff_ctl *ctl; 478 struct work_struct work; 479 }; 480 481 static int wmfw_add_ctl(struct wm_adsp *adsp, struct wm_coeff_ctl *ctl) 482 { 483 struct snd_kcontrol_new *kcontrol; 484 int ret; 485 486 if (!ctl || !ctl->name) 487 return -EINVAL; 488 489 kcontrol = kzalloc(sizeof(*kcontrol), GFP_KERNEL); 490 if (!kcontrol) 491 return -ENOMEM; 492 kcontrol->iface = SNDRV_CTL_ELEM_IFACE_MIXER; 493 494 kcontrol->name = ctl->name; 495 kcontrol->info = wm_coeff_info; 496 kcontrol->get = wm_coeff_get; 497 kcontrol->put = wm_coeff_put; 498 kcontrol->private_value = (unsigned long)ctl; 499 500 ret = snd_soc_add_card_controls(adsp->card, 501 kcontrol, 1); 502 if (ret < 0) 503 goto err_kcontrol; 504 505 kfree(kcontrol); 506 507 ctl->kcontrol = snd_soc_card_get_kcontrol(adsp->card, 508 ctl->name); 509 510 list_add(&ctl->list, &adsp->ctl_list); 511 return 0; 512 513 err_kcontrol: 514 kfree(kcontrol); 515 return ret; 516 } 517 518 static int wm_adsp_load(struct wm_adsp *dsp) 519 { 520 LIST_HEAD(buf_list); 521 const struct firmware *firmware; 522 struct regmap *regmap = dsp->regmap; 523 unsigned int pos = 0; 524 const struct wmfw_header *header; 525 const struct wmfw_adsp1_sizes *adsp1_sizes; 526 const struct wmfw_adsp2_sizes *adsp2_sizes; 527 const struct wmfw_footer *footer; 528 const struct wmfw_region *region; 529 const struct wm_adsp_region *mem; 530 const char *region_name; 531 char *file, *text; 532 struct wm_adsp_buf *buf; 533 unsigned int reg; 534 int regions = 0; 535 int ret, offset, type, sizes; 536 537 file = kzalloc(PAGE_SIZE, GFP_KERNEL); 538 if (file == NULL) 539 return -ENOMEM; 540 541 snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.wmfw", dsp->part, dsp->num, 542 wm_adsp_fw[dsp->fw].file); 543 file[PAGE_SIZE - 1] = '\0'; 544 545 ret = request_firmware(&firmware, file, dsp->dev); 546 if (ret != 0) { 547 adsp_err(dsp, "Failed to request '%s'\n", file); 548 goto out; 549 } 550 ret = -EINVAL; 551 552 pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); 553 if (pos >= firmware->size) { 554 adsp_err(dsp, "%s: file too short, %zu bytes\n", 555 file, firmware->size); 556 goto out_fw; 557 } 558 559 header = (void*)&firmware->data[0]; 560 561 if (memcmp(&header->magic[0], "WMFW", 4) != 0) { 562 adsp_err(dsp, "%s: invalid magic\n", file); 563 goto out_fw; 564 } 565 566 if (header->ver != 0) { 567 adsp_err(dsp, "%s: unknown file format %d\n", 568 file, header->ver); 569 goto out_fw; 570 } 571 572 if (header->core != dsp->type) { 573 adsp_err(dsp, "%s: invalid core %d != %d\n", 574 file, header->core, dsp->type); 575 goto out_fw; 576 } 577 578 switch (dsp->type) { 579 case WMFW_ADSP1: 580 pos = sizeof(*header) + sizeof(*adsp1_sizes) + sizeof(*footer); 581 adsp1_sizes = (void *)&(header[1]); 582 footer = (void *)&(adsp1_sizes[1]); 583 sizes = sizeof(*adsp1_sizes); 584 585 adsp_dbg(dsp, "%s: %d DM, %d PM, %d ZM\n", 586 file, le32_to_cpu(adsp1_sizes->dm), 587 le32_to_cpu(adsp1_sizes->pm), 588 le32_to_cpu(adsp1_sizes->zm)); 589 break; 590 591 case WMFW_ADSP2: 592 pos = sizeof(*header) + sizeof(*adsp2_sizes) + sizeof(*footer); 593 adsp2_sizes = (void *)&(header[1]); 594 footer = (void *)&(adsp2_sizes[1]); 595 sizes = sizeof(*adsp2_sizes); 596 597 adsp_dbg(dsp, "%s: %d XM, %d YM %d PM, %d ZM\n", 598 file, le32_to_cpu(adsp2_sizes->xm), 599 le32_to_cpu(adsp2_sizes->ym), 600 le32_to_cpu(adsp2_sizes->pm), 601 le32_to_cpu(adsp2_sizes->zm)); 602 break; 603 604 default: 605 BUG_ON(NULL == "Unknown DSP type"); 606 goto out_fw; 607 } 608 609 if (le32_to_cpu(header->len) != sizeof(*header) + 610 sizes + sizeof(*footer)) { 611 adsp_err(dsp, "%s: unexpected header length %d\n", 612 file, le32_to_cpu(header->len)); 613 goto out_fw; 614 } 615 616 adsp_dbg(dsp, "%s: timestamp %llu\n", file, 617 le64_to_cpu(footer->timestamp)); 618 619 while (pos < firmware->size && 620 pos - firmware->size > sizeof(*region)) { 621 region = (void *)&(firmware->data[pos]); 622 region_name = "Unknown"; 623 reg = 0; 624 text = NULL; 625 offset = le32_to_cpu(region->offset) & 0xffffff; 626 type = be32_to_cpu(region->type) & 0xff; 627 mem = wm_adsp_find_region(dsp, type); 628 629 switch (type) { 630 case WMFW_NAME_TEXT: 631 region_name = "Firmware name"; 632 text = kzalloc(le32_to_cpu(region->len) + 1, 633 GFP_KERNEL); 634 break; 635 case WMFW_INFO_TEXT: 636 region_name = "Information"; 637 text = kzalloc(le32_to_cpu(region->len) + 1, 638 GFP_KERNEL); 639 break; 640 case WMFW_ABSOLUTE: 641 region_name = "Absolute"; 642 reg = offset; 643 break; 644 case WMFW_ADSP1_PM: 645 BUG_ON(!mem); 646 region_name = "PM"; 647 reg = wm_adsp_region_to_reg(mem, offset); 648 break; 649 case WMFW_ADSP1_DM: 650 BUG_ON(!mem); 651 region_name = "DM"; 652 reg = wm_adsp_region_to_reg(mem, offset); 653 break; 654 case WMFW_ADSP2_XM: 655 BUG_ON(!mem); 656 region_name = "XM"; 657 reg = wm_adsp_region_to_reg(mem, offset); 658 break; 659 case WMFW_ADSP2_YM: 660 BUG_ON(!mem); 661 region_name = "YM"; 662 reg = wm_adsp_region_to_reg(mem, offset); 663 break; 664 case WMFW_ADSP1_ZM: 665 BUG_ON(!mem); 666 region_name = "ZM"; 667 reg = wm_adsp_region_to_reg(mem, offset); 668 break; 669 default: 670 adsp_warn(dsp, 671 "%s.%d: Unknown region type %x at %d(%x)\n", 672 file, regions, type, pos, pos); 673 break; 674 } 675 676 adsp_dbg(dsp, "%s.%d: %d bytes at %d in %s\n", file, 677 regions, le32_to_cpu(region->len), offset, 678 region_name); 679 680 if (text) { 681 memcpy(text, region->data, le32_to_cpu(region->len)); 682 adsp_info(dsp, "%s: %s\n", file, text); 683 kfree(text); 684 } 685 686 if (reg) { 687 buf = wm_adsp_buf_alloc(region->data, 688 le32_to_cpu(region->len), 689 &buf_list); 690 if (!buf) { 691 adsp_err(dsp, "Out of memory\n"); 692 return -ENOMEM; 693 } 694 695 ret = regmap_raw_write_async(regmap, reg, buf->buf, 696 le32_to_cpu(region->len)); 697 if (ret != 0) { 698 adsp_err(dsp, 699 "%s.%d: Failed to write %d bytes at %d in %s: %d\n", 700 file, regions, 701 le32_to_cpu(region->len), offset, 702 region_name, ret); 703 goto out_fw; 704 } 705 } 706 707 pos += le32_to_cpu(region->len) + sizeof(*region); 708 regions++; 709 } 710 711 ret = regmap_async_complete(regmap); 712 if (ret != 0) { 713 adsp_err(dsp, "Failed to complete async write: %d\n", ret); 714 goto out_fw; 715 } 716 717 if (pos > firmware->size) 718 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", 719 file, regions, pos - firmware->size); 720 721 out_fw: 722 regmap_async_complete(regmap); 723 wm_adsp_buf_free(&buf_list); 724 release_firmware(firmware); 725 out: 726 kfree(file); 727 728 return ret; 729 } 730 731 static int wm_coeff_init_control_caches(struct wm_adsp *adsp) 732 { 733 struct wm_coeff_ctl *ctl; 734 int ret; 735 736 list_for_each_entry(ctl, &adsp->ctl_list, list) { 737 if (!ctl->enabled || ctl->set) 738 continue; 739 ret = wm_coeff_read_control(ctl->kcontrol, 740 ctl->cache, 741 ctl->len); 742 if (ret < 0) 743 return ret; 744 } 745 746 return 0; 747 } 748 749 static int wm_coeff_sync_controls(struct wm_adsp *adsp) 750 { 751 struct wm_coeff_ctl *ctl; 752 int ret; 753 754 list_for_each_entry(ctl, &adsp->ctl_list, list) { 755 if (!ctl->enabled) 756 continue; 757 if (ctl->set) { 758 ret = wm_coeff_write_control(ctl->kcontrol, 759 ctl->cache, 760 ctl->len); 761 if (ret < 0) 762 return ret; 763 } 764 } 765 766 return 0; 767 } 768 769 static void wm_adsp_ctl_work(struct work_struct *work) 770 { 771 struct wmfw_ctl_work *ctl_work = container_of(work, 772 struct wmfw_ctl_work, 773 work); 774 775 wmfw_add_ctl(ctl_work->adsp, ctl_work->ctl); 776 kfree(ctl_work); 777 } 778 779 static int wm_adsp_create_control(struct wm_adsp *dsp, 780 const struct wm_adsp_alg_region *region) 781 782 { 783 struct wm_coeff_ctl *ctl; 784 struct wmfw_ctl_work *ctl_work; 785 char *name; 786 char *region_name; 787 int ret; 788 789 name = kmalloc(PAGE_SIZE, GFP_KERNEL); 790 if (!name) 791 return -ENOMEM; 792 793 switch (region->type) { 794 case WMFW_ADSP1_PM: 795 region_name = "PM"; 796 break; 797 case WMFW_ADSP1_DM: 798 region_name = "DM"; 799 break; 800 case WMFW_ADSP2_XM: 801 region_name = "XM"; 802 break; 803 case WMFW_ADSP2_YM: 804 region_name = "YM"; 805 break; 806 case WMFW_ADSP1_ZM: 807 region_name = "ZM"; 808 break; 809 default: 810 ret = -EINVAL; 811 goto err_name; 812 } 813 814 snprintf(name, PAGE_SIZE, "DSP%d %s %x", 815 dsp->num, region_name, region->alg); 816 817 list_for_each_entry(ctl, &dsp->ctl_list, 818 list) { 819 if (!strcmp(ctl->name, name)) { 820 if (!ctl->enabled) 821 ctl->enabled = 1; 822 goto found; 823 } 824 } 825 826 ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); 827 if (!ctl) { 828 ret = -ENOMEM; 829 goto err_name; 830 } 831 ctl->region = *region; 832 ctl->name = kmemdup(name, strlen(name) + 1, GFP_KERNEL); 833 if (!ctl->name) { 834 ret = -ENOMEM; 835 goto err_ctl; 836 } 837 ctl->enabled = 1; 838 ctl->set = 0; 839 ctl->ops.xget = wm_coeff_get; 840 ctl->ops.xput = wm_coeff_put; 841 ctl->adsp = dsp; 842 843 ctl->len = region->len; 844 ctl->cache = kzalloc(ctl->len, GFP_KERNEL); 845 if (!ctl->cache) { 846 ret = -ENOMEM; 847 goto err_ctl_name; 848 } 849 850 ctl_work = kzalloc(sizeof(*ctl_work), GFP_KERNEL); 851 if (!ctl_work) { 852 ret = -ENOMEM; 853 goto err_ctl_cache; 854 } 855 856 ctl_work->adsp = dsp; 857 ctl_work->ctl = ctl; 858 INIT_WORK(&ctl_work->work, wm_adsp_ctl_work); 859 schedule_work(&ctl_work->work); 860 861 found: 862 kfree(name); 863 864 return 0; 865 866 err_ctl_cache: 867 kfree(ctl->cache); 868 err_ctl_name: 869 kfree(ctl->name); 870 err_ctl: 871 kfree(ctl); 872 err_name: 873 kfree(name); 874 return ret; 875 } 876 877 static int wm_adsp_setup_algs(struct wm_adsp *dsp) 878 { 879 struct regmap *regmap = dsp->regmap; 880 struct wmfw_adsp1_id_hdr adsp1_id; 881 struct wmfw_adsp2_id_hdr adsp2_id; 882 struct wmfw_adsp1_alg_hdr *adsp1_alg; 883 struct wmfw_adsp2_alg_hdr *adsp2_alg; 884 void *alg, *buf; 885 struct wm_adsp_alg_region *region; 886 const struct wm_adsp_region *mem; 887 unsigned int pos, term; 888 size_t algs, buf_size; 889 __be32 val; 890 int i, ret; 891 892 switch (dsp->type) { 893 case WMFW_ADSP1: 894 mem = wm_adsp_find_region(dsp, WMFW_ADSP1_DM); 895 break; 896 case WMFW_ADSP2: 897 mem = wm_adsp_find_region(dsp, WMFW_ADSP2_XM); 898 break; 899 default: 900 mem = NULL; 901 break; 902 } 903 904 if (mem == NULL) { 905 BUG_ON(mem != NULL); 906 return -EINVAL; 907 } 908 909 switch (dsp->type) { 910 case WMFW_ADSP1: 911 ret = regmap_raw_read(regmap, mem->base, &adsp1_id, 912 sizeof(adsp1_id)); 913 if (ret != 0) { 914 adsp_err(dsp, "Failed to read algorithm info: %d\n", 915 ret); 916 return ret; 917 } 918 919 buf = &adsp1_id; 920 buf_size = sizeof(adsp1_id); 921 922 algs = be32_to_cpu(adsp1_id.algs); 923 dsp->fw_id = be32_to_cpu(adsp1_id.fw.id); 924 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", 925 dsp->fw_id, 926 (be32_to_cpu(adsp1_id.fw.ver) & 0xff0000) >> 16, 927 (be32_to_cpu(adsp1_id.fw.ver) & 0xff00) >> 8, 928 be32_to_cpu(adsp1_id.fw.ver) & 0xff, 929 algs); 930 931 region = kzalloc(sizeof(*region), GFP_KERNEL); 932 if (!region) 933 return -ENOMEM; 934 region->type = WMFW_ADSP1_ZM; 935 region->alg = be32_to_cpu(adsp1_id.fw.id); 936 region->base = be32_to_cpu(adsp1_id.zm); 937 list_add_tail(®ion->list, &dsp->alg_regions); 938 939 region = kzalloc(sizeof(*region), GFP_KERNEL); 940 if (!region) 941 return -ENOMEM; 942 region->type = WMFW_ADSP1_DM; 943 region->alg = be32_to_cpu(adsp1_id.fw.id); 944 region->base = be32_to_cpu(adsp1_id.dm); 945 list_add_tail(®ion->list, &dsp->alg_regions); 946 947 pos = sizeof(adsp1_id) / 2; 948 term = pos + ((sizeof(*adsp1_alg) * algs) / 2); 949 break; 950 951 case WMFW_ADSP2: 952 ret = regmap_raw_read(regmap, mem->base, &adsp2_id, 953 sizeof(adsp2_id)); 954 if (ret != 0) { 955 adsp_err(dsp, "Failed to read algorithm info: %d\n", 956 ret); 957 return ret; 958 } 959 960 buf = &adsp2_id; 961 buf_size = sizeof(adsp2_id); 962 963 algs = be32_to_cpu(adsp2_id.algs); 964 dsp->fw_id = be32_to_cpu(adsp2_id.fw.id); 965 adsp_info(dsp, "Firmware: %x v%d.%d.%d, %zu algorithms\n", 966 dsp->fw_id, 967 (be32_to_cpu(adsp2_id.fw.ver) & 0xff0000) >> 16, 968 (be32_to_cpu(adsp2_id.fw.ver) & 0xff00) >> 8, 969 be32_to_cpu(adsp2_id.fw.ver) & 0xff, 970 algs); 971 972 region = kzalloc(sizeof(*region), GFP_KERNEL); 973 if (!region) 974 return -ENOMEM; 975 region->type = WMFW_ADSP2_XM; 976 region->alg = be32_to_cpu(adsp2_id.fw.id); 977 region->base = be32_to_cpu(adsp2_id.xm); 978 list_add_tail(®ion->list, &dsp->alg_regions); 979 980 region = kzalloc(sizeof(*region), GFP_KERNEL); 981 if (!region) 982 return -ENOMEM; 983 region->type = WMFW_ADSP2_YM; 984 region->alg = be32_to_cpu(adsp2_id.fw.id); 985 region->base = be32_to_cpu(adsp2_id.ym); 986 list_add_tail(®ion->list, &dsp->alg_regions); 987 988 region = kzalloc(sizeof(*region), GFP_KERNEL); 989 if (!region) 990 return -ENOMEM; 991 region->type = WMFW_ADSP2_ZM; 992 region->alg = be32_to_cpu(adsp2_id.fw.id); 993 region->base = be32_to_cpu(adsp2_id.zm); 994 list_add_tail(®ion->list, &dsp->alg_regions); 995 996 pos = sizeof(adsp2_id) / 2; 997 term = pos + ((sizeof(*adsp2_alg) * algs) / 2); 998 break; 999 1000 default: 1001 BUG_ON(NULL == "Unknown DSP type"); 1002 return -EINVAL; 1003 } 1004 1005 if (algs == 0) { 1006 adsp_err(dsp, "No algorithms\n"); 1007 return -EINVAL; 1008 } 1009 1010 if (algs > 1024) { 1011 adsp_err(dsp, "Algorithm count %zx excessive\n", algs); 1012 print_hex_dump_bytes(dev_name(dsp->dev), DUMP_PREFIX_OFFSET, 1013 buf, buf_size); 1014 return -EINVAL; 1015 } 1016 1017 /* Read the terminator first to validate the length */ 1018 ret = regmap_raw_read(regmap, mem->base + term, &val, sizeof(val)); 1019 if (ret != 0) { 1020 adsp_err(dsp, "Failed to read algorithm list end: %d\n", 1021 ret); 1022 return ret; 1023 } 1024 1025 if (be32_to_cpu(val) != 0xbedead) 1026 adsp_warn(dsp, "Algorithm list end %x 0x%x != 0xbeadead\n", 1027 term, be32_to_cpu(val)); 1028 1029 alg = kzalloc((term - pos) * 2, GFP_KERNEL | GFP_DMA); 1030 if (!alg) 1031 return -ENOMEM; 1032 1033 ret = regmap_raw_read(regmap, mem->base + pos, alg, (term - pos) * 2); 1034 if (ret != 0) { 1035 adsp_err(dsp, "Failed to read algorithm list: %d\n", 1036 ret); 1037 goto out; 1038 } 1039 1040 adsp1_alg = alg; 1041 adsp2_alg = alg; 1042 1043 for (i = 0; i < algs; i++) { 1044 switch (dsp->type) { 1045 case WMFW_ADSP1: 1046 adsp_info(dsp, "%d: ID %x v%d.%d.%d DM@%x ZM@%x\n", 1047 i, be32_to_cpu(adsp1_alg[i].alg.id), 1048 (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff0000) >> 16, 1049 (be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff00) >> 8, 1050 be32_to_cpu(adsp1_alg[i].alg.ver) & 0xff, 1051 be32_to_cpu(adsp1_alg[i].dm), 1052 be32_to_cpu(adsp1_alg[i].zm)); 1053 1054 region = kzalloc(sizeof(*region), GFP_KERNEL); 1055 if (!region) 1056 return -ENOMEM; 1057 region->type = WMFW_ADSP1_DM; 1058 region->alg = be32_to_cpu(adsp1_alg[i].alg.id); 1059 region->base = be32_to_cpu(adsp1_alg[i].dm); 1060 region->len = 0; 1061 list_add_tail(®ion->list, &dsp->alg_regions); 1062 if (i + 1 < algs) { 1063 region->len = be32_to_cpu(adsp1_alg[i + 1].dm); 1064 region->len -= be32_to_cpu(adsp1_alg[i].dm); 1065 wm_adsp_create_control(dsp, region); 1066 } else { 1067 adsp_warn(dsp, "Missing length info for region DM with ID %x\n", 1068 be32_to_cpu(adsp1_alg[i].alg.id)); 1069 } 1070 1071 region = kzalloc(sizeof(*region), GFP_KERNEL); 1072 if (!region) 1073 return -ENOMEM; 1074 region->type = WMFW_ADSP1_ZM; 1075 region->alg = be32_to_cpu(adsp1_alg[i].alg.id); 1076 region->base = be32_to_cpu(adsp1_alg[i].zm); 1077 region->len = 0; 1078 list_add_tail(®ion->list, &dsp->alg_regions); 1079 if (i + 1 < algs) { 1080 region->len = be32_to_cpu(adsp1_alg[i + 1].zm); 1081 region->len -= be32_to_cpu(adsp1_alg[i].zm); 1082 wm_adsp_create_control(dsp, region); 1083 } else { 1084 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", 1085 be32_to_cpu(adsp1_alg[i].alg.id)); 1086 } 1087 break; 1088 1089 case WMFW_ADSP2: 1090 adsp_info(dsp, 1091 "%d: ID %x v%d.%d.%d XM@%x YM@%x ZM@%x\n", 1092 i, be32_to_cpu(adsp2_alg[i].alg.id), 1093 (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff0000) >> 16, 1094 (be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff00) >> 8, 1095 be32_to_cpu(adsp2_alg[i].alg.ver) & 0xff, 1096 be32_to_cpu(adsp2_alg[i].xm), 1097 be32_to_cpu(adsp2_alg[i].ym), 1098 be32_to_cpu(adsp2_alg[i].zm)); 1099 1100 region = kzalloc(sizeof(*region), GFP_KERNEL); 1101 if (!region) 1102 return -ENOMEM; 1103 region->type = WMFW_ADSP2_XM; 1104 region->alg = be32_to_cpu(adsp2_alg[i].alg.id); 1105 region->base = be32_to_cpu(adsp2_alg[i].xm); 1106 region->len = 0; 1107 list_add_tail(®ion->list, &dsp->alg_regions); 1108 if (i + 1 < algs) { 1109 region->len = be32_to_cpu(adsp2_alg[i + 1].xm); 1110 region->len -= be32_to_cpu(adsp2_alg[i].xm); 1111 wm_adsp_create_control(dsp, region); 1112 } else { 1113 adsp_warn(dsp, "Missing length info for region XM with ID %x\n", 1114 be32_to_cpu(adsp2_alg[i].alg.id)); 1115 } 1116 1117 region = kzalloc(sizeof(*region), GFP_KERNEL); 1118 if (!region) 1119 return -ENOMEM; 1120 region->type = WMFW_ADSP2_YM; 1121 region->alg = be32_to_cpu(adsp2_alg[i].alg.id); 1122 region->base = be32_to_cpu(adsp2_alg[i].ym); 1123 region->len = 0; 1124 list_add_tail(®ion->list, &dsp->alg_regions); 1125 if (i + 1 < algs) { 1126 region->len = be32_to_cpu(adsp2_alg[i + 1].ym); 1127 region->len -= be32_to_cpu(adsp2_alg[i].ym); 1128 wm_adsp_create_control(dsp, region); 1129 } else { 1130 adsp_warn(dsp, "Missing length info for region YM with ID %x\n", 1131 be32_to_cpu(adsp2_alg[i].alg.id)); 1132 } 1133 1134 region = kzalloc(sizeof(*region), GFP_KERNEL); 1135 if (!region) 1136 return -ENOMEM; 1137 region->type = WMFW_ADSP2_ZM; 1138 region->alg = be32_to_cpu(adsp2_alg[i].alg.id); 1139 region->base = be32_to_cpu(adsp2_alg[i].zm); 1140 region->len = 0; 1141 list_add_tail(®ion->list, &dsp->alg_regions); 1142 if (i + 1 < algs) { 1143 region->len = be32_to_cpu(adsp2_alg[i + 1].zm); 1144 region->len -= be32_to_cpu(adsp2_alg[i].zm); 1145 wm_adsp_create_control(dsp, region); 1146 } else { 1147 adsp_warn(dsp, "Missing length info for region ZM with ID %x\n", 1148 be32_to_cpu(adsp2_alg[i].alg.id)); 1149 } 1150 break; 1151 } 1152 } 1153 1154 out: 1155 kfree(alg); 1156 return ret; 1157 } 1158 1159 static int wm_adsp_load_coeff(struct wm_adsp *dsp) 1160 { 1161 LIST_HEAD(buf_list); 1162 struct regmap *regmap = dsp->regmap; 1163 struct wmfw_coeff_hdr *hdr; 1164 struct wmfw_coeff_item *blk; 1165 const struct firmware *firmware; 1166 const struct wm_adsp_region *mem; 1167 struct wm_adsp_alg_region *alg_region; 1168 const char *region_name; 1169 int ret, pos, blocks, type, offset, reg; 1170 char *file; 1171 struct wm_adsp_buf *buf; 1172 int tmp; 1173 1174 file = kzalloc(PAGE_SIZE, GFP_KERNEL); 1175 if (file == NULL) 1176 return -ENOMEM; 1177 1178 snprintf(file, PAGE_SIZE, "%s-dsp%d-%s.bin", dsp->part, dsp->num, 1179 wm_adsp_fw[dsp->fw].file); 1180 file[PAGE_SIZE - 1] = '\0'; 1181 1182 ret = request_firmware(&firmware, file, dsp->dev); 1183 if (ret != 0) { 1184 adsp_warn(dsp, "Failed to request '%s'\n", file); 1185 ret = 0; 1186 goto out; 1187 } 1188 ret = -EINVAL; 1189 1190 if (sizeof(*hdr) >= firmware->size) { 1191 adsp_err(dsp, "%s: file too short, %zu bytes\n", 1192 file, firmware->size); 1193 goto out_fw; 1194 } 1195 1196 hdr = (void*)&firmware->data[0]; 1197 if (memcmp(hdr->magic, "WMDR", 4) != 0) { 1198 adsp_err(dsp, "%s: invalid magic\n", file); 1199 goto out_fw; 1200 } 1201 1202 switch (be32_to_cpu(hdr->rev) & 0xff) { 1203 case 1: 1204 break; 1205 default: 1206 adsp_err(dsp, "%s: Unsupported coefficient file format %d\n", 1207 file, be32_to_cpu(hdr->rev) & 0xff); 1208 ret = -EINVAL; 1209 goto out_fw; 1210 } 1211 1212 adsp_dbg(dsp, "%s: v%d.%d.%d\n", file, 1213 (le32_to_cpu(hdr->ver) >> 16) & 0xff, 1214 (le32_to_cpu(hdr->ver) >> 8) & 0xff, 1215 le32_to_cpu(hdr->ver) & 0xff); 1216 1217 pos = le32_to_cpu(hdr->len); 1218 1219 blocks = 0; 1220 while (pos < firmware->size && 1221 pos - firmware->size > sizeof(*blk)) { 1222 blk = (void*)(&firmware->data[pos]); 1223 1224 type = le16_to_cpu(blk->type); 1225 offset = le16_to_cpu(blk->offset); 1226 1227 adsp_dbg(dsp, "%s.%d: %x v%d.%d.%d\n", 1228 file, blocks, le32_to_cpu(blk->id), 1229 (le32_to_cpu(blk->ver) >> 16) & 0xff, 1230 (le32_to_cpu(blk->ver) >> 8) & 0xff, 1231 le32_to_cpu(blk->ver) & 0xff); 1232 adsp_dbg(dsp, "%s.%d: %d bytes at 0x%x in %x\n", 1233 file, blocks, le32_to_cpu(blk->len), offset, type); 1234 1235 reg = 0; 1236 region_name = "Unknown"; 1237 switch (type) { 1238 case (WMFW_NAME_TEXT << 8): 1239 case (WMFW_INFO_TEXT << 8): 1240 break; 1241 case (WMFW_ABSOLUTE << 8): 1242 /* 1243 * Old files may use this for global 1244 * coefficients. 1245 */ 1246 if (le32_to_cpu(blk->id) == dsp->fw_id && 1247 offset == 0) { 1248 region_name = "global coefficients"; 1249 mem = wm_adsp_find_region(dsp, type); 1250 if (!mem) { 1251 adsp_err(dsp, "No ZM\n"); 1252 break; 1253 } 1254 reg = wm_adsp_region_to_reg(mem, 0); 1255 1256 } else { 1257 region_name = "register"; 1258 reg = offset; 1259 } 1260 break; 1261 1262 case WMFW_ADSP1_DM: 1263 case WMFW_ADSP1_ZM: 1264 case WMFW_ADSP2_XM: 1265 case WMFW_ADSP2_YM: 1266 adsp_dbg(dsp, "%s.%d: %d bytes in %x for %x\n", 1267 file, blocks, le32_to_cpu(blk->len), 1268 type, le32_to_cpu(blk->id)); 1269 1270 mem = wm_adsp_find_region(dsp, type); 1271 if (!mem) { 1272 adsp_err(dsp, "No base for region %x\n", type); 1273 break; 1274 } 1275 1276 reg = 0; 1277 list_for_each_entry(alg_region, 1278 &dsp->alg_regions, list) { 1279 if (le32_to_cpu(blk->id) == alg_region->alg && 1280 type == alg_region->type) { 1281 reg = alg_region->base; 1282 reg = wm_adsp_region_to_reg(mem, 1283 reg); 1284 reg += offset; 1285 } 1286 } 1287 1288 if (reg == 0) 1289 adsp_err(dsp, "No %x for algorithm %x\n", 1290 type, le32_to_cpu(blk->id)); 1291 break; 1292 1293 default: 1294 adsp_err(dsp, "%s.%d: Unknown region type %x at %d\n", 1295 file, blocks, type, pos); 1296 break; 1297 } 1298 1299 if (reg) { 1300 buf = wm_adsp_buf_alloc(blk->data, 1301 le32_to_cpu(blk->len), 1302 &buf_list); 1303 if (!buf) { 1304 adsp_err(dsp, "Out of memory\n"); 1305 ret = -ENOMEM; 1306 goto out_fw; 1307 } 1308 1309 adsp_dbg(dsp, "%s.%d: Writing %d bytes at %x\n", 1310 file, blocks, le32_to_cpu(blk->len), 1311 reg); 1312 ret = regmap_raw_write_async(regmap, reg, buf->buf, 1313 le32_to_cpu(blk->len)); 1314 if (ret != 0) { 1315 adsp_err(dsp, 1316 "%s.%d: Failed to write to %x in %s\n", 1317 file, blocks, reg, region_name); 1318 } 1319 } 1320 1321 tmp = le32_to_cpu(blk->len) % 4; 1322 if (tmp) 1323 pos += le32_to_cpu(blk->len) + (4 - tmp) + sizeof(*blk); 1324 else 1325 pos += le32_to_cpu(blk->len) + sizeof(*blk); 1326 1327 blocks++; 1328 } 1329 1330 ret = regmap_async_complete(regmap); 1331 if (ret != 0) 1332 adsp_err(dsp, "Failed to complete async write: %d\n", ret); 1333 1334 if (pos > firmware->size) 1335 adsp_warn(dsp, "%s.%d: %zu bytes at end of file\n", 1336 file, blocks, pos - firmware->size); 1337 1338 out_fw: 1339 release_firmware(firmware); 1340 wm_adsp_buf_free(&buf_list); 1341 out: 1342 kfree(file); 1343 return ret; 1344 } 1345 1346 int wm_adsp1_init(struct wm_adsp *adsp) 1347 { 1348 INIT_LIST_HEAD(&adsp->alg_regions); 1349 1350 return 0; 1351 } 1352 EXPORT_SYMBOL_GPL(wm_adsp1_init); 1353 1354 int wm_adsp1_event(struct snd_soc_dapm_widget *w, 1355 struct snd_kcontrol *kcontrol, 1356 int event) 1357 { 1358 struct snd_soc_codec *codec = w->codec; 1359 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 1360 struct wm_adsp *dsp = &dsps[w->shift]; 1361 struct wm_coeff_ctl *ctl; 1362 int ret; 1363 int val; 1364 1365 dsp->card = codec->card; 1366 1367 switch (event) { 1368 case SND_SOC_DAPM_POST_PMU: 1369 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1370 ADSP1_SYS_ENA, ADSP1_SYS_ENA); 1371 1372 /* 1373 * For simplicity set the DSP clock rate to be the 1374 * SYSCLK rate rather than making it configurable. 1375 */ 1376 if(dsp->sysclk_reg) { 1377 ret = regmap_read(dsp->regmap, dsp->sysclk_reg, &val); 1378 if (ret != 0) { 1379 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", 1380 ret); 1381 return ret; 1382 } 1383 1384 val = (val & dsp->sysclk_mask) 1385 >> dsp->sysclk_shift; 1386 1387 ret = regmap_update_bits(dsp->regmap, 1388 dsp->base + ADSP1_CONTROL_31, 1389 ADSP1_CLK_SEL_MASK, val); 1390 if (ret != 0) { 1391 adsp_err(dsp, "Failed to set clock rate: %d\n", 1392 ret); 1393 return ret; 1394 } 1395 } 1396 1397 ret = wm_adsp_load(dsp); 1398 if (ret != 0) 1399 goto err; 1400 1401 ret = wm_adsp_setup_algs(dsp); 1402 if (ret != 0) 1403 goto err; 1404 1405 ret = wm_adsp_load_coeff(dsp); 1406 if (ret != 0) 1407 goto err; 1408 1409 /* Initialize caches for enabled and unset controls */ 1410 ret = wm_coeff_init_control_caches(dsp); 1411 if (ret != 0) 1412 goto err; 1413 1414 /* Sync set controls */ 1415 ret = wm_coeff_sync_controls(dsp); 1416 if (ret != 0) 1417 goto err; 1418 1419 /* Start the core running */ 1420 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1421 ADSP1_CORE_ENA | ADSP1_START, 1422 ADSP1_CORE_ENA | ADSP1_START); 1423 break; 1424 1425 case SND_SOC_DAPM_PRE_PMD: 1426 /* Halt the core */ 1427 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1428 ADSP1_CORE_ENA | ADSP1_START, 0); 1429 1430 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_19, 1431 ADSP1_WDMA_BUFFER_LENGTH_MASK, 0); 1432 1433 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1434 ADSP1_SYS_ENA, 0); 1435 1436 list_for_each_entry(ctl, &dsp->ctl_list, list) 1437 ctl->enabled = 0; 1438 break; 1439 1440 default: 1441 break; 1442 } 1443 1444 return 0; 1445 1446 err: 1447 regmap_update_bits(dsp->regmap, dsp->base + ADSP1_CONTROL_30, 1448 ADSP1_SYS_ENA, 0); 1449 return ret; 1450 } 1451 EXPORT_SYMBOL_GPL(wm_adsp1_event); 1452 1453 static int wm_adsp2_ena(struct wm_adsp *dsp) 1454 { 1455 unsigned int val; 1456 int ret, count; 1457 1458 ret = regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 1459 ADSP2_SYS_ENA, ADSP2_SYS_ENA); 1460 if (ret != 0) 1461 return ret; 1462 1463 /* Wait for the RAM to start, should be near instantaneous */ 1464 count = 0; 1465 do { 1466 ret = regmap_read(dsp->regmap, dsp->base + ADSP2_STATUS1, 1467 &val); 1468 if (ret != 0) 1469 return ret; 1470 } while (!(val & ADSP2_RAM_RDY) && ++count < 10); 1471 1472 if (!(val & ADSP2_RAM_RDY)) { 1473 adsp_err(dsp, "Failed to start DSP RAM\n"); 1474 return -EBUSY; 1475 } 1476 1477 adsp_dbg(dsp, "RAM ready after %d polls\n", count); 1478 adsp_info(dsp, "RAM ready after %d polls\n", count); 1479 1480 return 0; 1481 } 1482 1483 int wm_adsp2_event(struct snd_soc_dapm_widget *w, 1484 struct snd_kcontrol *kcontrol, int event) 1485 { 1486 struct snd_soc_codec *codec = w->codec; 1487 struct wm_adsp *dsps = snd_soc_codec_get_drvdata(codec); 1488 struct wm_adsp *dsp = &dsps[w->shift]; 1489 struct wm_adsp_alg_region *alg_region; 1490 struct wm_coeff_ctl *ctl; 1491 unsigned int val; 1492 int ret; 1493 1494 dsp->card = codec->card; 1495 1496 switch (event) { 1497 case SND_SOC_DAPM_POST_PMU: 1498 /* 1499 * For simplicity set the DSP clock rate to be the 1500 * SYSCLK rate rather than making it configurable. 1501 */ 1502 ret = regmap_read(dsp->regmap, ARIZONA_SYSTEM_CLOCK_1, &val); 1503 if (ret != 0) { 1504 adsp_err(dsp, "Failed to read SYSCLK state: %d\n", 1505 ret); 1506 return ret; 1507 } 1508 val = (val & ARIZONA_SYSCLK_FREQ_MASK) 1509 >> ARIZONA_SYSCLK_FREQ_SHIFT; 1510 1511 ret = regmap_update_bits(dsp->regmap, 1512 dsp->base + ADSP2_CLOCKING, 1513 ADSP2_CLK_SEL_MASK, val); 1514 if (ret != 0) { 1515 adsp_err(dsp, "Failed to set clock rate: %d\n", 1516 ret); 1517 return ret; 1518 } 1519 1520 if (dsp->dvfs) { 1521 ret = regmap_read(dsp->regmap, 1522 dsp->base + ADSP2_CLOCKING, &val); 1523 if (ret != 0) { 1524 dev_err(dsp->dev, 1525 "Failed to read clocking: %d\n", ret); 1526 return ret; 1527 } 1528 1529 if ((val & ADSP2_CLK_SEL_MASK) >= 3) { 1530 ret = regulator_enable(dsp->dvfs); 1531 if (ret != 0) { 1532 dev_err(dsp->dev, 1533 "Failed to enable supply: %d\n", 1534 ret); 1535 return ret; 1536 } 1537 1538 ret = regulator_set_voltage(dsp->dvfs, 1539 1800000, 1540 1800000); 1541 if (ret != 0) { 1542 dev_err(dsp->dev, 1543 "Failed to raise supply: %d\n", 1544 ret); 1545 return ret; 1546 } 1547 } 1548 } 1549 1550 ret = wm_adsp2_ena(dsp); 1551 if (ret != 0) 1552 return ret; 1553 1554 ret = wm_adsp_load(dsp); 1555 if (ret != 0) 1556 goto err; 1557 1558 ret = wm_adsp_setup_algs(dsp); 1559 if (ret != 0) 1560 goto err; 1561 1562 ret = wm_adsp_load_coeff(dsp); 1563 if (ret != 0) 1564 goto err; 1565 1566 /* Initialize caches for enabled and unset controls */ 1567 ret = wm_coeff_init_control_caches(dsp); 1568 if (ret != 0) 1569 goto err; 1570 1571 /* Sync set controls */ 1572 ret = wm_coeff_sync_controls(dsp); 1573 if (ret != 0) 1574 goto err; 1575 1576 ret = regmap_update_bits(dsp->regmap, 1577 dsp->base + ADSP2_CONTROL, 1578 ADSP2_CORE_ENA | ADSP2_START, 1579 ADSP2_CORE_ENA | ADSP2_START); 1580 if (ret != 0) 1581 goto err; 1582 1583 dsp->running = true; 1584 break; 1585 1586 case SND_SOC_DAPM_PRE_PMD: 1587 dsp->running = false; 1588 1589 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 1590 ADSP2_SYS_ENA | ADSP2_CORE_ENA | 1591 ADSP2_START, 0); 1592 1593 /* Make sure DMAs are quiesced */ 1594 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_1, 0); 1595 regmap_write(dsp->regmap, dsp->base + ADSP2_WDMA_CONFIG_2, 0); 1596 regmap_write(dsp->regmap, dsp->base + ADSP2_RDMA_CONFIG_1, 0); 1597 1598 if (dsp->dvfs) { 1599 ret = regulator_set_voltage(dsp->dvfs, 1200000, 1600 1800000); 1601 if (ret != 0) 1602 dev_warn(dsp->dev, 1603 "Failed to lower supply: %d\n", 1604 ret); 1605 1606 ret = regulator_disable(dsp->dvfs); 1607 if (ret != 0) 1608 dev_err(dsp->dev, 1609 "Failed to enable supply: %d\n", 1610 ret); 1611 } 1612 1613 list_for_each_entry(ctl, &dsp->ctl_list, list) 1614 ctl->enabled = 0; 1615 1616 while (!list_empty(&dsp->alg_regions)) { 1617 alg_region = list_first_entry(&dsp->alg_regions, 1618 struct wm_adsp_alg_region, 1619 list); 1620 list_del(&alg_region->list); 1621 kfree(alg_region); 1622 } 1623 break; 1624 1625 default: 1626 break; 1627 } 1628 1629 return 0; 1630 err: 1631 regmap_update_bits(dsp->regmap, dsp->base + ADSP2_CONTROL, 1632 ADSP2_SYS_ENA | ADSP2_CORE_ENA | ADSP2_START, 0); 1633 return ret; 1634 } 1635 EXPORT_SYMBOL_GPL(wm_adsp2_event); 1636 1637 int wm_adsp2_init(struct wm_adsp *adsp, bool dvfs) 1638 { 1639 int ret; 1640 1641 /* 1642 * Disable the DSP memory by default when in reset for a small 1643 * power saving. 1644 */ 1645 ret = regmap_update_bits(adsp->regmap, adsp->base + ADSP2_CONTROL, 1646 ADSP2_MEM_ENA, 0); 1647 if (ret != 0) { 1648 adsp_err(adsp, "Failed to clear memory retention: %d\n", ret); 1649 return ret; 1650 } 1651 1652 INIT_LIST_HEAD(&adsp->alg_regions); 1653 INIT_LIST_HEAD(&adsp->ctl_list); 1654 1655 if (dvfs) { 1656 adsp->dvfs = devm_regulator_get(adsp->dev, "DCVDD"); 1657 if (IS_ERR(adsp->dvfs)) { 1658 ret = PTR_ERR(adsp->dvfs); 1659 dev_err(adsp->dev, "Failed to get DCVDD: %d\n", ret); 1660 return ret; 1661 } 1662 1663 ret = regulator_enable(adsp->dvfs); 1664 if (ret != 0) { 1665 dev_err(adsp->dev, "Failed to enable DCVDD: %d\n", 1666 ret); 1667 return ret; 1668 } 1669 1670 ret = regulator_set_voltage(adsp->dvfs, 1200000, 1800000); 1671 if (ret != 0) { 1672 dev_err(adsp->dev, "Failed to initialise DVFS: %d\n", 1673 ret); 1674 return ret; 1675 } 1676 1677 ret = regulator_disable(adsp->dvfs); 1678 if (ret != 0) { 1679 dev_err(adsp->dev, "Failed to disable DCVDD: %d\n", 1680 ret); 1681 return ret; 1682 } 1683 } 1684 1685 return 0; 1686 } 1687 EXPORT_SYMBOL_GPL(wm_adsp2_init); 1688