Skip to content

Commit 7fef752

Browse files
LaurentiuM1234bardliao
authored andcommitted
ASoC: SOF: imx: add driver for the imx95 chip
Add SOF support for the imx95 chip. Although the support is just for the imx95 chip, the driver is intended for all chips in the imx9 family. Note that the imx95 support could have just as easily been added to the imx8 platform driver but a new platform driver was created because the intention is to keep the families in separate drivers. Signed-off-by: Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
1 parent c5fadb4 commit 7fef752

File tree

3 files changed

+146
-0
lines changed

3 files changed

+146
-0
lines changed

sound/soc/sof/imx/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,13 @@ config SND_SOC_SOF_IMX8
3232
Say Y if you have such a device.
3333
If unsure select "N".
3434

35+
config SND_SOC_SOF_IMX9
36+
tristate "SOF support for i.MX9"
37+
depends on IMX_DSP
38+
select SND_SOC_SOF_IMX_COMMON
39+
help
40+
This adds support for Sound Open Firmware for NXP i.MX9 platforms.
41+
Say Y if you need such a device.
42+
If unsure select "N".
43+
3544
endif ## SND_SOC_SOF_IMX_TOPLEVEL

sound/soc/sof/imx/Makefile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
22
snd-sof-imx8-y := imx8.o
3+
snd-sof-imx9-y := imx9.o
34

45
snd-sof-imx-common-y := imx-common.o
56

67
obj-$(CONFIG_SND_SOC_SOF_IMX8) += snd-sof-imx8.o
8+
obj-$(CONFIG_SND_SOC_SOF_IMX9) += snd-sof-imx9.o
79
obj-$(CONFIG_SND_SOC_SOF_IMX_COMMON) += imx-common.o

sound/soc/sof/imx/imx9.c

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

0 commit comments

Comments
 (0)