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