1 // SPDX-License-Identifier: (GPL-2.0-only 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 // Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> 9 // 10 11 #include <linux/firmware.h> 12 #include <linux/dmi.h> 13 #include <linux/module.h> 14 #include <linux/pci.h> 15 #include <linux/pm_runtime.h> 16 #include <sound/intel-dsp-config.h> 17 #include <sound/soc-acpi.h> 18 #include <sound/soc-acpi-intel-match.h> 19 #include <sound/sof.h> 20 #include "ops.h" 21 22 /* platform specific devices */ 23 #include "intel/shim.h" 24 #include "intel/hda.h" 25 26 static char *fw_path; 27 module_param(fw_path, charp, 0444); 28 MODULE_PARM_DESC(fw_path, "alternate path for SOF firmware."); 29 30 static char *tplg_path; 31 module_param(tplg_path, charp, 0444); 32 MODULE_PARM_DESC(tplg_path, "alternate path for SOF topology."); 33 34 static int sof_pci_debug; 35 module_param_named(sof_pci_debug, sof_pci_debug, int, 0444); 36 MODULE_PARM_DESC(sof_pci_debug, "SOF PCI debug options (0x0 all off)"); 37 38 static const char *sof_override_tplg_name; 39 40 #define SOF_PCI_DISABLE_PM_RUNTIME BIT(0) 41 42 static int sof_tplg_cb(const struct dmi_system_id *id) 43 { 44 sof_override_tplg_name = id->driver_data; 45 return 1; 46 } 47 48 static const struct dmi_system_id sof_tplg_table[] = { 49 { 50 .callback = sof_tplg_cb, 51 .matches = { 52 DMI_MATCH(DMI_PRODUCT_FAMILY, "Google_Volteer"), 53 DMI_MATCH(DMI_OEM_STRING, "AUDIO-MAX98373_ALC5682I_I2S_UP4"), 54 }, 55 .driver_data = "sof-tgl-rt5682-ssp0-max98373-ssp2.tplg", 56 }, 57 {} 58 }; 59 60 static const struct dmi_system_id community_key_platforms[] = { 61 { 62 .ident = "Up Squared", 63 .matches = { 64 DMI_MATCH(DMI_SYS_VENDOR, "AAEON"), 65 DMI_MATCH(DMI_BOARD_NAME, "UP-APL01"), 66 } 67 }, 68 { 69 .ident = "Google Chromebooks", 70 .matches = { 71 DMI_MATCH(DMI_SYS_VENDOR, "Google"), 72 } 73 }, 74 {}, 75 }; 76 77 #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) 78 static const struct sof_dev_desc bxt_desc = { 79 .machines = snd_soc_acpi_intel_bxt_machines, 80 .use_acpi_target_states = true, 81 .resindex_lpe_base = 0, 82 .resindex_pcicfg_base = -1, 83 .resindex_imr_base = -1, 84 .irqindex_host_ipc = -1, 85 .resindex_dma_base = -1, 86 .chip_info = &apl_chip_info, 87 .default_fw_path = "intel/sof", 88 .default_tplg_path = "intel/sof-tplg", 89 .default_fw_filename = "sof-apl.ri", 90 .nocodec_tplg_filename = "sof-apl-nocodec.tplg", 91 .ops = &sof_apl_ops, 92 }; 93 #endif 94 95 #if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE) 96 static const struct sof_dev_desc glk_desc = { 97 .machines = snd_soc_acpi_intel_glk_machines, 98 .use_acpi_target_states = true, 99 .resindex_lpe_base = 0, 100 .resindex_pcicfg_base = -1, 101 .resindex_imr_base = -1, 102 .irqindex_host_ipc = -1, 103 .resindex_dma_base = -1, 104 .chip_info = &apl_chip_info, 105 .default_fw_path = "intel/sof", 106 .default_tplg_path = "intel/sof-tplg", 107 .default_fw_filename = "sof-glk.ri", 108 .nocodec_tplg_filename = "sof-glk-nocodec.tplg", 109 .ops = &sof_apl_ops, 110 }; 111 #endif 112 113 #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) 114 static struct snd_soc_acpi_mach sof_tng_machines[] = { 115 { 116 .id = "INT343A", 117 .drv_name = "edison", 118 .sof_fw_filename = "sof-byt.ri", 119 .sof_tplg_filename = "sof-byt.tplg", 120 }, 121 {} 122 }; 123 124 static const struct sof_dev_desc tng_desc = { 125 .machines = sof_tng_machines, 126 .resindex_lpe_base = 3, /* IRAM, but subtract IRAM offset */ 127 .resindex_pcicfg_base = -1, 128 .resindex_imr_base = 0, 129 .irqindex_host_ipc = -1, 130 .resindex_dma_base = -1, 131 .chip_info = &tng_chip_info, 132 .default_fw_path = "intel/sof", 133 .default_tplg_path = "intel/sof-tplg", 134 .default_fw_filename = "sof-byt.ri", 135 .nocodec_tplg_filename = "sof-byt.tplg", 136 .ops = &sof_tng_ops, 137 }; 138 #endif 139 140 #if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE) 141 static const struct sof_dev_desc cnl_desc = { 142 .machines = snd_soc_acpi_intel_cnl_machines, 143 .alt_machines = snd_soc_acpi_intel_cnl_sdw_machines, 144 .use_acpi_target_states = true, 145 .resindex_lpe_base = 0, 146 .resindex_pcicfg_base = -1, 147 .resindex_imr_base = -1, 148 .irqindex_host_ipc = -1, 149 .resindex_dma_base = -1, 150 .chip_info = &cnl_chip_info, 151 .default_fw_path = "intel/sof", 152 .default_tplg_path = "intel/sof-tplg", 153 .default_fw_filename = "sof-cnl.ri", 154 .nocodec_tplg_filename = "sof-cnl-nocodec.tplg", 155 .ops = &sof_cnl_ops, 156 }; 157 #endif 158 159 #if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE) 160 static const struct sof_dev_desc cfl_desc = { 161 .machines = snd_soc_acpi_intel_cfl_machines, 162 .alt_machines = snd_soc_acpi_intel_cfl_sdw_machines, 163 .use_acpi_target_states = true, 164 .resindex_lpe_base = 0, 165 .resindex_pcicfg_base = -1, 166 .resindex_imr_base = -1, 167 .irqindex_host_ipc = -1, 168 .resindex_dma_base = -1, 169 .chip_info = &cnl_chip_info, 170 .default_fw_path = "intel/sof", 171 .default_tplg_path = "intel/sof-tplg", 172 .default_fw_filename = "sof-cfl.ri", 173 .nocodec_tplg_filename = "sof-cnl-nocodec.tplg", 174 .ops = &sof_cnl_ops, 175 }; 176 #endif 177 178 #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE) 179 static const struct sof_dev_desc cml_desc = { 180 .machines = snd_soc_acpi_intel_cml_machines, 181 .alt_machines = snd_soc_acpi_intel_cml_sdw_machines, 182 .use_acpi_target_states = true, 183 .resindex_lpe_base = 0, 184 .resindex_pcicfg_base = -1, 185 .resindex_imr_base = -1, 186 .irqindex_host_ipc = -1, 187 .resindex_dma_base = -1, 188 .chip_info = &cnl_chip_info, 189 .default_fw_path = "intel/sof", 190 .default_tplg_path = "intel/sof-tplg", 191 .default_fw_filename = "sof-cml.ri", 192 .nocodec_tplg_filename = "sof-cnl-nocodec.tplg", 193 .ops = &sof_cnl_ops, 194 }; 195 #endif 196 197 #if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) 198 static const struct sof_dev_desc icl_desc = { 199 .machines = snd_soc_acpi_intel_icl_machines, 200 .alt_machines = snd_soc_acpi_intel_icl_sdw_machines, 201 .use_acpi_target_states = true, 202 .resindex_lpe_base = 0, 203 .resindex_pcicfg_base = -1, 204 .resindex_imr_base = -1, 205 .irqindex_host_ipc = -1, 206 .resindex_dma_base = -1, 207 .chip_info = &icl_chip_info, 208 .default_fw_path = "intel/sof", 209 .default_tplg_path = "intel/sof-tplg", 210 .default_fw_filename = "sof-icl.ri", 211 .nocodec_tplg_filename = "sof-icl-nocodec.tplg", 212 .ops = &sof_icl_ops, 213 }; 214 #endif 215 216 #if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) || IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE) 217 static const struct sof_dev_desc tgl_desc = { 218 .machines = snd_soc_acpi_intel_tgl_machines, 219 .alt_machines = snd_soc_acpi_intel_tgl_sdw_machines, 220 .use_acpi_target_states = true, 221 .resindex_lpe_base = 0, 222 .resindex_pcicfg_base = -1, 223 .resindex_imr_base = -1, 224 .irqindex_host_ipc = -1, 225 .resindex_dma_base = -1, 226 .chip_info = &tgl_chip_info, 227 .default_fw_path = "intel/sof", 228 .default_tplg_path = "intel/sof-tplg", 229 .default_fw_filename = "sof-tgl.ri", 230 .nocodec_tplg_filename = "sof-tgl-nocodec.tplg", 231 .ops = &sof_tgl_ops, 232 }; 233 #endif 234 235 #if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) 236 static const struct sof_dev_desc tglh_desc = { 237 .machines = snd_soc_acpi_intel_tgl_machines, 238 .alt_machines = snd_soc_acpi_intel_tgl_sdw_machines, 239 .resindex_lpe_base = 0, 240 .resindex_pcicfg_base = -1, 241 .resindex_imr_base = -1, 242 .irqindex_host_ipc = -1, 243 .resindex_dma_base = -1, 244 .chip_info = &tglh_chip_info, 245 .default_fw_path = "intel/sof", 246 .default_tplg_path = "intel/sof-tplg", 247 .default_fw_filename = "sof-tgl-h.ri", 248 .nocodec_tplg_filename = "sof-tgl-nocodec.tplg", 249 .ops = &sof_tgl_ops, 250 }; 251 #endif 252 253 #if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE) 254 static const struct sof_dev_desc ehl_desc = { 255 .machines = snd_soc_acpi_intel_ehl_machines, 256 .use_acpi_target_states = true, 257 .resindex_lpe_base = 0, 258 .resindex_pcicfg_base = -1, 259 .resindex_imr_base = -1, 260 .irqindex_host_ipc = -1, 261 .resindex_dma_base = -1, 262 .chip_info = &ehl_chip_info, 263 .default_fw_path = "intel/sof", 264 .default_tplg_path = "intel/sof-tplg", 265 .default_fw_filename = "sof-ehl.ri", 266 .nocodec_tplg_filename = "sof-ehl-nocodec.tplg", 267 .ops = &sof_cnl_ops, 268 }; 269 #endif 270 271 #if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE) 272 static const struct sof_dev_desc jsl_desc = { 273 .machines = snd_soc_acpi_intel_jsl_machines, 274 .use_acpi_target_states = true, 275 .resindex_lpe_base = 0, 276 .resindex_pcicfg_base = -1, 277 .resindex_imr_base = -1, 278 .irqindex_host_ipc = -1, 279 .resindex_dma_base = -1, 280 .chip_info = &jsl_chip_info, 281 .default_fw_path = "intel/sof", 282 .default_tplg_path = "intel/sof-tplg", 283 .default_fw_filename = "sof-jsl.ri", 284 .nocodec_tplg_filename = "sof-jsl-nocodec.tplg", 285 .ops = &sof_cnl_ops, 286 }; 287 #endif 288 289 #if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE) 290 static const struct sof_dev_desc adls_desc = { 291 .machines = snd_soc_acpi_intel_adl_machines, 292 .alt_machines = snd_soc_acpi_intel_adl_sdw_machines, 293 .resindex_lpe_base = 0, 294 .resindex_pcicfg_base = -1, 295 .resindex_imr_base = -1, 296 .irqindex_host_ipc = -1, 297 .resindex_dma_base = -1, 298 .chip_info = &adls_chip_info, 299 .default_fw_path = "intel/sof", 300 .default_tplg_path = "intel/sof-tplg", 301 .default_fw_filename = "sof-adl-s.ri", 302 .nocodec_tplg_filename = "sof-adl-nocodec.tplg", 303 .ops = &sof_tgl_ops, 304 }; 305 #endif 306 307 static const struct dev_pm_ops sof_pci_pm = { 308 .prepare = snd_sof_prepare, 309 .complete = snd_sof_complete, 310 SET_SYSTEM_SLEEP_PM_OPS(snd_sof_suspend, snd_sof_resume) 311 SET_RUNTIME_PM_OPS(snd_sof_runtime_suspend, snd_sof_runtime_resume, 312 snd_sof_runtime_idle) 313 }; 314 315 static void sof_pci_probe_complete(struct device *dev) 316 { 317 dev_dbg(dev, "Completing SOF PCI probe"); 318 319 if (sof_pci_debug & SOF_PCI_DISABLE_PM_RUNTIME) 320 return; 321 322 /* allow runtime_pm */ 323 pm_runtime_set_autosuspend_delay(dev, SND_SOF_SUSPEND_DELAY_MS); 324 pm_runtime_use_autosuspend(dev); 325 326 /* 327 * runtime pm for pci device is "forbidden" by default. 328 * so call pm_runtime_allow() to enable it. 329 */ 330 pm_runtime_allow(dev); 331 332 /* mark last_busy for pm_runtime to make sure not suspend immediately */ 333 pm_runtime_mark_last_busy(dev); 334 335 /* follow recommendation in pci-driver.c to decrement usage counter */ 336 pm_runtime_put_noidle(dev); 337 } 338 339 static int sof_pci_probe(struct pci_dev *pci, 340 const struct pci_device_id *pci_id) 341 { 342 struct device *dev = &pci->dev; 343 const struct sof_dev_desc *desc = 344 (const struct sof_dev_desc *)pci_id->driver_data; 345 struct snd_sof_pdata *sof_pdata; 346 const struct snd_sof_dsp_ops *ops; 347 int ret; 348 349 ret = snd_intel_dsp_driver_probe(pci); 350 if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) { 351 dev_dbg(&pci->dev, "SOF PCI driver not selected, aborting probe\n"); 352 return -ENODEV; 353 } 354 dev_dbg(&pci->dev, "PCI DSP detected"); 355 356 /* get ops for platform */ 357 ops = desc->ops; 358 if (!ops) { 359 dev_err(dev, "error: no matching PCI descriptor ops\n"); 360 return -ENODEV; 361 } 362 363 sof_pdata = devm_kzalloc(dev, sizeof(*sof_pdata), GFP_KERNEL); 364 if (!sof_pdata) 365 return -ENOMEM; 366 367 ret = pcim_enable_device(pci); 368 if (ret < 0) 369 return ret; 370 371 ret = pci_request_regions(pci, "Audio DSP"); 372 if (ret < 0) 373 return ret; 374 375 sof_pdata->name = pci_name(pci); 376 sof_pdata->desc = (struct sof_dev_desc *)pci_id->driver_data; 377 sof_pdata->dev = dev; 378 sof_pdata->fw_filename = desc->default_fw_filename; 379 380 /* 381 * for platforms using the SOF community key, change the 382 * default path automatically to pick the right files from the 383 * linux-firmware tree. This can be overridden with the 384 * fw_path kernel parameter, e.g. for developers. 385 */ 386 387 /* alternate fw and tplg filenames ? */ 388 if (fw_path) { 389 sof_pdata->fw_filename_prefix = fw_path; 390 391 dev_dbg(dev, 392 "Module parameter used, changed fw path to %s\n", 393 sof_pdata->fw_filename_prefix); 394 395 } else if (dmi_check_system(community_key_platforms)) { 396 sof_pdata->fw_filename_prefix = 397 devm_kasprintf(dev, GFP_KERNEL, "%s/%s", 398 sof_pdata->desc->default_fw_path, 399 "community"); 400 401 dev_dbg(dev, 402 "Platform uses community key, changed fw path to %s\n", 403 sof_pdata->fw_filename_prefix); 404 } else { 405 sof_pdata->fw_filename_prefix = 406 sof_pdata->desc->default_fw_path; 407 } 408 409 if (tplg_path) 410 sof_pdata->tplg_filename_prefix = tplg_path; 411 else 412 sof_pdata->tplg_filename_prefix = 413 sof_pdata->desc->default_tplg_path; 414 415 dmi_check_system(sof_tplg_table); 416 if (sof_override_tplg_name) 417 sof_pdata->tplg_filename = sof_override_tplg_name; 418 419 #if IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE) 420 /* set callback to enable runtime_pm */ 421 sof_pdata->sof_probe_complete = sof_pci_probe_complete; 422 #endif 423 /* call sof helper for DSP hardware probe */ 424 ret = snd_sof_device_probe(dev, sof_pdata); 425 if (ret) { 426 dev_err(dev, "error: failed to probe DSP hardware!\n"); 427 goto release_regions; 428 } 429 430 #if !IS_ENABLED(CONFIG_SND_SOC_SOF_PROBE_WORK_QUEUE) 431 sof_pci_probe_complete(dev); 432 #endif 433 434 return ret; 435 436 release_regions: 437 pci_release_regions(pci); 438 439 return ret; 440 } 441 442 static void sof_pci_remove(struct pci_dev *pci) 443 { 444 /* call sof helper for DSP hardware remove */ 445 snd_sof_device_remove(&pci->dev); 446 447 /* follow recommendation in pci-driver.c to increment usage counter */ 448 if (!(sof_pci_debug & SOF_PCI_DISABLE_PM_RUNTIME)) 449 pm_runtime_get_noresume(&pci->dev); 450 451 /* release pci regions and disable device */ 452 pci_release_regions(pci); 453 } 454 455 static void sof_pci_shutdown(struct pci_dev *pci) 456 { 457 snd_sof_device_shutdown(&pci->dev); 458 } 459 460 /* PCI IDs */ 461 static const struct pci_device_id sof_pci_ids[] = { 462 #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) 463 { PCI_DEVICE(0x8086, 0x119a), 464 .driver_data = (unsigned long)&tng_desc}, 465 #endif 466 #if IS_ENABLED(CONFIG_SND_SOC_SOF_APOLLOLAKE) 467 /* BXT-P & Apollolake */ 468 { PCI_DEVICE(0x8086, 0x5a98), 469 .driver_data = (unsigned long)&bxt_desc}, 470 { PCI_DEVICE(0x8086, 0x1a98), 471 .driver_data = (unsigned long)&bxt_desc}, 472 #endif 473 #if IS_ENABLED(CONFIG_SND_SOC_SOF_GEMINILAKE) 474 { PCI_DEVICE(0x8086, 0x3198), 475 .driver_data = (unsigned long)&glk_desc}, 476 #endif 477 #if IS_ENABLED(CONFIG_SND_SOC_SOF_CANNONLAKE) 478 { PCI_DEVICE(0x8086, 0x9dc8), 479 .driver_data = (unsigned long)&cnl_desc}, 480 #endif 481 #if IS_ENABLED(CONFIG_SND_SOC_SOF_COFFEELAKE) 482 { PCI_DEVICE(0x8086, 0xa348), 483 .driver_data = (unsigned long)&cfl_desc}, 484 #endif 485 #if IS_ENABLED(CONFIG_SND_SOC_SOF_ICELAKE) 486 { PCI_DEVICE(0x8086, 0x34C8), /* ICL-LP */ 487 .driver_data = (unsigned long)&icl_desc}, 488 { PCI_DEVICE(0x8086, 0x3dc8), /* ICL-H */ 489 .driver_data = (unsigned long)&icl_desc}, 490 491 #endif 492 #if IS_ENABLED(CONFIG_SND_SOC_SOF_JASPERLAKE) 493 { PCI_DEVICE(0x8086, 0x38c8), 494 .driver_data = (unsigned long)&jsl_desc}, 495 { PCI_DEVICE(0x8086, 0x4dc8), 496 .driver_data = (unsigned long)&jsl_desc}, 497 #endif 498 #if IS_ENABLED(CONFIG_SND_SOC_SOF_COMETLAKE) 499 { PCI_DEVICE(0x8086, 0x02c8), /* CML-LP */ 500 .driver_data = (unsigned long)&cml_desc}, 501 { PCI_DEVICE(0x8086, 0x06c8), /* CML-H */ 502 .driver_data = (unsigned long)&cml_desc}, 503 { PCI_DEVICE(0x8086, 0xa3f0), /* CML-S */ 504 .driver_data = (unsigned long)&cml_desc}, 505 #endif 506 #if IS_ENABLED(CONFIG_SND_SOC_SOF_TIGERLAKE) 507 { PCI_DEVICE(0x8086, 0xa0c8), /* TGL-LP */ 508 .driver_data = (unsigned long)&tgl_desc}, 509 { PCI_DEVICE(0x8086, 0x43c8), /* TGL-H */ 510 .driver_data = (unsigned long)&tglh_desc}, 511 512 #endif 513 #if IS_ENABLED(CONFIG_SND_SOC_SOF_ELKHARTLAKE) 514 { PCI_DEVICE(0x8086, 0x4b55), 515 .driver_data = (unsigned long)&ehl_desc}, 516 { PCI_DEVICE(0x8086, 0x4b58), 517 .driver_data = (unsigned long)&ehl_desc}, 518 #endif 519 #if IS_ENABLED(CONFIG_SND_SOC_SOF_ALDERLAKE) 520 { PCI_DEVICE(0x8086, 0x7ad0), 521 .driver_data = (unsigned long)&adls_desc}, 522 { PCI_DEVICE(0x8086, 0x51c8), 523 .driver_data = (unsigned long)&tgl_desc}, 524 #endif 525 { 0, } 526 }; 527 MODULE_DEVICE_TABLE(pci, sof_pci_ids); 528 529 /* pci_driver definition */ 530 static struct pci_driver snd_sof_pci_driver = { 531 .name = "sof-audio-pci", 532 .id_table = sof_pci_ids, 533 .probe = sof_pci_probe, 534 .remove = sof_pci_remove, 535 .shutdown = sof_pci_shutdown, 536 .driver = { 537 .pm = &sof_pci_pm, 538 }, 539 }; 540 module_pci_driver(snd_sof_pci_driver); 541 542 MODULE_LICENSE("Dual BSD/GPL"); 543 MODULE_IMPORT_NS(SND_SOC_SOF_MERRIFIELD); 544 MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HDA_COMMON); 545