1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
3 // Copyright(c) 2021 Mediatek Inc. All rights reserved.
5 // Author: YC Hung <yc.hung@mediatek.com>
9 * Hardware interface for audio DSP on mt8195
12 #include <linux/delay.h>
13 #include <linux/firmware.h>
15 #include <linux/of_address.h>
16 #include <linux/of_irq.h>
17 #include <linux/of_platform.h>
18 #include <linux/of_reserved_mem.h>
19 #include <linux/module.h>
21 #include <sound/sof.h>
22 #include <sound/sof/xtensa.h>
23 #include "../../ops.h"
24 #include "../../sof-of-dev.h"
25 #include "../../sof-audio.h"
26 #include "../adsp_helper.h"
27 #include "../mtk-adsp-common.h"
29 #include "mt8195-clk.h"
31 static int mt8195_get_mailbox_offset(struct snd_sof_dev
*sdev
)
36 static int mt8195_get_window_offset(struct snd_sof_dev
*sdev
, u32 id
)
41 static int mt8195_send_msg(struct snd_sof_dev
*sdev
,
42 struct snd_sof_ipc_msg
*msg
)
44 struct adsp_priv
*priv
= sdev
->pdata
->hw_pdata
;
46 sof_mailbox_write(sdev
, sdev
->host_box
.offset
, msg
->msg_data
,
49 return mtk_adsp_ipc_send(priv
->dsp_ipc
, MTK_ADSP_IPC_REQ
, MTK_ADSP_IPC_OP_REQ
);
52 static void mt8195_dsp_handle_reply(struct mtk_adsp_ipc
*ipc
)
54 struct adsp_priv
*priv
= mtk_adsp_ipc_get_data(ipc
);
57 spin_lock_irqsave(&priv
->sdev
->ipc_lock
, flags
);
58 snd_sof_ipc_process_reply(priv
->sdev
, 0);
59 spin_unlock_irqrestore(&priv
->sdev
->ipc_lock
, flags
);
62 static void mt8195_dsp_handle_request(struct mtk_adsp_ipc
*ipc
)
64 struct adsp_priv
*priv
= mtk_adsp_ipc_get_data(ipc
);
65 u32 p
; /* panic code */
68 /* Read the message from the debug box. */
69 sof_mailbox_read(priv
->sdev
, priv
->sdev
->debug_box
.offset
+ 4,
72 /* Check to see if the message is a panic code 0x0dead*** */
73 if ((p
& SOF_IPC_PANIC_MAGIC_MASK
) == SOF_IPC_PANIC_MAGIC
) {
74 snd_sof_dsp_panic(priv
->sdev
, p
, true);
76 snd_sof_ipc_msgs_rx(priv
->sdev
);
78 /* tell DSP cmd is done */
79 ret
= mtk_adsp_ipc_send(priv
->dsp_ipc
, MTK_ADSP_IPC_RSP
, MTK_ADSP_IPC_OP_RSP
);
81 dev_err(priv
->dev
, "request send ipc failed");
85 static const struct mtk_adsp_ipc_ops dsp_ops
= {
86 .handle_reply
= mt8195_dsp_handle_reply
,
87 .handle_request
= mt8195_dsp_handle_request
,
90 static int platform_parse_resource(struct platform_device
*pdev
, void *data
)
92 struct resource
*mmio
;
94 struct device_node
*mem_region
;
95 struct device
*dev
= &pdev
->dev
;
96 struct mtk_adsp_chip_info
*adsp
= data
;
99 ret
= of_reserved_mem_device_init(dev
);
101 dev_err(dev
, "of_reserved_mem_device_init failed\n");
105 mem_region
= of_parse_phandle(dev
->of_node
, "memory-region", 1);
107 dev_err(dev
, "no memory-region sysmem phandle\n");
111 ret
= of_address_to_resource(mem_region
, 0, &res
);
112 of_node_put(mem_region
);
114 dev_err(dev
, "of_address_to_resource sysmem failed\n");
118 adsp
->pa_dram
= (phys_addr_t
)res
.start
;
119 adsp
->dramsize
= resource_size(&res
);
120 if (adsp
->pa_dram
& DRAM_REMAP_MASK
) {
121 dev_err(dev
, "adsp memory(%#x) is not 4K-aligned\n",
126 if (adsp
->dramsize
< TOTAL_SIZE_SHARED_DRAM_FROM_TAIL
) {
127 dev_err(dev
, "adsp memory(%#x) is not enough for share\n",
132 dev_dbg(dev
, "dram pbase=%pa, dramsize=%#x\n",
133 &adsp
->pa_dram
, adsp
->dramsize
);
136 mmio
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "cfg");
138 dev_err(dev
, "no ADSP-CFG register resource\n");
141 /* remap for DSP register accessing */
142 adsp
->va_cfgreg
= devm_ioremap_resource(dev
, mmio
);
143 if (IS_ERR(adsp
->va_cfgreg
))
144 return PTR_ERR(adsp
->va_cfgreg
);
146 adsp
->pa_cfgreg
= (phys_addr_t
)mmio
->start
;
147 adsp
->cfgregsize
= resource_size(mmio
);
149 dev_dbg(dev
, "cfgreg-vbase=%p, cfgregsize=%#x\n",
150 adsp
->va_cfgreg
, adsp
->cfgregsize
);
153 mmio
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "sram");
155 dev_err(dev
, "no SRAM resource\n");
159 adsp
->pa_sram
= (phys_addr_t
)mmio
->start
;
160 adsp
->sramsize
= resource_size(mmio
);
162 dev_dbg(dev
, "sram pbase=%pa,%#x\n", &adsp
->pa_sram
, adsp
->sramsize
);
167 static int adsp_sram_power_on(struct device
*dev
, bool on
)
169 void __iomem
*va_dspsysreg
;
172 va_dspsysreg
= ioremap(ADSP_SRAM_POOL_CON
, 0x4);
174 dev_err(dev
, "failed to ioremap sram pool base %#x\n",
179 srampool_con
= readl(va_dspsysreg
);
181 writel(srampool_con
& ~DSP_SRAM_POOL_PD_MASK
, va_dspsysreg
);
183 writel(srampool_con
| DSP_SRAM_POOL_PD_MASK
, va_dspsysreg
);
185 iounmap(va_dspsysreg
);
189 /* Init the basic DSP DRAM address */
190 static int adsp_memory_remap_init(struct device
*dev
, struct mtk_adsp_chip_info
*adsp
)
192 void __iomem
*vaddr_emi_map
;
198 vaddr_emi_map
= devm_ioremap(dev
, DSP_EMI_MAP_ADDR
, 0x4);
199 if (!vaddr_emi_map
) {
200 dev_err(dev
, "failed to ioremap emi map base %#x\n",
205 offset
= adsp
->pa_dram
- DRAM_PHYS_BASE_FROM_DSP_VIEW
;
206 adsp
->dram_offset
= offset
;
207 offset
>>= DRAM_REMAP_SHIFT
;
208 dev_dbg(dev
, "adsp->pa_dram %pa, offset %#x\n", &adsp
->pa_dram
, offset
);
209 writel(offset
, vaddr_emi_map
);
210 if (offset
!= readl(vaddr_emi_map
)) {
211 dev_err(dev
, "write emi map fail : %#x\n", readl(vaddr_emi_map
));
218 static int mt8195_run(struct snd_sof_dev
*sdev
)
220 u32 adsp_bootup_addr
;
222 adsp_bootup_addr
= SRAM_PHYS_BASE_FROM_DSP_VIEW
;
223 dev_dbg(sdev
->dev
, "HIFIxDSP boot from base : 0x%08X\n", adsp_bootup_addr
);
224 sof_hifixdsp_boot_sequence(sdev
, adsp_bootup_addr
);
229 static int mt8195_dsp_probe(struct snd_sof_dev
*sdev
)
231 struct platform_device
*pdev
= container_of(sdev
->dev
, struct platform_device
, dev
);
232 struct adsp_priv
*priv
;
235 priv
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
239 sdev
->pdata
->hw_pdata
= priv
;
240 priv
->dev
= sdev
->dev
;
243 priv
->adsp
= devm_kzalloc(&pdev
->dev
, sizeof(struct mtk_adsp_chip_info
), GFP_KERNEL
);
247 ret
= platform_parse_resource(pdev
, priv
->adsp
);
251 ret
= mt8195_adsp_init_clock(sdev
);
253 dev_err(sdev
->dev
, "mt8195_adsp_init_clock failed\n");
257 ret
= adsp_clock_on(sdev
);
259 dev_err(sdev
->dev
, "adsp_clock_on fail!\n");
263 ret
= adsp_sram_power_on(sdev
->dev
, true);
265 dev_err(sdev
->dev
, "adsp_sram_power_on fail!\n");
266 goto exit_clk_disable
;
269 ret
= adsp_memory_remap_init(&pdev
->dev
, priv
->adsp
);
271 dev_err(sdev
->dev
, "adsp_memory_remap_init fail!\n");
272 goto err_adsp_sram_power_off
;
275 sdev
->bar
[SOF_FW_BLK_TYPE_IRAM
] = devm_ioremap(sdev
->dev
,
277 priv
->adsp
->sramsize
);
278 if (!sdev
->bar
[SOF_FW_BLK_TYPE_IRAM
]) {
279 dev_err(sdev
->dev
, "failed to ioremap base %pa size %#x\n",
280 &priv
->adsp
->pa_sram
, priv
->adsp
->sramsize
);
282 goto err_adsp_sram_power_off
;
285 priv
->adsp
->va_sram
= sdev
->bar
[SOF_FW_BLK_TYPE_IRAM
];
287 sdev
->bar
[SOF_FW_BLK_TYPE_SRAM
] = devm_ioremap(sdev
->dev
,
289 priv
->adsp
->dramsize
);
290 if (!sdev
->bar
[SOF_FW_BLK_TYPE_SRAM
]) {
291 dev_err(sdev
->dev
, "failed to ioremap base %pa size %#x\n",
292 &priv
->adsp
->pa_dram
, priv
->adsp
->dramsize
);
294 goto err_adsp_sram_power_off
;
296 priv
->adsp
->va_dram
= sdev
->bar
[SOF_FW_BLK_TYPE_SRAM
];
298 sdev
->bar
[DSP_REG_BAR
] = priv
->adsp
->va_cfgreg
;
300 sdev
->mmio_bar
= SOF_FW_BLK_TYPE_SRAM
;
301 sdev
->mailbox_bar
= SOF_FW_BLK_TYPE_SRAM
;
303 /* set default mailbox offset for FW ready message */
304 sdev
->dsp_box
.offset
= mt8195_get_mailbox_offset(sdev
);
306 priv
->ipc_dev
= platform_device_register_data(&pdev
->dev
, "mtk-adsp-ipc",
308 pdev
, sizeof(*pdev
));
309 if (IS_ERR(priv
->ipc_dev
)) {
310 ret
= PTR_ERR(priv
->ipc_dev
);
311 dev_err(sdev
->dev
, "failed to register mtk-adsp-ipc device\n");
312 goto err_adsp_sram_power_off
;
315 priv
->dsp_ipc
= dev_get_drvdata(&priv
->ipc_dev
->dev
);
316 if (!priv
->dsp_ipc
) {
318 dev_err(sdev
->dev
, "failed to get drvdata\n");
319 goto exit_pdev_unregister
;
322 mtk_adsp_ipc_set_data(priv
->dsp_ipc
, priv
);
323 priv
->dsp_ipc
->ops
= &dsp_ops
;
327 exit_pdev_unregister
:
328 platform_device_unregister(priv
->ipc_dev
);
329 err_adsp_sram_power_off
:
330 adsp_sram_power_on(&pdev
->dev
, false);
332 adsp_clock_off(sdev
);
337 static int mt8195_dsp_shutdown(struct snd_sof_dev
*sdev
)
339 return snd_sof_suspend(sdev
->dev
);
342 static void mt8195_dsp_remove(struct snd_sof_dev
*sdev
)
344 struct platform_device
*pdev
= container_of(sdev
->dev
, struct platform_device
, dev
);
345 struct adsp_priv
*priv
= sdev
->pdata
->hw_pdata
;
347 platform_device_unregister(priv
->ipc_dev
);
348 adsp_sram_power_on(&pdev
->dev
, false);
349 adsp_clock_off(sdev
);
352 static int mt8195_dsp_suspend(struct snd_sof_dev
*sdev
, u32 target_state
)
354 struct platform_device
*pdev
= container_of(sdev
->dev
, struct platform_device
, dev
);
356 u32 reset_sw
, dbg_pc
;
358 /* wait dsp enter idle, timeout is 1 second */
359 ret
= snd_sof_dsp_read_poll_timeout(sdev
, DSP_REG_BAR
,
360 DSP_RESET_SW
, reset_sw
,
361 ((reset_sw
& ADSP_PWAIT
) == ADSP_PWAIT
),
362 SUSPEND_DSP_IDLE_POLL_INTERVAL_US
,
363 SUSPEND_DSP_IDLE_TIMEOUT_US
);
365 dbg_pc
= snd_sof_dsp_read(sdev
, DSP_REG_BAR
, DSP_PDEBUGPC
);
366 dev_warn(sdev
->dev
, "dsp not idle, powering off anyway : swrest %#x, pc %#x, ret %d\n",
367 reset_sw
, dbg_pc
, ret
);
370 /* stall and reset dsp */
371 sof_hifixdsp_shutdown(sdev
);
373 /* power down adsp sram */
374 ret
= adsp_sram_power_on(&pdev
->dev
, false);
376 dev_err(sdev
->dev
, "adsp_sram_power_off fail!\n");
380 /* turn off adsp clock */
381 return adsp_clock_off(sdev
);
384 static int mt8195_dsp_resume(struct snd_sof_dev
*sdev
)
388 /* turn on adsp clock */
389 ret
= adsp_clock_on(sdev
);
391 dev_err(sdev
->dev
, "adsp_clock_on fail!\n");
395 /* power on adsp sram */
396 ret
= adsp_sram_power_on(sdev
->dev
, true);
398 dev_err(sdev
->dev
, "adsp_sram_power_on fail!\n");
403 /* on mt8195 there is 1 to 1 match between type and BAR idx */
404 static int mt8195_get_bar_index(struct snd_sof_dev
*sdev
, u32 type
)
409 static int mt8195_pcm_hw_params(struct snd_sof_dev
*sdev
,
410 struct snd_pcm_substream
*substream
,
411 struct snd_pcm_hw_params
*params
,
412 struct snd_sof_platform_stream_params
*platform_params
)
414 platform_params
->cont_update_posn
= 1;
419 static snd_pcm_uframes_t
mt8195_pcm_pointer(struct snd_sof_dev
*sdev
,
420 struct snd_pcm_substream
*substream
)
423 snd_pcm_uframes_t pos
;
424 struct snd_sof_pcm
*spcm
;
425 struct sof_ipc_stream_posn posn
;
426 struct snd_sof_pcm_stream
*stream
;
427 struct snd_soc_component
*scomp
= sdev
->component
;
428 struct snd_soc_pcm_runtime
*rtd
= snd_soc_substream_to_rtd(substream
);
430 spcm
= snd_sof_find_spcm_dai(scomp
, rtd
);
432 dev_warn_ratelimited(sdev
->dev
, "warn: can't find PCM with DAI ID %d\n",
437 stream
= &spcm
->stream
[substream
->stream
];
438 ret
= snd_sof_ipc_msg_data(sdev
, stream
, &posn
, sizeof(posn
));
440 dev_warn(sdev
->dev
, "failed to read stream position: %d\n", ret
);
444 memcpy(&stream
->posn
, &posn
, sizeof(posn
));
445 pos
= spcm
->stream
[substream
->stream
].posn
.host_posn
;
446 pos
= bytes_to_frames(substream
->runtime
, pos
);
451 static void mt8195_adsp_dump(struct snd_sof_dev
*sdev
, u32 flags
)
453 u32 dbg_pc
, dbg_data
, dbg_bus0
, dbg_bus1
, dbg_inst
;
454 u32 dbg_ls0stat
, dbg_ls1stat
, faultbus
, faultinfo
, swrest
;
456 /* dump debug registers */
457 dbg_pc
= snd_sof_dsp_read(sdev
, DSP_REG_BAR
, DSP_PDEBUGPC
);
458 dbg_data
= snd_sof_dsp_read(sdev
, DSP_REG_BAR
, DSP_PDEBUGDATA
);
459 dbg_bus0
= snd_sof_dsp_read(sdev
, DSP_REG_BAR
, DSP_PDEBUGBUS0
);
460 dbg_bus1
= snd_sof_dsp_read(sdev
, DSP_REG_BAR
, DSP_PDEBUGBUS1
);
461 dbg_inst
= snd_sof_dsp_read(sdev
, DSP_REG_BAR
, DSP_PDEBUGINST
);
462 dbg_ls0stat
= snd_sof_dsp_read(sdev
, DSP_REG_BAR
, DSP_PDEBUGLS0STAT
);
463 dbg_ls1stat
= snd_sof_dsp_read(sdev
, DSP_REG_BAR
, DSP_PDEBUGLS1STAT
);
464 faultbus
= snd_sof_dsp_read(sdev
, DSP_REG_BAR
, DSP_PFAULTBUS
);
465 faultinfo
= snd_sof_dsp_read(sdev
, DSP_REG_BAR
, DSP_PFAULTINFO
);
466 swrest
= snd_sof_dsp_read(sdev
, DSP_REG_BAR
, DSP_RESET_SW
);
468 dev_info(sdev
->dev
, "adsp dump : pc %#x, data %#x, bus0 %#x, bus1 %#x, swrest %#x",
469 dbg_pc
, dbg_data
, dbg_bus0
, dbg_bus1
, swrest
);
470 dev_info(sdev
->dev
, "dbg_inst %#x, ls0stat %#x, ls1stat %#x, faultbus %#x, faultinfo %#x",
471 dbg_inst
, dbg_ls0stat
, dbg_ls1stat
, faultbus
, faultinfo
);
473 mtk_adsp_dump(sdev
, flags
);
476 static struct snd_soc_dai_driver mt8195_dai
[] = {
508 static const struct snd_sof_dsp_ops sof_mt8195_ops
= {
509 /* probe and remove */
510 .probe
= mt8195_dsp_probe
,
511 .remove
= mt8195_dsp_remove
,
512 .shutdown
= mt8195_dsp_shutdown
,
518 .block_read
= sof_block_read
,
519 .block_write
= sof_block_write
,
522 .mailbox_read
= sof_mailbox_read
,
523 .mailbox_write
= sof_mailbox_write
,
526 .write
= sof_io_write
,
528 .write64
= sof_io_write64
,
529 .read64
= sof_io_read64
,
532 .send_msg
= mt8195_send_msg
,
533 .get_mailbox_offset
= mt8195_get_mailbox_offset
,
534 .get_window_offset
= mt8195_get_window_offset
,
535 .ipc_msg_data
= sof_ipc_msg_data
,
536 .set_stream_data_offset
= sof_set_stream_data_offset
,
539 .get_bar_index
= mt8195_get_bar_index
,
541 /* stream callbacks */
542 .pcm_open
= sof_stream_pcm_open
,
543 .pcm_hw_params
= mt8195_pcm_hw_params
,
544 .pcm_pointer
= mt8195_pcm_pointer
,
545 .pcm_close
= sof_stream_pcm_close
,
547 /* firmware loading */
548 .load_firmware
= snd_sof_load_firmware_memcpy
,
551 .dsp_arch_ops
= &sof_xtensa_arch_ops
,
553 /* Debug information */
554 .dbg_dump
= mt8195_adsp_dump
,
555 .debugfs_add_region_item
= snd_sof_debugfs_add_region_item_iomem
,
559 .num_drv
= ARRAY_SIZE(mt8195_dai
),
562 .suspend
= mt8195_dsp_suspend
,
563 .resume
= mt8195_dsp_resume
,
565 /* ALSA HW info flags */
566 .hw_info
= SNDRV_PCM_INFO_MMAP
|
567 SNDRV_PCM_INFO_MMAP_VALID
|
568 SNDRV_PCM_INFO_INTERLEAVED
|
569 SNDRV_PCM_INFO_PAUSE
|
570 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP
,
573 static struct snd_sof_of_mach sof_mt8195_machs
[] = {
575 .compatible
= "google,tomato",
576 .sof_tplg_filename
= "sof-mt8195-mt6359-rt1019-rt5682.tplg"
578 .compatible
= "google,dojo",
579 .sof_tplg_filename
= "sof-mt8195-mt6359-max98390-rt5682.tplg"
581 .compatible
= "mediatek,mt8195",
582 .sof_tplg_filename
= "sof-mt8195.tplg"
588 static const struct sof_dev_desc sof_of_mt8195_desc
= {
589 .of_machines
= sof_mt8195_machs
,
590 .ipc_supported_mask
= BIT(SOF_IPC_TYPE_3
),
591 .ipc_default
= SOF_IPC_TYPE_3
,
593 [SOF_IPC_TYPE_3
] = "mediatek/sof",
595 .default_tplg_path
= {
596 [SOF_IPC_TYPE_3
] = "mediatek/sof-tplg",
598 .default_fw_filename
= {
599 [SOF_IPC_TYPE_3
] = "sof-mt8195.ri",
601 .nocodec_tplg_filename
= "sof-mt8195-nocodec.tplg",
602 .ops
= &sof_mt8195_ops
,
606 static const struct of_device_id sof_of_mt8195_ids
[] = {
607 { .compatible
= "mediatek,mt8195-dsp", .data
= &sof_of_mt8195_desc
},
610 MODULE_DEVICE_TABLE(of
, sof_of_mt8195_ids
);
612 /* DT driver definition */
613 static struct platform_driver snd_sof_of_mt8195_driver
= {
614 .probe
= sof_of_probe
,
615 .remove
= sof_of_remove
,
616 .shutdown
= sof_of_shutdown
,
618 .name
= "sof-audio-of-mt8195",
620 .of_match_table
= sof_of_mt8195_ids
,
623 module_platform_driver(snd_sof_of_mt8195_driver
);
625 MODULE_LICENSE("Dual BSD/GPL");
626 MODULE_DESCRIPTION("SOF support for MTL 8195 platforms");
627 MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA");
628 MODULE_IMPORT_NS("SND_SOC_SOF_MTK_COMMON");