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