Lines Matching +full:ipc +full:-
1 // SPDX-License-Identifier: GPL-2.0-only
3 * cnl-sst.c - DSP library functions for CNL platform
5 * Copyright (C) 2016-17, Intel Corporation.
11 * Copyright (C) 2014-15, Intel Corporation.
23 #include "../common/sst-dsp.h"
24 #include "../common/sst-dsp-priv.h"
25 #include "../common/sst-ipc.h"
26 #include "cnl-sst-dsp.h"
51 stream_tag = ctx->dsp_ops.prepare(ctx->dev, 0x40, fwsize, &ctx->dmab); in cnl_prepare_fw()
53 dev_err(ctx->dev, "dma prepare failed: 0%#x\n", stream_tag); in cnl_prepare_fw()
57 ctx->dsp_ops.stream_tag = stream_tag; in cnl_prepare_fw()
58 memcpy(ctx->dmab.area, fwdata, fwsize); in cnl_prepare_fw()
62 dev_err(ctx->dev, "dsp core0 power up failed\n"); in cnl_prepare_fw()
63 ret = -EIO; in cnl_prepare_fw()
70 ((stream_tag - 1) << CNL_ROM_CTRL_DMA_ID))); in cnl_prepare_fw()
74 dev_err(ctx->dev, "Start dsp core failed ret: %d\n", ret); in cnl_prepare_fw()
75 ret = -EIO; in cnl_prepare_fw()
84 dev_err(ctx->dev, "timeout for purge request: %d\n", ret); in cnl_prepare_fw()
96 dev_err(ctx->dev, "rom init timeout, ret: %d\n", ret); in cnl_prepare_fw()
103 ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, stream_tag); in cnl_prepare_fw()
113 ctx->dsp_ops.trigger(ctx->dev, true, ctx->dsp_ops.stream_tag); in sst_transfer_fw_host_dma()
118 ctx->dsp_ops.trigger(ctx->dev, false, ctx->dsp_ops.stream_tag); in sst_transfer_fw_host_dma()
119 ctx->dsp_ops.cleanup(ctx->dev, &ctx->dmab, ctx->dsp_ops.stream_tag); in sst_transfer_fw_host_dma()
127 struct skl_dev *cnl = ctx->thread_context; in cnl_load_base_firmware()
130 if (!ctx->fw) { in cnl_load_base_firmware()
131 ret = request_firmware(&ctx->fw, ctx->fw_name, ctx->dev); in cnl_load_base_firmware()
133 dev_err(ctx->dev, "request firmware failed: %d\n", ret); in cnl_load_base_firmware()
139 if (cnl->is_first_boot) { in cnl_load_base_firmware()
140 ret = snd_skl_parse_uuids(ctx, ctx->fw, in cnl_load_base_firmware()
146 stripped_fw.data = ctx->fw->data; in cnl_load_base_firmware()
147 stripped_fw.size = ctx->fw->size; in cnl_load_base_firmware()
154 dev_dbg(ctx->dev, "prepare firmware failed: %d\n", ret); in cnl_load_base_firmware()
162 dev_err(ctx->dev, "transfer firmware failed: %d\n", ret); in cnl_load_base_firmware()
167 ret = wait_event_timeout(cnl->boot_wait, cnl->boot_complete, in cnl_load_base_firmware()
170 dev_err(ctx->dev, "FW ready timed-out\n"); in cnl_load_base_firmware()
172 ret = -EIO; in cnl_load_base_firmware()
176 cnl->fw_loaded = true; in cnl_load_base_firmware()
181 dev_err(ctx->dev, "firmware load failed: %d\n", ret); in cnl_load_base_firmware()
182 release_firmware(ctx->fw); in cnl_load_base_firmware()
183 ctx->fw = NULL; in cnl_load_base_firmware()
190 struct skl_dev *cnl = ctx->thread_context; in cnl_set_dsp_D0()
195 if (!cnl->fw_loaded) { in cnl_set_dsp_D0()
196 cnl->boot_complete = false; in cnl_set_dsp_D0()
199 dev_err(ctx->dev, "fw reload failed: %d\n", ret); in cnl_set_dsp_D0()
203 cnl->cores.state[core_id] = SKL_DSP_RUNNING; in cnl_set_dsp_D0()
209 dev_err(ctx->dev, "enable dsp core %d failed: %d\n", in cnl_set_dsp_D0()
218 cnl->boot_complete = false; in cnl_set_dsp_D0()
220 ret = wait_event_timeout(cnl->boot_wait, cnl->boot_complete, in cnl_set_dsp_D0()
223 dev_err(ctx->dev, in cnl_set_dsp_D0()
227 ret = -ETIMEDOUT; in cnl_set_dsp_D0()
234 ret = skl_ipc_set_dx(&cnl->ipc, CNL_INSTANCE_ID, in cnl_set_dsp_D0()
237 dev_err(ctx->dev, "set_dx failed, core: %d ret: %d\n", in cnl_set_dsp_D0()
242 cnl->cores.state[core_id] = SKL_DSP_RUNNING; in cnl_set_dsp_D0()
253 struct skl_dev *cnl = ctx->thread_context; in cnl_set_dsp_D3()
261 ret = skl_ipc_set_dx(&cnl->ipc, CNL_INSTANCE_ID, in cnl_set_dsp_D3()
264 dev_err(ctx->dev, in cnl_set_dsp_D3()
267 cnl->fw_loaded = false; in cnl_set_dsp_D3()
278 dev_err(ctx->dev, "disable dsp core %d failed: %d\n", in cnl_set_dsp_D3()
283 cnl->cores.state[core_id] = SKL_DSP_RESET; in cnl_set_dsp_D3()
315 struct skl_dev *cnl = dsp->thread_context; in cnl_dsp_irq_thread_handler()
316 struct sst_generic_ipc *ipc = &cnl->ipc; in cnl_dsp_irq_thread_handler() local
321 /* here we handle ipc interrupts only */ in cnl_dsp_irq_thread_handler()
322 if (!(dsp->intr_status & CNL_ADSPIS_IPC)) in cnl_dsp_irq_thread_handler()
334 /* clear done bit - tell dsp operation is complete */ in cnl_dsp_irq_thread_handler()
349 dev_dbg(dsp->dev, "IPC irq: Firmware respond primary:%x", in cnl_dsp_irq_thread_handler()
351 dev_dbg(dsp->dev, "IPC irq: Firmware respond extension:%x", in cnl_dsp_irq_thread_handler()
356 skl_ipc_process_reply(ipc, header); in cnl_dsp_irq_thread_handler()
358 dev_dbg(dsp->dev, "IPC irq: Notification from firmware\n"); in cnl_dsp_irq_thread_handler()
359 skl_ipc_process_notification(ipc, header); in cnl_dsp_irq_thread_handler()
377 schedule_work(&ipc->kwork); in cnl_dsp_irq_thread_handler()
387 static void cnl_ipc_tx_msg(struct sst_generic_ipc *ipc, struct ipc_message *msg) in cnl_ipc_tx_msg() argument
389 struct skl_ipc_header *header = (struct skl_ipc_header *)(&msg->tx.header); in cnl_ipc_tx_msg()
391 if (msg->tx.size) in cnl_ipc_tx_msg()
392 sst_dsp_outbox_write(ipc->dsp, msg->tx.data, msg->tx.size); in cnl_ipc_tx_msg()
393 sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDD, in cnl_ipc_tx_msg()
394 header->extension); in cnl_ipc_tx_msg()
395 sst_dsp_shim_write_unlocked(ipc->dsp, CNL_ADSP_REG_HIPCIDR, in cnl_ipc_tx_msg()
396 header->primary | CNL_ADSP_REG_HIPCIDR_BUSY); in cnl_ipc_tx_msg()
410 struct sst_generic_ipc *ipc; in cnl_ipc_init() local
413 ipc = &cnl->ipc; in cnl_ipc_init()
414 ipc->dsp = cnl->dsp; in cnl_ipc_init()
415 ipc->dev = dev; in cnl_ipc_init()
417 ipc->tx_data_max_size = CNL_ADSP_W1_SZ; in cnl_ipc_init()
418 ipc->rx_data_max_size = CNL_ADSP_W0_UP_SZ; in cnl_ipc_init()
420 err = sst_ipc_init(ipc); in cnl_ipc_init()
426 * ipc registers are different for cnl in cnl_ipc_init()
428 ipc->ops.tx_msg = cnl_ipc_tx_msg; in cnl_ipc_init()
429 ipc->ops.tx_data_copy = skl_ipc_tx_data_copy; in cnl_ipc_init()
430 ipc->ops.is_dsp_busy = cnl_ipc_is_dsp_busy; in cnl_ipc_init()
450 sst = cnl->dsp; in cnl_sst_dsp_init()
451 sst->fw_ops = cnl_fw_ops; in cnl_sst_dsp_init()
452 sst->addr.lpe = mmio_base; in cnl_sst_dsp_init()
453 sst->addr.shim = mmio_base; in cnl_sst_dsp_init()
454 sst->addr.sram0_base = CNL_ADSP_SRAM0_BASE; in cnl_sst_dsp_init()
455 sst->addr.sram1_base = CNL_ADSP_SRAM1_BASE; in cnl_sst_dsp_init()
456 sst->addr.w0_stat_sz = CNL_ADSP_W0_STAT_SZ; in cnl_sst_dsp_init()
457 sst->addr.w0_up_sz = CNL_ADSP_W0_UP_SZ; in cnl_sst_dsp_init()
469 cnl->boot_complete = false; in cnl_sst_dsp_init()
470 init_waitqueue_head(&cnl->boot_wait); in cnl_sst_dsp_init()
479 struct sst_dsp *sst = skl->dsp; in cnl_sst_init_fw()
481 ret = skl->dsp->fw_ops.load_fw(sst); in cnl_sst_init_fw()
489 skl->is_first_boot = false; in cnl_sst_init_fw()
497 if (skl->dsp->fw) in cnl_sst_dsp_cleanup()
498 release_firmware(skl->dsp->fw); in cnl_sst_dsp_cleanup()
501 cnl_ipc_free(&skl->ipc); in cnl_sst_dsp_cleanup()
503 skl->dsp->ops->free(skl->dsp); in cnl_sst_dsp_cleanup()
508 MODULE_DESCRIPTION("Intel Cannonlake IPC driver");