root/sound/soc/sof/intel/bdw.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. bdw_run
  2. bdw_reset
  3. bdw_set_dsp_D0
  4. bdw_get_registers
  5. bdw_dump
  6. bdw_irq_handler
  7. bdw_irq_thread
  8. bdw_send_msg
  9. bdw_get_reply
  10. bdw_get_mailbox_offset
  11. bdw_get_window_offset
  12. bdw_host_done
  13. bdw_dsp_done
  14. bdw_probe

   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 Broadwell
  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 /* BARs */
  22 #define BDW_DSP_BAR 0
  23 #define BDW_PCI_BAR 1
  24 
  25 /*
  26  * Debug
  27  */
  28 
  29 /* DSP memories for BDW */
  30 #define IRAM_OFFSET     0xA0000
  31 #define BDW_IRAM_SIZE       (10 * 32 * 1024)
  32 #define DRAM_OFFSET     0x00000
  33 #define BDW_DRAM_SIZE       (20 * 32 * 1024)
  34 #define SHIM_OFFSET     0xFB000
  35 #define SHIM_SIZE       0x100
  36 #define MBOX_OFFSET     0x9E000
  37 #define MBOX_SIZE       0x1000
  38 #define MBOX_DUMP_SIZE 0x30
  39 #define EXCEPT_OFFSET   0x800
  40 #define EXCEPT_MAX_HDR_SIZE     0x400
  41 
  42 /* DSP peripherals */
  43 #define DMAC0_OFFSET    0xFE000
  44 #define DMAC1_OFFSET    0xFF000
  45 #define DMAC_SIZE       0x420
  46 #define SSP0_OFFSET     0xFC000
  47 #define SSP1_OFFSET     0xFD000
  48 #define SSP_SIZE        0x100
  49 
  50 #define BDW_STACK_DUMP_SIZE     32
  51 
  52 #define BDW_PANIC_OFFSET(x)     ((x) & 0xFFFF)
  53 
  54 static const struct snd_sof_debugfs_map bdw_debugfs[] = {
  55         {"dmac0", BDW_DSP_BAR, DMAC0_OFFSET, DMAC_SIZE,
  56          SOF_DEBUGFS_ACCESS_ALWAYS},
  57         {"dmac1", BDW_DSP_BAR, DMAC1_OFFSET, DMAC_SIZE,
  58          SOF_DEBUGFS_ACCESS_ALWAYS},
  59         {"ssp0", BDW_DSP_BAR, SSP0_OFFSET, SSP_SIZE,
  60          SOF_DEBUGFS_ACCESS_ALWAYS},
  61         {"ssp1", BDW_DSP_BAR, SSP1_OFFSET, SSP_SIZE,
  62          SOF_DEBUGFS_ACCESS_ALWAYS},
  63         {"iram", BDW_DSP_BAR, IRAM_OFFSET, BDW_IRAM_SIZE,
  64          SOF_DEBUGFS_ACCESS_D0_ONLY},
  65         {"dram", BDW_DSP_BAR, DRAM_OFFSET, BDW_DRAM_SIZE,
  66          SOF_DEBUGFS_ACCESS_D0_ONLY},
  67         {"shim", BDW_DSP_BAR, SHIM_OFFSET, SHIM_SIZE,
  68          SOF_DEBUGFS_ACCESS_ALWAYS},
  69 };
  70 
  71 static void bdw_host_done(struct snd_sof_dev *sdev);
  72 static void bdw_dsp_done(struct snd_sof_dev *sdev);
  73 static void bdw_get_reply(struct snd_sof_dev *sdev);
  74 
  75 /*
  76  * DSP Control.
  77  */
  78 
  79 static int bdw_run(struct snd_sof_dev *sdev)
  80 {
  81         /* set opportunistic mode on engine 0,1 for all channels */
  82         snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_HMDC,
  83                                 SHIM_HMDC_HDDA_E0_ALLCH |
  84                                 SHIM_HMDC_HDDA_E1_ALLCH, 0);
  85 
  86         /* set DSP to RUN */
  87         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
  88                                          SHIM_CSR_STALL, 0x0);
  89 
  90         /* return init core mask */
  91         return 1;
  92 }
  93 
  94 static int bdw_reset(struct snd_sof_dev *sdev)
  95 {
  96         /* put DSP into reset and stall */
  97         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
  98                                          SHIM_CSR_RST | SHIM_CSR_STALL,
  99                                          SHIM_CSR_RST | SHIM_CSR_STALL);
 100 
 101         /* keep in reset for 10ms */
 102         mdelay(10);
 103 
 104         /* take DSP out of reset and keep stalled for FW loading */
 105         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
 106                                          SHIM_CSR_RST | SHIM_CSR_STALL,
 107                                          SHIM_CSR_STALL);
 108 
 109         return 0;
 110 }
 111 
 112 static int bdw_set_dsp_D0(struct snd_sof_dev *sdev)
 113 {
 114         int tries = 10;
 115         u32 reg;
 116 
 117         /* Disable core clock gating (VDRTCTL2.DCLCGE = 0) */
 118         snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL2,
 119                                          PCI_VDRTCL2_DCLCGE |
 120                                          PCI_VDRTCL2_DTCGE, 0);
 121 
 122         /* Disable D3PG (VDRTCTL0.D3PGD = 1) */
 123         snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL0,
 124                                          PCI_VDRTCL0_D3PGD, PCI_VDRTCL0_D3PGD);
 125 
 126         /* Set D0 state */
 127         snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_PMCS,
 128                                          PCI_PMCS_PS_MASK, 0);
 129 
 130         /* check that ADSP shim is enabled */
 131         while (tries--) {
 132                 reg = readl(sdev->bar[BDW_PCI_BAR] + PCI_PMCS)
 133                         & PCI_PMCS_PS_MASK;
 134                 if (reg == 0)
 135                         goto finish;
 136 
 137                 msleep(20);
 138         }
 139 
 140         return -ENODEV;
 141 
 142 finish:
 143         /*
 144          * select SSP1 19.2MHz base clock, SSP clock 0,
 145          * turn off Low Power Clock
 146          */
 147         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CSR,
 148                                          SHIM_CSR_S1IOCS | SHIM_CSR_SBCS1 |
 149                                          SHIM_CSR_LPCS, 0x0);
 150 
 151         /* stall DSP core, set clk to 192/96Mhz */
 152         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,
 153                                          SHIM_CSR, SHIM_CSR_STALL |
 154                                          SHIM_CSR_DCS_MASK,
 155                                          SHIM_CSR_STALL |
 156                                          SHIM_CSR_DCS(4));
 157 
 158         /* Set 24MHz MCLK, prevent local clock gating, enable SSP0 clock */
 159         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_CLKCTL,
 160                                          SHIM_CLKCTL_MASK |
 161                                          SHIM_CLKCTL_DCPLCG |
 162                                          SHIM_CLKCTL_SCOE0,
 163                                          SHIM_CLKCTL_MASK |
 164                                          SHIM_CLKCTL_DCPLCG |
 165                                          SHIM_CLKCTL_SCOE0);
 166 
 167         /* Stall and reset core, set CSR */
 168         bdw_reset(sdev);
 169 
 170         /* Enable core clock gating (VDRTCTL2.DCLCGE = 1), delay 50 us */
 171         snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL2,
 172                                          PCI_VDRTCL2_DCLCGE |
 173                                          PCI_VDRTCL2_DTCGE,
 174                                          PCI_VDRTCL2_DCLCGE |
 175                                          PCI_VDRTCL2_DTCGE);
 176 
 177         usleep_range(50, 55);
 178 
 179         /* switch on audio PLL */
 180         snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL2,
 181                                          PCI_VDRTCL2_APLLSE_MASK, 0);
 182 
 183         /*
 184          * set default power gating control, enable power gating control for
 185          * all blocks. that is, can't be accessed, please enable each block
 186          * before accessing.
 187          */
 188         snd_sof_dsp_update_bits_unlocked(sdev, BDW_PCI_BAR, PCI_VDRTCTL0,
 189                                          0xfffffffC, 0x0);
 190 
 191         /* disable DMA finish function for SSP0 & SSP1 */
 192         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,  SHIM_CSR2,
 193                                          SHIM_CSR2_SDFD_SSP1,
 194                                          SHIM_CSR2_SDFD_SSP1);
 195 
 196         /* set on-demond mode on engine 0,1 for all channels */
 197         snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_HMDC,
 198                                 SHIM_HMDC_HDDA_E0_ALLCH |
 199                                 SHIM_HMDC_HDDA_E1_ALLCH,
 200                                 SHIM_HMDC_HDDA_E0_ALLCH |
 201                                 SHIM_HMDC_HDDA_E1_ALLCH);
 202 
 203         /* Enable Interrupt from both sides */
 204         snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_IMRX,
 205                                 (SHIM_IMRX_BUSY | SHIM_IMRX_DONE), 0x0);
 206         snd_sof_dsp_update_bits(sdev, BDW_DSP_BAR, SHIM_IMRD,
 207                                 (SHIM_IMRD_DONE | SHIM_IMRD_BUSY |
 208                                 SHIM_IMRD_SSP0 | SHIM_IMRD_DMAC), 0x0);
 209 
 210         /* clear IPC registers */
 211         snd_sof_dsp_write(sdev, BDW_DSP_BAR, SHIM_IPCX, 0x0);
 212         snd_sof_dsp_write(sdev, BDW_DSP_BAR, SHIM_IPCD, 0x0);
 213         snd_sof_dsp_write(sdev, BDW_DSP_BAR, 0x80, 0x6);
 214         snd_sof_dsp_write(sdev, BDW_DSP_BAR, 0xe0, 0x300a);
 215 
 216         return 0;
 217 }
 218 
 219 static void bdw_get_registers(struct snd_sof_dev *sdev,
 220                               struct sof_ipc_dsp_oops_xtensa *xoops,
 221                               struct sof_ipc_panic_info *panic_info,
 222                               u32 *stack, size_t stack_words)
 223 {
 224         u32 offset = sdev->dsp_oops_offset;
 225 
 226         /* first read registers */
 227         sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops));
 228 
 229         /* note: variable AR register array is not read */
 230 
 231         /* then get panic info */
 232         if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) {
 233                 dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n",
 234                         xoops->arch_hdr.totalsize);
 235                 return;
 236         }
 237         offset += xoops->arch_hdr.totalsize;
 238         sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info));
 239 
 240         /* then get the stack */
 241         offset += sizeof(*panic_info);
 242         sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32));
 243 }
 244 
 245 static void bdw_dump(struct snd_sof_dev *sdev, u32 flags)
 246 {
 247         struct sof_ipc_dsp_oops_xtensa xoops;
 248         struct sof_ipc_panic_info panic_info;
 249         u32 stack[BDW_STACK_DUMP_SIZE];
 250         u32 status, panic;
 251 
 252         /* now try generic SOF status messages */
 253         status = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCD);
 254         panic = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCX);
 255         bdw_get_registers(sdev, &xoops, &panic_info, stack,
 256                           BDW_STACK_DUMP_SIZE);
 257         snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack,
 258                            BDW_STACK_DUMP_SIZE);
 259 }
 260 
 261 /*
 262  * IPC Doorbell IRQ handler and thread.
 263  */
 264 
 265 static irqreturn_t bdw_irq_handler(int irq, void *context)
 266 {
 267         struct snd_sof_dev *sdev = context;
 268         u32 isr;
 269         int ret = IRQ_NONE;
 270 
 271         /* Interrupt arrived, check src */
 272         isr = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_ISRX);
 273         if (isr & (SHIM_ISRX_DONE | SHIM_ISRX_BUSY))
 274                 ret = IRQ_WAKE_THREAD;
 275 
 276         return ret;
 277 }
 278 
 279 static irqreturn_t bdw_irq_thread(int irq, void *context)
 280 {
 281         struct snd_sof_dev *sdev = context;
 282         u32 ipcx, ipcd, imrx;
 283 
 284         imrx = snd_sof_dsp_read64(sdev, BDW_DSP_BAR, SHIM_IMRX);
 285         ipcx = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCX);
 286 
 287         /* reply message from DSP */
 288         if (ipcx & SHIM_IPCX_DONE &&
 289             !(imrx & SHIM_IMRX_DONE)) {
 290                 /* Mask Done interrupt before return */
 291                 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,
 292                                                  SHIM_IMRX, SHIM_IMRX_DONE,
 293                                                  SHIM_IMRX_DONE);
 294 
 295                 spin_lock_irq(&sdev->ipc_lock);
 296 
 297                 /*
 298                  * handle immediate reply from DSP core. If the msg is
 299                  * found, set done bit in cmd_done which is called at the
 300                  * end of message processing function, else set it here
 301                  * because the done bit can't be set in cmd_done function
 302                  * which is triggered by msg
 303                  */
 304                 bdw_get_reply(sdev);
 305                 snd_sof_ipc_reply(sdev, ipcx);
 306 
 307                 bdw_dsp_done(sdev);
 308 
 309                 spin_unlock_irq(&sdev->ipc_lock);
 310         }
 311 
 312         ipcd = snd_sof_dsp_read(sdev, BDW_DSP_BAR, SHIM_IPCD);
 313 
 314         /* new message from DSP */
 315         if (ipcd & SHIM_IPCD_BUSY &&
 316             !(imrx & SHIM_IMRX_BUSY)) {
 317                 /* Mask Busy interrupt before return */
 318                 snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR,
 319                                                  SHIM_IMRX, SHIM_IMRX_BUSY,
 320                                                  SHIM_IMRX_BUSY);
 321 
 322                 /* Handle messages from DSP Core */
 323                 if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) {
 324                         snd_sof_dsp_panic(sdev, BDW_PANIC_OFFSET(ipcx) +
 325                                           MBOX_OFFSET);
 326                 } else {
 327                         snd_sof_ipc_msgs_rx(sdev);
 328                 }
 329 
 330                 bdw_host_done(sdev);
 331         }
 332 
 333         return IRQ_HANDLED;
 334 }
 335 
 336 /*
 337  * IPC Mailbox IO
 338  */
 339 
 340 static int bdw_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg)
 341 {
 342         /* send the message */
 343         sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data,
 344                           msg->msg_size);
 345         snd_sof_dsp_write(sdev, BDW_DSP_BAR, SHIM_IPCX, SHIM_IPCX_BUSY);
 346 
 347         return 0;
 348 }
 349 
 350 static void bdw_get_reply(struct snd_sof_dev *sdev)
 351 {
 352         struct snd_sof_ipc_msg *msg = sdev->msg;
 353         struct sof_ipc_reply reply;
 354         int ret = 0;
 355 
 356         /*
 357          * Sometimes, there is unexpected reply ipc arriving. The reply
 358          * ipc belongs to none of the ipcs sent from driver.
 359          * In this case, the driver must ignore the ipc.
 360          */
 361         if (!msg) {
 362                 dev_warn(sdev->dev, "unexpected ipc interrupt raised!\n");
 363                 return;
 364         }
 365 
 366         /* get reply */
 367         sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply));
 368 
 369         if (reply.error < 0) {
 370                 memcpy(msg->reply_data, &reply, sizeof(reply));
 371                 ret = reply.error;
 372         } else {
 373                 /* reply correct size ? */
 374                 if (reply.hdr.size != msg->reply_size) {
 375                         dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n",
 376                                 msg->reply_size, reply.hdr.size);
 377                         ret = -EINVAL;
 378                 }
 379 
 380                 /* read the message */
 381                 if (msg->reply_size > 0)
 382                         sof_mailbox_read(sdev, sdev->host_box.offset,
 383                                          msg->reply_data, msg->reply_size);
 384         }
 385 
 386         msg->reply_error = ret;
 387 }
 388 
 389 static int bdw_get_mailbox_offset(struct snd_sof_dev *sdev)
 390 {
 391         return MBOX_OFFSET;
 392 }
 393 
 394 static int bdw_get_window_offset(struct snd_sof_dev *sdev, u32 id)
 395 {
 396         return MBOX_OFFSET;
 397 }
 398 
 399 static void bdw_host_done(struct snd_sof_dev *sdev)
 400 {
 401         /* clear BUSY bit and set DONE bit - accept new messages */
 402         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IPCD,
 403                                          SHIM_IPCD_BUSY | SHIM_IPCD_DONE,
 404                                          SHIM_IPCD_DONE);
 405 
 406         /* unmask busy interrupt */
 407         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IMRX,
 408                                          SHIM_IMRX_BUSY, 0);
 409 }
 410 
 411 static void bdw_dsp_done(struct snd_sof_dev *sdev)
 412 {
 413         /* clear DONE bit - tell DSP we have completed */
 414         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IPCX,
 415                                          SHIM_IPCX_DONE, 0);
 416 
 417         /* unmask Done interrupt */
 418         snd_sof_dsp_update_bits_unlocked(sdev, BDW_DSP_BAR, SHIM_IMRX,
 419                                          SHIM_IMRX_DONE, 0);
 420 }
 421 
 422 /*
 423  * Probe and remove.
 424  */
 425 static int bdw_probe(struct snd_sof_dev *sdev)
 426 {
 427         struct snd_sof_pdata *pdata = sdev->pdata;
 428         const struct sof_dev_desc *desc = pdata->desc;
 429         struct platform_device *pdev =
 430                 container_of(sdev->dev, struct platform_device, dev);
 431         struct resource *mmio;
 432         u32 base, size;
 433         int ret;
 434 
 435         /* LPE base */
 436         mmio = platform_get_resource(pdev, IORESOURCE_MEM,
 437                                      desc->resindex_lpe_base);
 438         if (mmio) {
 439                 base = mmio->start;
 440                 size = resource_size(mmio);
 441         } else {
 442                 dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n",
 443                         desc->resindex_lpe_base);
 444                 return -EINVAL;
 445         }
 446 
 447         dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size);
 448         sdev->bar[BDW_DSP_BAR] = devm_ioremap(sdev->dev, base, size);
 449         if (!sdev->bar[BDW_DSP_BAR]) {
 450                 dev_err(sdev->dev,
 451                         "error: failed to ioremap LPE base 0x%x size 0x%x\n",
 452                         base, size);
 453                 return -ENODEV;
 454         }
 455         dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BDW_DSP_BAR]);
 456 
 457         /* TODO: add offsets */
 458         sdev->mmio_bar = BDW_DSP_BAR;
 459         sdev->mailbox_bar = BDW_DSP_BAR;
 460         sdev->dsp_oops_offset = MBOX_OFFSET;
 461 
 462         /* PCI base */
 463         mmio = platform_get_resource(pdev, IORESOURCE_MEM,
 464                                      desc->resindex_pcicfg_base);
 465         if (mmio) {
 466                 base = mmio->start;
 467                 size = resource_size(mmio);
 468         } else {
 469                 dev_err(sdev->dev, "error: failed to get PCI base at idx %d\n",
 470                         desc->resindex_pcicfg_base);
 471                 return -ENODEV;
 472         }
 473 
 474         dev_dbg(sdev->dev, "PCI base at 0x%x size 0x%x", base, size);
 475         sdev->bar[BDW_PCI_BAR] = devm_ioremap(sdev->dev, base, size);
 476         if (!sdev->bar[BDW_PCI_BAR]) {
 477                 dev_err(sdev->dev,
 478                         "error: failed to ioremap PCI base 0x%x size 0x%x\n",
 479                         base, size);
 480                 return -ENODEV;
 481         }
 482         dev_dbg(sdev->dev, "PCI VADDR %p\n", sdev->bar[BDW_PCI_BAR]);
 483 
 484         /* register our IRQ */
 485         sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
 486         if (sdev->ipc_irq < 0)
 487                 return sdev->ipc_irq;
 488 
 489         dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq);
 490         ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq,
 491                                         bdw_irq_handler, bdw_irq_thread,
 492                                         IRQF_SHARED, "AudioDSP", sdev);
 493         if (ret < 0) {
 494                 dev_err(sdev->dev, "error: failed to register IRQ %d\n",
 495                         sdev->ipc_irq);
 496                 return ret;
 497         }
 498 
 499         /* enable the DSP SHIM */
 500         ret = bdw_set_dsp_D0(sdev);
 501         if (ret < 0) {
 502                 dev_err(sdev->dev, "error: failed to set DSP D0\n");
 503                 return ret;
 504         }
 505 
 506         /* DSP DMA can only access low 31 bits of host memory */
 507         ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31));
 508         if (ret < 0) {
 509                 dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret);
 510                 return ret;
 511         }
 512 
 513         /* set default mailbox */
 514         snd_sof_dsp_mailbox_init(sdev, MBOX_OFFSET, MBOX_SIZE, 0, 0);
 515 
 516         return ret;
 517 }
 518 
 519 /* Broadwell DAIs */
 520 static struct snd_soc_dai_driver bdw_dai[] = {
 521 {
 522         .name = "ssp0-port",
 523 },
 524 {
 525         .name = "ssp1-port",
 526 },
 527 };
 528 
 529 /* broadwell ops */
 530 const struct snd_sof_dsp_ops sof_bdw_ops = {
 531         /*Device init */
 532         .probe          = bdw_probe,
 533 
 534         /* DSP Core Control */
 535         .run            = bdw_run,
 536         .reset          = bdw_reset,
 537 
 538         /* Register IO */
 539         .write          = sof_io_write,
 540         .read           = sof_io_read,
 541         .write64        = sof_io_write64,
 542         .read64         = sof_io_read64,
 543 
 544         /* Block IO */
 545         .block_read     = sof_block_read,
 546         .block_write    = sof_block_write,
 547 
 548         /* ipc */
 549         .send_msg       = bdw_send_msg,
 550         .fw_ready       = sof_fw_ready,
 551         .get_mailbox_offset = bdw_get_mailbox_offset,
 552         .get_window_offset = bdw_get_window_offset,
 553 
 554         .ipc_msg_data   = intel_ipc_msg_data,
 555         .ipc_pcm_params = intel_ipc_pcm_params,
 556 
 557         /* debug */
 558         .debug_map  = bdw_debugfs,
 559         .debug_map_count    = ARRAY_SIZE(bdw_debugfs),
 560         .dbg_dump   = bdw_dump,
 561 
 562         /* stream callbacks */
 563         .pcm_open       = intel_pcm_open,
 564         .pcm_close      = intel_pcm_close,
 565 
 566         /* Module loading */
 567         .load_module    = snd_sof_parse_module_memcpy,
 568 
 569         /*Firmware loading */
 570         .load_firmware  = snd_sof_load_firmware_memcpy,
 571 
 572         /* DAI drivers */
 573         .drv = bdw_dai,
 574         .num_drv = ARRAY_SIZE(bdw_dai)
 575 };
 576 EXPORT_SYMBOL(sof_bdw_ops);
 577 
 578 const struct sof_intel_dsp_desc bdw_chip_info = {
 579         .cores_num = 1,
 580         .cores_mask = 1,
 581 };
 582 EXPORT_SYMBOL(bdw_chip_info);
 583 
 584 MODULE_LICENSE("Dual BSD/GPL");

/* [<][>][^][v][top][bottom][index][help] */