xref: /kernel/linux/linux-6.6/sound/soc/sof/intel/tgl.c (revision 62306a36)
1// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause)
2//
3// Copyright(c) 2020 Intel Corporation. All rights reserved.
4//
5// Authors: Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
6//
7
8/*
9 * Hardware interface for audio DSP on Tigerlake.
10 */
11
12#include <sound/sof/ext_manifest4.h>
13#include "../ipc4-priv.h"
14#include "../ops.h"
15#include "hda.h"
16#include "hda-ipc.h"
17#include "../sof-audio.h"
18
19static const struct snd_sof_debugfs_map tgl_dsp_debugfs[] = {
20	{"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS},
21	{"pp", HDA_DSP_PP_BAR,  0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS},
22	{"dsp", HDA_DSP_BAR,  0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS},
23};
24
25static int tgl_dsp_core_get(struct snd_sof_dev *sdev, int core)
26{
27	const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm;
28
29	/* power up primary core if not already powered up and return */
30	if (core == SOF_DSP_PRIMARY_CORE)
31		return hda_dsp_enable_core(sdev, BIT(core));
32
33	if (pm_ops->set_core_state)
34		return pm_ops->set_core_state(sdev, core, true);
35
36	return 0;
37}
38
39static int tgl_dsp_core_put(struct snd_sof_dev *sdev, int core)
40{
41	const struct sof_ipc_pm_ops *pm_ops = sdev->ipc->ops->pm;
42	int ret;
43
44	if (pm_ops->set_core_state) {
45		ret = pm_ops->set_core_state(sdev, core, false);
46		if (ret < 0)
47			return ret;
48	}
49
50	/* power down primary core and return */
51	if (core == SOF_DSP_PRIMARY_CORE)
52		return hda_dsp_core_reset_power_down(sdev, BIT(core));
53
54	return 0;
55}
56
57/* Tigerlake ops */
58struct snd_sof_dsp_ops sof_tgl_ops;
59EXPORT_SYMBOL_NS(sof_tgl_ops, SND_SOC_SOF_INTEL_HDA_COMMON);
60
61int sof_tgl_ops_init(struct snd_sof_dev *sdev)
62{
63	/* common defaults */
64	memcpy(&sof_tgl_ops, &sof_hda_common_ops, sizeof(struct snd_sof_dsp_ops));
65
66	/* probe/remove/shutdown */
67	sof_tgl_ops.shutdown	= hda_dsp_shutdown_dma_flush;
68
69	if (sdev->pdata->ipc_type == SOF_IPC) {
70		/* doorbell */
71		sof_tgl_ops.irq_thread	= cnl_ipc_irq_thread;
72
73		/* ipc */
74		sof_tgl_ops.send_msg	= cnl_ipc_send_msg;
75
76		/* debug */
77		sof_tgl_ops.ipc_dump	= cnl_ipc_dump;
78
79		sof_tgl_ops.set_power_state = hda_dsp_set_power_state_ipc3;
80	}
81
82	if (sdev->pdata->ipc_type == SOF_INTEL_IPC4) {
83		struct sof_ipc4_fw_data *ipc4_data;
84
85		sdev->private = devm_kzalloc(sdev->dev, sizeof(*ipc4_data), GFP_KERNEL);
86		if (!sdev->private)
87			return -ENOMEM;
88
89		ipc4_data = sdev->private;
90		ipc4_data->manifest_fw_hdr_offset = SOF_MAN4_FW_HDR_OFFSET;
91
92		ipc4_data->mtrace_type = SOF_IPC4_MTRACE_INTEL_CAVS_2;
93
94		/* External library loading support */
95		ipc4_data->load_library = hda_dsp_ipc4_load_library;
96
97		/* doorbell */
98		sof_tgl_ops.irq_thread	= cnl_ipc4_irq_thread;
99
100		/* ipc */
101		sof_tgl_ops.send_msg	= cnl_ipc4_send_msg;
102
103		/* debug */
104		sof_tgl_ops.ipc_dump	= cnl_ipc4_dump;
105
106		sof_tgl_ops.set_power_state = hda_dsp_set_power_state_ipc4;
107	}
108
109	/* set DAI driver ops */
110	hda_set_dai_drv_ops(sdev, &sof_tgl_ops);
111
112	/* debug */
113	sof_tgl_ops.debug_map	= tgl_dsp_debugfs;
114	sof_tgl_ops.debug_map_count	= ARRAY_SIZE(tgl_dsp_debugfs);
115
116	/* pre/post fw run */
117	sof_tgl_ops.post_fw_run = hda_dsp_post_fw_run;
118
119	/* firmware run */
120	sof_tgl_ops.run = hda_dsp_cl_boot_firmware_iccmax;
121
122	/* dsp core get/put */
123	sof_tgl_ops.core_get = tgl_dsp_core_get;
124	sof_tgl_ops.core_put = tgl_dsp_core_put;
125
126	return 0;
127};
128EXPORT_SYMBOL_NS(sof_tgl_ops_init, SND_SOC_SOF_INTEL_HDA_COMMON);
129
130const struct sof_intel_dsp_desc tgl_chip_info = {
131	/* Tigerlake , Alderlake */
132	.cores_num = 4,
133	.init_core_mask = 1,
134	.host_managed_cores_mask = BIT(0),
135	.ipc_req = CNL_DSP_REG_HIPCIDR,
136	.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
137	.ipc_ack = CNL_DSP_REG_HIPCIDA,
138	.ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
139	.ipc_ctl = CNL_DSP_REG_HIPCCTL,
140	.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
141	.rom_init_timeout	= 300,
142	.ssp_count = TGL_SSP_COUNT,
143	.ssp_base_offset = CNL_SSP_BASE_OFFSET,
144	.sdw_shim_base = SDW_SHIM_BASE,
145	.sdw_alh_base = SDW_ALH_BASE,
146	.d0i3_offset = SOF_HDA_VS_D0I3C,
147	.read_sdw_lcount =  hda_sdw_check_lcount_common,
148	.enable_sdw_irq	= hda_common_enable_sdw_irq,
149	.check_sdw_irq	= hda_common_check_sdw_irq,
150	.check_sdw_wakeen_irq = hda_sdw_check_wakeen_irq_common,
151	.check_ipc_irq	= hda_dsp_check_ipc_irq,
152	.cl_init = cl_dsp_init,
153	.power_down_dsp = hda_power_down_dsp,
154	.disable_interrupts = hda_dsp_disable_interrupts,
155	.hw_ip_version = SOF_INTEL_CAVS_2_5,
156};
157EXPORT_SYMBOL_NS(tgl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
158
159const struct sof_intel_dsp_desc tglh_chip_info = {
160	/* Tigerlake-H */
161	.cores_num = 2,
162	.init_core_mask = 1,
163	.host_managed_cores_mask = BIT(0),
164	.ipc_req = CNL_DSP_REG_HIPCIDR,
165	.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
166	.ipc_ack = CNL_DSP_REG_HIPCIDA,
167	.ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
168	.ipc_ctl = CNL_DSP_REG_HIPCCTL,
169	.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
170	.rom_init_timeout	= 300,
171	.ssp_count = TGL_SSP_COUNT,
172	.ssp_base_offset = CNL_SSP_BASE_OFFSET,
173	.sdw_shim_base = SDW_SHIM_BASE,
174	.sdw_alh_base = SDW_ALH_BASE,
175	.d0i3_offset = SOF_HDA_VS_D0I3C,
176	.read_sdw_lcount =  hda_sdw_check_lcount_common,
177	.enable_sdw_irq	= hda_common_enable_sdw_irq,
178	.check_sdw_irq	= hda_common_check_sdw_irq,
179	.check_sdw_wakeen_irq = hda_sdw_check_wakeen_irq_common,
180	.check_ipc_irq	= hda_dsp_check_ipc_irq,
181	.cl_init = cl_dsp_init,
182	.power_down_dsp = hda_power_down_dsp,
183	.disable_interrupts = hda_dsp_disable_interrupts,
184	.hw_ip_version = SOF_INTEL_CAVS_2_5,
185};
186EXPORT_SYMBOL_NS(tglh_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
187
188const struct sof_intel_dsp_desc ehl_chip_info = {
189	/* Elkhartlake */
190	.cores_num = 4,
191	.init_core_mask = 1,
192	.host_managed_cores_mask = BIT(0),
193	.ipc_req = CNL_DSP_REG_HIPCIDR,
194	.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
195	.ipc_ack = CNL_DSP_REG_HIPCIDA,
196	.ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
197	.ipc_ctl = CNL_DSP_REG_HIPCCTL,
198	.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
199	.rom_init_timeout	= 300,
200	.ssp_count = TGL_SSP_COUNT,
201	.ssp_base_offset = CNL_SSP_BASE_OFFSET,
202	.sdw_shim_base = SDW_SHIM_BASE,
203	.sdw_alh_base = SDW_ALH_BASE,
204	.d0i3_offset = SOF_HDA_VS_D0I3C,
205	.read_sdw_lcount =  hda_sdw_check_lcount_common,
206	.enable_sdw_irq	= hda_common_enable_sdw_irq,
207	.check_sdw_irq	= hda_common_check_sdw_irq,
208	.check_sdw_wakeen_irq = hda_sdw_check_wakeen_irq_common,
209	.check_ipc_irq	= hda_dsp_check_ipc_irq,
210	.cl_init = cl_dsp_init,
211	.power_down_dsp = hda_power_down_dsp,
212	.disable_interrupts = hda_dsp_disable_interrupts,
213	.hw_ip_version = SOF_INTEL_CAVS_2_5,
214};
215EXPORT_SYMBOL_NS(ehl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
216
217const struct sof_intel_dsp_desc adls_chip_info = {
218	/* Alderlake-S */
219	.cores_num = 2,
220	.init_core_mask = BIT(0),
221	.host_managed_cores_mask = BIT(0),
222	.ipc_req = CNL_DSP_REG_HIPCIDR,
223	.ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
224	.ipc_ack = CNL_DSP_REG_HIPCIDA,
225	.ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
226	.ipc_ctl = CNL_DSP_REG_HIPCCTL,
227	.rom_status_reg = HDA_DSP_SRAM_REG_ROM_STATUS,
228	.rom_init_timeout	= 300,
229	.ssp_count = TGL_SSP_COUNT,
230	.ssp_base_offset = CNL_SSP_BASE_OFFSET,
231	.sdw_shim_base = SDW_SHIM_BASE,
232	.sdw_alh_base = SDW_ALH_BASE,
233	.d0i3_offset = SOF_HDA_VS_D0I3C,
234	.read_sdw_lcount =  hda_sdw_check_lcount_common,
235	.enable_sdw_irq	= hda_common_enable_sdw_irq,
236	.check_sdw_irq	= hda_common_check_sdw_irq,
237	.check_sdw_wakeen_irq = hda_sdw_check_wakeen_irq_common,
238	.check_ipc_irq	= hda_dsp_check_ipc_irq,
239	.cl_init = cl_dsp_init,
240	.power_down_dsp = hda_power_down_dsp,
241	.disable_interrupts = hda_dsp_disable_interrupts,
242	.hw_ip_version = SOF_INTEL_CAVS_2_5,
243};
244EXPORT_SYMBOL_NS(adls_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
245