Lines Matching +full:dsp +full:- +full:reset
1 // SPDX-License-Identifier: GPL-2.0-only
3 * wm0010.c -- WM0010 DSP Driver
97 struct gpio_desc *reset; member
136 "Out of reset", in wm0010_state_to_str()
147 /* Called with wm0010->lock held */
155 spin_lock_irqsave(&wm0010->irq_lock, flags); in wm0010_halt()
156 state = wm0010->state; in wm0010_halt()
157 spin_unlock_irqrestore(&wm0010->irq_lock, flags); in wm0010_halt()
167 /* Remember to put chip back into reset */ in wm0010_halt()
168 gpiod_set_value_cansleep(wm0010->reset, 1); in wm0010_halt()
170 regulator_disable(wm0010->dbvdd); in wm0010_halt()
171 regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies), in wm0010_halt()
172 wm0010->core_supplies); in wm0010_halt()
176 spin_lock_irqsave(&wm0010->irq_lock, flags); in wm0010_halt()
177 wm0010->state = WM0010_POWER_OFF; in wm0010_halt()
178 spin_unlock_irqrestore(&wm0010->irq_lock, flags); in wm0010_halt()
189 /* Called with wm0010->lock held */
195 spin_lock_irqsave(&wm0010->irq_lock, flags); in wm0010_mark_boot_failure()
196 state = wm0010->state; in wm0010_mark_boot_failure()
197 spin_unlock_irqrestore(&wm0010->irq_lock, flags); in wm0010_mark_boot_failure()
199 dev_err(wm0010->dev, "Failed to transition from `%s' state to `%s' state\n", in wm0010_mark_boot_failure()
202 wm0010->boot_failed = true; in wm0010_mark_boot_failure()
208 struct snd_soc_component *component = xfer->component; in wm0010_boot_xfer_complete()
210 u32 *out32 = xfer->t.rx_buf; in wm0010_boot_xfer_complete()
213 if (xfer->m.status != 0) { in wm0010_boot_xfer_complete()
214 dev_err(component->dev, "SPI transfer failed: %d\n", in wm0010_boot_xfer_complete()
215 xfer->m.status); in wm0010_boot_xfer_complete()
217 if (xfer->done) in wm0010_boot_xfer_complete()
218 complete(xfer->done); in wm0010_boot_xfer_complete()
222 for (i = 0; i < xfer->t.len / 4; i++) { in wm0010_boot_xfer_complete()
223 dev_dbg(component->dev, "%d: %04x\n", i, out32[i]); in wm0010_boot_xfer_complete()
227 dev_err(component->dev, in wm0010_boot_xfer_complete()
233 if (wm0010->state < WM0010_STAGE2) in wm0010_boot_xfer_complete()
235 dev_err(component->dev, in wm0010_boot_xfer_complete()
241 dev_dbg(component->dev, "Stage2 loader running\n"); in wm0010_boot_xfer_complete()
245 dev_dbg(component->dev, "CODE_HDR packet received\n"); in wm0010_boot_xfer_complete()
249 dev_dbg(component->dev, "CODE_DATA packet received\n"); in wm0010_boot_xfer_complete()
253 dev_dbg(component->dev, "Download complete\n"); in wm0010_boot_xfer_complete()
257 dev_dbg(component->dev, "Application start\n"); in wm0010_boot_xfer_complete()
261 dev_dbg(component->dev, "PLL packet received\n"); in wm0010_boot_xfer_complete()
262 wm0010->pll_running = true; in wm0010_boot_xfer_complete()
266 dev_err(component->dev, "Device reports image too long\n"); in wm0010_boot_xfer_complete()
271 dev_err(component->dev, "Device reports bad SPI packet\n"); in wm0010_boot_xfer_complete()
276 dev_err(component->dev, "Device reports SPI read overflow\n"); in wm0010_boot_xfer_complete()
281 dev_err(component->dev, "Device reports SPI underclock\n"); in wm0010_boot_xfer_complete()
286 dev_err(component->dev, "Device reports bad header packet\n"); in wm0010_boot_xfer_complete()
291 dev_err(component->dev, "Device reports invalid packet type\n"); in wm0010_boot_xfer_complete()
296 dev_err(component->dev, "Device reports data before header error\n"); in wm0010_boot_xfer_complete()
301 dev_err(component->dev, "Device reports invalid PLL packet\n"); in wm0010_boot_xfer_complete()
305 dev_err(component->dev, "Device reports packet alignment error\n"); in wm0010_boot_xfer_complete()
310 dev_err(component->dev, "Unrecognised return 0x%x\n", in wm0010_boot_xfer_complete()
316 if (wm0010->boot_failed) in wm0010_boot_xfer_complete()
320 if (xfer->done) in wm0010_boot_xfer_complete()
321 complete(xfer->done); in wm0010_boot_xfer_complete()
334 struct spi_device *spi = to_spi_device(component->dev); in wm0010_firmware_load()
344 u8 *out, dsp; in wm0010_firmware_load() local
349 ret = request_firmware(&fw, name, component->dev); in wm0010_firmware_load()
351 dev_err(component->dev, "Failed to request application(%s): %d\n", in wm0010_firmware_load()
356 rec = (const struct dfw_binrec *)fw->data; in wm0010_firmware_load()
357 inforec = (const struct dfw_inforec *)rec->data; in wm0010_firmware_load()
359 dsp = inforec->dsp_target; in wm0010_firmware_load()
360 wm0010->boot_failed = false; in wm0010_firmware_load()
362 return -EINVAL; in wm0010_firmware_load()
365 if (rec->command != DFW_CMD_INFO) { in wm0010_firmware_load()
366 dev_err(component->dev, "First record not INFO\r\n"); in wm0010_firmware_load()
367 ret = -EINVAL; in wm0010_firmware_load()
371 if (inforec->info_version != INFO_VERSION) { in wm0010_firmware_load()
372 dev_err(component->dev, in wm0010_firmware_load()
374 inforec->info_version); in wm0010_firmware_load()
375 ret = -EINVAL; in wm0010_firmware_load()
379 dev_dbg(component->dev, "Version v%02d INFO record found\r\n", in wm0010_firmware_load()
380 inforec->info_version); in wm0010_firmware_load()
382 /* Check it's a DSP file */ in wm0010_firmware_load()
383 if (dsp != DEVICE_ID_WM0010) { in wm0010_firmware_load()
384 dev_err(component->dev, "Not a WM0010 firmware file.\r\n"); in wm0010_firmware_load()
385 ret = -EINVAL; in wm0010_firmware_load()
390 offset += ((rec->length) + 8); in wm0010_firmware_load()
391 rec = (void *)&rec->data[rec->length]; in wm0010_firmware_load()
393 while (offset < fw->size) { in wm0010_firmware_load()
394 dev_dbg(component->dev, in wm0010_firmware_load()
396 rec->command, rec->length); in wm0010_firmware_load()
397 len = rec->length + 8; in wm0010_firmware_load()
401 ret = -ENOMEM; in wm0010_firmware_load()
405 xfer->component = component; in wm0010_firmware_load()
406 list_add_tail(&xfer->list, &xfer_list); in wm0010_firmware_load()
410 ret = -ENOMEM; in wm0010_firmware_load()
413 xfer->t.rx_buf = out; in wm0010_firmware_load()
417 ret = -ENOMEM; in wm0010_firmware_load()
420 xfer->t.tx_buf = img; in wm0010_firmware_load()
422 byte_swap_64((u64 *)&rec->command, img, len); in wm0010_firmware_load()
424 spi_message_init(&xfer->m); in wm0010_firmware_load()
425 xfer->m.complete = wm0010_boot_xfer_complete; in wm0010_firmware_load()
426 xfer->m.context = xfer; in wm0010_firmware_load()
427 xfer->t.len = len; in wm0010_firmware_load()
428 xfer->t.bits_per_word = 8; in wm0010_firmware_load()
430 if (!wm0010->pll_running) { in wm0010_firmware_load()
431 xfer->t.speed_hz = wm0010->sysclk / 6; in wm0010_firmware_load()
433 xfer->t.speed_hz = wm0010->max_spi_freq; in wm0010_firmware_load()
435 if (wm0010->board_max_spi_speed && in wm0010_firmware_load()
436 (wm0010->board_max_spi_speed < wm0010->max_spi_freq)) in wm0010_firmware_load()
437 xfer->t.speed_hz = wm0010->board_max_spi_speed; in wm0010_firmware_load()
441 wm0010->max_spi_freq = xfer->t.speed_hz; in wm0010_firmware_load()
443 spi_message_add_tail(&xfer->t, &xfer->m); in wm0010_firmware_load()
445 offset += ((rec->length) + 8); in wm0010_firmware_load()
446 rec = (void *)&rec->data[rec->length]; in wm0010_firmware_load()
448 if (offset >= fw->size) { in wm0010_firmware_load()
449 dev_dbg(component->dev, "All transfers scheduled\n"); in wm0010_firmware_load()
450 xfer->done = &done; in wm0010_firmware_load()
453 ret = spi_async(spi, &xfer->m); in wm0010_firmware_load()
455 dev_err(component->dev, "Write failed: %d\n", ret); in wm0010_firmware_load()
459 if (wm0010->boot_failed) { in wm0010_firmware_load()
460 dev_dbg(component->dev, "Boot fail!\n"); in wm0010_firmware_load()
461 ret = -EINVAL; in wm0010_firmware_load()
474 kfree(xfer->t.rx_buf); in wm0010_firmware_load()
475 kfree(xfer->t.tx_buf); in wm0010_firmware_load()
476 list_del(&xfer->list); in wm0010_firmware_load()
487 struct spi_device *spi = to_spi_device(component->dev); in wm0010_stage2_load()
497 ret = request_firmware(&fw, "wm0010_stage2.bin", component->dev); in wm0010_stage2_load()
499 dev_err(component->dev, "Failed to request stage2 loader: %d\n", in wm0010_stage2_load()
504 dev_dbg(component->dev, "Downloading %zu byte stage 2 loader\n", fw->size); in wm0010_stage2_load()
507 img = kmemdup(&fw->data[0], fw->size, GFP_KERNEL | GFP_DMA); in wm0010_stage2_load()
509 ret = -ENOMEM; in wm0010_stage2_load()
513 out = kzalloc(fw->size, GFP_KERNEL | GFP_DMA); in wm0010_stage2_load()
515 ret = -ENOMEM; in wm0010_stage2_load()
523 t.len = fw->size; in wm0010_stage2_load()
525 t.speed_hz = wm0010->sysclk / 10; in wm0010_stage2_load()
528 dev_dbg(component->dev, "Starting initial download at %dHz\n", in wm0010_stage2_load()
533 dev_err(component->dev, "Initial download failed: %d\n", ret); in wm0010_stage2_load()
538 for (i = 0; i < fw->size; i++) { in wm0010_stage2_load()
540 dev_err(component->dev, "Boot ROM error: %x in %d\n", in wm0010_stage2_load()
543 ret = -EBUSY; in wm0010_stage2_load()
559 struct spi_device *spi = to_spi_device(component->dev); in wm0010_boot()
571 spin_lock_irqsave(&wm0010->irq_lock, flags); in wm0010_boot()
572 if (wm0010->state != WM0010_POWER_OFF) in wm0010_boot()
573 dev_warn(wm0010->dev, "DSP already powered up!\n"); in wm0010_boot()
574 spin_unlock_irqrestore(&wm0010->irq_lock, flags); in wm0010_boot()
576 if (wm0010->sysclk > 26000000) { in wm0010_boot()
577 dev_err(component->dev, "Max DSP clock frequency is 26MHz\n"); in wm0010_boot()
578 ret = -ECANCELED; in wm0010_boot()
582 mutex_lock(&wm0010->lock); in wm0010_boot()
583 wm0010->pll_running = false; in wm0010_boot()
585 dev_dbg(component->dev, "max_spi_freq: %d\n", wm0010->max_spi_freq); in wm0010_boot()
587 ret = regulator_bulk_enable(ARRAY_SIZE(wm0010->core_supplies), in wm0010_boot()
588 wm0010->core_supplies); in wm0010_boot()
590 dev_err(&spi->dev, "Failed to enable core supplies: %d\n", in wm0010_boot()
592 mutex_unlock(&wm0010->lock); in wm0010_boot()
596 ret = regulator_enable(wm0010->dbvdd); in wm0010_boot()
598 dev_err(&spi->dev, "Failed to enable DBVDD: %d\n", ret); in wm0010_boot()
602 /* Release reset */ in wm0010_boot()
603 gpiod_set_value_cansleep(wm0010->reset, 0); in wm0010_boot()
604 spin_lock_irqsave(&wm0010->irq_lock, flags); in wm0010_boot()
605 wm0010->state = WM0010_OUT_OF_RESET; in wm0010_boot()
606 spin_unlock_irqrestore(&wm0010->irq_lock, flags); in wm0010_boot()
608 if (!wait_for_completion_timeout(&wm0010->boot_completion, in wm0010_boot()
610 dev_err(component->dev, "Failed to get interrupt from DSP\n"); in wm0010_boot()
612 spin_lock_irqsave(&wm0010->irq_lock, flags); in wm0010_boot()
613 wm0010->state = WM0010_BOOTROM; in wm0010_boot()
614 spin_unlock_irqrestore(&wm0010->irq_lock, flags); in wm0010_boot()
620 if (!wait_for_completion_timeout(&wm0010->boot_completion, in wm0010_boot()
622 dev_err(component->dev, "Failed to get interrupt from DSP loader.\n"); in wm0010_boot()
624 spin_lock_irqsave(&wm0010->irq_lock, flags); in wm0010_boot()
625 wm0010->state = WM0010_STAGE2; in wm0010_boot()
626 spin_unlock_irqrestore(&wm0010->irq_lock, flags); in wm0010_boot()
629 if (wm0010->max_spi_freq) { in wm0010_boot()
634 pll_rec.length = (sizeof(pll_rec) - 8); in wm0010_boot()
637 pll_rec.clkctrl1 = wm0010->pll_clkctrl1; in wm0010_boot()
639 ret = -ENOMEM; in wm0010_boot()
649 /* We need to re-order for 0010 */ in wm0010_boot()
658 t.speed_hz = wm0010->sysclk / 6; in wm0010_boot()
663 dev_err(component->dev, "First PLL write failed: %d\n", ret); in wm0010_boot()
670 dev_err(component->dev, "Second PLL write failed: %d\n", ret); in wm0010_boot()
676 /* Look for PLL active code from the DSP */ in wm0010_boot()
679 dev_dbg(component->dev, "PLL packet received\n"); in wm0010_boot()
680 wm0010->pll_running = true; in wm0010_boot()
689 dev_dbg(component->dev, "Not enabling DSP PLL."); in wm0010_boot()
696 spin_lock_irqsave(&wm0010->irq_lock, flags); in wm0010_boot()
697 wm0010->state = WM0010_FIRMWARE; in wm0010_boot()
698 spin_unlock_irqrestore(&wm0010->irq_lock, flags); in wm0010_boot()
700 mutex_unlock(&wm0010->lock); in wm0010_boot()
709 /* Put the chip back into reset */ in wm0010_boot()
711 mutex_unlock(&wm0010->lock); in wm0010_boot()
715 mutex_unlock(&wm0010->lock); in wm0010_boot()
716 regulator_bulk_disable(ARRAY_SIZE(wm0010->core_supplies), in wm0010_boot()
717 wm0010->core_supplies); in wm0010_boot()
736 mutex_lock(&wm0010->lock); in wm0010_set_bias_level()
738 mutex_unlock(&wm0010->lock); in wm0010_set_bias_level()
754 wm0010->sysclk = freq; in wm0010_set_sysclk()
756 if (freq < pll_clock_map[ARRAY_SIZE(pll_clock_map)-1].max_sysclk) { in wm0010_set_sysclk()
757 wm0010->max_spi_freq = 0; in wm0010_set_sysclk()
761 wm0010->max_spi_freq = pll_clock_map[i].max_pll_spi_speed; in wm0010_set_sysclk()
762 wm0010->pll_clkctrl1 = pll_clock_map[i].pll_clkctrl1; in wm0010_set_sysclk()
791 .name = "wm0010-sdi1",
808 .name = "wm0010-sdi2",
830 switch (wm0010->state) { in wm0010_irq()
834 spin_lock(&wm0010->irq_lock); in wm0010_irq()
835 complete(&wm0010->boot_completion); in wm0010_irq()
836 spin_unlock(&wm0010->irq_lock); in wm0010_irq()
849 wm0010->component = component; in wm0010_probe()
861 wm0010 = devm_kzalloc(&spi->dev, sizeof(*wm0010), in wm0010_spi_probe()
864 return -ENOMEM; in wm0010_spi_probe()
866 mutex_init(&wm0010->lock); in wm0010_spi_probe()
867 spin_lock_init(&wm0010->irq_lock); in wm0010_spi_probe()
870 wm0010->dev = &spi->dev; in wm0010_spi_probe()
872 if (dev_get_platdata(&spi->dev)) in wm0010_spi_probe()
873 memcpy(&wm0010->pdata, dev_get_platdata(&spi->dev), in wm0010_spi_probe()
874 sizeof(wm0010->pdata)); in wm0010_spi_probe()
876 init_completion(&wm0010->boot_completion); in wm0010_spi_probe()
878 wm0010->core_supplies[0].supply = "AVDD"; in wm0010_spi_probe()
879 wm0010->core_supplies[1].supply = "DCVDD"; in wm0010_spi_probe()
880 ret = devm_regulator_bulk_get(wm0010->dev, ARRAY_SIZE(wm0010->core_supplies), in wm0010_spi_probe()
881 wm0010->core_supplies); in wm0010_spi_probe()
883 dev_err(wm0010->dev, "Failed to obtain core supplies: %d\n", in wm0010_spi_probe()
888 wm0010->dbvdd = devm_regulator_get(wm0010->dev, "DBVDD"); in wm0010_spi_probe()
889 if (IS_ERR(wm0010->dbvdd)) { in wm0010_spi_probe()
890 ret = PTR_ERR(wm0010->dbvdd); in wm0010_spi_probe()
891 dev_err(wm0010->dev, "Failed to obtain DBVDD: %d\n", ret); in wm0010_spi_probe()
895 wm0010->reset = devm_gpiod_get(wm0010->dev, "reset", GPIOD_OUT_HIGH); in wm0010_spi_probe()
896 if (IS_ERR(wm0010->reset)) in wm0010_spi_probe()
897 return dev_err_probe(wm0010->dev, PTR_ERR(wm0010->reset), in wm0010_spi_probe()
898 "could not get RESET GPIO\n"); in wm0010_spi_probe()
899 gpiod_set_consumer_name(wm0010->reset, "wm0010 reset"); in wm0010_spi_probe()
901 wm0010->state = WM0010_POWER_OFF; in wm0010_spi_probe()
903 irq = spi->irq; in wm0010_spi_probe()
904 if (wm0010->pdata.irq_flags) in wm0010_spi_probe()
905 trigger = wm0010->pdata.irq_flags; in wm0010_spi_probe()
913 dev_err(wm0010->dev, "Failed to request IRQ %d: %d\n", in wm0010_spi_probe()
917 wm0010->irq = irq; in wm0010_spi_probe()
921 dev_err(wm0010->dev, "Failed to set IRQ %d as wake source: %d\n", in wm0010_spi_probe()
926 if (spi->max_speed_hz) in wm0010_spi_probe()
927 wm0010->board_max_spi_speed = spi->max_speed_hz; in wm0010_spi_probe()
929 wm0010->board_max_spi_speed = 0; in wm0010_spi_probe()
931 ret = devm_snd_soc_register_component(&spi->dev, in wm0010_spi_probe()
944 gpiod_set_value_cansleep(wm0010->reset, 1); in wm0010_spi_remove()
946 irq_set_irq_wake(wm0010->irq, 0); in wm0010_spi_remove()
948 if (wm0010->irq) in wm0010_spi_remove()
949 free_irq(wm0010->irq, wm0010); in wm0010_spi_remove()