xref: /linux/sound/soc/sof/imx/imx9.c (revision b61104e7a6349bd2c2b3e2fb3260d87f15eda8f4)
1 // SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2 /*
3  * Copyright 2025 NXP
4  */
5 
6 #include <linux/firmware/imx/sm.h>
7 
8 #include "imx-common.h"
9 
10 #define IMX95_M7_CPU_ID 0x1
11 #define IMX95_M7_LM_ID 0x1
12 
13 static struct snd_soc_dai_driver imx95_dai[] = {
14 	IMX_SOF_DAI_DRV_ENTRY_BIDIR("sai3", 1, 32),
15 };
16 
17 static struct snd_sof_dsp_ops sof_imx9_ops;
18 
19 static int imx95_ops_init(struct snd_sof_dev *sdev)
20 {
21 	/* first copy from template */
22 	memcpy(&sof_imx9_ops, &sof_imx_ops, sizeof(sof_imx_ops));
23 
24 	/* ... and finally set DAI driver */
25 	sof_imx9_ops.drv = get_chip_info(sdev)->drv;
26 	sof_imx9_ops.num_drv = get_chip_info(sdev)->num_drv;
27 
28 	return 0;
29 }
30 
31 static int imx95_chip_probe(struct snd_sof_dev *sdev)
32 {
33 	struct platform_device *pdev;
34 	struct resource *res;
35 
36 	pdev = to_platform_device(sdev->dev);
37 
38 	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "sram");
39 	if (!res)
40 		return dev_err_probe(sdev->dev, -ENODEV,
41 				     "failed to fetch SRAM region\n");
42 
43 	return scmi_imx_lmm_reset_vector_set(IMX95_M7_LM_ID, IMX95_M7_CPU_ID,
44 					     0, res->start);
45 }
46 
47 static int imx95_core_kick(struct snd_sof_dev *sdev)
48 {
49 	return scmi_imx_lmm_operation(IMX95_M7_LM_ID, SCMI_IMX_LMM_BOOT, 0);
50 }
51 
52 static int imx95_core_shutdown(struct snd_sof_dev *sdev)
53 {
54 	return scmi_imx_lmm_operation(IMX95_M7_LM_ID,
55 				      SCMI_IMX_LMM_SHUTDOWN,
56 				      SCMI_IMX_LMM_OP_FORCEFUL);
57 }
58 
59 static const struct imx_chip_ops imx95_chip_ops = {
60 	.probe = imx95_chip_probe,
61 	.core_kick = imx95_core_kick,
62 	.core_shutdown = imx95_core_shutdown,
63 };
64 
65 static struct imx_memory_info imx95_memory_regions[] = {
66 	{ .name = "sram", .reserved = false },
67 	{ }
68 };
69 
70 static const struct imx_chip_info imx95_chip_info = {
71 	.ipc_info = {
72 		.boot_mbox_offset = 0x6001000,
73 		.window_offset = 0x6000000,
74 	},
75 	.has_dma_reserved = true,
76 	.memory = imx95_memory_regions,
77 	.drv = imx95_dai,
78 	.num_drv = ARRAY_SIZE(imx95_dai),
79 	.ops = &imx95_chip_ops,
80 };
81 
82 static struct snd_sof_of_mach sof_imx9_machs[] = {
83 	{
84 		.compatible = "fsl,imx95-19x19-evk",
85 		.sof_tplg_filename = "sof-imx95-wm8962.tplg",
86 		.drv_name = "asoc-audio-graph-card2",
87 	},
88 	{
89 	}
90 };
91 
92 IMX_SOF_DEV_DESC(imx95, sof_imx9_machs, &imx95_chip_info, &sof_imx9_ops, imx95_ops_init);
93 
94 static const struct of_device_id sof_of_imx9_ids[] = {
95 	{
96 		.compatible = "fsl,imx95-cm7-sof",
97 		.data = &IMX_SOF_DEV_DESC_NAME(imx95),
98 	},
99 	{
100 	},
101 };
102 MODULE_DEVICE_TABLE(of, sof_of_imx9_ids);
103 
104 static struct platform_driver snd_sof_of_imx9_driver = {
105 	.probe = sof_of_probe,
106 	.remove = sof_of_remove,
107 	.driver = {
108 		.name = "sof-audio-of-imx9",
109 		.pm = pm_ptr(&sof_of_pm),
110 		.of_match_table = sof_of_imx9_ids,
111 	},
112 };
113 module_platform_driver(snd_sof_of_imx9_driver);
114 
115 MODULE_LICENSE("Dual BSD/GPL");
116 MODULE_DESCRIPTION("SOF driver for imx9 platforms");
117 MODULE_AUTHOR("Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>");
118