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