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_BYT 0x100 28 #define SHIM_SIZE_CHT 0x118 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_BYT, 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_CHT, 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 u64 status, panic, imrd, imrx; 150 151 /* now try generic SOF status messages */ 152 status = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD); 153 panic = snd_sof_dsp_read64(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_read64(sdev, BYT_DSP_BAR, SHIM_IMRX); 161 imrd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRD); 162 dev_err(sdev->dev, 163 "error: ipc host -> DSP: pending %s complete %s raw 0x%llx\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%llx\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%llx\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%llx\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 /* Baytrail DAIs */ 387 static struct snd_soc_dai_driver byt_dai[] = { 388 { 389 .name = "ssp0-port", 390 }, 391 { 392 .name = "ssp1-port", 393 }, 394 { 395 .name = "ssp2-port", 396 }, 397 { 398 .name = "ssp3-port", 399 }, 400 { 401 .name = "ssp4-port", 402 }, 403 { 404 .name = "ssp5-port", 405 }, 406 }; 407 408 /* 409 * Probe and remove. 410 */ 411 412 #if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) 413 414 static int tangier_pci_probe(struct snd_sof_dev *sdev) 415 { 416 struct snd_sof_pdata *pdata = sdev->pdata; 417 const struct sof_dev_desc *desc = pdata->desc; 418 struct pci_dev *pci = to_pci_dev(sdev->dev); 419 u32 base, size; 420 int ret; 421 422 /* DSP DMA can only access low 31 bits of host memory */ 423 ret = dma_coerce_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31)); 424 if (ret < 0) { 425 dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret); 426 return ret; 427 } 428 429 /* LPE base */ 430 base = pci_resource_start(pci, desc->resindex_lpe_base) - IRAM_OFFSET; 431 size = BYT_PCI_BAR_SIZE; 432 433 dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size); 434 sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size); 435 if (!sdev->bar[BYT_DSP_BAR]) { 436 dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n", 437 base, size); 438 return -ENODEV; 439 } 440 dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]); 441 442 /* IMR base - optional */ 443 if (desc->resindex_imr_base == -1) 444 goto irq; 445 446 base = pci_resource_start(pci, desc->resindex_imr_base); 447 size = pci_resource_len(pci, desc->resindex_imr_base); 448 449 /* some BIOSes don't map IMR */ 450 if (base == 0x55aa55aa || base == 0x0) { 451 dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n"); 452 goto irq; 453 } 454 455 dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size); 456 sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size); 457 if (!sdev->bar[BYT_IMR_BAR]) { 458 dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n", 459 base, size); 460 return -ENODEV; 461 } 462 dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]); 463 464 irq: 465 /* register our IRQ */ 466 sdev->ipc_irq = pci->irq; 467 dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); 468 ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq, 469 byt_irq_handler, byt_irq_thread, 470 0, "AudioDSP", sdev); 471 if (ret < 0) { 472 dev_err(sdev->dev, "error: failed to register IRQ %d\n", 473 sdev->ipc_irq); 474 return ret; 475 } 476 477 /* enable Interrupt from both sides */ 478 snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0); 479 snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0); 480 481 /* set default mailbox offset for FW ready message */ 482 sdev->dsp_box.offset = MBOX_OFFSET; 483 484 return ret; 485 } 486 487 const struct snd_sof_dsp_ops sof_tng_ops = { 488 /* device init */ 489 .probe = tangier_pci_probe, 490 491 /* DSP core boot / reset */ 492 .run = byt_run, 493 .reset = byt_reset, 494 495 /* Register IO */ 496 .write = sof_io_write, 497 .read = sof_io_read, 498 .write64 = sof_io_write64, 499 .read64 = sof_io_read64, 500 501 /* Block IO */ 502 .block_read = sof_block_read, 503 .block_write = sof_block_write, 504 505 /* doorbell */ 506 .irq_handler = byt_irq_handler, 507 .irq_thread = byt_irq_thread, 508 509 /* ipc */ 510 .send_msg = byt_send_msg, 511 .fw_ready = sof_fw_ready, 512 .get_mailbox_offset = byt_get_mailbox_offset, 513 .get_window_offset = byt_get_window_offset, 514 515 .ipc_msg_data = intel_ipc_msg_data, 516 .ipc_pcm_params = intel_ipc_pcm_params, 517 518 /* debug */ 519 .debug_map = byt_debugfs, 520 .debug_map_count = ARRAY_SIZE(byt_debugfs), 521 .dbg_dump = byt_dump, 522 523 /* stream callbacks */ 524 .pcm_open = intel_pcm_open, 525 .pcm_close = intel_pcm_close, 526 527 /* module loading */ 528 .load_module = snd_sof_parse_module_memcpy, 529 530 /*Firmware loading */ 531 .load_firmware = snd_sof_load_firmware_memcpy, 532 533 /* DAI drivers */ 534 .drv = byt_dai, 535 .num_drv = 3, /* we have only 3 SSPs on byt*/ 536 537 /* ALSA HW info flags */ 538 .hw_info = SNDRV_PCM_INFO_MMAP | 539 SNDRV_PCM_INFO_MMAP_VALID | 540 SNDRV_PCM_INFO_INTERLEAVED | 541 SNDRV_PCM_INFO_PAUSE | 542 SNDRV_PCM_INFO_BATCH, 543 }; 544 EXPORT_SYMBOL(sof_tng_ops); 545 546 const struct sof_intel_dsp_desc tng_chip_info = { 547 .cores_num = 1, 548 .cores_mask = 1, 549 }; 550 EXPORT_SYMBOL(tng_chip_info); 551 552 #endif /* CONFIG_SND_SOC_SOF_MERRIFIELD */ 553 554 #if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) 555 556 static int byt_acpi_probe(struct snd_sof_dev *sdev) 557 { 558 struct snd_sof_pdata *pdata = sdev->pdata; 559 const struct sof_dev_desc *desc = pdata->desc; 560 struct platform_device *pdev = 561 container_of(sdev->dev, struct platform_device, dev); 562 struct resource *mmio; 563 u32 base, size; 564 int ret; 565 566 /* DSP DMA can only access low 31 bits of host memory */ 567 ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31)); 568 if (ret < 0) { 569 dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret); 570 return ret; 571 } 572 573 /* LPE base */ 574 mmio = platform_get_resource(pdev, IORESOURCE_MEM, 575 desc->resindex_lpe_base); 576 if (mmio) { 577 base = mmio->start; 578 size = resource_size(mmio); 579 } else { 580 dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n", 581 desc->resindex_lpe_base); 582 return -EINVAL; 583 } 584 585 dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size); 586 sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size); 587 if (!sdev->bar[BYT_DSP_BAR]) { 588 dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n", 589 base, size); 590 return -ENODEV; 591 } 592 dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]); 593 594 /* TODO: add offsets */ 595 sdev->mmio_bar = BYT_DSP_BAR; 596 sdev->mailbox_bar = BYT_DSP_BAR; 597 598 /* IMR base - optional */ 599 if (desc->resindex_imr_base == -1) 600 goto irq; 601 602 mmio = platform_get_resource(pdev, IORESOURCE_MEM, 603 desc->resindex_imr_base); 604 if (mmio) { 605 base = mmio->start; 606 size = resource_size(mmio); 607 } else { 608 dev_err(sdev->dev, "error: failed to get IMR base at idx %d\n", 609 desc->resindex_imr_base); 610 return -ENODEV; 611 } 612 613 /* some BIOSes don't map IMR */ 614 if (base == 0x55aa55aa || base == 0x0) { 615 dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n"); 616 goto irq; 617 } 618 619 dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size); 620 sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size); 621 if (!sdev->bar[BYT_IMR_BAR]) { 622 dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n", 623 base, size); 624 return -ENODEV; 625 } 626 dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]); 627 628 irq: 629 /* register our IRQ */ 630 sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc); 631 if (sdev->ipc_irq < 0) 632 return sdev->ipc_irq; 633 634 dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); 635 ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq, 636 byt_irq_handler, byt_irq_thread, 637 IRQF_SHARED, "AudioDSP", sdev); 638 if (ret < 0) { 639 dev_err(sdev->dev, "error: failed to register IRQ %d\n", 640 sdev->ipc_irq); 641 return ret; 642 } 643 644 /* enable Interrupt from both sides */ 645 snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x0); 646 snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x0); 647 648 /* set default mailbox offset for FW ready message */ 649 sdev->dsp_box.offset = MBOX_OFFSET; 650 651 return ret; 652 } 653 654 /* baytrail ops */ 655 const struct snd_sof_dsp_ops sof_byt_ops = { 656 /* device init */ 657 .probe = byt_acpi_probe, 658 659 /* DSP core boot / reset */ 660 .run = byt_run, 661 .reset = byt_reset, 662 663 /* Register IO */ 664 .write = sof_io_write, 665 .read = sof_io_read, 666 .write64 = sof_io_write64, 667 .read64 = sof_io_read64, 668 669 /* Block IO */ 670 .block_read = sof_block_read, 671 .block_write = sof_block_write, 672 673 /* doorbell */ 674 .irq_handler = byt_irq_handler, 675 .irq_thread = byt_irq_thread, 676 677 /* ipc */ 678 .send_msg = byt_send_msg, 679 .fw_ready = sof_fw_ready, 680 .get_mailbox_offset = byt_get_mailbox_offset, 681 .get_window_offset = byt_get_window_offset, 682 683 .ipc_msg_data = intel_ipc_msg_data, 684 .ipc_pcm_params = intel_ipc_pcm_params, 685 686 /* debug */ 687 .debug_map = byt_debugfs, 688 .debug_map_count = ARRAY_SIZE(byt_debugfs), 689 .dbg_dump = byt_dump, 690 691 /* stream callbacks */ 692 .pcm_open = intel_pcm_open, 693 .pcm_close = intel_pcm_close, 694 695 /* module loading */ 696 .load_module = snd_sof_parse_module_memcpy, 697 698 /*Firmware loading */ 699 .load_firmware = snd_sof_load_firmware_memcpy, 700 701 /* DAI drivers */ 702 .drv = byt_dai, 703 .num_drv = 3, /* we have only 3 SSPs on byt*/ 704 705 /* ALSA HW info flags */ 706 .hw_info = SNDRV_PCM_INFO_MMAP | 707 SNDRV_PCM_INFO_MMAP_VALID | 708 SNDRV_PCM_INFO_INTERLEAVED | 709 SNDRV_PCM_INFO_PAUSE | 710 SNDRV_PCM_INFO_BATCH, 711 }; 712 EXPORT_SYMBOL(sof_byt_ops); 713 714 const struct sof_intel_dsp_desc byt_chip_info = { 715 .cores_num = 1, 716 .cores_mask = 1, 717 }; 718 EXPORT_SYMBOL(byt_chip_info); 719 720 /* cherrytrail and braswell ops */ 721 const struct snd_sof_dsp_ops sof_cht_ops = { 722 /* device init */ 723 .probe = byt_acpi_probe, 724 725 /* DSP core boot / reset */ 726 .run = byt_run, 727 .reset = byt_reset, 728 729 /* Register IO */ 730 .write = sof_io_write, 731 .read = sof_io_read, 732 .write64 = sof_io_write64, 733 .read64 = sof_io_read64, 734 735 /* Block IO */ 736 .block_read = sof_block_read, 737 .block_write = sof_block_write, 738 739 /* doorbell */ 740 .irq_handler = byt_irq_handler, 741 .irq_thread = byt_irq_thread, 742 743 /* ipc */ 744 .send_msg = byt_send_msg, 745 .fw_ready = sof_fw_ready, 746 .get_mailbox_offset = byt_get_mailbox_offset, 747 .get_window_offset = byt_get_window_offset, 748 749 .ipc_msg_data = intel_ipc_msg_data, 750 .ipc_pcm_params = intel_ipc_pcm_params, 751 752 /* debug */ 753 .debug_map = cht_debugfs, 754 .debug_map_count = ARRAY_SIZE(cht_debugfs), 755 .dbg_dump = byt_dump, 756 757 /* stream callbacks */ 758 .pcm_open = intel_pcm_open, 759 .pcm_close = intel_pcm_close, 760 761 /* module loading */ 762 .load_module = snd_sof_parse_module_memcpy, 763 764 /*Firmware loading */ 765 .load_firmware = snd_sof_load_firmware_memcpy, 766 767 /* DAI drivers */ 768 .drv = byt_dai, 769 /* all 6 SSPs may be available for cherrytrail */ 770 .num_drv = ARRAY_SIZE(byt_dai), 771 772 /* ALSA HW info flags */ 773 .hw_info = SNDRV_PCM_INFO_MMAP | 774 SNDRV_PCM_INFO_MMAP_VALID | 775 SNDRV_PCM_INFO_INTERLEAVED | 776 SNDRV_PCM_INFO_PAUSE | 777 SNDRV_PCM_INFO_BATCH, 778 }; 779 EXPORT_SYMBOL(sof_cht_ops); 780 781 const struct sof_intel_dsp_desc cht_chip_info = { 782 .cores_num = 1, 783 .cores_mask = 1, 784 }; 785 EXPORT_SYMBOL(cht_chip_info); 786 787 #endif /* CONFIG_SND_SOC_SOF_BAYTRAIL */ 788 789 MODULE_LICENSE("Dual BSD/GPL"); 790