1 // SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) 2 // 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. 5 // 6 // Copyright(c) 2018 Intel Corporation. All rights reserved. 7 // 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> 12 // 13 14 /* 15 * Hardware interface for generic Intel audio DSP HDA IP 16 */ 17 18 #include <linux/module.h> 19 #include <sound/hdaudio_ext.h> 20 #include <sound/sof.h> 21 #include <sound/sof/xtensa.h> 22 #include "../ops.h" 23 #include "hda.h" 24 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 25 #include "../../codecs/hdac_hda.h" 26 #endif 27 28 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 29 #include <sound/soc-acpi-intel-match.h> 30 #endif 31 32 /* platform specific devices */ 33 #include "shim.h" 34 35 /* 36 * Debug 37 */ 38 39 struct hda_dsp_msg_code { 40 u32 code; 41 const char *msg; 42 }; 43 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"}, 64 }; 65 66 static void hda_dsp_get_status_skl(struct snd_sof_dev *sdev) 67 { 68 u32 status; 69 int i; 70 71 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, 72 HDA_ADSP_FW_STATUS_SKL); 73 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); 78 return; 79 } 80 } 81 82 /* not for us, must be generic sof message */ 83 dev_dbg(sdev->dev, "unknown ROM status value %8.8x\n", status); 84 } 85 86 static void hda_dsp_get_status(struct snd_sof_dev *sdev) 87 { 88 u32 status; 89 int i; 90 91 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, 92 HDA_DSP_SRAM_REG_ROM_STATUS); 93 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); 98 return; 99 } 100 } 101 102 /* not for us, must be generic sof message */ 103 dev_dbg(sdev->dev, "unknown ROM status value %8.8x\n", status); 104 } 105 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) 110 { 111 u32 offset = sdev->dsp_oops_offset; 112 113 /* first read registers */ 114 sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops)); 115 116 /* note: variable AR register array is not read */ 117 118 /* then get panic info */ 119 offset += xoops->arch_hdr.totalsize; 120 sof_block_read(sdev, sdev->mmio_bar, offset, 121 panic_info, sizeof(*panic_info)); 122 123 /* then get the stack */ 124 offset += sizeof(*panic_info); 125 sof_block_read(sdev, sdev->mmio_bar, offset, stack, 126 stack_words * sizeof(u32)); 127 } 128 129 void hda_dsp_dump_skl(struct snd_sof_dev *sdev, u32 flags) 130 { 131 struct sof_ipc_dsp_oops_xtensa xoops; 132 struct sof_ipc_panic_info panic_info; 133 u32 stack[HDA_DSP_STACK_DUMP_SIZE]; 134 u32 status, panic; 135 136 /* try APL specific status message types first */ 137 hda_dsp_get_status_skl(sdev); 138 139 /* now try generic SOF status messages */ 140 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, 141 HDA_ADSP_ERROR_CODE_SKL); 142 143 /*TODO: Check: there is no define in spec, but it is used in the code*/ 144 panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, 145 HDA_ADSP_ERROR_CODE_SKL + 0x4); 146 147 if (sdev->boot_complete) { 148 hda_dsp_get_registers(sdev, &xoops, &panic_info, stack, 149 HDA_DSP_STACK_DUMP_SIZE); 150 snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, 151 stack, HDA_DSP_STACK_DUMP_SIZE); 152 } else { 153 dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n", 154 status, panic); 155 hda_dsp_get_status_skl(sdev); 156 } 157 } 158 159 void hda_dsp_dump(struct snd_sof_dev *sdev, u32 flags) 160 { 161 struct sof_ipc_dsp_oops_xtensa xoops; 162 struct sof_ipc_panic_info panic_info; 163 u32 stack[HDA_DSP_STACK_DUMP_SIZE]; 164 u32 status, panic; 165 166 /* try APL specific status message types first */ 167 hda_dsp_get_status(sdev); 168 169 /* now try generic SOF status messages */ 170 status = snd_sof_dsp_read(sdev, HDA_DSP_BAR, 171 HDA_DSP_SRAM_REG_FW_STATUS); 172 panic = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_SRAM_REG_FW_TRACEP); 173 174 if (sdev->boot_complete) { 175 hda_dsp_get_registers(sdev, &xoops, &panic_info, stack, 176 HDA_DSP_STACK_DUMP_SIZE); 177 snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, 178 stack, HDA_DSP_STACK_DUMP_SIZE); 179 } else { 180 dev_err(sdev->dev, "error: status = 0x%8.8x panic = 0x%8.8x\n", 181 status, panic); 182 hda_dsp_get_status(sdev); 183 } 184 } 185 186 void hda_ipc_dump(struct snd_sof_dev *sdev) 187 { 188 u32 hipcie; 189 u32 hipct; 190 u32 hipcctl; 191 192 /* read IPC status */ 193 hipcie = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCIE); 194 hipct = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCT); 195 hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, HDA_DSP_REG_HIPCCTL); 196 197 /* dump the IPC regs */ 198 /* TODO: parse the raw msg */ 199 dev_err(sdev->dev, 200 "error: host status 0x%8.8x dsp status 0x%8.8x mask 0x%8.8x\n", 201 hipcie, hipct, hipcctl); 202 } 203 204 static int hda_init(struct snd_sof_dev *sdev) 205 { 206 struct hda_bus *hbus; 207 struct hdac_bus *bus; 208 struct hdac_ext_bus_ops *ext_ops = NULL; 209 struct pci_dev *pci = to_pci_dev(sdev->dev); 210 int ret; 211 212 hbus = sof_to_hbus(sdev); 213 bus = sof_to_bus(sdev); 214 215 /* HDA bus init */ 216 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC) 217 ext_ops = snd_soc_hdac_hda_get_ops(); 218 #endif 219 sof_hda_bus_init(bus, &pci->dev, ext_ops); 220 bus->use_posbuf = 1; 221 bus->bdl_pos_adj = 0; 222 223 mutex_init(&hbus->prepare_mutex); 224 hbus->pci = pci; 225 hbus->mixer_assigned = -1; 226 hbus->modelname = "sofbus"; 227 228 /* initialise hdac bus */ 229 bus->addr = pci_resource_start(pci, 0); 230 #if IS_ENABLED(CONFIG_PCI) 231 bus->remap_addr = pci_ioremap_bar(pci, 0); 232 #endif 233 if (!bus->remap_addr) { 234 dev_err(bus->dev, "error: ioremap error\n"); 235 return -ENXIO; 236 } 237 238 /* HDA base */ 239 sdev->bar[HDA_DSP_HDA_BAR] = bus->remap_addr; 240 241 /* get controller capabilities */ 242 ret = hda_dsp_ctrl_get_caps(sdev); 243 if (ret < 0) 244 dev_err(sdev->dev, "error: get caps error\n"); 245 246 return ret; 247 } 248 249 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 250 251 static const char *fixup_tplg_name(struct snd_sof_dev *sdev, 252 const char *sof_tplg_filename) 253 { 254 const char *tplg_filename = NULL; 255 char *filename; 256 char *split_ext; 257 258 filename = devm_kstrdup(sdev->dev, sof_tplg_filename, GFP_KERNEL); 259 if (!filename) 260 return NULL; 261 262 /* this assumes a .tplg extension */ 263 split_ext = strsep(&filename, "."); 264 if (split_ext) { 265 tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, 266 "%s-idisp.tplg", split_ext); 267 if (!tplg_filename) 268 return NULL; 269 } 270 return tplg_filename; 271 } 272 273 #endif 274 275 static int hda_init_caps(struct snd_sof_dev *sdev) 276 { 277 struct hdac_bus *bus = sof_to_bus(sdev); 278 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 279 struct hdac_ext_link *hlink; 280 struct snd_soc_acpi_mach_params *mach_params; 281 struct snd_soc_acpi_mach *hda_mach; 282 struct snd_sof_pdata *pdata = sdev->pdata; 283 struct snd_soc_acpi_mach *mach; 284 const char *tplg_filename; 285 int codec_num = 0; 286 int i; 287 #endif 288 int ret = 0; 289 290 device_disable_async_suspend(bus->dev); 291 292 /* check if dsp is there */ 293 if (bus->ppcap) 294 dev_dbg(sdev->dev, "PP capability, will probe DSP later.\n"); 295 296 ret = hda_dsp_ctrl_init_chip(sdev, true); 297 if (ret < 0) { 298 dev_err(bus->dev, "error: init chip failed with ret: %d\n", 299 ret); 300 return ret; 301 } 302 303 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 304 if (bus->mlcap) 305 snd_hdac_ext_bus_get_ml_capabilities(bus); 306 307 /* init i915 and HDMI codecs */ 308 ret = hda_codec_i915_init(sdev); 309 if (ret < 0) { 310 dev_err(sdev->dev, "error: no HDMI audio devices found\n"); 311 return ret; 312 } 313 314 /* codec detection */ 315 if (!bus->codec_mask) { 316 dev_info(bus->dev, "no hda codecs found!\n"); 317 } else { 318 dev_info(bus->dev, "hda codecs found, mask %lx\n", 319 bus->codec_mask); 320 321 for (i = 0; i < HDA_MAX_CODECS; i++) { 322 if (bus->codec_mask & (1 << i)) 323 codec_num++; 324 } 325 326 /* 327 * If no machine driver is found, then: 328 * 329 * hda machine driver is used if : 330 * 1. there is one HDMI codec and one external HDAudio codec 331 * 2. only HDMI codec 332 */ 333 if (!pdata->machine && codec_num <= 2 && 334 HDA_IDISP_CODEC(bus->codec_mask)) { 335 hda_mach = snd_soc_acpi_intel_hda_machines; 336 pdata->machine = hda_mach; 337 338 /* topology: use the info from hda_machines */ 339 pdata->tplg_filename = 340 hda_mach->sof_tplg_filename; 341 342 /* firmware: pick the first in machine list */ 343 mach = pdata->desc->machines; 344 pdata->fw_filename = mach->sof_fw_filename; 345 346 dev_info(bus->dev, "using HDA machine driver %s now\n", 347 hda_mach->drv_name); 348 349 /* fixup topology file for HDMI only platforms */ 350 if (codec_num == 1) { 351 /* use local variable for readability */ 352 tplg_filename = pdata->tplg_filename; 353 tplg_filename = fixup_tplg_name(sdev, tplg_filename); 354 if (!tplg_filename) { 355 hda_codec_i915_exit(sdev); 356 return ret; 357 } 358 pdata->tplg_filename = tplg_filename; 359 } 360 } 361 } 362 363 /* used by hda machine driver to create dai links */ 364 if (pdata->machine) { 365 mach_params = (struct snd_soc_acpi_mach_params *) 366 &pdata->machine->mach_params; 367 mach_params->codec_mask = bus->codec_mask; 368 mach_params->platform = dev_name(sdev->dev); 369 } 370 371 /* create codec instances */ 372 hda_codec_probe_bus(sdev); 373 374 hda_codec_i915_put(sdev); 375 376 /* 377 * we are done probing so decrement link counts 378 */ 379 list_for_each_entry(hlink, &bus->hlink_list, list) 380 snd_hdac_ext_bus_link_put(bus, hlink); 381 #endif 382 return 0; 383 } 384 385 static const struct sof_intel_dsp_desc 386 *get_chip_info(struct snd_sof_pdata *pdata) 387 { 388 const struct sof_dev_desc *desc = pdata->desc; 389 const struct sof_intel_dsp_desc *chip_info; 390 391 chip_info = desc->chip_info; 392 393 return chip_info; 394 } 395 396 int hda_dsp_probe(struct snd_sof_dev *sdev) 397 { 398 struct pci_dev *pci = to_pci_dev(sdev->dev); 399 struct sof_intel_hda_dev *hdev; 400 struct hdac_bus *bus; 401 const struct sof_intel_dsp_desc *chip; 402 int ret = 0; 403 404 /* 405 * detect DSP by checking class/subclass/prog-id information 406 * class=04 subclass 03 prog-if 00: no DSP, legacy driver is required 407 * class=04 subclass 01 prog-if 00: DSP is present 408 * (and may be required e.g. for DMIC or SSP support) 409 * class=04 subclass 03 prog-if 80: either of DSP or legacy mode works 410 */ 411 if (pci->class == 0x040300) { 412 dev_err(sdev->dev, "error: the DSP is not enabled on this platform, aborting probe\n"); 413 return -ENODEV; 414 } else if (pci->class != 0x040100 && pci->class != 0x040380) { 415 dev_err(sdev->dev, "error: unknown PCI class/subclass/prog-if 0x%06x found, aborting probe\n", pci->class); 416 return -ENODEV; 417 } 418 dev_info(sdev->dev, "DSP detected with PCI class/subclass/prog-if 0x%06x\n", pci->class); 419 420 chip = get_chip_info(sdev->pdata); 421 if (!chip) { 422 dev_err(sdev->dev, "error: no such device supported, chip id:%x\n", 423 pci->device); 424 ret = -EIO; 425 goto err; 426 } 427 428 hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL); 429 if (!hdev) 430 return -ENOMEM; 431 sdev->pdata->hw_pdata = hdev; 432 hdev->desc = chip; 433 434 hdev->dmic_dev = platform_device_register_data(sdev->dev, "dmic-codec", 435 PLATFORM_DEVID_NONE, 436 NULL, 0); 437 if (IS_ERR(hdev->dmic_dev)) { 438 dev_err(sdev->dev, "error: failed to create DMIC device\n"); 439 return PTR_ERR(hdev->dmic_dev); 440 } 441 442 /* 443 * use position update IPC if either it is forced 444 * or we don't have other choice 445 */ 446 #if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_FORCE_IPC_POSITION) 447 hdev->no_ipc_position = 0; 448 #else 449 hdev->no_ipc_position = sof_ops(sdev)->pcm_pointer ? 1 : 0; 450 #endif 451 452 /* set up HDA base */ 453 bus = sof_to_bus(sdev); 454 ret = hda_init(sdev); 455 if (ret < 0) 456 goto hdac_bus_unmap; 457 458 /* DSP base */ 459 #if IS_ENABLED(CONFIG_PCI) 460 sdev->bar[HDA_DSP_BAR] = pci_ioremap_bar(pci, HDA_DSP_BAR); 461 #endif 462 if (!sdev->bar[HDA_DSP_BAR]) { 463 dev_err(sdev->dev, "error: ioremap error\n"); 464 ret = -ENXIO; 465 goto hdac_bus_unmap; 466 } 467 468 sdev->mmio_bar = HDA_DSP_BAR; 469 sdev->mailbox_bar = HDA_DSP_BAR; 470 471 /* allow 64bit DMA address if supported by H/W */ 472 if (!dma_set_mask(&pci->dev, DMA_BIT_MASK(64))) { 473 dev_dbg(sdev->dev, "DMA mask is 64 bit\n"); 474 dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(64)); 475 } else { 476 dev_dbg(sdev->dev, "DMA mask is 32 bit\n"); 477 dma_set_mask(&pci->dev, DMA_BIT_MASK(32)); 478 dma_set_coherent_mask(&pci->dev, DMA_BIT_MASK(32)); 479 } 480 481 /* init streams */ 482 ret = hda_dsp_stream_init(sdev); 483 if (ret < 0) { 484 dev_err(sdev->dev, "error: failed to init streams\n"); 485 /* 486 * not all errors are due to memory issues, but trying 487 * to free everything does not harm 488 */ 489 goto free_streams; 490 } 491 492 /* 493 * register our IRQ 494 * let's try to enable msi firstly 495 * if it fails, use legacy interrupt mode 496 * TODO: support interrupt mode selection with kernel parameter 497 * support msi multiple vectors 498 */ 499 ret = pci_alloc_irq_vectors(pci, 1, 1, PCI_IRQ_MSI); 500 if (ret < 0) { 501 dev_info(sdev->dev, "use legacy interrupt mode\n"); 502 /* 503 * in IO-APIC mode, hda->irq and ipc_irq are using the same 504 * irq number of pci->irq 505 */ 506 hdev->irq = pci->irq; 507 sdev->ipc_irq = pci->irq; 508 sdev->msi_enabled = 0; 509 } else { 510 dev_info(sdev->dev, "use msi interrupt mode\n"); 511 hdev->irq = pci_irq_vector(pci, 0); 512 /* ipc irq number is the same of hda irq */ 513 sdev->ipc_irq = hdev->irq; 514 sdev->msi_enabled = 1; 515 } 516 517 dev_dbg(sdev->dev, "using HDA IRQ %d\n", hdev->irq); 518 ret = request_threaded_irq(hdev->irq, hda_dsp_stream_interrupt, 519 hda_dsp_stream_threaded_handler, 520 IRQF_SHARED, "AudioHDA", bus); 521 if (ret < 0) { 522 dev_err(sdev->dev, "error: failed to register HDA IRQ %d\n", 523 hdev->irq); 524 goto free_irq_vector; 525 } 526 527 dev_dbg(sdev->dev, "using IPC IRQ %d\n", sdev->ipc_irq); 528 ret = request_threaded_irq(sdev->ipc_irq, hda_dsp_ipc_irq_handler, 529 sof_ops(sdev)->irq_thread, IRQF_SHARED, 530 "AudioDSP", sdev); 531 if (ret < 0) { 532 dev_err(sdev->dev, "error: failed to register IPC IRQ %d\n", 533 sdev->ipc_irq); 534 goto free_hda_irq; 535 } 536 537 pci_set_master(pci); 538 synchronize_irq(pci->irq); 539 540 /* 541 * clear TCSEL to clear playback on some HD Audio 542 * codecs. PCI TCSEL is defined in the Intel manuals. 543 */ 544 snd_sof_pci_update_bits(sdev, PCI_TCSEL, 0x07, 0); 545 546 /* init HDA capabilities */ 547 ret = hda_init_caps(sdev); 548 if (ret < 0) 549 goto free_ipc_irq; 550 551 /* enable ppcap interrupt */ 552 hda_dsp_ctrl_ppcap_enable(sdev, true); 553 hda_dsp_ctrl_ppcap_int_enable(sdev, true); 554 555 /* initialize waitq for code loading */ 556 init_waitqueue_head(&sdev->waitq); 557 558 /* set default mailbox offset for FW ready message */ 559 sdev->dsp_box.offset = HDA_DSP_MBOX_UPLINK_OFFSET; 560 561 return 0; 562 563 free_ipc_irq: 564 free_irq(sdev->ipc_irq, sdev); 565 free_hda_irq: 566 free_irq(hdev->irq, bus); 567 free_irq_vector: 568 if (sdev->msi_enabled) 569 pci_free_irq_vectors(pci); 570 free_streams: 571 hda_dsp_stream_free(sdev); 572 /* dsp_unmap: not currently used */ 573 iounmap(sdev->bar[HDA_DSP_BAR]); 574 hdac_bus_unmap: 575 iounmap(bus->remap_addr); 576 err: 577 return ret; 578 } 579 580 int hda_dsp_remove(struct snd_sof_dev *sdev) 581 { 582 struct sof_intel_hda_dev *hda = sdev->pdata->hw_pdata; 583 struct hdac_bus *bus = sof_to_bus(sdev); 584 struct pci_dev *pci = to_pci_dev(sdev->dev); 585 const struct sof_intel_dsp_desc *chip = hda->desc; 586 587 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 588 /* codec removal, invoke bus_device_remove */ 589 snd_hdac_ext_bus_device_remove(bus); 590 #endif 591 592 if (!IS_ERR_OR_NULL(hda->dmic_dev)) 593 platform_device_unregister(hda->dmic_dev); 594 595 /* disable DSP IRQ */ 596 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, 597 SOF_HDA_PPCTL_PIE, 0); 598 599 /* disable CIE and GIE interrupts */ 600 snd_sof_dsp_update_bits(sdev, HDA_DSP_HDA_BAR, SOF_HDA_INTCTL, 601 SOF_HDA_INT_CTRL_EN | SOF_HDA_INT_GLOBAL_EN, 0); 602 603 /* disable cores */ 604 if (chip) 605 hda_dsp_core_reset_power_down(sdev, chip->cores_mask); 606 607 /* disable DSP */ 608 snd_sof_dsp_update_bits(sdev, HDA_DSP_PP_BAR, SOF_HDA_REG_PP_PPCTL, 609 SOF_HDA_PPCTL_GPROCEN, 0); 610 611 free_irq(sdev->ipc_irq, sdev); 612 free_irq(hda->irq, bus); 613 if (sdev->msi_enabled) 614 pci_free_irq_vectors(pci); 615 616 hda_dsp_stream_free(sdev); 617 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 618 snd_hdac_link_free_all(bus); 619 #endif 620 621 iounmap(sdev->bar[HDA_DSP_BAR]); 622 iounmap(bus->remap_addr); 623 624 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) 625 snd_hdac_ext_bus_exit(bus); 626 #endif 627 hda_codec_i915_exit(sdev); 628 629 return 0; 630 } 631 632 MODULE_LICENSE("Dual BSD/GPL"); 633