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 /* 12 * Hardware interface for audio DSP on Baytrail, Braswell and Cherrytrail. 13 */ 14 15 #include <linux/module.h> 16 #include <sound/sof.h> 17 #include <sound/sof/xtensa.h> 18 #include <sound/soc-acpi.h> 19 #include <sound/soc-acpi-intel-match.h> 20 #include <sound/intel-dsp-config.h> 21 #include "../ops.h" 22 #include "shim.h" 23 #include "../sof-acpi-dev.h" 24 #include "../sof-audio.h" 25 #include "../../intel/common/soc-intel-quirks.h" 26 27 /* DSP memories */ 28 #define IRAM_OFFSET 0x0C0000 29 #define IRAM_SIZE (80 * 1024) 30 #define DRAM_OFFSET 0x100000 31 #define DRAM_SIZE (160 * 1024) 32 #define SHIM_OFFSET 0x140000 33 #define SHIM_SIZE_BYT 0x100 34 #define SHIM_SIZE_CHT 0x118 35 #define MBOX_OFFSET 0x144000 36 #define MBOX_SIZE 0x1000 37 #define EXCEPT_OFFSET 0x800 38 #define EXCEPT_MAX_HDR_SIZE 0x400 39 40 /* DSP peripherals */ 41 #define DMAC0_OFFSET 0x098000 42 #define DMAC1_OFFSET 0x09c000 43 #define DMAC2_OFFSET 0x094000 44 #define DMAC_SIZE 0x420 45 #define SSP0_OFFSET 0x0a0000 46 #define SSP1_OFFSET 0x0a1000 47 #define SSP2_OFFSET 0x0a2000 48 #define SSP3_OFFSET 0x0a4000 49 #define SSP4_OFFSET 0x0a5000 50 #define SSP5_OFFSET 0x0a6000 51 #define SSP_SIZE 0x100 52 53 #define STACK_DUMP_SIZE 32 54 55 #define PCI_BAR_SIZE 0x200000 56 57 #define PANIC_OFFSET(x) (((x) & GENMASK_ULL(47, 32)) >> 32) 58 59 /* 60 * Debug 61 */ 62 63 #define MBOX_DUMP_SIZE 0x30 64 65 /* BARs */ 66 #define DSP_BAR 0 67 #define PCI_BAR 1 68 #define IMR_BAR 2 69 70 static const struct snd_sof_debugfs_map byt_debugfs[] = { 71 {"dmac0", DSP_BAR, DMAC0_OFFSET, DMAC_SIZE, 72 SOF_DEBUGFS_ACCESS_ALWAYS}, 73 {"dmac1", DSP_BAR, DMAC1_OFFSET, DMAC_SIZE, 74 SOF_DEBUGFS_ACCESS_ALWAYS}, 75 {"ssp0", DSP_BAR, SSP0_OFFSET, SSP_SIZE, 76 SOF_DEBUGFS_ACCESS_ALWAYS}, 77 {"ssp1", DSP_BAR, SSP1_OFFSET, SSP_SIZE, 78 SOF_DEBUGFS_ACCESS_ALWAYS}, 79 {"ssp2", DSP_BAR, SSP2_OFFSET, SSP_SIZE, 80 SOF_DEBUGFS_ACCESS_ALWAYS}, 81 {"iram", DSP_BAR, IRAM_OFFSET, IRAM_SIZE, 82 SOF_DEBUGFS_ACCESS_D0_ONLY}, 83 {"dram", DSP_BAR, DRAM_OFFSET, DRAM_SIZE, 84 SOF_DEBUGFS_ACCESS_D0_ONLY}, 85 {"shim", DSP_BAR, SHIM_OFFSET, SHIM_SIZE_BYT, 86 SOF_DEBUGFS_ACCESS_ALWAYS}, 87 }; 88 89 static const struct snd_sof_debugfs_map tng_debugfs[] = { 90 {"dmac0", DSP_BAR, DMAC0_OFFSET, DMAC_SIZE, 91 SOF_DEBUGFS_ACCESS_ALWAYS}, 92 {"dmac1", DSP_BAR, DMAC1_OFFSET, DMAC_SIZE, 93 SOF_DEBUGFS_ACCESS_ALWAYS}, 94 {"ssp0", DSP_BAR, SSP0_OFFSET, SSP_SIZE, 95 SOF_DEBUGFS_ACCESS_ALWAYS}, 96 {"ssp1", DSP_BAR, SSP1_OFFSET, SSP_SIZE, 97 SOF_DEBUGFS_ACCESS_ALWAYS}, 98 {"ssp2", DSP_BAR, SSP2_OFFSET, SSP_SIZE, 99 SOF_DEBUGFS_ACCESS_ALWAYS}, 100 {"iram", DSP_BAR, IRAM_OFFSET, IRAM_SIZE, 101 SOF_DEBUGFS_ACCESS_D0_ONLY}, 102 {"dram", DSP_BAR, DRAM_OFFSET, DRAM_SIZE, 103 SOF_DEBUGFS_ACCESS_D0_ONLY}, 104 {"shim", DSP_BAR, SHIM_OFFSET, SHIM_SIZE_BYT, 105 SOF_DEBUGFS_ACCESS_ALWAYS}, 106 }; 107 108 static void atom_host_done(struct snd_sof_dev *sdev); 109 static void atom_dsp_done(struct snd_sof_dev *sdev); 110 static void atom_get_reply(struct snd_sof_dev *sdev); 111 112 /* 113 * Debug 114 */ 115 116 static void atom_get_registers(struct snd_sof_dev *sdev, 117 struct sof_ipc_dsp_oops_xtensa *xoops, 118 struct sof_ipc_panic_info *panic_info, 119 u32 *stack, size_t stack_words) 120 { 121 u32 offset = sdev->dsp_oops_offset; 122 123 /* first read regsisters */ 124 sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops)); 125 126 /* note: variable AR register array is not read */ 127 128 /* then get panic info */ 129 if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) { 130 dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n", 131 xoops->arch_hdr.totalsize); 132 return; 133 } 134 offset += xoops->arch_hdr.totalsize; 135 sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info)); 136 137 /* then get the stack */ 138 offset += sizeof(*panic_info); 139 sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32)); 140 } 141 142 static void atom_dump(struct snd_sof_dev *sdev, u32 flags) 143 { 144 struct sof_ipc_dsp_oops_xtensa xoops; 145 struct sof_ipc_panic_info panic_info; 146 u32 stack[STACK_DUMP_SIZE]; 147 u64 status, panic, imrd, imrx; 148 149 /* now try generic SOF status messages */ 150 status = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCD); 151 panic = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCX); 152 atom_get_registers(sdev, &xoops, &panic_info, stack, 153 STACK_DUMP_SIZE); 154 snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack, 155 STACK_DUMP_SIZE); 156 157 /* provide some context for firmware debug */ 158 imrx = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IMRX); 159 imrd = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IMRD); 160 dev_err(sdev->dev, 161 "error: ipc host -> DSP: pending %s complete %s raw 0x%llx\n", 162 (panic & SHIM_IPCX_BUSY) ? "yes" : "no", 163 (panic & SHIM_IPCX_DONE) ? "yes" : "no", panic); 164 dev_err(sdev->dev, 165 "error: mask host: pending %s complete %s raw 0x%llx\n", 166 (imrx & SHIM_IMRX_BUSY) ? "yes" : "no", 167 (imrx & SHIM_IMRX_DONE) ? "yes" : "no", imrx); 168 dev_err(sdev->dev, 169 "error: ipc DSP -> host: pending %s complete %s raw 0x%llx\n", 170 (status & SHIM_IPCD_BUSY) ? "yes" : "no", 171 (status & SHIM_IPCD_DONE) ? "yes" : "no", status); 172 dev_err(sdev->dev, 173 "error: mask DSP: pending %s complete %s raw 0x%llx\n", 174 (imrd & SHIM_IMRD_BUSY) ? "yes" : "no", 175 (imrd & SHIM_IMRD_DONE) ? "yes" : "no", imrd); 176 177 } 178 179 /* 180 * IPC Doorbell IRQ handler and thread. 181 */ 182 183 static irqreturn_t atom_irq_handler(int irq, void *context) 184 { 185 struct snd_sof_dev *sdev = context; 186 u64 ipcx, ipcd; 187 int ret = IRQ_NONE; 188 189 ipcx = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCX); 190 ipcd = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCD); 191 192 if (ipcx & SHIM_BYT_IPCX_DONE) { 193 194 /* reply message from DSP, Mask Done interrupt first */ 195 snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, 196 SHIM_IMRX, 197 SHIM_IMRX_DONE, 198 SHIM_IMRX_DONE); 199 ret = IRQ_WAKE_THREAD; 200 } 201 202 if (ipcd & SHIM_BYT_IPCD_BUSY) { 203 204 /* new message from DSP, Mask Busy interrupt first */ 205 snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, 206 SHIM_IMRX, 207 SHIM_IMRX_BUSY, 208 SHIM_IMRX_BUSY); 209 ret = IRQ_WAKE_THREAD; 210 } 211 212 return ret; 213 } 214 215 static irqreturn_t atom_irq_thread(int irq, void *context) 216 { 217 struct snd_sof_dev *sdev = context; 218 u64 ipcx, ipcd; 219 220 ipcx = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCX); 221 ipcd = snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_IPCD); 222 223 /* reply message from DSP */ 224 if (ipcx & SHIM_BYT_IPCX_DONE) { 225 226 spin_lock_irq(&sdev->ipc_lock); 227 228 /* 229 * handle immediate reply from DSP core. If the msg is 230 * found, set done bit in cmd_done which is called at the 231 * end of message processing function, else set it here 232 * because the done bit can't be set in cmd_done function 233 * which is triggered by msg 234 */ 235 atom_get_reply(sdev); 236 snd_sof_ipc_reply(sdev, ipcx); 237 238 atom_dsp_done(sdev); 239 240 spin_unlock_irq(&sdev->ipc_lock); 241 } 242 243 /* new message from DSP */ 244 if (ipcd & SHIM_BYT_IPCD_BUSY) { 245 246 /* Handle messages from DSP Core */ 247 if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { 248 snd_sof_dsp_panic(sdev, PANIC_OFFSET(ipcd) + 249 MBOX_OFFSET); 250 } else { 251 snd_sof_ipc_msgs_rx(sdev); 252 } 253 254 atom_host_done(sdev); 255 } 256 257 return IRQ_HANDLED; 258 } 259 260 static int atom_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) 261 { 262 /* unmask and prepare to receive Done interrupt */ 263 snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, SHIM_IMRX, 264 SHIM_IMRX_DONE, 0); 265 266 /* send the message */ 267 sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, 268 msg->msg_size); 269 snd_sof_dsp_write64(sdev, DSP_BAR, SHIM_IPCX, SHIM_BYT_IPCX_BUSY); 270 271 return 0; 272 } 273 274 static void atom_get_reply(struct snd_sof_dev *sdev) 275 { 276 struct snd_sof_ipc_msg *msg = sdev->msg; 277 struct sof_ipc_reply reply; 278 int ret = 0; 279 280 /* 281 * Sometimes, there is unexpected reply ipc arriving. The reply 282 * ipc belongs to none of the ipcs sent from driver. 283 * In this case, the driver must ignore the ipc. 284 */ 285 if (!msg) { 286 dev_warn(sdev->dev, "unexpected ipc interrupt raised!\n"); 287 return; 288 } 289 290 /* get reply */ 291 sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply)); 292 293 if (reply.error < 0) { 294 memcpy(msg->reply_data, &reply, sizeof(reply)); 295 ret = reply.error; 296 } else { 297 /* reply correct size ? */ 298 if (reply.hdr.size != msg->reply_size) { 299 dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n", 300 msg->reply_size, reply.hdr.size); 301 ret = -EINVAL; 302 } 303 304 /* read the message */ 305 if (msg->reply_size > 0) 306 sof_mailbox_read(sdev, sdev->host_box.offset, 307 msg->reply_data, msg->reply_size); 308 } 309 310 msg->reply_error = ret; 311 } 312 313 static int atom_get_mailbox_offset(struct snd_sof_dev *sdev) 314 { 315 return MBOX_OFFSET; 316 } 317 318 static int atom_get_window_offset(struct snd_sof_dev *sdev, u32 id) 319 { 320 return MBOX_OFFSET; 321 } 322 323 static void atom_host_done(struct snd_sof_dev *sdev) 324 { 325 /* clear BUSY bit and set DONE bit - accept new messages */ 326 snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, SHIM_IPCD, 327 SHIM_BYT_IPCD_BUSY | 328 SHIM_BYT_IPCD_DONE, 329 SHIM_BYT_IPCD_DONE); 330 331 /* unmask and prepare to receive next new message */ 332 snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, SHIM_IMRX, 333 SHIM_IMRX_BUSY, 0); 334 } 335 336 static void atom_dsp_done(struct snd_sof_dev *sdev) 337 { 338 /* clear DONE bit - tell DSP we have completed */ 339 snd_sof_dsp_update_bits64_unlocked(sdev, DSP_BAR, SHIM_IPCX, 340 SHIM_BYT_IPCX_DONE, 0); 341 } 342 343 /* 344 * DSP control. 345 */ 346 347 static int atom_run(struct snd_sof_dev *sdev) 348 { 349 int tries = 10; 350 351 /* release stall and wait to unstall */ 352 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR, 353 SHIM_BYT_CSR_STALL, 0x0); 354 while (tries--) { 355 if (!(snd_sof_dsp_read64(sdev, DSP_BAR, SHIM_CSR) & 356 SHIM_BYT_CSR_PWAITMODE)) 357 break; 358 msleep(100); 359 } 360 if (tries < 0) { 361 dev_err(sdev->dev, "error: unable to run DSP firmware\n"); 362 atom_dump(sdev, SOF_DBG_DUMP_REGS | SOF_DBG_DUMP_MBOX); 363 return -ENODEV; 364 } 365 366 /* return init core mask */ 367 return 1; 368 } 369 370 static int atom_reset(struct snd_sof_dev *sdev) 371 { 372 /* put DSP into reset, set reset vector and stall */ 373 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR, 374 SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL | 375 SHIM_BYT_CSR_STALL, 376 SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL | 377 SHIM_BYT_CSR_STALL); 378 379 usleep_range(10, 15); 380 381 /* take DSP out of reset and keep stalled for FW loading */ 382 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR, 383 SHIM_BYT_CSR_RST, 0); 384 385 return 0; 386 } 387 388 static const char *fixup_tplg_name(struct snd_sof_dev *sdev, 389 const char *sof_tplg_filename, 390 const char *ssp_str) 391 { 392 const char *tplg_filename = NULL; 393 char *filename; 394 char *split_ext; 395 396 filename = devm_kstrdup(sdev->dev, sof_tplg_filename, GFP_KERNEL); 397 if (!filename) 398 return NULL; 399 400 /* this assumes a .tplg extension */ 401 split_ext = strsep(&filename, "."); 402 if (split_ext) { 403 tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, 404 "%s-%s.tplg", 405 split_ext, ssp_str); 406 if (!tplg_filename) 407 return NULL; 408 } 409 return tplg_filename; 410 } 411 412 static void atom_machine_select(struct snd_sof_dev *sdev) 413 { 414 struct snd_sof_pdata *sof_pdata = sdev->pdata; 415 const struct sof_dev_desc *desc = sof_pdata->desc; 416 struct snd_soc_acpi_mach *mach; 417 struct platform_device *pdev; 418 const char *tplg_filename; 419 420 mach = snd_soc_acpi_find_machine(desc->machines); 421 if (!mach) { 422 dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n"); 423 return; 424 } 425 426 pdev = to_platform_device(sdev->dev); 427 if (soc_intel_is_byt_cr(pdev)) { 428 dev_dbg(sdev->dev, 429 "BYT-CR detected, SSP0 used instead of SSP2\n"); 430 431 tplg_filename = fixup_tplg_name(sdev, 432 mach->sof_tplg_filename, 433 "ssp0"); 434 } else { 435 tplg_filename = mach->sof_tplg_filename; 436 } 437 438 if (!tplg_filename) { 439 dev_dbg(sdev->dev, 440 "error: no topology filename\n"); 441 return; 442 } 443 444 sof_pdata->tplg_filename = tplg_filename; 445 mach->mach_params.acpi_ipc_irq_index = desc->irqindex_host_ipc; 446 sof_pdata->machine = mach; 447 } 448 449 /* Atom DAIs */ 450 static struct snd_soc_dai_driver atom_dai[] = { 451 { 452 .name = "ssp0-port", 453 .playback = { 454 .channels_min = 1, 455 .channels_max = 8, 456 }, 457 .capture = { 458 .channels_min = 1, 459 .channels_max = 8, 460 }, 461 }, 462 { 463 .name = "ssp1-port", 464 .playback = { 465 .channels_min = 1, 466 .channels_max = 8, 467 }, 468 .capture = { 469 .channels_min = 1, 470 .channels_max = 8, 471 }, 472 }, 473 { 474 .name = "ssp2-port", 475 .playback = { 476 .channels_min = 1, 477 .channels_max = 8, 478 }, 479 .capture = { 480 .channels_min = 1, 481 .channels_max = 8, 482 } 483 }, 484 { 485 .name = "ssp3-port", 486 .playback = { 487 .channels_min = 1, 488 .channels_max = 8, 489 }, 490 .capture = { 491 .channels_min = 1, 492 .channels_max = 8, 493 }, 494 }, 495 { 496 .name = "ssp4-port", 497 .playback = { 498 .channels_min = 1, 499 .channels_max = 8, 500 }, 501 .capture = { 502 .channels_min = 1, 503 .channels_max = 8, 504 }, 505 }, 506 { 507 .name = "ssp5-port", 508 .playback = { 509 .channels_min = 1, 510 .channels_max = 8, 511 }, 512 .capture = { 513 .channels_min = 1, 514 .channels_max = 8, 515 }, 516 }, 517 }; 518 519 static void atom_set_mach_params(const struct snd_soc_acpi_mach *mach, 520 struct snd_sof_dev *sdev) 521 { 522 struct snd_sof_pdata *pdata = sdev->pdata; 523 const struct sof_dev_desc *desc = pdata->desc; 524 struct snd_soc_acpi_mach_params *mach_params; 525 526 mach_params = (struct snd_soc_acpi_mach_params *)&mach->mach_params; 527 mach_params->platform = dev_name(sdev->dev); 528 mach_params->num_dai_drivers = desc->ops->num_drv; 529 mach_params->dai_drivers = desc->ops->drv; 530 } 531 532 /* 533 * Probe and remove. 534 */ 535 536 #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) 537 538 static int tangier_pci_probe(struct snd_sof_dev *sdev) 539 { 540 struct snd_sof_pdata *pdata = sdev->pdata; 541 const struct sof_dev_desc *desc = pdata->desc; 542 struct pci_dev *pci = to_pci_dev(sdev->dev); 543 u32 base, size; 544 int ret; 545 546 /* DSP DMA can only access low 31 bits of host memory */ 547 ret = dma_coerce_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31)); 548 if (ret < 0) { 549 dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret); 550 return ret; 551 } 552 553 /* LPE base */ 554 base = pci_resource_start(pci, desc->resindex_lpe_base) - IRAM_OFFSET; 555 size = PCI_BAR_SIZE; 556 557 dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size); 558 sdev->bar[DSP_BAR] = devm_ioremap(sdev->dev, base, size); 559 if (!sdev->bar[DSP_BAR]) { 560 dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n", 561 base, size); 562 return -ENODEV; 563 } 564 dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[DSP_BAR]); 565 566 /* IMR base - optional */ 567 if (desc->resindex_imr_base == -1) 568 goto irq; 569 570 base = pci_resource_start(pci, desc->resindex_imr_base); 571 size = pci_resource_len(pci, desc->resindex_imr_base); 572 573 /* some BIOSes don't map IMR */ 574 if (base == 0x55aa55aa || base == 0x0) { 575 dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n"); 576 goto irq; 577 } 578 579 dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size); 580 sdev->bar[IMR_BAR] = devm_ioremap(sdev->dev, base, size); 581 if (!sdev->bar[IMR_BAR]) { 582 dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n", 583 base, size); 584 return -ENODEV; 585 } 586 dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[IMR_BAR]); 587 588 irq: 589 /* register our IRQ */ 590 sdev->ipc_irq = pci->irq; 591 dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); 592 ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq, 593 atom_irq_handler, atom_irq_thread, 594 0, "AudioDSP", sdev); 595 if (ret < 0) { 596 dev_err(sdev->dev, "error: failed to register IRQ %d\n", 597 sdev->ipc_irq); 598 return ret; 599 } 600 601 /* enable BUSY and disable DONE Interrupt by default */ 602 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX, 603 SHIM_IMRX_BUSY | SHIM_IMRX_DONE, 604 SHIM_IMRX_DONE); 605 606 /* set default mailbox offset for FW ready message */ 607 sdev->dsp_box.offset = MBOX_OFFSET; 608 609 return ret; 610 } 611 612 const struct snd_sof_dsp_ops sof_tng_ops = { 613 /* device init */ 614 .probe = tangier_pci_probe, 615 616 /* DSP core boot / reset */ 617 .run = atom_run, 618 .reset = atom_reset, 619 620 /* Register IO */ 621 .write = sof_io_write, 622 .read = sof_io_read, 623 .write64 = sof_io_write64, 624 .read64 = sof_io_read64, 625 626 /* Block IO */ 627 .block_read = sof_block_read, 628 .block_write = sof_block_write, 629 630 /* doorbell */ 631 .irq_handler = atom_irq_handler, 632 .irq_thread = atom_irq_thread, 633 634 /* ipc */ 635 .send_msg = atom_send_msg, 636 .fw_ready = sof_fw_ready, 637 .get_mailbox_offset = atom_get_mailbox_offset, 638 .get_window_offset = atom_get_window_offset, 639 640 .ipc_msg_data = intel_ipc_msg_data, 641 .ipc_pcm_params = intel_ipc_pcm_params, 642 643 /* machine driver */ 644 .machine_select = atom_machine_select, 645 .machine_register = sof_machine_register, 646 .machine_unregister = sof_machine_unregister, 647 .set_mach_params = atom_set_mach_params, 648 649 /* debug */ 650 .debug_map = tng_debugfs, 651 .debug_map_count = ARRAY_SIZE(tng_debugfs), 652 .dbg_dump = atom_dump, 653 654 /* stream callbacks */ 655 .pcm_open = intel_pcm_open, 656 .pcm_close = intel_pcm_close, 657 658 /* module loading */ 659 .load_module = snd_sof_parse_module_memcpy, 660 661 /*Firmware loading */ 662 .load_firmware = snd_sof_load_firmware_memcpy, 663 664 /* DAI drivers */ 665 .drv = atom_dai, 666 .num_drv = 3, /* we have only 3 SSPs on byt*/ 667 668 /* ALSA HW info flags */ 669 .hw_info = SNDRV_PCM_INFO_MMAP | 670 SNDRV_PCM_INFO_MMAP_VALID | 671 SNDRV_PCM_INFO_INTERLEAVED | 672 SNDRV_PCM_INFO_PAUSE | 673 SNDRV_PCM_INFO_BATCH, 674 675 .arch_ops = &sof_xtensa_arch_ops, 676 }; 677 EXPORT_SYMBOL_NS(sof_tng_ops, SND_SOC_SOF_MERRIFIELD); 678 679 const struct sof_intel_dsp_desc tng_chip_info = { 680 .cores_num = 1, 681 .host_managed_cores_mask = 1, 682 }; 683 EXPORT_SYMBOL_NS(tng_chip_info, SND_SOC_SOF_MERRIFIELD); 684 685 #endif /* CONFIG_SND_SOC_SOF_MERRIFIELD */ 686 687 #if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) 688 689 static void byt_reset_dsp_disable_int(struct snd_sof_dev *sdev) 690 { 691 /* Disable Interrupt from both sides */ 692 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX, 0x3, 0x3); 693 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRD, 0x3, 0x3); 694 695 /* Put DSP into reset, set reset vector */ 696 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_CSR, 697 SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL, 698 SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL); 699 } 700 701 static int byt_suspend(struct snd_sof_dev *sdev, u32 target_state) 702 { 703 byt_reset_dsp_disable_int(sdev); 704 705 return 0; 706 } 707 708 static int byt_resume(struct snd_sof_dev *sdev) 709 { 710 /* enable BUSY and disable DONE Interrupt by default */ 711 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX, 712 SHIM_IMRX_BUSY | SHIM_IMRX_DONE, 713 SHIM_IMRX_DONE); 714 715 return 0; 716 } 717 718 static int byt_remove(struct snd_sof_dev *sdev) 719 { 720 byt_reset_dsp_disable_int(sdev); 721 722 return 0; 723 } 724 725 static const struct snd_sof_debugfs_map cht_debugfs[] = { 726 {"dmac0", DSP_BAR, DMAC0_OFFSET, DMAC_SIZE, 727 SOF_DEBUGFS_ACCESS_ALWAYS}, 728 {"dmac1", DSP_BAR, DMAC1_OFFSET, DMAC_SIZE, 729 SOF_DEBUGFS_ACCESS_ALWAYS}, 730 {"dmac2", DSP_BAR, DMAC2_OFFSET, DMAC_SIZE, 731 SOF_DEBUGFS_ACCESS_ALWAYS}, 732 {"ssp0", DSP_BAR, SSP0_OFFSET, SSP_SIZE, 733 SOF_DEBUGFS_ACCESS_ALWAYS}, 734 {"ssp1", DSP_BAR, SSP1_OFFSET, SSP_SIZE, 735 SOF_DEBUGFS_ACCESS_ALWAYS}, 736 {"ssp2", DSP_BAR, SSP2_OFFSET, SSP_SIZE, 737 SOF_DEBUGFS_ACCESS_ALWAYS}, 738 {"ssp3", DSP_BAR, SSP3_OFFSET, SSP_SIZE, 739 SOF_DEBUGFS_ACCESS_ALWAYS}, 740 {"ssp4", DSP_BAR, SSP4_OFFSET, SSP_SIZE, 741 SOF_DEBUGFS_ACCESS_ALWAYS}, 742 {"ssp5", DSP_BAR, SSP5_OFFSET, SSP_SIZE, 743 SOF_DEBUGFS_ACCESS_ALWAYS}, 744 {"iram", DSP_BAR, IRAM_OFFSET, IRAM_SIZE, 745 SOF_DEBUGFS_ACCESS_D0_ONLY}, 746 {"dram", DSP_BAR, DRAM_OFFSET, DRAM_SIZE, 747 SOF_DEBUGFS_ACCESS_D0_ONLY}, 748 {"shim", DSP_BAR, SHIM_OFFSET, SHIM_SIZE_CHT, 749 SOF_DEBUGFS_ACCESS_ALWAYS}, 750 }; 751 752 static int byt_acpi_probe(struct snd_sof_dev *sdev) 753 { 754 struct snd_sof_pdata *pdata = sdev->pdata; 755 const struct sof_dev_desc *desc = pdata->desc; 756 struct platform_device *pdev = 757 container_of(sdev->dev, struct platform_device, dev); 758 struct resource *mmio; 759 u32 base, size; 760 int ret; 761 762 /* DSP DMA can only access low 31 bits of host memory */ 763 ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31)); 764 if (ret < 0) { 765 dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret); 766 return ret; 767 } 768 769 /* LPE base */ 770 mmio = platform_get_resource(pdev, IORESOURCE_MEM, 771 desc->resindex_lpe_base); 772 if (mmio) { 773 base = mmio->start; 774 size = resource_size(mmio); 775 } else { 776 dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n", 777 desc->resindex_lpe_base); 778 return -EINVAL; 779 } 780 781 dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size); 782 sdev->bar[DSP_BAR] = devm_ioremap(sdev->dev, base, size); 783 if (!sdev->bar[DSP_BAR]) { 784 dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n", 785 base, size); 786 return -ENODEV; 787 } 788 dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[DSP_BAR]); 789 790 /* TODO: add offsets */ 791 sdev->mmio_bar = DSP_BAR; 792 sdev->mailbox_bar = DSP_BAR; 793 794 /* IMR base - optional */ 795 if (desc->resindex_imr_base == -1) 796 goto irq; 797 798 mmio = platform_get_resource(pdev, IORESOURCE_MEM, 799 desc->resindex_imr_base); 800 if (mmio) { 801 base = mmio->start; 802 size = resource_size(mmio); 803 } else { 804 dev_err(sdev->dev, "error: failed to get IMR base at idx %d\n", 805 desc->resindex_imr_base); 806 return -ENODEV; 807 } 808 809 /* some BIOSes don't map IMR */ 810 if (base == 0x55aa55aa || base == 0x0) { 811 dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n"); 812 goto irq; 813 } 814 815 dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size); 816 sdev->bar[IMR_BAR] = devm_ioremap(sdev->dev, base, size); 817 if (!sdev->bar[IMR_BAR]) { 818 dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n", 819 base, size); 820 return -ENODEV; 821 } 822 dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[IMR_BAR]); 823 824 irq: 825 /* register our IRQ */ 826 sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc); 827 if (sdev->ipc_irq < 0) 828 return sdev->ipc_irq; 829 830 dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); 831 ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq, 832 atom_irq_handler, atom_irq_thread, 833 IRQF_SHARED, "AudioDSP", sdev); 834 if (ret < 0) { 835 dev_err(sdev->dev, "error: failed to register IRQ %d\n", 836 sdev->ipc_irq); 837 return ret; 838 } 839 840 /* enable BUSY and disable DONE Interrupt by default */ 841 snd_sof_dsp_update_bits64(sdev, DSP_BAR, SHIM_IMRX, 842 SHIM_IMRX_BUSY | SHIM_IMRX_DONE, 843 SHIM_IMRX_DONE); 844 845 /* set default mailbox offset for FW ready message */ 846 sdev->dsp_box.offset = MBOX_OFFSET; 847 848 return ret; 849 } 850 851 /* baytrail ops */ 852 static const struct snd_sof_dsp_ops sof_byt_ops = { 853 /* device init */ 854 .probe = byt_acpi_probe, 855 .remove = byt_remove, 856 857 /* DSP core boot / reset */ 858 .run = atom_run, 859 .reset = atom_reset, 860 861 /* Register IO */ 862 .write = sof_io_write, 863 .read = sof_io_read, 864 .write64 = sof_io_write64, 865 .read64 = sof_io_read64, 866 867 /* Block IO */ 868 .block_read = sof_block_read, 869 .block_write = sof_block_write, 870 871 /* doorbell */ 872 .irq_handler = atom_irq_handler, 873 .irq_thread = atom_irq_thread, 874 875 /* ipc */ 876 .send_msg = atom_send_msg, 877 .fw_ready = sof_fw_ready, 878 .get_mailbox_offset = atom_get_mailbox_offset, 879 .get_window_offset = atom_get_window_offset, 880 881 .ipc_msg_data = intel_ipc_msg_data, 882 .ipc_pcm_params = intel_ipc_pcm_params, 883 884 /* machine driver */ 885 .machine_select = atom_machine_select, 886 .machine_register = sof_machine_register, 887 .machine_unregister = sof_machine_unregister, 888 .set_mach_params = atom_set_mach_params, 889 890 /* debug */ 891 .debug_map = byt_debugfs, 892 .debug_map_count = ARRAY_SIZE(byt_debugfs), 893 .dbg_dump = atom_dump, 894 895 /* stream callbacks */ 896 .pcm_open = intel_pcm_open, 897 .pcm_close = intel_pcm_close, 898 899 /* module loading */ 900 .load_module = snd_sof_parse_module_memcpy, 901 902 /*Firmware loading */ 903 .load_firmware = snd_sof_load_firmware_memcpy, 904 905 /* PM */ 906 .suspend = byt_suspend, 907 .resume = byt_resume, 908 909 /* DAI drivers */ 910 .drv = atom_dai, 911 .num_drv = 3, /* we have only 3 SSPs on byt*/ 912 913 /* ALSA HW info flags */ 914 .hw_info = SNDRV_PCM_INFO_MMAP | 915 SNDRV_PCM_INFO_MMAP_VALID | 916 SNDRV_PCM_INFO_INTERLEAVED | 917 SNDRV_PCM_INFO_PAUSE | 918 SNDRV_PCM_INFO_BATCH, 919 920 .arch_ops = &sof_xtensa_arch_ops, 921 }; 922 923 static const struct sof_intel_dsp_desc byt_chip_info = { 924 .cores_num = 1, 925 .host_managed_cores_mask = 1, 926 }; 927 928 /* cherrytrail and braswell ops */ 929 static const struct snd_sof_dsp_ops sof_cht_ops = { 930 /* device init */ 931 .probe = byt_acpi_probe, 932 .remove = byt_remove, 933 934 /* DSP core boot / reset */ 935 .run = atom_run, 936 .reset = atom_reset, 937 938 /* Register IO */ 939 .write = sof_io_write, 940 .read = sof_io_read, 941 .write64 = sof_io_write64, 942 .read64 = sof_io_read64, 943 944 /* Block IO */ 945 .block_read = sof_block_read, 946 .block_write = sof_block_write, 947 948 /* doorbell */ 949 .irq_handler = atom_irq_handler, 950 .irq_thread = atom_irq_thread, 951 952 /* ipc */ 953 .send_msg = atom_send_msg, 954 .fw_ready = sof_fw_ready, 955 .get_mailbox_offset = atom_get_mailbox_offset, 956 .get_window_offset = atom_get_window_offset, 957 958 .ipc_msg_data = intel_ipc_msg_data, 959 .ipc_pcm_params = intel_ipc_pcm_params, 960 961 /* machine driver */ 962 .machine_select = atom_machine_select, 963 .machine_register = sof_machine_register, 964 .machine_unregister = sof_machine_unregister, 965 .set_mach_params = atom_set_mach_params, 966 967 /* debug */ 968 .debug_map = cht_debugfs, 969 .debug_map_count = ARRAY_SIZE(cht_debugfs), 970 .dbg_dump = atom_dump, 971 972 /* stream callbacks */ 973 .pcm_open = intel_pcm_open, 974 .pcm_close = intel_pcm_close, 975 976 /* module loading */ 977 .load_module = snd_sof_parse_module_memcpy, 978 979 /*Firmware loading */ 980 .load_firmware = snd_sof_load_firmware_memcpy, 981 982 /* PM */ 983 .suspend = byt_suspend, 984 .resume = byt_resume, 985 986 /* DAI drivers */ 987 .drv = atom_dai, 988 /* all 6 SSPs may be available for cherrytrail */ 989 .num_drv = 6, 990 991 /* ALSA HW info flags */ 992 .hw_info = SNDRV_PCM_INFO_MMAP | 993 SNDRV_PCM_INFO_MMAP_VALID | 994 SNDRV_PCM_INFO_INTERLEAVED | 995 SNDRV_PCM_INFO_PAUSE | 996 SNDRV_PCM_INFO_BATCH, 997 998 .arch_ops = &sof_xtensa_arch_ops, 999 }; 1000 1001 static const struct sof_intel_dsp_desc cht_chip_info = { 1002 .cores_num = 1, 1003 .host_managed_cores_mask = 1, 1004 }; 1005 1006 /* BYTCR uses different IRQ index */ 1007 static const struct sof_dev_desc sof_acpi_baytrailcr_desc = { 1008 .machines = snd_soc_acpi_intel_baytrail_machines, 1009 .resindex_lpe_base = 0, 1010 .resindex_pcicfg_base = 1, 1011 .resindex_imr_base = 2, 1012 .irqindex_host_ipc = 0, 1013 .chip_info = &byt_chip_info, 1014 .default_fw_path = "intel/sof", 1015 .default_tplg_path = "intel/sof-tplg", 1016 .default_fw_filename = "sof-byt.ri", 1017 .nocodec_tplg_filename = "sof-byt-nocodec.tplg", 1018 .ops = &sof_byt_ops, 1019 }; 1020 1021 static const struct sof_dev_desc sof_acpi_baytrail_desc = { 1022 .machines = snd_soc_acpi_intel_baytrail_machines, 1023 .resindex_lpe_base = 0, 1024 .resindex_pcicfg_base = 1, 1025 .resindex_imr_base = 2, 1026 .irqindex_host_ipc = 5, 1027 .chip_info = &byt_chip_info, 1028 .default_fw_path = "intel/sof", 1029 .default_tplg_path = "intel/sof-tplg", 1030 .default_fw_filename = "sof-byt.ri", 1031 .nocodec_tplg_filename = "sof-byt-nocodec.tplg", 1032 .ops = &sof_byt_ops, 1033 }; 1034 1035 static const struct sof_dev_desc sof_acpi_cherrytrail_desc = { 1036 .machines = snd_soc_acpi_intel_cherrytrail_machines, 1037 .resindex_lpe_base = 0, 1038 .resindex_pcicfg_base = 1, 1039 .resindex_imr_base = 2, 1040 .irqindex_host_ipc = 5, 1041 .chip_info = &cht_chip_info, 1042 .default_fw_path = "intel/sof", 1043 .default_tplg_path = "intel/sof-tplg", 1044 .default_fw_filename = "sof-cht.ri", 1045 .nocodec_tplg_filename = "sof-cht-nocodec.tplg", 1046 .ops = &sof_cht_ops, 1047 }; 1048 1049 static const struct acpi_device_id sof_baytrail_match[] = { 1050 { "80860F28", (unsigned long)&sof_acpi_baytrail_desc }, 1051 { "808622A8", (unsigned long)&sof_acpi_cherrytrail_desc }, 1052 { } 1053 }; 1054 MODULE_DEVICE_TABLE(acpi, sof_baytrail_match); 1055 1056 static int sof_baytrail_probe(struct platform_device *pdev) 1057 { 1058 struct device *dev = &pdev->dev; 1059 const struct sof_dev_desc *desc; 1060 const struct acpi_device_id *id; 1061 int ret; 1062 1063 id = acpi_match_device(dev->driver->acpi_match_table, dev); 1064 if (!id) 1065 return -ENODEV; 1066 1067 ret = snd_intel_acpi_dsp_driver_probe(dev, id->id); 1068 if (ret != SND_INTEL_DSP_DRIVER_ANY && ret != SND_INTEL_DSP_DRIVER_SOF) { 1069 dev_dbg(dev, "SOF ACPI driver not selected, aborting probe\n"); 1070 return -ENODEV; 1071 } 1072 1073 desc = device_get_match_data(&pdev->dev); 1074 if (!desc) 1075 return -ENODEV; 1076 1077 if (desc == &sof_acpi_baytrail_desc && soc_intel_is_byt_cr(pdev)) 1078 desc = &sof_acpi_baytrailcr_desc; 1079 1080 return sof_acpi_probe(pdev, desc); 1081 } 1082 1083 /* acpi_driver definition */ 1084 static struct platform_driver snd_sof_acpi_intel_byt_driver = { 1085 .probe = sof_baytrail_probe, 1086 .remove = sof_acpi_remove, 1087 .driver = { 1088 .name = "sof-audio-acpi-intel-byt", 1089 .pm = &sof_acpi_pm, 1090 .acpi_match_table = sof_baytrail_match, 1091 }, 1092 }; 1093 module_platform_driver(snd_sof_acpi_intel_byt_driver); 1094 1095 #endif /* CONFIG_SND_SOC_SOF_BAYTRAIL */ 1096 1097 MODULE_LICENSE("Dual BSD/GPL"); 1098 MODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC); 1099 MODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); 1100 MODULE_IMPORT_NS(SND_SOC_SOF_ACPI_DEV); 1101