| // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) |
| /* |
| * Copyright 2025 NXP |
| */ |
| |
| #include <linux/firmware/imx/sm.h> |
| |
| #include "imx-common.h" |
| |
| #define IMX95_M7_CPU_ID 0x1 |
| #define IMX95_M7_LM_ID 0x1 |
| |
| static struct snd_soc_dai_driver imx95_dai[] = { |
| IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai3", 1, 32), |
| }; |
| |
| static struct snd_sof_dsp_ops sof_imx9_ops; |
| |
| static int imx95_ops_init(struct snd_sof_dev *sdev) |
| { |
| /* first copy from template */ |
| memcpy(&sof_imx9_ops, &sof_imx_ops, sizeof(sof_imx_ops)); |
| |
| /* ... and finally set DAI driver */ |
| sof_imx9_ops.drv = get_chip_info(sdev)->drv; |
| sof_imx9_ops.num_drv = get_chip_info(sdev)->num_drv; |
| |
| return 0; |
| } |
| |
| static int imx95_chip_probe(struct snd_sof_dev *sdev) |
| { |
| struct platform_device *pdev; |
| struct resource *res; |
| |
| pdev = to_platform_device(sdev->dev); |
| |
| res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram"); |
| if (!res) |
| return dev_err_probe(sdev->dev, -ENODEV, |
| "failed to fetch SRAM region\n"); |
| |
| return scmi_imx_lmm_reset_vector_set(IMX95_M7_LM_ID, IMX95_M7_CPU_ID, |
| 0, res->start); |
| } |
| |
| static int imx95_core_kick(struct snd_sof_dev *sdev) |
| { |
| return scmi_imx_lmm_operation(IMX95_M7_LM_ID, SCMI_IMX_LMM_BOOT, 0); |
| } |
| |
| static int imx95_core_shutdown(struct snd_sof_dev *sdev) |
| { |
| return scmi_imx_lmm_operation(IMX95_M7_LM_ID, |
| SCMI_IMX_LMM_SHUTDOWN, |
| SCMI_IMX_LMM_OP_FORCEFUL); |
| } |
| |
| static const struct imx_chip_ops imx95_chip_ops = { |
| .probe = imx95_chip_probe, |
| .core_kick = imx95_core_kick, |
| .core_shutdown = imx95_core_shutdown, |
| }; |
| |
| static struct imx_memory_info imx95_memory_regions[] = { |
| { .name = "sram", .reserved = false }, |
| { } |
| }; |
| |
| static const struct imx_chip_info imx95_chip_info = { |
| .ipc_info = { |
| .boot_mbox_offset = 0x6001000, |
| .window_offset = 0x6000000, |
| }, |
| .has_dma_reserved = true, |
| .memory = imx95_memory_regions, |
| .drv = imx95_dai, |
| .num_drv = ARRAY_SIZE(imx95_dai), |
| .ops = &imx95_chip_ops, |
| }; |
| |
| static struct snd_sof_of_mach sof_imx9_machs[] = { |
| { |
| .compatible = "fsl,imx95-19x19-evk", |
| .sof_tplg_filename = "sof-imx95-wm8962.tplg", |
| .drv_name = "asoc-audio-graph-card2", |
| }, |
| { |
| } |
| }; |
| |
| IMX_SOF_DEV_DESC(imx95, sof_imx9_machs, &imx95_chip_info, &sof_imx9_ops, imx95_ops_init); |
| |
| static const struct of_device_id sof_of_imx9_ids[] = { |
| { |
| .compatible = "fsl,imx95-cm7-sof", |
| .data = &IMX_SOF_DEV_DESC_NAME(imx95), |
| }, |
| { |
| }, |
| }; |
| MODULE_DEVICE_TABLE(of, sof_of_imx9_ids); |
| |
| static struct platform_driver snd_sof_of_imx9_driver = { |
| .probe = sof_of_probe, |
| .remove = sof_of_remove, |
| .driver = { |
| .name = "sof-audio-of-imx9", |
| .pm = pm_ptr(&sof_of_pm), |
| .of_match_table = sof_of_imx9_ids, |
| }, |
| }; |
| module_platform_driver(snd_sof_of_imx9_driver); |
| |
| MODULE_LICENSE("Dual BSD/GPL"); |
| MODULE_DESCRIPTION("SOF driver for imx9 platforms"); |
| MODULE_AUTHOR("Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>"); |