1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include "../ops.h"
19#include "hda.h"
20#include "hda-ipc.h"
21#include "../sof-audio.h"
22
23static const struct snd_sof_debugfs_map cnl_dsp_debugfs[] = {
24 {"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS},
25 {"pp", HDA_DSP_PP_BAR, 0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS},
26 {"dsp", HDA_DSP_BAR, 0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS},
27};
28
29static void cnl_ipc_host_done(struct snd_sof_dev *sdev);
30static void cnl_ipc_dsp_done(struct snd_sof_dev *sdev);
31
32static irqreturn_t cnl_ipc_irq_thread(int irq, void *context)
33{
34 struct snd_sof_dev *sdev = context;
35 u32 hipci;
36 u32 hipcida;
37 u32 hipctdr;
38 u32 hipctdd;
39 u32 msg;
40 u32 msg_ext;
41 bool ipc_irq = false;
42
43 hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDA);
44 hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDR);
45 hipctdd = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDD);
46 hipci = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR);
47
48
49 if (hipcida & CNL_DSP_REG_HIPCIDA_DONE) {
50 msg_ext = hipci & CNL_DSP_REG_HIPCIDR_MSG_MASK;
51 msg = hipcida & CNL_DSP_REG_HIPCIDA_MSG_MASK;
52
53 dev_vdbg(sdev->dev,
54 "ipc: firmware response, msg:0x%x, msg_ext:0x%x\n",
55 msg, msg_ext);
56
57
58 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR,
59 CNL_DSP_REG_HIPCCTL,
60 CNL_DSP_REG_HIPCCTL_DONE, 0);
61
62 spin_lock_irq(&sdev->ipc_lock);
63
64
65 hda_dsp_ipc_get_reply(sdev);
66 snd_sof_ipc_reply(sdev, msg);
67
68 if (sdev->code_loading) {
69 sdev->code_loading = 0;
70 wake_up(&sdev->waitq);
71 }
72
73 cnl_ipc_dsp_done(sdev);
74
75 spin_unlock_irq(&sdev->ipc_lock);
76
77 ipc_irq = true;
78 }
79
80
81 if (hipctdr & CNL_DSP_REG_HIPCTDR_BUSY) {
82 msg = hipctdr & CNL_DSP_REG_HIPCTDR_MSG_MASK;
83 msg_ext = hipctdd & CNL_DSP_REG_HIPCTDD_MSG_MASK;
84
85 dev_vdbg(sdev->dev,
86 "ipc: firmware initiated, msg:0x%x, msg_ext:0x%x\n",
87 msg, msg_ext);
88
89
90 if ((hipctdr & SOF_IPC_PANIC_MAGIC_MASK) ==
91 SOF_IPC_PANIC_MAGIC) {
92 snd_sof_dsp_panic(sdev, HDA_DSP_PANIC_OFFSET(msg_ext));
93 } else {
94 snd_sof_ipc_msgs_rx(sdev);
95 }
96
97 cnl_ipc_host_done(sdev);
98
99 ipc_irq = true;
100 }
101
102 if (!ipc_irq) {
103
104
105
106 dev_dbg_ratelimited(sdev->dev,
107 "nothing to do in IPC IRQ thread\n");
108 }
109
110 return IRQ_HANDLED;
111}
112
113static void cnl_ipc_host_done(struct snd_sof_dev *sdev)
114{
115
116
117
118
119 snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR,
120 CNL_DSP_REG_HIPCTDR,
121 CNL_DSP_REG_HIPCTDR_BUSY,
122 CNL_DSP_REG_HIPCTDR_BUSY);
123
124
125
126
127 snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR,
128 CNL_DSP_REG_HIPCTDA,
129 CNL_DSP_REG_HIPCTDA_DONE,
130 CNL_DSP_REG_HIPCTDA_DONE);
131}
132
133static void cnl_ipc_dsp_done(struct snd_sof_dev *sdev)
134{
135
136
137
138
139 snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR,
140 CNL_DSP_REG_HIPCIDA,
141 CNL_DSP_REG_HIPCIDA_DONE,
142 CNL_DSP_REG_HIPCIDA_DONE);
143
144
145 snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR,
146 CNL_DSP_REG_HIPCCTL,
147 CNL_DSP_REG_HIPCCTL_DONE,
148 CNL_DSP_REG_HIPCCTL_DONE);
149}
150
151static bool cnl_compact_ipc_compress(struct snd_sof_ipc_msg *msg,
152 u32 *dr, u32 *dd)
153{
154 struct sof_ipc_pm_gate *pm_gate;
155
156 if (msg->header == (SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_GATE)) {
157 pm_gate = msg->msg_data;
158
159
160 *dr = HDA_IPC_MSG_COMPACT | HDA_IPC_PM_GATE;
161
162
163 *dd = pm_gate->flags;
164
165 return true;
166 }
167
168 return false;
169}
170
171static int cnl_ipc_send_msg(struct snd_sof_dev *sdev,
172 struct snd_sof_ipc_msg *msg)
173{
174 u32 dr = 0;
175 u32 dd = 0;
176
177 if (cnl_compact_ipc_compress(msg, &dr, &dd)) {
178
179 snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDD,
180 dd);
181 snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR,
182 CNL_DSP_REG_HIPCIDR_BUSY | dr);
183 } else {
184
185 sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
186 msg->msg_size);
187 snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR,
188 CNL_DSP_REG_HIPCIDR_BUSY);
189 }
190
191 return 0;
192}
193
194static void cnl_ipc_dump(struct snd_sof_dev *sdev)
195{
196 u32 hipcctl;
197 u32 hipcida;
198 u32 hipctdr;
199
200 hda_ipc_irq_dump(sdev);
201
202
203 hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDA);
204 hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCCTL);
205 hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDR);
206
207
208
209 dev_err(sdev->dev,
210 "error: host status 0x%8.8x dsp status 0x%8.8x mask 0x%8.8x\n",
211 hipcida, hipctdr, hipcctl);
212}
213
214
215const struct snd_sof_dsp_ops sof_cnl_ops = {
216
217 .probe = hda_dsp_probe,
218 .remove = hda_dsp_remove,
219
220
221 .write = sof_io_write,
222 .read = sof_io_read,
223 .write64 = sof_io_write64,
224 .read64 = sof_io_read64,
225
226
227 .block_read = sof_block_read,
228 .block_write = sof_block_write,
229
230
231 .irq_thread = cnl_ipc_irq_thread,
232
233
234 .send_msg = cnl_ipc_send_msg,
235 .fw_ready = sof_fw_ready,
236 .get_mailbox_offset = hda_dsp_ipc_get_mailbox_offset,
237 .get_window_offset = hda_dsp_ipc_get_window_offset,
238
239 .ipc_msg_data = hda_ipc_msg_data,
240 .ipc_pcm_params = hda_ipc_pcm_params,
241
242
243 .machine_select = hda_machine_select,
244 .machine_register = sof_machine_register,
245 .machine_unregister = sof_machine_unregister,
246 .set_mach_params = hda_set_mach_params,
247
248
249 .debug_map = cnl_dsp_debugfs,
250 .debug_map_count = ARRAY_SIZE(cnl_dsp_debugfs),
251 .dbg_dump = hda_dsp_dump,
252 .ipc_dump = cnl_ipc_dump,
253
254
255 .pcm_open = hda_dsp_pcm_open,
256 .pcm_close = hda_dsp_pcm_close,
257 .pcm_hw_params = hda_dsp_pcm_hw_params,
258 .pcm_hw_free = hda_dsp_stream_hw_free,
259 .pcm_trigger = hda_dsp_pcm_trigger,
260 .pcm_pointer = hda_dsp_pcm_pointer,
261
262
263 .load_firmware = snd_sof_load_firmware_raw,
264
265
266 .pre_fw_run = hda_dsp_pre_fw_run,
267 .post_fw_run = hda_dsp_post_fw_run,
268
269
270 .core_power_up = hda_dsp_enable_core,
271 .core_power_down = hda_dsp_core_reset_power_down,
272
273
274 .run = hda_dsp_cl_boot_firmware,
275
276
277 .trace_init = hda_dsp_trace_init,
278 .trace_release = hda_dsp_trace_release,
279 .trace_trigger = hda_dsp_trace_trigger,
280
281
282 .drv = skl_dai,
283 .num_drv = SOF_SKL_NUM_DAIS,
284
285
286 .suspend = hda_dsp_suspend,
287 .resume = hda_dsp_resume,
288 .runtime_suspend = hda_dsp_runtime_suspend,
289 .runtime_resume = hda_dsp_runtime_resume,
290 .runtime_idle = hda_dsp_runtime_idle,
291 .set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume,
292 .set_power_state = hda_dsp_set_power_state,
293
294
295 .hw_info = SNDRV_PCM_INFO_MMAP |
296 SNDRV_PCM_INFO_MMAP_VALID |
297 SNDRV_PCM_INFO_INTERLEAVED |
298 SNDRV_PCM_INFO_PAUSE |
299 SNDRV_PCM_INFO_NO_PERIOD_WAKEUP,
300
301 .arch_ops = &sof_xtensa_arch_ops,
302};
303EXPORT_SYMBOL_NS(sof_cnl_ops, SND_SOC_SOF_INTEL_HDA_COMMON);
304
305const struct sof_intel_dsp_desc cnl_chip_info = {
306
307 .cores_num = 4,
308 .init_core_mask = 1,
309 .cores_mask = HDA_DSP_CORE_MASK(0) |
310 HDA_DSP_CORE_MASK(1) |
311 HDA_DSP_CORE_MASK(2) |
312 HDA_DSP_CORE_MASK(3),
313 .ipc_req = CNL_DSP_REG_HIPCIDR,
314 .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
315 .ipc_ack = CNL_DSP_REG_HIPCIDA,
316 .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
317 .ipc_ctl = CNL_DSP_REG_HIPCCTL,
318 .rom_init_timeout = 300,
319 .ssp_count = CNL_SSP_COUNT,
320 .ssp_base_offset = CNL_SSP_BASE_OFFSET,
321};
322EXPORT_SYMBOL_NS(cnl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
323
324const struct sof_intel_dsp_desc icl_chip_info = {
325
326 .cores_num = 4,
327 .init_core_mask = 1,
328 .cores_mask = HDA_DSP_CORE_MASK(0) |
329 HDA_DSP_CORE_MASK(1) |
330 HDA_DSP_CORE_MASK(2) |
331 HDA_DSP_CORE_MASK(3),
332 .ipc_req = CNL_DSP_REG_HIPCIDR,
333 .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
334 .ipc_ack = CNL_DSP_REG_HIPCIDA,
335 .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
336 .ipc_ctl = CNL_DSP_REG_HIPCCTL,
337 .rom_init_timeout = 300,
338 .ssp_count = ICL_SSP_COUNT,
339 .ssp_base_offset = CNL_SSP_BASE_OFFSET,
340};
341EXPORT_SYMBOL_NS(icl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
342
343const struct sof_intel_dsp_desc tgl_chip_info = {
344
345 .cores_num = 4,
346 .init_core_mask = 1,
347 .cores_mask = HDA_DSP_CORE_MASK(0),
348 .ipc_req = CNL_DSP_REG_HIPCIDR,
349 .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
350 .ipc_ack = CNL_DSP_REG_HIPCIDA,
351 .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
352 .ipc_ctl = CNL_DSP_REG_HIPCCTL,
353 .rom_init_timeout = 300,
354 .ssp_count = ICL_SSP_COUNT,
355 .ssp_base_offset = CNL_SSP_BASE_OFFSET,
356};
357EXPORT_SYMBOL_NS(tgl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
358
359const struct sof_intel_dsp_desc ehl_chip_info = {
360
361 .cores_num = 4,
362 .init_core_mask = 1,
363 .cores_mask = HDA_DSP_CORE_MASK(0),
364 .ipc_req = CNL_DSP_REG_HIPCIDR,
365 .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
366 .ipc_ack = CNL_DSP_REG_HIPCIDA,
367 .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
368 .ipc_ctl = CNL_DSP_REG_HIPCCTL,
369 .rom_init_timeout = 300,
370 .ssp_count = ICL_SSP_COUNT,
371 .ssp_base_offset = CNL_SSP_BASE_OFFSET,
372};
373EXPORT_SYMBOL_NS(ehl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
374
375const struct sof_intel_dsp_desc jsl_chip_info = {
376
377 .cores_num = 2,
378 .init_core_mask = 1,
379 .cores_mask = HDA_DSP_CORE_MASK(0) |
380 HDA_DSP_CORE_MASK(1),
381 .ipc_req = CNL_DSP_REG_HIPCIDR,
382 .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY,
383 .ipc_ack = CNL_DSP_REG_HIPCIDA,
384 .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE,
385 .ipc_ctl = CNL_DSP_REG_HIPCCTL,
386 .rom_init_timeout = 300,
387 .ssp_count = ICL_SSP_COUNT,
388 .ssp_base_offset = CNL_SSP_BASE_OFFSET,
389};
390EXPORT_SYMBOL_NS(jsl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON);
391