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