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 // 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 "../ops.h" 19 #include "shim.h" 20 #include "../sof-audio.h" 21 22 /* DSP memories */ 23 #define IRAM_OFFSET 0x0C0000 24 #define IRAM_SIZE (80 * 1024) 25 #define DRAM_OFFSET 0x100000 26 #define DRAM_SIZE (160 * 1024) 27 #define SHIM_OFFSET 0x140000 28 #define SHIM_SIZE 0x100 29 #define MBOX_OFFSET 0x144000 30 #define MBOX_SIZE 0x1000 31 #define EXCEPT_OFFSET 0x800 32 #define EXCEPT_MAX_HDR_SIZE 0x400 33 34 /* DSP peripherals */ 35 #define DMAC0_OFFSET 0x098000 36 #define DMAC1_OFFSET 0x09c000 37 #define DMAC2_OFFSET 0x094000 38 #define DMAC_SIZE 0x420 39 #define SSP0_OFFSET 0x0a0000 40 #define SSP1_OFFSET 0x0a1000 41 #define SSP2_OFFSET 0x0a2000 42 #define SSP3_OFFSET 0x0a4000 43 #define SSP4_OFFSET 0x0a5000 44 #define SSP5_OFFSET 0x0a6000 45 #define SSP_SIZE 0x100 46 47 #define BYT_STACK_DUMP_SIZE 32 48 49 #define BYT_PCI_BAR_SIZE 0x200000 50 51 #define BYT_PANIC_OFFSET(x) (((x) & GENMASK_ULL(47, 32)) >> 32) 52 53 /* 54 * Debug 55 */ 56 57 #define MBOX_DUMP_SIZE 0x30 58 59 /* BARs */ 60 #define BYT_DSP_BAR 0 61 #define BYT_PCI_BAR 1 62 #define BYT_IMR_BAR 2 63 64 static const struct snd_sof_debugfs_map byt_debugfs[] = { 65 {"dmac0", BYT_DSP_BAR, DMAC0_OFFSET, DMAC_SIZE, 66 SOF_DEBUGFS_ACCESS_ALWAYS}, 67 {"dmac1", BYT_DSP_BAR, DMAC1_OFFSET, DMAC_SIZE, 68 SOF_DEBUGFS_ACCESS_ALWAYS}, 69 {"ssp0", BYT_DSP_BAR, SSP0_OFFSET, SSP_SIZE, 70 SOF_DEBUGFS_ACCESS_ALWAYS}, 71 {"ssp1", BYT_DSP_BAR, SSP1_OFFSET, SSP_SIZE, 72 SOF_DEBUGFS_ACCESS_ALWAYS}, 73 {"ssp2", BYT_DSP_BAR, SSP2_OFFSET, SSP_SIZE, 74 SOF_DEBUGFS_ACCESS_ALWAYS}, 75 {"iram", BYT_DSP_BAR, IRAM_OFFSET, IRAM_SIZE, 76 SOF_DEBUGFS_ACCESS_D0_ONLY}, 77 {"dram", BYT_DSP_BAR, DRAM_OFFSET, DRAM_SIZE, 78 SOF_DEBUGFS_ACCESS_D0_ONLY}, 79 {"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE, 80 SOF_DEBUGFS_ACCESS_ALWAYS}, 81 }; 82 83 static const struct snd_sof_debugfs_map cht_debugfs[] = { 84 {"dmac0", BYT_DSP_BAR, DMAC0_OFFSET, DMAC_SIZE, 85 SOF_DEBUGFS_ACCESS_ALWAYS}, 86 {"dmac1", BYT_DSP_BAR, DMAC1_OFFSET, DMAC_SIZE, 87 SOF_DEBUGFS_ACCESS_ALWAYS}, 88 {"dmac2", BYT_DSP_BAR, DMAC2_OFFSET, DMAC_SIZE, 89 SOF_DEBUGFS_ACCESS_ALWAYS}, 90 {"ssp0", BYT_DSP_BAR, SSP0_OFFSET, SSP_SIZE, 91 SOF_DEBUGFS_ACCESS_ALWAYS}, 92 {"ssp1", BYT_DSP_BAR, SSP1_OFFSET, SSP_SIZE, 93 SOF_DEBUGFS_ACCESS_ALWAYS}, 94 {"ssp2", BYT_DSP_BAR, SSP2_OFFSET, SSP_SIZE, 95 SOF_DEBUGFS_ACCESS_ALWAYS}, 96 {"ssp3", BYT_DSP_BAR, SSP3_OFFSET, SSP_SIZE, 97 SOF_DEBUGFS_ACCESS_ALWAYS}, 98 {"ssp4", BYT_DSP_BAR, SSP4_OFFSET, SSP_SIZE, 99 SOF_DEBUGFS_ACCESS_ALWAYS}, 100 {"ssp5", BYT_DSP_BAR, SSP5_OFFSET, SSP_SIZE, 101 SOF_DEBUGFS_ACCESS_ALWAYS}, 102 {"iram", BYT_DSP_BAR, IRAM_OFFSET, IRAM_SIZE, 103 SOF_DEBUGFS_ACCESS_D0_ONLY}, 104 {"dram", BYT_DSP_BAR, DRAM_OFFSET, DRAM_SIZE, 105 SOF_DEBUGFS_ACCESS_D0_ONLY}, 106 {"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE, 107 SOF_DEBUGFS_ACCESS_ALWAYS}, 108 }; 109 110 static void byt_host_done(struct snd_sof_dev *sdev); 111 static void byt_dsp_done(struct snd_sof_dev *sdev); 112 static void byt_get_reply(struct snd_sof_dev *sdev); 113 114 /* 115 * Debug 116 */ 117 118 static void byt_get_registers(struct snd_sof_dev *sdev, 119 struct sof_ipc_dsp_oops_xtensa *xoops, 120 struct sof_ipc_panic_info *panic_info, 121 u32 *stack, size_t stack_words) 122 { 123 u32 offset = sdev->dsp_oops_offset; 124 125 /* first read regsisters */ 126 sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops)); 127 128 /* note: variable AR register array is not read */ 129 130 /* then get panic info */ 131 if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) { 132 dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n", 133 xoops->arch_hdr.totalsize); 134 return; 135 } 136 offset += xoops->arch_hdr.totalsize; 137 sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info)); 138 139 /* then get the stack */ 140 offset += sizeof(*panic_info); 141 sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32)); 142 } 143 144 static void byt_dump(struct snd_sof_dev *sdev, u32 flags) 145 { 146 struct sof_ipc_dsp_oops_xtensa xoops; 147 struct sof_ipc_panic_info panic_info; 148 u32 stack[BYT_STACK_DUMP_SIZE]; 149 u32 status, panic, imrd, imrx; 150 151 /* now try generic SOF status messages */ 152 status = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IPCD); 153 panic = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IPCX); 154 byt_get_registers(sdev, &xoops, &panic_info, stack, 155 BYT_STACK_DUMP_SIZE); 156 snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack, 157 BYT_STACK_DUMP_SIZE); 158 159 /* provide some context for firmware debug */ 160 imrx = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IMRX); 161 imrd = snd_sof_dsp_read(sdev, BYT_DSP_BAR, SHIM_IMRD); 162 dev_err(sdev->dev, 163 "error: ipc host -> DSP: pending %s complete %s raw 0x%8.8x\n", 164 (panic & SHIM_IPCX_BUSY) ? "yes" : "no", 165 (panic & SHIM_IPCX_DONE) ? "yes" : "no", panic); 166 dev_err(sdev->dev, 167 "error: mask host: pending %s complete %s raw 0x%8.8x\n", 168 (imrx & SHIM_IMRX_BUSY) ? "yes" : "no", 169 (imrx & SHIM_IMRX_DONE) ? "yes" : "no", imrx); 170 dev_err(sdev->dev, 171 "error: ipc DSP -> host: pending %s complete %s raw 0x%8.8x\n", 172 (status & SHIM_IPCD_BUSY) ? "yes" : "no", 173 (status & SHIM_IPCD_DONE) ? "yes" : "no", status); 174 dev_err(sdev->dev, 175 "error: mask DSP: pending %s complete %s raw 0x%8.8x\n", 176 (imrd & SHIM_IMRD_BUSY) ? "yes" : "no", 177 (imrd & SHIM_IMRD_DONE) ? "yes" : "no", imrd); 178 179 } 180 181 /* 182 * IPC Doorbell IRQ handler and thread. 183 */ 184 185 static irqreturn_t byt_irq_handler(int irq, void *context) 186 { 187 struct snd_sof_dev *sdev = context; 188 u64 isr; 189 int ret = IRQ_NONE; 190 191 /* Interrupt arrived, check src */ 192 isr = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_ISRX); 193 if (isr & (SHIM_ISRX_DONE | SHIM_ISRX_BUSY)) 194 ret = IRQ_WAKE_THREAD; 195 196 return ret; 197 } 198 199 static irqreturn_t byt_irq_thread(int irq, void *context) 200 { 201 struct snd_sof_dev *sdev = context; 202 u64 ipcx, ipcd; 203 u64 imrx; 204 205 imrx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRX); 206 ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX); 207 208 /* reply message from DSP */ 209 if (ipcx & SHIM_BYT_IPCX_DONE && 210 !(imrx & SHIM_IMRX_DONE)) { 211 /* Mask Done interrupt before first */ 212 snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, 213 SHIM_IMRX, 214 SHIM_IMRX_DONE, 215 SHIM_IMRX_DONE); 216 217 spin_lock_irq(&sdev->ipc_lock); 218 219 /* 220 * handle immediate reply from DSP core. If the msg is 221 * found, set done bit in cmd_done which is called at the 222 * end of message processing function, else set it here 223 * because the done bit can't be set in cmd_done function 224 * which is triggered by msg 225 */ 226 byt_get_reply(sdev); 227 snd_sof_ipc_reply(sdev, ipcx); 228 229 byt_dsp_done(sdev); 230 231 spin_unlock_irq(&sdev->ipc_lock); 232 } 233 234 /* new message from DSP */ 235 ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD); 236 if (ipcd & SHIM_BYT_IPCD_BUSY && 237 !(imrx & SHIM_IMRX_BUSY)) { 238 /* Mask Busy interrupt before return */ 239 snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, 240 SHIM_IMRX, 241 SHIM_IMRX_BUSY, 242 SHIM_IMRX_BUSY); 243 244 /* Handle messages from DSP Core */ 245 if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { 246 snd_sof_dsp_panic(sdev, BYT_PANIC_OFFSET(ipcd) + 247 MBOX_OFFSET); 248 } else { 249 snd_sof_ipc_msgs_rx(sdev); 250 } 251 252 byt_host_done(sdev); 253 } 254 255 return IRQ_HANDLED; 256 } 257 258 static int byt_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) 259 { 260 /* send the message */ 261 sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, 262 msg->msg_size); 263 snd_sof_dsp_write64(sdev, BYT_DSP_BAR, SHIM_IPCX, SHIM_BYT_IPCX_BUSY); 264 265 return 0; 266 } 267 268 static void byt_get_reply(struct snd_sof_dev *sdev) 269 { 270 struct snd_sof_ipc_msg *msg = sdev->msg; 271 struct sof_ipc_reply reply; 272 int ret = 0; 273 274 /* 275 * Sometimes, there is unexpected reply ipc arriving. The reply 276 * ipc belongs to none of the ipcs sent from driver. 277 * In this case, the driver must ignore the ipc. 278 */ 279 if (!msg) { 280 dev_warn(sdev->dev, "unexpected ipc interrupt raised!\n"); 281 return; 282 } 283 284 /* get reply */ 285 sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply)); 286 287 if (reply.error < 0) { 288 memcpy(msg->reply_data, &reply, sizeof(reply)); 289 ret = reply.error; 290 } else { 291 /* reply correct size ? */ 292 if (reply.hdr.size != msg->reply_size) { 293 dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n", 294 msg->reply_size, reply.hdr.size); 295 ret = -EINVAL; 296 } 297 298 /* read the message */ 299 if (msg->reply_size > 0) 300 sof_mailbox_read(sdev, sdev->host_box.offset, 301 msg->reply_data, msg->reply_size); 302 } 303 304 msg->reply_error = ret; 305 } 306 307 static int byt_get_mailbox_offset(struct snd_sof_dev *sdev) 308 { 309 return MBOX_OFFSET; 310 } 311 312 static int byt_get_window_offset(struct snd_sof_dev *sdev, u32 id) 313 { 314 return MBOX_OFFSET; 315 } 316 317 static void byt_host_done(struct snd_sof_dev *sdev) 318 { 319 /* clear BUSY bit and set DONE bit - accept new messages */ 320 snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCD, 321 SHIM_BYT_IPCD_BUSY | 322 SHIM_BYT_IPCD_DONE, 323 SHIM_BYT_IPCD_DONE); 324 325 /* unmask busy interrupt */ 326 snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX, 327 SHIM_IMRX_BUSY, 0); 328 } 329 330 static void byt_dsp_done(struct snd_sof_dev *sdev) 331 { 332 /* clear DONE bit - tell DSP we have completed */ 333 snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCX, 334 SHIM_BYT_IPCX_DONE, 0); 335 336 /* unmask Done interrupt */ 337 snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX, 338 SHIM_IMRX_DONE, 0); 339 } 340 341 /* 342 * DSP control. 343 */ 344 345 static int byt_run(struct snd_sof_dev *sdev) 346 { 347 int tries = 10; 348 349 /* release stall and wait to unstall */ 350 snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR, 351 SHIM_BYT_CSR_STALL, 0x0); 352 while (tries--) { 353 if (!(snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_CSR) & 354 SHIM_BYT_CSR_PWAITMODE)) 355 break; 356 msleep(100); 357 } 358 if (tries < 0) { 359 dev_err(sdev->dev, "error: unable to run DSP firmware\n"); 360 byt_dump(sdev, SOF_DBG_REGS | SOF_DBG_MBOX); 361 return -ENODEV; 362 } 363 364 /* return init core mask */ 365 return 1; 366 } 367 368 static int byt_reset(struct snd_sof_dev *sdev) 369 { 370 /* put DSP into reset, set reset vector and stall */ 371 snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR, 372 SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL | 373 SHIM_BYT_CSR_STALL, 374 SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL | 375 SHIM_BYT_CSR_STALL); 376 377 usleep_range(10, 15); 378 379 /* take DSP out of reset and keep stalled for FW loading */ 380 snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR, 381 SHIM_BYT_CSR_RST, 0); 382 383 return 0; 384 } 385 386 static void byt_machine_select(struct snd_sof_dev *sdev) 387 { 388 struct snd_sof_pdata *sof_pdata = sdev->pdata; 389 const struct sof_dev_desc *desc = sof_pdata->desc; 390 struct snd_soc_acpi_mach *mach; 391 392 mach = snd_soc_acpi_find_machine(desc->machines); 393 if (!mach) { 394 dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n"); 395 return; 396 } 397 398 sof_pdata->tplg_filename = mach->sof_tplg_filename; 399 mach->mach_params.acpi_ipc_irq_index = desc->irqindex_host_ipc; 400 sof_pdata->machine = mach; 401 } 402 403 static void byt_set_mach_params(const struct snd_soc_acpi_mach *mach, 404 struct device *dev) 405 { 406 struct snd_soc_acpi_mach_params *mach_params; 407 408 mach_params = (struct snd_soc_acpi_mach_params *)&mach->mach_params; 409 mach_params->platform = dev_name(dev); 410 } 411 412 /* Baytrail DAIs */ 413 static struct snd_soc_dai_driver byt_dai[] = { 414 { 415 .name = "ssp0-port", 416 }, 417 { 418 .name = "ssp1-port", 419 }, 420 { 421 .name = "ssp2-port", 422 }, 423 { 424 .name = "ssp3-port", 425 }, 426 { 427 .name = "ssp4-port", 428 }, 429 { 430 .name = "ssp5-port", 431 }, 432 }; 433 434 /* 435 * Probe and remove. 436 */ 437 438 #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) 439 440 static int tangier_pci_probe(struct snd_sof_dev *sdev) 441 { 442 struct snd_sof_pdata *pdata = sdev->pdata; 443 const struct sof_dev_desc *desc = pdata->desc; 444 struct pci_dev *pci = to_pci_dev(sdev->dev); 445 u32 base, size; 446 int ret; 447 448 /* DSP DMA can only access low 31 bits of host memory */ 449 ret = dma_coerce_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31)); 450 if (ret < 0) { 451 dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret); 452 return ret; 453 } 454 455 /* LPE base */ 456 base = pci_resource_start(pci, desc->resindex_lpe_base) - IRAM_OFFSET; 457 size = BYT_PCI_BAR_SIZE; 458 459 dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size); 460 sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size); 461 if (!sdev->bar[BYT_DSP_BAR]) { 462 dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n", 463 base, size); 464 return -ENODEV; 465 } 466 dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]); 467 468 /* IMR base - optional */ 469 if (desc->resindex_imr_base == -1) 470 goto irq; 471 472 base = pci_resource_start(pci, desc->resindex_imr_base); 473 size = pci_resource_len(pci, desc->resindex_imr_base); 474 475 /* some BIOSes don't map IMR */ 476 if (base == 0x55aa55aa || base == 0x0) { 477 dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n"); 478 goto irq; 479 } 480 481 dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size); 482 sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size); 483 if (!sdev->bar[BYT_IMR_BAR]) { 484 dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n", 485 base, size); 486 return -ENODEV; 487 } 488 dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]); 489 490 irq: 491 /* register our IRQ */ 492 sdev->ipc_irq = pci->irq; 493 dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); 494 ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq, 495 byt_irq_handler, byt_irq_thread, 496 0, "AudioDSP", sdev); 497 if (ret < 0) { 498 dev_err(sdev->dev, "error: failed to register IRQ %d\n", 499 sdev->ipc_irq); 500 return ret; 501 } 502 503 /* enable Interrupt from both sides */ 504 snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0); 505 snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0); 506 507 /* set default mailbox offset for FW ready message */ 508 sdev->dsp_box.offset = MBOX_OFFSET; 509 510 return ret; 511 } 512 513 const struct snd_sof_dsp_ops sof_tng_ops = { 514 /* device init */ 515 .probe = tangier_pci_probe, 516 517 /* DSP core boot / reset */ 518 .run = byt_run, 519 .reset = byt_reset, 520 521 /* Register IO */ 522 .write = sof_io_write, 523 .read = sof_io_read, 524 .write64 = sof_io_write64, 525 .read64 = sof_io_read64, 526 527 /* Block IO */ 528 .block_read = sof_block_read, 529 .block_write = sof_block_write, 530 531 /* doorbell */ 532 .irq_handler = byt_irq_handler, 533 .irq_thread = byt_irq_thread, 534 535 /* ipc */ 536 .send_msg = byt_send_msg, 537 .fw_ready = sof_fw_ready, 538 .get_mailbox_offset = byt_get_mailbox_offset, 539 .get_window_offset = byt_get_window_offset, 540 541 .ipc_msg_data = intel_ipc_msg_data, 542 .ipc_pcm_params = intel_ipc_pcm_params, 543 544 /* machine driver */ 545 .machine_select = byt_machine_select, 546 .machine_register = sof_machine_register, 547 .machine_unregister = sof_machine_unregister, 548 .set_mach_params = byt_set_mach_params, 549 550 /* debug */ 551 .debug_map = byt_debugfs, 552 .debug_map_count = ARRAY_SIZE(byt_debugfs), 553 .dbg_dump = byt_dump, 554 555 /* stream callbacks */ 556 .pcm_open = intel_pcm_open, 557 .pcm_close = intel_pcm_close, 558 559 /* module loading */ 560 .load_module = snd_sof_parse_module_memcpy, 561 562 /*Firmware loading */ 563 .load_firmware = snd_sof_load_firmware_memcpy, 564 565 /* DAI drivers */ 566 .drv = byt_dai, 567 .num_drv = 3, /* we have only 3 SSPs on byt*/ 568 569 /* ALSA HW info flags */ 570 .hw_info = SNDRV_PCM_INFO_MMAP | 571 SNDRV_PCM_INFO_MMAP_VALID | 572 SNDRV_PCM_INFO_INTERLEAVED | 573 SNDRV_PCM_INFO_PAUSE | 574 SNDRV_PCM_INFO_BATCH, 575 }; 576 EXPORT_SYMBOL(sof_tng_ops); 577 578 const struct sof_intel_dsp_desc tng_chip_info = { 579 .cores_num = 1, 580 .cores_mask = 1, 581 }; 582 EXPORT_SYMBOL(tng_chip_info); 583 584 #endif /* CONFIG_SND_SOC_SOF_MERRIFIELD */ 585 586 #if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) 587 588 static int byt_acpi_probe(struct snd_sof_dev *sdev) 589 { 590 struct snd_sof_pdata *pdata = sdev->pdata; 591 const struct sof_dev_desc *desc = pdata->desc; 592 struct platform_device *pdev = 593 container_of(sdev->dev, struct platform_device, dev); 594 struct resource *mmio; 595 u32 base, size; 596 int ret; 597 598 /* DSP DMA can only access low 31 bits of host memory */ 599 ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31)); 600 if (ret < 0) { 601 dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret); 602 return ret; 603 } 604 605 /* LPE base */ 606 mmio = platform_get_resource(pdev, IORESOURCE_MEM, 607 desc->resindex_lpe_base); 608 if (mmio) { 609 base = mmio->start; 610 size = resource_size(mmio); 611 } else { 612 dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n", 613 desc->resindex_lpe_base); 614 return -EINVAL; 615 } 616 617 dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size); 618 sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size); 619 if (!sdev->bar[BYT_DSP_BAR]) { 620 dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n", 621 base, size); 622 return -ENODEV; 623 } 624 dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]); 625 626 /* TODO: add offsets */ 627 sdev->mmio_bar = BYT_DSP_BAR; 628 sdev->mailbox_bar = BYT_DSP_BAR; 629 630 /* IMR base - optional */ 631 if (desc->resindex_imr_base == -1) 632 goto irq; 633 634 mmio = platform_get_resource(pdev, IORESOURCE_MEM, 635 desc->resindex_imr_base); 636 if (mmio) { 637 base = mmio->start; 638 size = resource_size(mmio); 639 } else { 640 dev_err(sdev->dev, "error: failed to get IMR base at idx %d\n", 641 desc->resindex_imr_base); 642 return -ENODEV; 643 } 644 645 /* some BIOSes don't map IMR */ 646 if (base == 0x55aa55aa || base == 0x0) { 647 dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n"); 648 goto irq; 649 } 650 651 dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size); 652 sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size); 653 if (!sdev->bar[BYT_IMR_BAR]) { 654 dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n", 655 base, size); 656 return -ENODEV; 657 } 658 dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]); 659 660 irq: 661 /* register our IRQ */ 662 sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc); 663 if (sdev->ipc_irq < 0) 664 return sdev->ipc_irq; 665 666 dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); 667 ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq, 668 byt_irq_handler, byt_irq_thread, 669 IRQF_SHARED, "AudioDSP", sdev); 670 if (ret < 0) { 671 dev_err(sdev->dev, "error: failed to register IRQ %d\n", 672 sdev->ipc_irq); 673 return ret; 674 } 675 676 /* enable Interrupt from both sides */ 677 snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0); 678 snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0); 679 680 /* set default mailbox offset for FW ready message */ 681 sdev->dsp_box.offset = MBOX_OFFSET; 682 683 return ret; 684 } 685 686 /* baytrail ops */ 687 const struct snd_sof_dsp_ops sof_byt_ops = { 688 /* device init */ 689 .probe = byt_acpi_probe, 690 691 /* DSP core boot / reset */ 692 .run = byt_run, 693 .reset = byt_reset, 694 695 /* Register IO */ 696 .write = sof_io_write, 697 .read = sof_io_read, 698 .write64 = sof_io_write64, 699 .read64 = sof_io_read64, 700 701 /* Block IO */ 702 .block_read = sof_block_read, 703 .block_write = sof_block_write, 704 705 /* doorbell */ 706 .irq_handler = byt_irq_handler, 707 .irq_thread = byt_irq_thread, 708 709 /* ipc */ 710 .send_msg = byt_send_msg, 711 .fw_ready = sof_fw_ready, 712 .get_mailbox_offset = byt_get_mailbox_offset, 713 .get_window_offset = byt_get_window_offset, 714 715 .ipc_msg_data = intel_ipc_msg_data, 716 .ipc_pcm_params = intel_ipc_pcm_params, 717 718 /* machine driver */ 719 .machine_select = byt_machine_select, 720 .machine_register = sof_machine_register, 721 .machine_unregister = sof_machine_unregister, 722 .set_mach_params = byt_set_mach_params, 723 724 /* debug */ 725 .debug_map = byt_debugfs, 726 .debug_map_count = ARRAY_SIZE(byt_debugfs), 727 .dbg_dump = byt_dump, 728 729 /* stream callbacks */ 730 .pcm_open = intel_pcm_open, 731 .pcm_close = intel_pcm_close, 732 733 /* module loading */ 734 .load_module = snd_sof_parse_module_memcpy, 735 736 /*Firmware loading */ 737 .load_firmware = snd_sof_load_firmware_memcpy, 738 739 /* DAI drivers */ 740 .drv = byt_dai, 741 .num_drv = 3, /* we have only 3 SSPs on byt*/ 742 743 /* ALSA HW info flags */ 744 .hw_info = SNDRV_PCM_INFO_MMAP | 745 SNDRV_PCM_INFO_MMAP_VALID | 746 SNDRV_PCM_INFO_INTERLEAVED | 747 SNDRV_PCM_INFO_PAUSE | 748 SNDRV_PCM_INFO_BATCH, 749 }; 750 EXPORT_SYMBOL(sof_byt_ops); 751 752 const struct sof_intel_dsp_desc byt_chip_info = { 753 .cores_num = 1, 754 .cores_mask = 1, 755 }; 756 EXPORT_SYMBOL(byt_chip_info); 757 758 /* cherrytrail and braswell ops */ 759 const struct snd_sof_dsp_ops sof_cht_ops = { 760 /* device init */ 761 .probe = byt_acpi_probe, 762 763 /* DSP core boot / reset */ 764 .run = byt_run, 765 .reset = byt_reset, 766 767 /* Register IO */ 768 .write = sof_io_write, 769 .read = sof_io_read, 770 .write64 = sof_io_write64, 771 .read64 = sof_io_read64, 772 773 /* Block IO */ 774 .block_read = sof_block_read, 775 .block_write = sof_block_write, 776 777 /* doorbell */ 778 .irq_handler = byt_irq_handler, 779 .irq_thread = byt_irq_thread, 780 781 /* ipc */ 782 .send_msg = byt_send_msg, 783 .fw_ready = sof_fw_ready, 784 .get_mailbox_offset = byt_get_mailbox_offset, 785 .get_window_offset = byt_get_window_offset, 786 787 .ipc_msg_data = intel_ipc_msg_data, 788 .ipc_pcm_params = intel_ipc_pcm_params, 789 790 /* machine driver */ 791 .machine_select = byt_machine_select, 792 .machine_register = sof_machine_register, 793 .machine_unregister = sof_machine_unregister, 794 .set_mach_params = byt_set_mach_params, 795 796 /* debug */ 797 .debug_map = cht_debugfs, 798 .debug_map_count = ARRAY_SIZE(cht_debugfs), 799 .dbg_dump = byt_dump, 800 801 /* stream callbacks */ 802 .pcm_open = intel_pcm_open, 803 .pcm_close = intel_pcm_close, 804 805 /* module loading */ 806 .load_module = snd_sof_parse_module_memcpy, 807 808 /*Firmware loading */ 809 .load_firmware = snd_sof_load_firmware_memcpy, 810 811 /* DAI drivers */ 812 .drv = byt_dai, 813 /* all 6 SSPs may be available for cherrytrail */ 814 .num_drv = ARRAY_SIZE(byt_dai), 815 816 /* ALSA HW info flags */ 817 .hw_info = SNDRV_PCM_INFO_MMAP | 818 SNDRV_PCM_INFO_MMAP_VALID | 819 SNDRV_PCM_INFO_INTERLEAVED | 820 SNDRV_PCM_INFO_PAUSE | 821 SNDRV_PCM_INFO_BATCH, 822 }; 823 EXPORT_SYMBOL(sof_cht_ops); 824 825 const struct sof_intel_dsp_desc cht_chip_info = { 826 .cores_num = 1, 827 .cores_mask = 1, 828 }; 829 EXPORT_SYMBOL(cht_chip_info); 830 831 #endif /* CONFIG_SND_SOC_SOF_BAYTRAIL */ 832 833 MODULE_LICENSE("Dual BSD/GPL"); 834