1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
3 // This file is provided under a dual BSD/GPLv2 license. When using or
4 // redistributing this file, you may do so under either license.
6 // Copyright(c) 2018 Intel Corporation. All rights reserved.
8 // Authors: Liam Girdwood <liam.r.girdwood@linux.intel.com>
9 // Ranjani Sridharan <ranjani.sridharan@linux.intel.com>
10 // Rander Wang <rander.wang@intel.com>
11 // Keyon Jie <yang.jie@linux.intel.com>
15 * Hardware interface for generic Intel audio DSP HDA IP
18 #include <linux/module.h>
19 #include <sound/hdaudio_ext.h>
20 #include <sound/sof.h>
21 #include <sound/sof/xtensa.h>
24 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
25 #include "../../codecs/hdac_hda.h"
28 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
29 #include <sound/soc-acpi-intel-match.h>
32 /* platform specific devices */
39 struct hda_dsp_msg_code {
44 static const struct hda_dsp_msg_code hda_dsp_rom_msg[] = {
45 {HDA_DSP_ROM_FW_MANIFEST_LOADED, "status: manifest loaded"},
46 {HDA_DSP_ROM_FW_FW_LOADED, "status: fw loaded"},
47 {HDA_DSP_ROM_FW_ENTERED, "status: fw entered"},
48 {HDA_DSP_ROM_CSE_ERROR, "error: cse error"},
49 {HDA_DSP_ROM_CSE_WRONG_RESPONSE, "error: cse wrong response"},
50 {HDA_DSP_ROM_IMR_TO_SMALL, "error: IMR too small"},
51 {HDA_DSP_ROM_BASE_FW_NOT_FOUND, "error: base fw not found"},
52 {HDA_DSP_ROM_CSE_VALIDATION_FAILED, "error: signature verification failed"},
53 {HDA_DSP_ROM_IPC_FATAL_ERROR, "error: ipc fatal error"},
54 {HDA_DSP_ROM_L2_CACHE_ERROR, "error: L2 cache error"},
55 {HDA_DSP_ROM_LOAD_OFFSET_TO_SMALL, "error: load offset too small"},
56 {HDA_DSP_ROM_API_PTR_INVALID, "error: API ptr invalid"},
57 {HDA_DSP_ROM_BASEFW_INCOMPAT, "error: base fw incompatible"},
58 {HDA_DSP_ROM_UNHANDLED_INTERRUPT, "error: unhandled interrupt"},
59 {HDA_DSP_ROM_MEMORY_HOLE_ECC, "error: ECC memory hole"},
60 {HDA_DSP_ROM_KERNEL_EXCEPTION, "error: kernel exception"},
61 {HDA_DSP_ROM_USER_EXCEPTION, "error: user exception"},
62 {HDA_DSP_ROM_UNEXPECTED_RESET, "error: unexpected reset"},
63 {HDA_DSP_ROM_NULL_FW_ENTRY, "error: null FW entry point"},
66 static void hda_dsp_get_status_skl(struct snd_sof_dev *sdev)
71 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
72 HDA_ADSP_FW_STATUS_SKL);
74 for (i = 0; i < ARRAY_SIZE(hda_dsp_rom_msg); i++) {
75 if (status == hda_dsp_rom_msg[i].code) {
76 dev_err(sdev->dev, "%s - code %8.8x\n",
77 hda_dsp_rom_msg[i].msg, status);
82 /* not for us, must be generic sof message */
83 dev_dbg(sdev->dev, "unknown ROM status value %8.8x\n", status);
86 static void hda_dsp_get_status(struct snd_sof_dev *sdev)
91 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
92 HDA_DSP_SRAM_REG_ROM_STATUS);
94 for (i = 0; i < ARRAY_SIZE(hda_dsp_rom_msg); i++) {
95 if (status == hda_dsp_rom_msg[i].code) {
96 dev_err(sdev->dev, "%s - code %8.8x\n",
97 hda_dsp_rom_msg[i].msg, status);
102 /* not for us, must be generic sof message */
103 dev_dbg(sdev->dev, "unknown ROM status value %8.8x\n", status);
106 static void hda_dsp_get_registers(struct snd_sof_dev *sdev,
107 struct sof_ipc_dsp_oops_xtensa *xoops,
108 struct sof_ipc_panic_info *panic_info,
109 u32 *stack, size_t stack_words)
111 /* first read registers */
112 sof_block_read(sdev, sdev->mmio_bar, sdev->dsp_oops_offset, xoops,
115 /* then get panic info */
116 sof_block_read(sdev, sdev->mmio_bar, sdev->dsp_oops_offset +
117 sizeof(*xoops), panic_info, sizeof(*panic_info));
119 /* then get the stack */
120 sof_block_read(sdev, sdev->mmio_bar, sdev->dsp_oops_offset +
121 sizeof(*xoops) + sizeof(*panic_info), stack,
122 stack_words * sizeof(u32));
125 void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags)
127 struct sof_ipc_dsp_oops_xtensa xoops;
128 struct sof_ipc_panic_info panic_info;
129 u32 stack[HDA_DSP_STACK_DUMP_SIZE];
132 /* try APL specific status message types first */
133 hda_dsp_get_status_skl(sdev);
135 /* now try generic SOF status messages */
136 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
137 HDA_ADSP_ERROR_CODE_SKL);
139 /*TODO: Check: there is no define in spec, but it is used in the code*/
140 panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
141 HDA_ADSP_ERROR_CODE_SKL + 0x4);
143 if (sdev->boot_complete) {
144 hda_dsp_get_registers(sdev, &xoops, &panic_info, stack,
145 HDA_DSP_STACK_DUMP_SIZE);
146 snd_sof_get_status(sdev, status, panic, &xoops, &panic_info,
147 stack, HDA_DSP_STACK_DUMP_SIZE);
149 dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n",
151 hda_dsp_get_status_skl(sdev);
155 void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags)
157 struct sof_ipc_dsp_oops_xtensa xoops;
158 struct sof_ipc_panic_info panic_info;
159 u32 stack[HDA_DSP_STACK_DUMP_SIZE];
162 /* try APL specific status message types first */
163 hda_dsp_get_status(sdev);
165 /* now try generic SOF status messages */
166 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR,
167 HDA_DSP_SRAM_REG_FW_STATUS);
168 panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_FW_TRACEP);
170 if (sdev->boot_complete) {
171 hda_dsp_get_registers(sdev, &xoops, &panic_info, stack,
172 HDA_DSP_STACK_DUMP_SIZE);
173 snd_sof_get_status(sdev, status, panic, &xoops, &panic_info,
174 stack, HDA_DSP_STACK_DUMP_SIZE);
176 dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n",
178 hda_dsp_get_status(sdev);
182 void hda_ipc_dump(struct snd_sof_dev *sdev)
188 /* read IPC status */
189 hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCIE);
190 hipct = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCT);
191 hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCCTL);
193 /* dump the IPC regs */
194 /* TODO: parse the raw msg */
196 "error: host status 0x%8.8x dsp status 0x%8.8x mask 0x%8.8x\n",
197 hipcie, hipct, hipcctl);
200 static int hda_init(struct snd_sof_dev *sdev)
202 struct hda_bus *hbus;
203 struct hdac_bus *bus;
204 struct hdac_ext_bus_ops *ext_ops = NULL;
205 struct pci_dev *pci = to_pci_dev(sdev->dev);
208 hbus = sof_to_hbus(sdev);
209 bus = sof_to_bus(sdev);
212 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
213 ext_ops = snd_soc_hdac_hda_get_ops();
215 sof_hda_bus_init(bus, &pci->dev, ext_ops);
217 bus->bdl_pos_adj = 0;
219 mutex_init(&hbus->prepare_mutex);
221 hbus->mixer_assigned = -1;
222 hbus->modelname = "sofbus";
224 /* initialise hdac bus */
225 bus->addr = pci_resource_start(pci, 0);
226 bus->remap_addr = pci_ioremap_bar(pci, 0);
227 if (!bus->remap_addr) {
228 dev_err(bus->dev, "error: ioremap error\n");
233 sdev->bar[HDA_DSP_HDA_BAR] = bus->remap_addr;
235 /* get controller capabilities */
236 ret = hda_dsp_ctrl_get_caps(sdev);
238 dev_err(sdev->dev, "error: get caps error\n");
243 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
245 static const char *fixup_tplg_name(struct snd_sof_dev *sdev,
246 const char *sof_tplg_filename)
248 const char *tplg_filename = NULL;
252 filename = devm_kstrdup(sdev->dev, sof_tplg_filename, GFP_KERNEL);
256 /* this assumes a .tplg extension */
257 split_ext = strsep(&filename, ".");
259 tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL,
260 "%s-idisp.tplg", split_ext);
264 return tplg_filename;
267 static int hda_init_caps(struct snd_sof_dev *sdev)
269 struct hdac_bus *bus = sof_to_bus(sdev);
270 struct hdac_ext_link *hlink;
271 struct snd_soc_acpi_mach_params *mach_params;
272 struct snd_soc_acpi_mach *hda_mach;
273 struct snd_sof_pdata *pdata = sdev->pdata;
274 struct snd_soc_acpi_mach *mach;
275 const char *tplg_filename;
280 device_disable_async_suspend(bus->dev);
282 /* check if dsp is there */
284 dev_dbg(sdev->dev, "PP capability, will probe DSP later.\n");
287 snd_hdac_ext_bus_get_ml_capabilities(bus);
289 /* init i915 and HDMI codecs */
290 ret = hda_codec_i915_init(sdev);
292 dev_err(sdev->dev, "error: no HDMI audio devices found\n");
296 ret = hda_dsp_ctrl_init_chip(sdev, true);
298 dev_err(bus->dev, "error: init chip failed with ret: %d\n", ret);
302 /* codec detection */
303 if (!bus->codec_mask) {
304 dev_info(bus->dev, "no hda codecs found!\n");
306 dev_info(bus->dev, "hda codecs found, mask %lx\n",
309 for (i = 0; i < HDA_MAX_CODECS; i++) {
310 if (bus->codec_mask & (1 << i))
315 * If no machine driver is found, then:
317 * hda machine driver is used if :
318 * 1. there is one HDMI codec and one external HDAudio codec
321 if (!pdata->machine && codec_num <= 2 &&
322 HDA_IDISP_CODEC(bus->codec_mask)) {
323 hda_mach = snd_soc_acpi_intel_hda_machines;
324 pdata->machine = hda_mach;
326 /* topology: use the info from hda_machines */
327 pdata->tplg_filename =
328 hda_mach->sof_tplg_filename;
330 /* firmware: pick the first in machine list */
331 mach = pdata->desc->machines;
332 pdata->fw_filename = mach->sof_fw_filename;
334 dev_info(bus->dev, "using HDA machine driver %s now\n",
337 /* fixup topology file for HDMI only platforms */
338 if (codec_num == 1) {
339 /* use local variable for readability */
340 tplg_filename = pdata->tplg_filename;
341 tplg_filename = fixup_tplg_name(sdev, tplg_filename);
344 pdata->tplg_filename = tplg_filename;
349 /* used by hda machine driver to create dai links */
350 if (pdata->machine) {
351 mach_params = (struct snd_soc_acpi_mach_params *)
352 &pdata->machine->mach_params;
353 mach_params->codec_mask = bus->codec_mask;
354 mach_params->platform = dev_name(sdev->dev);
357 /* create codec instances */
358 hda_codec_probe_bus(sdev);
360 hda_codec_i915_put(sdev);
363 * we are done probing so decrement link counts
365 list_for_each_entry(hlink, &bus->hlink_list, list)
366 snd_hdac_ext_bus_link_put(bus, hlink);
371 hda_codec_i915_exit(sdev);
377 static int hda_init_caps(struct snd_sof_dev *sdev)
380 * set CGCTL.MISCBDCGE to 0 during reset and set back to 1
381 * when reset finished.
382 * TODO: maybe no need for init_caps?
384 hda_dsp_ctrl_misc_clock_gating(sdev, 0);
387 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS,
388 SOF_HDA_WAKESTS_INT_MASK,
389 SOF_HDA_WAKESTS_INT_MASK);
396 static const struct sof_intel_dsp_desc
397 *get_chip_info(struct snd_sof_pdata *pdata)
399 const struct sof_dev_desc *desc = pdata->desc;
400 const struct sof_intel_dsp_desc *chip_info;
402 chip_info = desc->chip_info;
407 int hda_dsp_probe(struct snd_sof_dev *sdev)
409 struct pci_dev *pci = to_pci_dev(sdev->dev);
410 struct sof_intel_hda_dev *hdev;
411 struct hdac_bus *bus;
412 struct hdac_stream *stream;
413 const struct sof_intel_dsp_desc *chip;
414 int sd_offset, ret = 0;
417 * detect DSP by checking class/subclass/prog-id information
418 * class=04 subclass 03 prog-if 00: no DSP, legacy driver is required
419 * class=04 subclass 01 prog-if 00: DSP is present
420 * (and may be required e.g. for DMIC or SSP support)
421 * class=04 subclass 03 prog-if 80: either of DSP or legacy mode works
423 if (pci->class == 0x040300) {
424 dev_err(sdev->dev, "error: the DSP is not enabled on this platform, aborting probe\n");
426 } else if (pci->class != 0x040100 && pci->class != 0x040380) {
427 dev_err(sdev->dev, "error: unknown PCI class/subclass/prog-if 0x%06x found, aborting probe\n", pci->class);
430 dev_info(sdev->dev, "DSP detected with PCI class/subclass/prog-if 0x%06x\n", pci->class);
432 chip = get_chip_info(sdev->pdata);
434 dev_err(sdev->dev, "error: no such device supported, chip id:%x\n",
440 hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL);
443 sdev->pdata->hw_pdata = hdev;
446 hdev->dmic_dev = platform_device_register_data(sdev->dev, "dmic-codec",
449 if (IS_ERR(hdev->dmic_dev)) {
450 dev_err(sdev->dev, "error: failed to create DMIC device\n");
451 return PTR_ERR(hdev->dmic_dev);
455 * use position update IPC if either it is forced
456 * or we don't have other choice
458 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_FORCE_IPC_POSITION)
459 hdev->no_ipc_position = 0;
461 hdev->no_ipc_position = sof_ops(sdev)->pcm_pointer ? 1 : 0;
464 /* set up HDA base */
465 bus = sof_to_bus(sdev);
466 ret = hda_init(sdev);
471 sdev->bar[HDA_DSP_BAR] = pci_ioremap_bar(pci, HDA_DSP_BAR);
472 if (!sdev->bar[HDA_DSP_BAR]) {
473 dev_err(sdev->dev, "error: ioremap error\n");
478 sdev->mmio_bar = HDA_DSP_BAR;
479 sdev->mailbox_bar = HDA_DSP_BAR;
481 /* allow 64bit DMA address if supported by H/W */
482 if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(64))) {
483 dev_dbg(sdev->dev, "DMA mask is 64 bit\n");
484 dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(64));
486 dev_dbg(sdev->dev, "DMA mask is 32 bit\n");
487 dma_set_mask(&pci->dev, DMA_BIT_MASK(32));
488 dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32));
492 ret = hda_dsp_stream_init(sdev);
494 dev_err(sdev->dev, "error: failed to init streams\n");
496 * not all errors are due to memory issues, but trying
497 * to free everything does not harm
504 * let's try to enable msi firstly
505 * if it fails, use legacy interrupt mode
506 * TODO: support interrupt mode selection with kernel parameter
507 * support msi multiple vectors
509 ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI);
511 dev_info(sdev->dev, "use legacy interrupt mode\n");
513 * in IO-APIC mode, hda->irq and ipc_irq are using the same
514 * irq number of pci->irq
516 hdev->irq = pci->irq;
517 sdev->ipc_irq = pci->irq;
518 sdev->msi_enabled = 0;
520 dev_info(sdev->dev, "use msi interrupt mode\n");
521 hdev->irq = pci_irq_vector(pci, 0);
522 /* ipc irq number is the same of hda irq */
523 sdev->ipc_irq = hdev->irq;
524 sdev->msi_enabled = 1;
527 dev_dbg(sdev->dev, "using HDA IRQ %d\n", hdev->irq);
528 ret = request_threaded_irq(hdev->irq, hda_dsp_stream_interrupt,
529 hda_dsp_stream_threaded_handler,
530 IRQF_SHARED, "AudioHDA", bus);
532 dev_err(sdev->dev, "error: failed to register HDA IRQ %d\n",
534 goto free_irq_vector;
537 dev_dbg(sdev->dev, "using IPC IRQ %d\n", sdev->ipc_irq);
538 ret = request_threaded_irq(sdev->ipc_irq, hda_dsp_ipc_irq_handler,
539 sof_ops(sdev)->irq_thread, IRQF_SHARED,
542 dev_err(sdev->dev, "error: failed to register IPC IRQ %d\n",
548 synchronize_irq(pci->irq);
551 * clear TCSEL to clear playback on some HD Audio
552 * codecs. PCI TCSEL is defined in the Intel manuals.
554 snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0);
556 /* init HDA capabilities */
557 ret = hda_init_caps(sdev);
561 /* reset HDA controller */
562 ret = hda_dsp_ctrl_link_reset(sdev, true);
564 dev_err(sdev->dev, "error: failed to reset HDA controller\n");
568 /* exit HDA controller reset */
569 ret = hda_dsp_ctrl_link_reset(sdev, false);
571 dev_err(sdev->dev, "error: failed to exit HDA controller reset\n");
575 /* clear stream status */
576 list_for_each_entry(stream, &bus->stream_list, list) {
577 sd_offset = SOF_STREAM_SD_OFFSET(stream);
578 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR,
580 SOF_HDA_ADSP_REG_CL_SD_STS,
581 SOF_HDA_CL_DMA_SD_INT_MASK,
582 SOF_HDA_CL_DMA_SD_INT_MASK);
586 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_WAKESTS,
587 SOF_HDA_WAKESTS_INT_MASK,
588 SOF_HDA_WAKESTS_INT_MASK);
590 /* clear interrupt status register */
591 snd_sof_dsp_write(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTSTS,
592 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_ALL_STREAM);
594 /* enable CIE and GIE interrupts */
595 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
596 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN,
597 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN);
599 /* re-enable CGCTL.MISCBDCGE after reset */
600 hda_dsp_ctrl_misc_clock_gating(sdev, true);
602 device_disable_async_suspend(&pci->dev);
604 /* enable DSP features */
605 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
606 SOF_HDA_PPCTL_GPROCEN, SOF_HDA_PPCTL_GPROCEN);
609 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
610 SOF_HDA_PPCTL_PIE, SOF_HDA_PPCTL_PIE);
612 /* initialize waitq for code loading */
613 init_waitqueue_head(&sdev->waitq);
615 /* set default mailbox offset for FW ready message */
616 sdev->dsp_box.offset = HDA_DSP_MBOX_UPLINK_OFFSET;
621 free_irq(sdev->ipc_irq, sdev);
623 free_irq(hdev->irq, bus);
625 if (sdev->msi_enabled)
626 pci_free_irq_vectors(pci);
628 hda_dsp_stream_free(sdev);
629 /* dsp_unmap: not currently used */
630 iounmap(sdev->bar[HDA_DSP_BAR]);
632 iounmap(bus->remap_addr);
637 int hda_dsp_remove(struct snd_sof_dev *sdev)
639 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata;
640 struct hdac_bus *bus = sof_to_bus(sdev);
641 struct pci_dev *pci = to_pci_dev(sdev->dev);
642 const struct sof_intel_dsp_desc *chip = hda->desc;
644 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
645 /* codec removal, invoke bus_device_remove */
646 snd_hdac_ext_bus_device_remove(bus);
649 if (!IS_ERR_OR_NULL(hda->dmic_dev))
650 platform_device_unregister(hda->dmic_dev);
652 /* disable DSP IRQ */
653 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
654 SOF_HDA_PPCTL_PIE, 0);
656 /* disable CIE and GIE interrupts */
657 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL,
658 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN, 0);
662 hda_dsp_core_reset_power_down(sdev, chip->cores_mask);
665 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL,
666 SOF_HDA_PPCTL_GPROCEN, 0);
668 free_irq(sdev->ipc_irq, sdev);
669 free_irq(hda->irq, bus);
670 if (sdev->msi_enabled)
671 pci_free_irq_vectors(pci);
673 hda_dsp_stream_free(sdev);
674 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
675 snd_hdac_link_free_all(bus);
678 iounmap(sdev->bar[HDA_DSP_BAR]);
679 iounmap(bus->remap_addr);
681 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
682 snd_hdac_ext_bus_exit(bus);
684 hda_codec_i915_exit(sdev);
689 MODULE_LICENSE("Dual BSD/GPL");