Lines Matching +full:dsp +full:- +full:ctrl
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
7 // Hardware interface for audio DSP on i.MX8M
20 #include <linux/firmware/imx/dsp.h>
23 #include "../sof-of-dev.h"
24 #include "imx-common.h"
35 /* DSP audio mix registers */
47 /* DSP IPC handler */
73 spin_lock_irqsave(&priv->sdev->ipc_lock, flags); in imx8m_dsp_handle_reply()
74 snd_sof_ipc_process_reply(priv->sdev, 0); in imx8m_dsp_handle_reply()
75 spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags); in imx8m_dsp_handle_reply()
84 sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, &p, sizeof(p)); in imx8m_dsp_handle_request()
88 snd_sof_dsp_panic(priv->sdev, p, true); in imx8m_dsp_handle_request()
90 snd_sof_ipc_msgs_rx(priv->sdev); in imx8m_dsp_handle_request()
100 struct imx8m_priv *priv = sdev->pdata->hw_pdata; in imx8m_send_msg()
102 sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, in imx8m_send_msg()
103 msg->msg_size); in imx8m_send_msg()
104 imx_dsp_ring_doorbell(priv->dsp_ipc, 0); in imx8m_send_msg()
110 * DSP control.
114 struct imx8m_priv *priv = (struct imx8m_priv *)sdev->pdata->hw_pdata; in imx8m_run()
116 regmap_update_bits(priv->regmap, AudioDSP_REG2, AudioDSP_REG2_RUNSTALL, 0); in imx8m_run()
123 struct imx8m_priv *priv = (struct imx8m_priv *)sdev->pdata->hw_pdata; in imx8m_reset()
126 /* put DSP into reset and stall */ in imx8m_reset()
127 pwrctl = readl(priv->dap + IMX8M_DAP_PWRCTL); in imx8m_reset()
129 writel(pwrctl, priv->dap + IMX8M_DAP_PWRCTL); in imx8m_reset()
134 regmap_update_bits(priv->regmap, AudioDSP_REG2, in imx8m_reset()
137 /* take the DSP out of reset and keep stalled for FW loading */ in imx8m_reset()
138 pwrctl = readl(priv->dap + IMX8M_DAP_PWRCTL); in imx8m_reset()
140 writel(pwrctl, priv->dap + IMX8M_DAP_PWRCTL); in imx8m_reset()
147 struct platform_device *pdev = to_platform_device(sdev->dev); in imx8m_probe()
148 struct device_node *np = pdev->dev.of_node; in imx8m_probe()
156 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in imx8m_probe()
158 return -ENOMEM; in imx8m_probe()
160 sdev->num_cores = 1; in imx8m_probe()
161 sdev->pdata->hw_pdata = priv; in imx8m_probe()
162 priv->dev = sdev->dev; in imx8m_probe()
163 priv->sdev = sdev; in imx8m_probe()
165 priv->ipc_dev = platform_device_register_data(sdev->dev, "imx-dsp", in imx8m_probe()
168 if (IS_ERR(priv->ipc_dev)) in imx8m_probe()
169 return PTR_ERR(priv->ipc_dev); in imx8m_probe()
171 priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev); in imx8m_probe()
172 if (!priv->dsp_ipc) { in imx8m_probe()
173 /* DSP IPC driver not probed yet, try later */ in imx8m_probe()
174 ret = -EPROBE_DEFER; in imx8m_probe()
175 dev_err(sdev->dev, "Failed to get drvdata\n"); in imx8m_probe()
179 imx_dsp_set_data(priv->dsp_ipc, priv); in imx8m_probe()
180 priv->dsp_ipc->ops = &imx8m_dsp_ops; in imx8m_probe()
182 /* DSP base */ in imx8m_probe()
185 base = mmio->start; in imx8m_probe()
188 dev_err(sdev->dev, "error: failed to get DSP base at idx 0\n"); in imx8m_probe()
189 ret = -EINVAL; in imx8m_probe()
193 priv->dap = devm_ioremap(sdev->dev, IMX8M_DAP_DEBUG, IMX8M_DAP_DEBUG_SIZE); in imx8m_probe()
194 if (!priv->dap) { in imx8m_probe()
195 dev_err(sdev->dev, "error: failed to map DAP debug memory area"); in imx8m_probe()
196 ret = -ENODEV; in imx8m_probe()
200 sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev, base, size); in imx8m_probe()
201 if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) { in imx8m_probe()
202 dev_err(sdev->dev, "failed to ioremap base 0x%x size 0x%x\n", in imx8m_probe()
204 ret = -ENODEV; in imx8m_probe()
207 sdev->mmio_bar = SOF_FW_BLK_TYPE_IRAM; in imx8m_probe()
209 res_node = of_parse_phandle(np, "memory-region", 0); in imx8m_probe()
211 dev_err(&pdev->dev, "failed to get memory region node\n"); in imx8m_probe()
212 ret = -ENODEV; in imx8m_probe()
219 dev_err(&pdev->dev, "failed to get reserved region address\n"); in imx8m_probe()
223 sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev, res.start, in imx8m_probe()
225 if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) { in imx8m_probe()
226 dev_err(sdev->dev, "failed to ioremap mem 0x%x size 0x%x\n", in imx8m_probe()
228 ret = -ENOMEM; in imx8m_probe()
231 sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM; in imx8m_probe()
234 sdev->dsp_box.offset = MBOX_OFFSET; in imx8m_probe()
236 priv->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,dsp-ctrl"); in imx8m_probe()
237 if (IS_ERR(priv->regmap)) { in imx8m_probe()
238 dev_err(sdev->dev, "cannot find dsp-ctrl registers"); in imx8m_probe()
239 ret = PTR_ERR(priv->regmap); in imx8m_probe()
243 ret = devm_clk_bulk_get_all(sdev->dev, &priv->clks); in imx8m_probe()
245 dev_err(sdev->dev, "failed to fetch clocks: %d\n", ret); in imx8m_probe()
248 priv->clk_num = ret; in imx8m_probe()
250 ret = clk_bulk_prepare_enable(priv->clk_num, priv->clks); in imx8m_probe()
252 dev_err(sdev->dev, "failed to enable clocks: %d\n", ret); in imx8m_probe()
259 platform_device_unregister(priv->ipc_dev); in imx8m_probe()
265 struct imx8m_priv *priv = sdev->pdata->hw_pdata; in imx8m_remove()
267 clk_bulk_disable_unprepare(priv->clk_num, priv->clks); in imx8m_remove()
268 platform_device_unregister(priv->ipc_dev); in imx8m_remove()
280 return -EINVAL; in imx8m_get_bar_index()
363 sdev->dsp_power_state = *target_state; in imx8m_dsp_set_power_state()
370 struct imx8m_priv *priv = (struct imx8m_priv *)sdev->pdata->hw_pdata; in imx8m_resume()
374 ret = clk_bulk_prepare_enable(priv->clk_num, priv->clks); in imx8m_resume()
376 dev_err(sdev->dev, "failed to enable clocks: %d\n", ret); in imx8m_resume()
381 imx_dsp_request_channel(priv->dsp_ipc, i); in imx8m_resume()
388 struct imx8m_priv *priv = (struct imx8m_priv *)sdev->pdata->hw_pdata; in imx8m_suspend()
392 imx_dsp_free_channel(priv->dsp_ipc, i); in imx8m_suspend()
394 clk_bulk_disable_unprepare(priv->clk_num, priv->clks); in imx8m_suspend()
433 if (pm_runtime_suspended(sdev->dev)) { in imx8m_dsp_resume()
434 pm_runtime_disable(sdev->dev); in imx8m_dsp_resume()
435 pm_runtime_set_active(sdev->dev); in imx8m_dsp_resume()
436 pm_runtime_mark_last_busy(sdev->dev); in imx8m_dsp_resume()
437 pm_runtime_enable(sdev->dev); in imx8m_dsp_resume()
438 pm_runtime_idle(sdev->dev); in imx8m_dsp_resume()
450 if (!pm_runtime_suspended(sdev->dev)) in imx8m_dsp_suspend()
461 /* DSP core boot */
518 .compatible = "fsl,imx8mp-evk-revb4",
519 .sof_tplg_filename = "sof-imx8mp-wm8962.tplg",
520 .drv_name = "asoc-audio-graph-card2",
523 .compatible = "fsl,imx8mp-evk",
524 .sof_tplg_filename = "sof-imx8mp-wm8960.tplg",
525 .drv_name = "asoc-audio-graph-card2",
538 [SOF_IPC_TYPE_3] = "imx/sof-tplg",
541 [SOF_IPC_TYPE_3] = "sof-imx8m.ri",
543 .nocodec_tplg_filename = "sof-imx8-nocodec.tplg",
548 { .compatible = "fsl,imx8mp-dsp", .data = &sof_of_imx8mp_desc},
558 .name = "sof-audio-of-imx8m",