Lines Matching +full:dsp +full:- +full:reset
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
3 // Copyright 2021-2022 NXP
7 // Hardware interface for audio DSP on i.MX8ULP
9 #include <linux/arm-smccc.h>
12 #include <linux/firmware/imx/dsp.h>
26 #include "../sof-of-dev.h"
27 #include "imx-common.h"
47 /* DSP IPC handler */
58 /* Controls the HiFi4 DSP Reset: 1 in reset, 0 out of reset */ in imx8ulp_sim_lpav_start()
59 regmap_update_bits(priv->regmap, SYSCTRL0, RESET_BIT, 0); in imx8ulp_sim_lpav_start()
61 /* Reset HiFi4 DSP Debug logic: 1 debug reset, 0 out of reset*/ in imx8ulp_sim_lpav_start()
62 regmap_update_bits(priv->regmap, SYSCTRL0, DEBUG_LOGIC_BIT, 0); in imx8ulp_sim_lpav_start()
64 /* Stall HIFI4 DSP Execution: 1 stall, 0 run */ in imx8ulp_sim_lpav_start()
65 regmap_update_bits(priv->regmap, SYSCTRL0, EXECUTE_BIT, 0); in imx8ulp_sim_lpav_start()
83 spin_lock_irqsave(&priv->sdev->ipc_lock, flags); in imx8ulp_dsp_handle_reply()
85 snd_sof_ipc_process_reply(priv->sdev, 0); in imx8ulp_dsp_handle_reply()
87 spin_unlock_irqrestore(&priv->sdev->ipc_lock, flags); in imx8ulp_dsp_handle_reply()
96 sof_mailbox_read(priv->sdev, priv->sdev->debug_box.offset + 4, &p, sizeof(p)); in imx8ulp_dsp_handle_request()
100 snd_sof_dsp_panic(priv->sdev, p, true); in imx8ulp_dsp_handle_request()
102 snd_sof_ipc_msgs_rx(priv->sdev); in imx8ulp_dsp_handle_request()
112 struct imx8ulp_priv *priv = sdev->pdata->hw_pdata; in imx8ulp_send_msg()
114 sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, in imx8ulp_send_msg()
115 msg->msg_size); in imx8ulp_send_msg()
116 imx_dsp_ring_doorbell(priv->dsp_ipc, 0); in imx8ulp_send_msg()
123 struct imx8ulp_priv *priv = sdev->pdata->hw_pdata; in imx8ulp_run()
132 struct imx8ulp_priv *priv = sdev->pdata->hw_pdata; in imx8ulp_reset()
136 regmap_update_bits(priv->regmap, SYSCTRL0, PLAT_CLK_BIT, PLAT_CLK_BIT); in imx8ulp_reset()
139 regmap_update_bits(priv->regmap, SYSCTRL0, PB_CLK_BIT, PB_CLK_BIT); in imx8ulp_reset()
142 regmap_update_bits(priv->regmap, SYSCTRL0, HIFI4_CLK_BIT, HIFI4_CLK_BIT); in imx8ulp_reset()
144 regmap_update_bits(priv->regmap, SYSCTRL0, RESET_BIT, RESET_BIT); in imx8ulp_reset()
147 /* Stall HIFI4 DSP Execution: 1 stall, 0 not stall */ in imx8ulp_reset()
148 regmap_update_bits(priv->regmap, SYSCTRL0, EXECUTE_BIT, EXECUTE_BIT); in imx8ulp_reset()
159 container_of(sdev->dev, struct platform_device, dev); in imx8ulp_probe()
160 struct device_node *np = pdev->dev.of_node; in imx8ulp_probe()
168 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); in imx8ulp_probe()
170 return -ENOMEM; in imx8ulp_probe()
172 sdev->num_cores = 1; in imx8ulp_probe()
173 sdev->pdata->hw_pdata = priv; in imx8ulp_probe()
174 priv->dev = sdev->dev; in imx8ulp_probe()
175 priv->sdev = sdev; in imx8ulp_probe()
177 /* System integration module(SIM) control dsp configuration */ in imx8ulp_probe()
178 priv->regmap = syscon_regmap_lookup_by_phandle(np, "fsl,dsp-ctrl"); in imx8ulp_probe()
179 if (IS_ERR(priv->regmap)) in imx8ulp_probe()
180 return PTR_ERR(priv->regmap); in imx8ulp_probe()
182 priv->ipc_dev = platform_device_register_data(sdev->dev, "imx-dsp", in imx8ulp_probe()
185 if (IS_ERR(priv->ipc_dev)) in imx8ulp_probe()
186 return PTR_ERR(priv->ipc_dev); in imx8ulp_probe()
188 priv->dsp_ipc = dev_get_drvdata(&priv->ipc_dev->dev); in imx8ulp_probe()
189 if (!priv->dsp_ipc) { in imx8ulp_probe()
190 /* DSP IPC driver not probed yet, try later */ in imx8ulp_probe()
191 ret = -EPROBE_DEFER; in imx8ulp_probe()
192 dev_err(sdev->dev, "Failed to get drvdata\n"); in imx8ulp_probe()
196 imx_dsp_set_data(priv->dsp_ipc, priv); in imx8ulp_probe()
197 priv->dsp_ipc->ops = &dsp_ops; in imx8ulp_probe()
199 /* DSP base */ in imx8ulp_probe()
202 base = mmio->start; in imx8ulp_probe()
205 dev_err(sdev->dev, "error: failed to get DSP base at idx 0\n"); in imx8ulp_probe()
206 ret = -EINVAL; in imx8ulp_probe()
210 sdev->bar[SOF_FW_BLK_TYPE_IRAM] = devm_ioremap(sdev->dev, base, size); in imx8ulp_probe()
211 if (!sdev->bar[SOF_FW_BLK_TYPE_IRAM]) { in imx8ulp_probe()
212 dev_err(sdev->dev, "failed to ioremap base 0x%x size 0x%x\n", in imx8ulp_probe()
214 ret = -ENODEV; in imx8ulp_probe()
217 sdev->mmio_bar = SOF_FW_BLK_TYPE_IRAM; in imx8ulp_probe()
219 res_node = of_parse_phandle(np, "memory-reserved", 0); in imx8ulp_probe()
221 dev_err(&pdev->dev, "failed to get memory region node\n"); in imx8ulp_probe()
222 ret = -ENODEV; in imx8ulp_probe()
229 dev_err(&pdev->dev, "failed to get reserved region address\n"); in imx8ulp_probe()
233 sdev->bar[SOF_FW_BLK_TYPE_SRAM] = devm_ioremap_wc(sdev->dev, res.start, in imx8ulp_probe()
235 if (!sdev->bar[SOF_FW_BLK_TYPE_SRAM]) { in imx8ulp_probe()
236 dev_err(sdev->dev, "failed to ioremap mem 0x%x size 0x%x\n", in imx8ulp_probe()
238 ret = -ENOMEM; in imx8ulp_probe()
241 sdev->mailbox_bar = SOF_FW_BLK_TYPE_SRAM; in imx8ulp_probe()
244 sdev->dsp_box.offset = MBOX_OFFSET; in imx8ulp_probe()
246 ret = of_reserved_mem_device_init(sdev->dev); in imx8ulp_probe()
248 dev_err(&pdev->dev, "failed to init reserved memory region %d\n", ret); in imx8ulp_probe()
252 ret = devm_clk_bulk_get_all(sdev->dev, &priv->clks); in imx8ulp_probe()
254 dev_err(sdev->dev, "failed to fetch clocks: %d\n", ret); in imx8ulp_probe()
257 priv->clk_num = ret; in imx8ulp_probe()
259 ret = clk_bulk_prepare_enable(priv->clk_num, priv->clks); in imx8ulp_probe()
261 dev_err(sdev->dev, "failed to enable clocks: %d\n", ret); in imx8ulp_probe()
268 platform_device_unregister(priv->ipc_dev); in imx8ulp_probe()
275 struct imx8ulp_priv *priv = sdev->pdata->hw_pdata; in imx8ulp_remove()
277 clk_bulk_disable_unprepare(priv->clk_num, priv->clks); in imx8ulp_remove()
278 platform_device_unregister(priv->ipc_dev); in imx8ulp_remove()
290 struct imx8ulp_priv *priv = (struct imx8ulp_priv *)sdev->pdata->hw_pdata; in imx8ulp_suspend()
292 /*Stall DSP, release in .run() */ in imx8ulp_suspend()
293 regmap_update_bits(priv->regmap, SYSCTRL0, EXECUTE_BIT, EXECUTE_BIT); in imx8ulp_suspend()
296 imx_dsp_free_channel(priv->dsp_ipc, i); in imx8ulp_suspend()
298 clk_bulk_disable_unprepare(priv->clk_num, priv->clks); in imx8ulp_suspend()
305 struct imx8ulp_priv *priv = (struct imx8ulp_priv *)sdev->pdata->hw_pdata; in imx8ulp_resume()
308 ret = clk_bulk_prepare_enable(priv->clk_num, priv->clks); in imx8ulp_resume()
310 dev_err(sdev->dev, "failed to enable clocks: %d\n", ret); in imx8ulp_resume()
315 imx_dsp_request_channel(priv->dsp_ipc, i); in imx8ulp_resume()
351 if (!pm_runtime_suspended(sdev->dev)) in imx8ulp_dsp_suspend()
366 if (pm_runtime_suspended(sdev->dev)) { in imx8ulp_dsp_resume()
367 pm_runtime_disable(sdev->dev); in imx8ulp_dsp_resume()
368 pm_runtime_set_active(sdev->dev); in imx8ulp_dsp_resume()
369 pm_runtime_mark_last_busy(sdev->dev); in imx8ulp_dsp_resume()
370 pm_runtime_enable(sdev->dev); in imx8ulp_dsp_resume()
371 pm_runtime_idle(sdev->dev); in imx8ulp_dsp_resume()
405 sdev->dsp_power_state = *target_state; in imx8ulp_dsp_set_power_state()
415 /* DSP core boot */
417 .reset = imx8ulp_reset,
477 .compatible = "fsl,imx8ulp-evk",
478 .sof_tplg_filename = "sof-imx8ulp-btsco.tplg",
479 .drv_name = "asoc-audio-graph-card2",
492 [SOF_IPC_TYPE_3] = "imx/sof-tplg",
495 [SOF_IPC_TYPE_3] = "sof-imx8ulp.ri",
497 .nocodec_tplg_filename = "sof-imx8ulp-nocodec.tplg",
502 { .compatible = "fsl,imx8ulp-dsp", .data = &sof_of_imx8ulp_desc},
512 .name = "sof-audio-of-imx8ulp",