18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) 28c2ecf20Sopenharmony_ci// 38c2ecf20Sopenharmony_ci// This file is provided under a dual BSD/GPLv2 license. When using or 48c2ecf20Sopenharmony_ci// redistributing this file, you may do so under either license. 58c2ecf20Sopenharmony_ci// 68c2ecf20Sopenharmony_ci// Copyright(c) 2018 Intel Corporation. All rights reserved. 78c2ecf20Sopenharmony_ci// 88c2ecf20Sopenharmony_ci// Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> 98c2ecf20Sopenharmony_ci// 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci/* 128c2ecf20Sopenharmony_ci * Hardware interface for audio DSP on Baytrail, Braswell and Cherrytrail. 138c2ecf20Sopenharmony_ci */ 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#include <linux/module.h> 168c2ecf20Sopenharmony_ci#include <sound/sof.h> 178c2ecf20Sopenharmony_ci#include <sound/sof/xtensa.h> 188c2ecf20Sopenharmony_ci#include "../ops.h" 198c2ecf20Sopenharmony_ci#include "shim.h" 208c2ecf20Sopenharmony_ci#include "../sof-audio.h" 218c2ecf20Sopenharmony_ci#include "../../intel/common/soc-intel-quirks.h" 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci/* DSP memories */ 248c2ecf20Sopenharmony_ci#define IRAM_OFFSET 0x0C0000 258c2ecf20Sopenharmony_ci#define IRAM_SIZE (80 * 1024) 268c2ecf20Sopenharmony_ci#define DRAM_OFFSET 0x100000 278c2ecf20Sopenharmony_ci#define DRAM_SIZE (160 * 1024) 288c2ecf20Sopenharmony_ci#define SHIM_OFFSET 0x140000 298c2ecf20Sopenharmony_ci#define SHIM_SIZE_BYT 0x100 308c2ecf20Sopenharmony_ci#define SHIM_SIZE_CHT 0x118 318c2ecf20Sopenharmony_ci#define MBOX_OFFSET 0x144000 328c2ecf20Sopenharmony_ci#define MBOX_SIZE 0x1000 338c2ecf20Sopenharmony_ci#define EXCEPT_OFFSET 0x800 348c2ecf20Sopenharmony_ci#define EXCEPT_MAX_HDR_SIZE 0x400 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci/* DSP peripherals */ 378c2ecf20Sopenharmony_ci#define DMAC0_OFFSET 0x098000 388c2ecf20Sopenharmony_ci#define DMAC1_OFFSET 0x09c000 398c2ecf20Sopenharmony_ci#define DMAC2_OFFSET 0x094000 408c2ecf20Sopenharmony_ci#define DMAC_SIZE 0x420 418c2ecf20Sopenharmony_ci#define SSP0_OFFSET 0x0a0000 428c2ecf20Sopenharmony_ci#define SSP1_OFFSET 0x0a1000 438c2ecf20Sopenharmony_ci#define SSP2_OFFSET 0x0a2000 448c2ecf20Sopenharmony_ci#define SSP3_OFFSET 0x0a4000 458c2ecf20Sopenharmony_ci#define SSP4_OFFSET 0x0a5000 468c2ecf20Sopenharmony_ci#define SSP5_OFFSET 0x0a6000 478c2ecf20Sopenharmony_ci#define SSP_SIZE 0x100 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define BYT_STACK_DUMP_SIZE 32 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci#define BYT_PCI_BAR_SIZE 0x200000 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci#define BYT_PANIC_OFFSET(x) (((x) & GENMASK_ULL(47, 32)) >> 32) 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci/* 568c2ecf20Sopenharmony_ci * Debug 578c2ecf20Sopenharmony_ci */ 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci#define MBOX_DUMP_SIZE 0x30 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci/* BARs */ 628c2ecf20Sopenharmony_ci#define BYT_DSP_BAR 0 638c2ecf20Sopenharmony_ci#define BYT_PCI_BAR 1 648c2ecf20Sopenharmony_ci#define BYT_IMR_BAR 2 658c2ecf20Sopenharmony_ci 668c2ecf20Sopenharmony_cistatic const struct snd_sof_debugfs_map byt_debugfs[] = { 678c2ecf20Sopenharmony_ci {"dmac0", BYT_DSP_BAR, DMAC0_OFFSET, DMAC_SIZE, 688c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 698c2ecf20Sopenharmony_ci {"dmac1", BYT_DSP_BAR, DMAC1_OFFSET, DMAC_SIZE, 708c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 718c2ecf20Sopenharmony_ci {"ssp0", BYT_DSP_BAR, SSP0_OFFSET, SSP_SIZE, 728c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 738c2ecf20Sopenharmony_ci {"ssp1", BYT_DSP_BAR, SSP1_OFFSET, SSP_SIZE, 748c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 758c2ecf20Sopenharmony_ci {"ssp2", BYT_DSP_BAR, SSP2_OFFSET, SSP_SIZE, 768c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 778c2ecf20Sopenharmony_ci {"iram", BYT_DSP_BAR, IRAM_OFFSET, IRAM_SIZE, 788c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_D0_ONLY}, 798c2ecf20Sopenharmony_ci {"dram", BYT_DSP_BAR, DRAM_OFFSET, DRAM_SIZE, 808c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_D0_ONLY}, 818c2ecf20Sopenharmony_ci {"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE_BYT, 828c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 838c2ecf20Sopenharmony_ci}; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_cistatic void byt_host_done(struct snd_sof_dev *sdev); 868c2ecf20Sopenharmony_cistatic void byt_dsp_done(struct snd_sof_dev *sdev); 878c2ecf20Sopenharmony_cistatic void byt_get_reply(struct snd_sof_dev *sdev); 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci/* 908c2ecf20Sopenharmony_ci * Debug 918c2ecf20Sopenharmony_ci */ 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_cistatic void byt_get_registers(struct snd_sof_dev *sdev, 948c2ecf20Sopenharmony_ci struct sof_ipc_dsp_oops_xtensa *xoops, 958c2ecf20Sopenharmony_ci struct sof_ipc_panic_info *panic_info, 968c2ecf20Sopenharmony_ci u32 *stack, size_t stack_words) 978c2ecf20Sopenharmony_ci{ 988c2ecf20Sopenharmony_ci u32 offset = sdev->dsp_oops_offset; 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci /* first read regsisters */ 1018c2ecf20Sopenharmony_ci sof_mailbox_read(sdev, offset, xoops, sizeof(*xoops)); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci /* note: variable AR register array is not read */ 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci /* then get panic info */ 1068c2ecf20Sopenharmony_ci if (xoops->arch_hdr.totalsize > EXCEPT_MAX_HDR_SIZE) { 1078c2ecf20Sopenharmony_ci dev_err(sdev->dev, "invalid header size 0x%x. FW oops is bogus\n", 1088c2ecf20Sopenharmony_ci xoops->arch_hdr.totalsize); 1098c2ecf20Sopenharmony_ci return; 1108c2ecf20Sopenharmony_ci } 1118c2ecf20Sopenharmony_ci offset += xoops->arch_hdr.totalsize; 1128c2ecf20Sopenharmony_ci sof_mailbox_read(sdev, offset, panic_info, sizeof(*panic_info)); 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci /* then get the stack */ 1158c2ecf20Sopenharmony_ci offset += sizeof(*panic_info); 1168c2ecf20Sopenharmony_ci sof_mailbox_read(sdev, offset, stack, stack_words * sizeof(u32)); 1178c2ecf20Sopenharmony_ci} 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_cistatic void byt_dump(struct snd_sof_dev *sdev, u32 flags) 1208c2ecf20Sopenharmony_ci{ 1218c2ecf20Sopenharmony_ci struct sof_ipc_dsp_oops_xtensa xoops; 1228c2ecf20Sopenharmony_ci struct sof_ipc_panic_info panic_info; 1238c2ecf20Sopenharmony_ci u32 stack[BYT_STACK_DUMP_SIZE]; 1248c2ecf20Sopenharmony_ci u64 status, panic, imrd, imrx; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci /* now try generic SOF status messages */ 1278c2ecf20Sopenharmony_ci status = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD); 1288c2ecf20Sopenharmony_ci panic = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX); 1298c2ecf20Sopenharmony_ci byt_get_registers(sdev, &xoops, &panic_info, stack, 1308c2ecf20Sopenharmony_ci BYT_STACK_DUMP_SIZE); 1318c2ecf20Sopenharmony_ci snd_sof_get_status(sdev, status, panic, &xoops, &panic_info, stack, 1328c2ecf20Sopenharmony_ci BYT_STACK_DUMP_SIZE); 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci /* provide some context for firmware debug */ 1358c2ecf20Sopenharmony_ci imrx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRX); 1368c2ecf20Sopenharmony_ci imrd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IMRD); 1378c2ecf20Sopenharmony_ci dev_err(sdev->dev, 1388c2ecf20Sopenharmony_ci "error: ipc host -> DSP: pending %s complete %s raw 0x%llx\n", 1398c2ecf20Sopenharmony_ci (panic & SHIM_IPCX_BUSY) ? "yes" : "no", 1408c2ecf20Sopenharmony_ci (panic & SHIM_IPCX_DONE) ? "yes" : "no", panic); 1418c2ecf20Sopenharmony_ci dev_err(sdev->dev, 1428c2ecf20Sopenharmony_ci "error: mask host: pending %s complete %s raw 0x%llx\n", 1438c2ecf20Sopenharmony_ci (imrx & SHIM_IMRX_BUSY) ? "yes" : "no", 1448c2ecf20Sopenharmony_ci (imrx & SHIM_IMRX_DONE) ? "yes" : "no", imrx); 1458c2ecf20Sopenharmony_ci dev_err(sdev->dev, 1468c2ecf20Sopenharmony_ci "error: ipc DSP -> host: pending %s complete %s raw 0x%llx\n", 1478c2ecf20Sopenharmony_ci (status & SHIM_IPCD_BUSY) ? "yes" : "no", 1488c2ecf20Sopenharmony_ci (status & SHIM_IPCD_DONE) ? "yes" : "no", status); 1498c2ecf20Sopenharmony_ci dev_err(sdev->dev, 1508c2ecf20Sopenharmony_ci "error: mask DSP: pending %s complete %s raw 0x%llx\n", 1518c2ecf20Sopenharmony_ci (imrd & SHIM_IMRD_BUSY) ? "yes" : "no", 1528c2ecf20Sopenharmony_ci (imrd & SHIM_IMRD_DONE) ? "yes" : "no", imrd); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci} 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci/* 1578c2ecf20Sopenharmony_ci * IPC Doorbell IRQ handler and thread. 1588c2ecf20Sopenharmony_ci */ 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_cistatic irqreturn_t byt_irq_handler(int irq, void *context) 1618c2ecf20Sopenharmony_ci{ 1628c2ecf20Sopenharmony_ci struct snd_sof_dev *sdev = context; 1638c2ecf20Sopenharmony_ci u64 ipcx, ipcd; 1648c2ecf20Sopenharmony_ci int ret = IRQ_NONE; 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX); 1678c2ecf20Sopenharmony_ci ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD); 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci if (ipcx & SHIM_BYT_IPCX_DONE) { 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci /* reply message from DSP, Mask Done interrupt first */ 1728c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, 1738c2ecf20Sopenharmony_ci SHIM_IMRX, 1748c2ecf20Sopenharmony_ci SHIM_IMRX_DONE, 1758c2ecf20Sopenharmony_ci SHIM_IMRX_DONE); 1768c2ecf20Sopenharmony_ci ret = IRQ_WAKE_THREAD; 1778c2ecf20Sopenharmony_ci } 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci if (ipcd & SHIM_BYT_IPCD_BUSY) { 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci /* new message from DSP, Mask Busy interrupt first */ 1828c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, 1838c2ecf20Sopenharmony_ci SHIM_IMRX, 1848c2ecf20Sopenharmony_ci SHIM_IMRX_BUSY, 1858c2ecf20Sopenharmony_ci SHIM_IMRX_BUSY); 1868c2ecf20Sopenharmony_ci ret = IRQ_WAKE_THREAD; 1878c2ecf20Sopenharmony_ci } 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_ci return ret; 1908c2ecf20Sopenharmony_ci} 1918c2ecf20Sopenharmony_ci 1928c2ecf20Sopenharmony_cistatic irqreturn_t byt_irq_thread(int irq, void *context) 1938c2ecf20Sopenharmony_ci{ 1948c2ecf20Sopenharmony_ci struct snd_sof_dev *sdev = context; 1958c2ecf20Sopenharmony_ci u64 ipcx, ipcd; 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_ci ipcx = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCX); 1988c2ecf20Sopenharmony_ci ipcd = snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_IPCD); 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci /* reply message from DSP */ 2018c2ecf20Sopenharmony_ci if (ipcx & SHIM_BYT_IPCX_DONE) { 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci spin_lock_irq(&sdev->ipc_lock); 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci /* 2068c2ecf20Sopenharmony_ci * handle immediate reply from DSP core. If the msg is 2078c2ecf20Sopenharmony_ci * found, set done bit in cmd_done which is called at the 2088c2ecf20Sopenharmony_ci * end of message processing function, else set it here 2098c2ecf20Sopenharmony_ci * because the done bit can't be set in cmd_done function 2108c2ecf20Sopenharmony_ci * which is triggered by msg 2118c2ecf20Sopenharmony_ci */ 2128c2ecf20Sopenharmony_ci byt_get_reply(sdev); 2138c2ecf20Sopenharmony_ci snd_sof_ipc_reply(sdev, ipcx); 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci byt_dsp_done(sdev); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci spin_unlock_irq(&sdev->ipc_lock); 2188c2ecf20Sopenharmony_ci } 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci /* new message from DSP */ 2218c2ecf20Sopenharmony_ci if (ipcd & SHIM_BYT_IPCD_BUSY) { 2228c2ecf20Sopenharmony_ci 2238c2ecf20Sopenharmony_ci /* Handle messages from DSP Core */ 2248c2ecf20Sopenharmony_ci if ((ipcd & SOF_IPC_PANIC_MAGIC_MASK) == SOF_IPC_PANIC_MAGIC) { 2258c2ecf20Sopenharmony_ci snd_sof_dsp_panic(sdev, BYT_PANIC_OFFSET(ipcd) + 2268c2ecf20Sopenharmony_ci MBOX_OFFSET); 2278c2ecf20Sopenharmony_ci } else { 2288c2ecf20Sopenharmony_ci snd_sof_ipc_msgs_rx(sdev); 2298c2ecf20Sopenharmony_ci } 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci byt_host_done(sdev); 2328c2ecf20Sopenharmony_ci } 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci return IRQ_HANDLED; 2358c2ecf20Sopenharmony_ci} 2368c2ecf20Sopenharmony_ci 2378c2ecf20Sopenharmony_cistatic int byt_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) 2388c2ecf20Sopenharmony_ci{ 2398c2ecf20Sopenharmony_ci /* unmask and prepare to receive Done interrupt */ 2408c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX, 2418c2ecf20Sopenharmony_ci SHIM_IMRX_DONE, 0); 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci /* send the message */ 2448c2ecf20Sopenharmony_ci sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, 2458c2ecf20Sopenharmony_ci msg->msg_size); 2468c2ecf20Sopenharmony_ci snd_sof_dsp_write64(sdev, BYT_DSP_BAR, SHIM_IPCX, SHIM_BYT_IPCX_BUSY); 2478c2ecf20Sopenharmony_ci 2488c2ecf20Sopenharmony_ci return 0; 2498c2ecf20Sopenharmony_ci} 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cistatic void byt_get_reply(struct snd_sof_dev *sdev) 2528c2ecf20Sopenharmony_ci{ 2538c2ecf20Sopenharmony_ci struct snd_sof_ipc_msg *msg = sdev->msg; 2548c2ecf20Sopenharmony_ci struct sof_ipc_reply reply; 2558c2ecf20Sopenharmony_ci int ret = 0; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci /* 2588c2ecf20Sopenharmony_ci * Sometimes, there is unexpected reply ipc arriving. The reply 2598c2ecf20Sopenharmony_ci * ipc belongs to none of the ipcs sent from driver. 2608c2ecf20Sopenharmony_ci * In this case, the driver must ignore the ipc. 2618c2ecf20Sopenharmony_ci */ 2628c2ecf20Sopenharmony_ci if (!msg) { 2638c2ecf20Sopenharmony_ci dev_warn(sdev->dev, "unexpected ipc interrupt raised!\n"); 2648c2ecf20Sopenharmony_ci return; 2658c2ecf20Sopenharmony_ci } 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci /* get reply */ 2688c2ecf20Sopenharmony_ci sof_mailbox_read(sdev, sdev->host_box.offset, &reply, sizeof(reply)); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci if (reply.error < 0) { 2718c2ecf20Sopenharmony_ci memcpy(msg->reply_data, &reply, sizeof(reply)); 2728c2ecf20Sopenharmony_ci ret = reply.error; 2738c2ecf20Sopenharmony_ci } else { 2748c2ecf20Sopenharmony_ci /* reply correct size ? */ 2758c2ecf20Sopenharmony_ci if (reply.hdr.size != msg->reply_size) { 2768c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: reply expected %zu got %u bytes\n", 2778c2ecf20Sopenharmony_ci msg->reply_size, reply.hdr.size); 2788c2ecf20Sopenharmony_ci ret = -EINVAL; 2798c2ecf20Sopenharmony_ci } 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci /* read the message */ 2828c2ecf20Sopenharmony_ci if (msg->reply_size > 0) 2838c2ecf20Sopenharmony_ci sof_mailbox_read(sdev, sdev->host_box.offset, 2848c2ecf20Sopenharmony_ci msg->reply_data, msg->reply_size); 2858c2ecf20Sopenharmony_ci } 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci msg->reply_error = ret; 2888c2ecf20Sopenharmony_ci} 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_cistatic int byt_get_mailbox_offset(struct snd_sof_dev *sdev) 2918c2ecf20Sopenharmony_ci{ 2928c2ecf20Sopenharmony_ci return MBOX_OFFSET; 2938c2ecf20Sopenharmony_ci} 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_cistatic int byt_get_window_offset(struct snd_sof_dev *sdev, u32 id) 2968c2ecf20Sopenharmony_ci{ 2978c2ecf20Sopenharmony_ci return MBOX_OFFSET; 2988c2ecf20Sopenharmony_ci} 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_cistatic void byt_host_done(struct snd_sof_dev *sdev) 3018c2ecf20Sopenharmony_ci{ 3028c2ecf20Sopenharmony_ci /* clear BUSY bit and set DONE bit - accept new messages */ 3038c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCD, 3048c2ecf20Sopenharmony_ci SHIM_BYT_IPCD_BUSY | 3058c2ecf20Sopenharmony_ci SHIM_BYT_IPCD_DONE, 3068c2ecf20Sopenharmony_ci SHIM_BYT_IPCD_DONE); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci /* unmask and prepare to receive next new message */ 3098c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IMRX, 3108c2ecf20Sopenharmony_ci SHIM_IMRX_BUSY, 0); 3118c2ecf20Sopenharmony_ci} 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_cistatic void byt_dsp_done(struct snd_sof_dev *sdev) 3148c2ecf20Sopenharmony_ci{ 3158c2ecf20Sopenharmony_ci /* clear DONE bit - tell DSP we have completed */ 3168c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64_unlocked(sdev, BYT_DSP_BAR, SHIM_IPCX, 3178c2ecf20Sopenharmony_ci SHIM_BYT_IPCX_DONE, 0); 3188c2ecf20Sopenharmony_ci} 3198c2ecf20Sopenharmony_ci 3208c2ecf20Sopenharmony_ci/* 3218c2ecf20Sopenharmony_ci * DSP control. 3228c2ecf20Sopenharmony_ci */ 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_cistatic int byt_run(struct snd_sof_dev *sdev) 3258c2ecf20Sopenharmony_ci{ 3268c2ecf20Sopenharmony_ci int tries = 10; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci /* release stall and wait to unstall */ 3298c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR, 3308c2ecf20Sopenharmony_ci SHIM_BYT_CSR_STALL, 0x0); 3318c2ecf20Sopenharmony_ci while (tries--) { 3328c2ecf20Sopenharmony_ci if (!(snd_sof_dsp_read64(sdev, BYT_DSP_BAR, SHIM_CSR) & 3338c2ecf20Sopenharmony_ci SHIM_BYT_CSR_PWAITMODE)) 3348c2ecf20Sopenharmony_ci break; 3358c2ecf20Sopenharmony_ci msleep(100); 3368c2ecf20Sopenharmony_ci } 3378c2ecf20Sopenharmony_ci if (tries < 0) { 3388c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: unable to run DSP firmware\n"); 3398c2ecf20Sopenharmony_ci byt_dump(sdev, SOF_DBG_REGS | SOF_DBG_MBOX); 3408c2ecf20Sopenharmony_ci return -ENODEV; 3418c2ecf20Sopenharmony_ci } 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci /* return init core mask */ 3448c2ecf20Sopenharmony_ci return 1; 3458c2ecf20Sopenharmony_ci} 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_cistatic int byt_reset(struct snd_sof_dev *sdev) 3488c2ecf20Sopenharmony_ci{ 3498c2ecf20Sopenharmony_ci /* put DSP into reset, set reset vector and stall */ 3508c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR, 3518c2ecf20Sopenharmony_ci SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL | 3528c2ecf20Sopenharmony_ci SHIM_BYT_CSR_STALL, 3538c2ecf20Sopenharmony_ci SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL | 3548c2ecf20Sopenharmony_ci SHIM_BYT_CSR_STALL); 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci usleep_range(10, 15); 3578c2ecf20Sopenharmony_ci 3588c2ecf20Sopenharmony_ci /* take DSP out of reset and keep stalled for FW loading */ 3598c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR, 3608c2ecf20Sopenharmony_ci SHIM_BYT_CSR_RST, 0); 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci return 0; 3638c2ecf20Sopenharmony_ci} 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_cistatic const char *fixup_tplg_name(struct snd_sof_dev *sdev, 3668c2ecf20Sopenharmony_ci const char *sof_tplg_filename, 3678c2ecf20Sopenharmony_ci const char *ssp_str) 3688c2ecf20Sopenharmony_ci{ 3698c2ecf20Sopenharmony_ci const char *tplg_filename = NULL; 3708c2ecf20Sopenharmony_ci char *filename; 3718c2ecf20Sopenharmony_ci char *split_ext; 3728c2ecf20Sopenharmony_ci 3738c2ecf20Sopenharmony_ci filename = devm_kstrdup(sdev->dev, sof_tplg_filename, GFP_KERNEL); 3748c2ecf20Sopenharmony_ci if (!filename) 3758c2ecf20Sopenharmony_ci return NULL; 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci /* this assumes a .tplg extension */ 3788c2ecf20Sopenharmony_ci split_ext = strsep(&filename, "."); 3798c2ecf20Sopenharmony_ci if (split_ext) { 3808c2ecf20Sopenharmony_ci tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, 3818c2ecf20Sopenharmony_ci "%s-%s.tplg", 3828c2ecf20Sopenharmony_ci split_ext, ssp_str); 3838c2ecf20Sopenharmony_ci if (!tplg_filename) 3848c2ecf20Sopenharmony_ci return NULL; 3858c2ecf20Sopenharmony_ci } 3868c2ecf20Sopenharmony_ci return tplg_filename; 3878c2ecf20Sopenharmony_ci} 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_cistatic void byt_machine_select(struct snd_sof_dev *sdev) 3908c2ecf20Sopenharmony_ci{ 3918c2ecf20Sopenharmony_ci struct snd_sof_pdata *sof_pdata = sdev->pdata; 3928c2ecf20Sopenharmony_ci const struct sof_dev_desc *desc = sof_pdata->desc; 3938c2ecf20Sopenharmony_ci struct snd_soc_acpi_mach *mach; 3948c2ecf20Sopenharmony_ci struct platform_device *pdev; 3958c2ecf20Sopenharmony_ci const char *tplg_filename; 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ci mach = snd_soc_acpi_find_machine(desc->machines); 3988c2ecf20Sopenharmony_ci if (!mach) { 3998c2ecf20Sopenharmony_ci dev_warn(sdev->dev, "warning: No matching ASoC machine driver found\n"); 4008c2ecf20Sopenharmony_ci return; 4018c2ecf20Sopenharmony_ci } 4028c2ecf20Sopenharmony_ci 4038c2ecf20Sopenharmony_ci pdev = to_platform_device(sdev->dev); 4048c2ecf20Sopenharmony_ci if (soc_intel_is_byt_cr(pdev)) { 4058c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, 4068c2ecf20Sopenharmony_ci "BYT-CR detected, SSP0 used instead of SSP2\n"); 4078c2ecf20Sopenharmony_ci 4088c2ecf20Sopenharmony_ci tplg_filename = fixup_tplg_name(sdev, 4098c2ecf20Sopenharmony_ci mach->sof_tplg_filename, 4108c2ecf20Sopenharmony_ci "ssp0"); 4118c2ecf20Sopenharmony_ci } else { 4128c2ecf20Sopenharmony_ci tplg_filename = mach->sof_tplg_filename; 4138c2ecf20Sopenharmony_ci } 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_ci if (!tplg_filename) { 4168c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, 4178c2ecf20Sopenharmony_ci "error: no topology filename\n"); 4188c2ecf20Sopenharmony_ci return; 4198c2ecf20Sopenharmony_ci } 4208c2ecf20Sopenharmony_ci 4218c2ecf20Sopenharmony_ci sof_pdata->tplg_filename = tplg_filename; 4228c2ecf20Sopenharmony_ci mach->mach_params.acpi_ipc_irq_index = desc->irqindex_host_ipc; 4238c2ecf20Sopenharmony_ci sof_pdata->machine = mach; 4248c2ecf20Sopenharmony_ci} 4258c2ecf20Sopenharmony_ci 4268c2ecf20Sopenharmony_cistatic void byt_set_mach_params(const struct snd_soc_acpi_mach *mach, 4278c2ecf20Sopenharmony_ci struct device *dev) 4288c2ecf20Sopenharmony_ci{ 4298c2ecf20Sopenharmony_ci struct snd_soc_acpi_mach_params *mach_params; 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci mach_params = (struct snd_soc_acpi_mach_params *)&mach->mach_params; 4328c2ecf20Sopenharmony_ci mach_params->platform = dev_name(dev); 4338c2ecf20Sopenharmony_ci} 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci/* Baytrail DAIs */ 4368c2ecf20Sopenharmony_cistatic struct snd_soc_dai_driver byt_dai[] = { 4378c2ecf20Sopenharmony_ci{ 4388c2ecf20Sopenharmony_ci .name = "ssp0-port", 4398c2ecf20Sopenharmony_ci .playback = { 4408c2ecf20Sopenharmony_ci .channels_min = 1, 4418c2ecf20Sopenharmony_ci .channels_max = 8, 4428c2ecf20Sopenharmony_ci }, 4438c2ecf20Sopenharmony_ci .capture = { 4448c2ecf20Sopenharmony_ci .channels_min = 1, 4458c2ecf20Sopenharmony_ci .channels_max = 8, 4468c2ecf20Sopenharmony_ci }, 4478c2ecf20Sopenharmony_ci}, 4488c2ecf20Sopenharmony_ci{ 4498c2ecf20Sopenharmony_ci .name = "ssp1-port", 4508c2ecf20Sopenharmony_ci .playback = { 4518c2ecf20Sopenharmony_ci .channels_min = 1, 4528c2ecf20Sopenharmony_ci .channels_max = 8, 4538c2ecf20Sopenharmony_ci }, 4548c2ecf20Sopenharmony_ci .capture = { 4558c2ecf20Sopenharmony_ci .channels_min = 1, 4568c2ecf20Sopenharmony_ci .channels_max = 8, 4578c2ecf20Sopenharmony_ci }, 4588c2ecf20Sopenharmony_ci}, 4598c2ecf20Sopenharmony_ci{ 4608c2ecf20Sopenharmony_ci .name = "ssp2-port", 4618c2ecf20Sopenharmony_ci .playback = { 4628c2ecf20Sopenharmony_ci .channels_min = 1, 4638c2ecf20Sopenharmony_ci .channels_max = 8, 4648c2ecf20Sopenharmony_ci }, 4658c2ecf20Sopenharmony_ci .capture = { 4668c2ecf20Sopenharmony_ci .channels_min = 1, 4678c2ecf20Sopenharmony_ci .channels_max = 8, 4688c2ecf20Sopenharmony_ci } 4698c2ecf20Sopenharmony_ci}, 4708c2ecf20Sopenharmony_ci{ 4718c2ecf20Sopenharmony_ci .name = "ssp3-port", 4728c2ecf20Sopenharmony_ci .playback = { 4738c2ecf20Sopenharmony_ci .channels_min = 1, 4748c2ecf20Sopenharmony_ci .channels_max = 8, 4758c2ecf20Sopenharmony_ci }, 4768c2ecf20Sopenharmony_ci .capture = { 4778c2ecf20Sopenharmony_ci .channels_min = 1, 4788c2ecf20Sopenharmony_ci .channels_max = 8, 4798c2ecf20Sopenharmony_ci }, 4808c2ecf20Sopenharmony_ci}, 4818c2ecf20Sopenharmony_ci{ 4828c2ecf20Sopenharmony_ci .name = "ssp4-port", 4838c2ecf20Sopenharmony_ci .playback = { 4848c2ecf20Sopenharmony_ci .channels_min = 1, 4858c2ecf20Sopenharmony_ci .channels_max = 8, 4868c2ecf20Sopenharmony_ci }, 4878c2ecf20Sopenharmony_ci .capture = { 4888c2ecf20Sopenharmony_ci .channels_min = 1, 4898c2ecf20Sopenharmony_ci .channels_max = 8, 4908c2ecf20Sopenharmony_ci }, 4918c2ecf20Sopenharmony_ci}, 4928c2ecf20Sopenharmony_ci{ 4938c2ecf20Sopenharmony_ci .name = "ssp5-port", 4948c2ecf20Sopenharmony_ci .playback = { 4958c2ecf20Sopenharmony_ci .channels_min = 1, 4968c2ecf20Sopenharmony_ci .channels_max = 8, 4978c2ecf20Sopenharmony_ci }, 4988c2ecf20Sopenharmony_ci .capture = { 4998c2ecf20Sopenharmony_ci .channels_min = 1, 5008c2ecf20Sopenharmony_ci .channels_max = 8, 5018c2ecf20Sopenharmony_ci }, 5028c2ecf20Sopenharmony_ci}, 5038c2ecf20Sopenharmony_ci}; 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci/* 5068c2ecf20Sopenharmony_ci * Probe and remove. 5078c2ecf20Sopenharmony_ci */ 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_MERRIFIELD) 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_cistatic int tangier_pci_probe(struct snd_sof_dev *sdev) 5128c2ecf20Sopenharmony_ci{ 5138c2ecf20Sopenharmony_ci struct snd_sof_pdata *pdata = sdev->pdata; 5148c2ecf20Sopenharmony_ci const struct sof_dev_desc *desc = pdata->desc; 5158c2ecf20Sopenharmony_ci struct pci_dev *pci = to_pci_dev(sdev->dev); 5168c2ecf20Sopenharmony_ci u32 base, size; 5178c2ecf20Sopenharmony_ci int ret; 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_ci /* DSP DMA can only access low 31 bits of host memory */ 5208c2ecf20Sopenharmony_ci ret = dma_coerce_mask_and_coherent(&pci->dev, DMA_BIT_MASK(31)); 5218c2ecf20Sopenharmony_ci if (ret < 0) { 5228c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret); 5238c2ecf20Sopenharmony_ci return ret; 5248c2ecf20Sopenharmony_ci } 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci /* LPE base */ 5278c2ecf20Sopenharmony_ci base = pci_resource_start(pci, desc->resindex_lpe_base) - IRAM_OFFSET; 5288c2ecf20Sopenharmony_ci size = BYT_PCI_BAR_SIZE; 5298c2ecf20Sopenharmony_ci 5308c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size); 5318c2ecf20Sopenharmony_ci sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size); 5328c2ecf20Sopenharmony_ci if (!sdev->bar[BYT_DSP_BAR]) { 5338c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n", 5348c2ecf20Sopenharmony_ci base, size); 5358c2ecf20Sopenharmony_ci return -ENODEV; 5368c2ecf20Sopenharmony_ci } 5378c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]); 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_ci /* IMR base - optional */ 5408c2ecf20Sopenharmony_ci if (desc->resindex_imr_base == -1) 5418c2ecf20Sopenharmony_ci goto irq; 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci base = pci_resource_start(pci, desc->resindex_imr_base); 5448c2ecf20Sopenharmony_ci size = pci_resource_len(pci, desc->resindex_imr_base); 5458c2ecf20Sopenharmony_ci 5468c2ecf20Sopenharmony_ci /* some BIOSes don't map IMR */ 5478c2ecf20Sopenharmony_ci if (base == 0x55aa55aa || base == 0x0) { 5488c2ecf20Sopenharmony_ci dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n"); 5498c2ecf20Sopenharmony_ci goto irq; 5508c2ecf20Sopenharmony_ci } 5518c2ecf20Sopenharmony_ci 5528c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size); 5538c2ecf20Sopenharmony_ci sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size); 5548c2ecf20Sopenharmony_ci if (!sdev->bar[BYT_IMR_BAR]) { 5558c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n", 5568c2ecf20Sopenharmony_ci base, size); 5578c2ecf20Sopenharmony_ci return -ENODEV; 5588c2ecf20Sopenharmony_ci } 5598c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]); 5608c2ecf20Sopenharmony_ci 5618c2ecf20Sopenharmony_ciirq: 5628c2ecf20Sopenharmony_ci /* register our IRQ */ 5638c2ecf20Sopenharmony_ci sdev->ipc_irq = pci->irq; 5648c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); 5658c2ecf20Sopenharmony_ci ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq, 5668c2ecf20Sopenharmony_ci byt_irq_handler, byt_irq_thread, 5678c2ecf20Sopenharmony_ci 0, "AudioDSP", sdev); 5688c2ecf20Sopenharmony_ci if (ret < 0) { 5698c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: failed to register IRQ %d\n", 5708c2ecf20Sopenharmony_ci sdev->ipc_irq); 5718c2ecf20Sopenharmony_ci return ret; 5728c2ecf20Sopenharmony_ci } 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci /* enable BUSY and disable DONE Interrupt by default */ 5758c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 5768c2ecf20Sopenharmony_ci SHIM_IMRX_BUSY | SHIM_IMRX_DONE, 5778c2ecf20Sopenharmony_ci SHIM_IMRX_DONE); 5788c2ecf20Sopenharmony_ci 5798c2ecf20Sopenharmony_ci /* set default mailbox offset for FW ready message */ 5808c2ecf20Sopenharmony_ci sdev->dsp_box.offset = MBOX_OFFSET; 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_ci return ret; 5838c2ecf20Sopenharmony_ci} 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_ciconst struct snd_sof_dsp_ops sof_tng_ops = { 5868c2ecf20Sopenharmony_ci /* device init */ 5878c2ecf20Sopenharmony_ci .probe = tangier_pci_probe, 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_ci /* DSP core boot / reset */ 5908c2ecf20Sopenharmony_ci .run = byt_run, 5918c2ecf20Sopenharmony_ci .reset = byt_reset, 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci /* Register IO */ 5948c2ecf20Sopenharmony_ci .write = sof_io_write, 5958c2ecf20Sopenharmony_ci .read = sof_io_read, 5968c2ecf20Sopenharmony_ci .write64 = sof_io_write64, 5978c2ecf20Sopenharmony_ci .read64 = sof_io_read64, 5988c2ecf20Sopenharmony_ci 5998c2ecf20Sopenharmony_ci /* Block IO */ 6008c2ecf20Sopenharmony_ci .block_read = sof_block_read, 6018c2ecf20Sopenharmony_ci .block_write = sof_block_write, 6028c2ecf20Sopenharmony_ci 6038c2ecf20Sopenharmony_ci /* doorbell */ 6048c2ecf20Sopenharmony_ci .irq_handler = byt_irq_handler, 6058c2ecf20Sopenharmony_ci .irq_thread = byt_irq_thread, 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_ci /* ipc */ 6088c2ecf20Sopenharmony_ci .send_msg = byt_send_msg, 6098c2ecf20Sopenharmony_ci .fw_ready = sof_fw_ready, 6108c2ecf20Sopenharmony_ci .get_mailbox_offset = byt_get_mailbox_offset, 6118c2ecf20Sopenharmony_ci .get_window_offset = byt_get_window_offset, 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_ci .ipc_msg_data = intel_ipc_msg_data, 6148c2ecf20Sopenharmony_ci .ipc_pcm_params = intel_ipc_pcm_params, 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_ci /* machine driver */ 6178c2ecf20Sopenharmony_ci .machine_select = byt_machine_select, 6188c2ecf20Sopenharmony_ci .machine_register = sof_machine_register, 6198c2ecf20Sopenharmony_ci .machine_unregister = sof_machine_unregister, 6208c2ecf20Sopenharmony_ci .set_mach_params = byt_set_mach_params, 6218c2ecf20Sopenharmony_ci 6228c2ecf20Sopenharmony_ci /* debug */ 6238c2ecf20Sopenharmony_ci .debug_map = byt_debugfs, 6248c2ecf20Sopenharmony_ci .debug_map_count = ARRAY_SIZE(byt_debugfs), 6258c2ecf20Sopenharmony_ci .dbg_dump = byt_dump, 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci /* stream callbacks */ 6288c2ecf20Sopenharmony_ci .pcm_open = intel_pcm_open, 6298c2ecf20Sopenharmony_ci .pcm_close = intel_pcm_close, 6308c2ecf20Sopenharmony_ci 6318c2ecf20Sopenharmony_ci /* module loading */ 6328c2ecf20Sopenharmony_ci .load_module = snd_sof_parse_module_memcpy, 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ci /*Firmware loading */ 6358c2ecf20Sopenharmony_ci .load_firmware = snd_sof_load_firmware_memcpy, 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci /* DAI drivers */ 6388c2ecf20Sopenharmony_ci .drv = byt_dai, 6398c2ecf20Sopenharmony_ci .num_drv = 3, /* we have only 3 SSPs on byt*/ 6408c2ecf20Sopenharmony_ci 6418c2ecf20Sopenharmony_ci /* ALSA HW info flags */ 6428c2ecf20Sopenharmony_ci .hw_info = SNDRV_PCM_INFO_MMAP | 6438c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_MMAP_VALID | 6448c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_INTERLEAVED | 6458c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_PAUSE | 6468c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_BATCH, 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci .arch_ops = &sof_xtensa_arch_ops, 6498c2ecf20Sopenharmony_ci}; 6508c2ecf20Sopenharmony_ciEXPORT_SYMBOL_NS(sof_tng_ops, SND_SOC_SOF_MERRIFIELD); 6518c2ecf20Sopenharmony_ci 6528c2ecf20Sopenharmony_ciconst struct sof_intel_dsp_desc tng_chip_info = { 6538c2ecf20Sopenharmony_ci .cores_num = 1, 6548c2ecf20Sopenharmony_ci .host_managed_cores_mask = 1, 6558c2ecf20Sopenharmony_ci}; 6568c2ecf20Sopenharmony_ciEXPORT_SYMBOL_NS(tng_chip_info, SND_SOC_SOF_MERRIFIELD); 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ci#endif /* CONFIG_SND_SOC_SOF_MERRIFIELD */ 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_BAYTRAIL) 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_cistatic void byt_reset_dsp_disable_int(struct snd_sof_dev *sdev) 6638c2ecf20Sopenharmony_ci{ 6648c2ecf20Sopenharmony_ci /* Disable Interrupt from both sides */ 6658c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 0x3, 0x3); 6668c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRD, 0x3, 0x3); 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_ci /* Put DSP into reset, set reset vector */ 6698c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_CSR, 6708c2ecf20Sopenharmony_ci SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL, 6718c2ecf20Sopenharmony_ci SHIM_BYT_CSR_RST | SHIM_BYT_CSR_VECTOR_SEL); 6728c2ecf20Sopenharmony_ci} 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_cistatic int byt_suspend(struct snd_sof_dev *sdev, u32 target_state) 6758c2ecf20Sopenharmony_ci{ 6768c2ecf20Sopenharmony_ci byt_reset_dsp_disable_int(sdev); 6778c2ecf20Sopenharmony_ci 6788c2ecf20Sopenharmony_ci return 0; 6798c2ecf20Sopenharmony_ci} 6808c2ecf20Sopenharmony_ci 6818c2ecf20Sopenharmony_cistatic int byt_resume(struct snd_sof_dev *sdev) 6828c2ecf20Sopenharmony_ci{ 6838c2ecf20Sopenharmony_ci /* enable BUSY and disable DONE Interrupt by default */ 6848c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 6858c2ecf20Sopenharmony_ci SHIM_IMRX_BUSY | SHIM_IMRX_DONE, 6868c2ecf20Sopenharmony_ci SHIM_IMRX_DONE); 6878c2ecf20Sopenharmony_ci 6888c2ecf20Sopenharmony_ci return 0; 6898c2ecf20Sopenharmony_ci} 6908c2ecf20Sopenharmony_ci 6918c2ecf20Sopenharmony_cistatic int byt_remove(struct snd_sof_dev *sdev) 6928c2ecf20Sopenharmony_ci{ 6938c2ecf20Sopenharmony_ci byt_reset_dsp_disable_int(sdev); 6948c2ecf20Sopenharmony_ci 6958c2ecf20Sopenharmony_ci return 0; 6968c2ecf20Sopenharmony_ci} 6978c2ecf20Sopenharmony_ci 6988c2ecf20Sopenharmony_cistatic const struct snd_sof_debugfs_map cht_debugfs[] = { 6998c2ecf20Sopenharmony_ci {"dmac0", BYT_DSP_BAR, DMAC0_OFFSET, DMAC_SIZE, 7008c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 7018c2ecf20Sopenharmony_ci {"dmac1", BYT_DSP_BAR, DMAC1_OFFSET, DMAC_SIZE, 7028c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 7038c2ecf20Sopenharmony_ci {"dmac2", BYT_DSP_BAR, DMAC2_OFFSET, DMAC_SIZE, 7048c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 7058c2ecf20Sopenharmony_ci {"ssp0", BYT_DSP_BAR, SSP0_OFFSET, SSP_SIZE, 7068c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 7078c2ecf20Sopenharmony_ci {"ssp1", BYT_DSP_BAR, SSP1_OFFSET, SSP_SIZE, 7088c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 7098c2ecf20Sopenharmony_ci {"ssp2", BYT_DSP_BAR, SSP2_OFFSET, SSP_SIZE, 7108c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 7118c2ecf20Sopenharmony_ci {"ssp3", BYT_DSP_BAR, SSP3_OFFSET, SSP_SIZE, 7128c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 7138c2ecf20Sopenharmony_ci {"ssp4", BYT_DSP_BAR, SSP4_OFFSET, SSP_SIZE, 7148c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 7158c2ecf20Sopenharmony_ci {"ssp5", BYT_DSP_BAR, SSP5_OFFSET, SSP_SIZE, 7168c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 7178c2ecf20Sopenharmony_ci {"iram", BYT_DSP_BAR, IRAM_OFFSET, IRAM_SIZE, 7188c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_D0_ONLY}, 7198c2ecf20Sopenharmony_ci {"dram", BYT_DSP_BAR, DRAM_OFFSET, DRAM_SIZE, 7208c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_D0_ONLY}, 7218c2ecf20Sopenharmony_ci {"shim", BYT_DSP_BAR, SHIM_OFFSET, SHIM_SIZE_CHT, 7228c2ecf20Sopenharmony_ci SOF_DEBUGFS_ACCESS_ALWAYS}, 7238c2ecf20Sopenharmony_ci}; 7248c2ecf20Sopenharmony_ci 7258c2ecf20Sopenharmony_cistatic int byt_acpi_probe(struct snd_sof_dev *sdev) 7268c2ecf20Sopenharmony_ci{ 7278c2ecf20Sopenharmony_ci struct snd_sof_pdata *pdata = sdev->pdata; 7288c2ecf20Sopenharmony_ci const struct sof_dev_desc *desc = pdata->desc; 7298c2ecf20Sopenharmony_ci struct platform_device *pdev = 7308c2ecf20Sopenharmony_ci container_of(sdev->dev, struct platform_device, dev); 7318c2ecf20Sopenharmony_ci struct resource *mmio; 7328c2ecf20Sopenharmony_ci u32 base, size; 7338c2ecf20Sopenharmony_ci int ret; 7348c2ecf20Sopenharmony_ci 7358c2ecf20Sopenharmony_ci /* DSP DMA can only access low 31 bits of host memory */ 7368c2ecf20Sopenharmony_ci ret = dma_coerce_mask_and_coherent(sdev->dev, DMA_BIT_MASK(31)); 7378c2ecf20Sopenharmony_ci if (ret < 0) { 7388c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: failed to set DMA mask %d\n", ret); 7398c2ecf20Sopenharmony_ci return ret; 7408c2ecf20Sopenharmony_ci } 7418c2ecf20Sopenharmony_ci 7428c2ecf20Sopenharmony_ci /* LPE base */ 7438c2ecf20Sopenharmony_ci mmio = platform_get_resource(pdev, IORESOURCE_MEM, 7448c2ecf20Sopenharmony_ci desc->resindex_lpe_base); 7458c2ecf20Sopenharmony_ci if (mmio) { 7468c2ecf20Sopenharmony_ci base = mmio->start; 7478c2ecf20Sopenharmony_ci size = resource_size(mmio); 7488c2ecf20Sopenharmony_ci } else { 7498c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: failed to get LPE base at idx %d\n", 7508c2ecf20Sopenharmony_ci desc->resindex_lpe_base); 7518c2ecf20Sopenharmony_ci return -EINVAL; 7528c2ecf20Sopenharmony_ci } 7538c2ecf20Sopenharmony_ci 7548c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, "LPE PHY base at 0x%x size 0x%x", base, size); 7558c2ecf20Sopenharmony_ci sdev->bar[BYT_DSP_BAR] = devm_ioremap(sdev->dev, base, size); 7568c2ecf20Sopenharmony_ci if (!sdev->bar[BYT_DSP_BAR]) { 7578c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: failed to ioremap LPE base 0x%x size 0x%x\n", 7588c2ecf20Sopenharmony_ci base, size); 7598c2ecf20Sopenharmony_ci return -ENODEV; 7608c2ecf20Sopenharmony_ci } 7618c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, "LPE VADDR %p\n", sdev->bar[BYT_DSP_BAR]); 7628c2ecf20Sopenharmony_ci 7638c2ecf20Sopenharmony_ci /* TODO: add offsets */ 7648c2ecf20Sopenharmony_ci sdev->mmio_bar = BYT_DSP_BAR; 7658c2ecf20Sopenharmony_ci sdev->mailbox_bar = BYT_DSP_BAR; 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ci /* IMR base - optional */ 7688c2ecf20Sopenharmony_ci if (desc->resindex_imr_base == -1) 7698c2ecf20Sopenharmony_ci goto irq; 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_ci mmio = platform_get_resource(pdev, IORESOURCE_MEM, 7728c2ecf20Sopenharmony_ci desc->resindex_imr_base); 7738c2ecf20Sopenharmony_ci if (mmio) { 7748c2ecf20Sopenharmony_ci base = mmio->start; 7758c2ecf20Sopenharmony_ci size = resource_size(mmio); 7768c2ecf20Sopenharmony_ci } else { 7778c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: failed to get IMR base at idx %d\n", 7788c2ecf20Sopenharmony_ci desc->resindex_imr_base); 7798c2ecf20Sopenharmony_ci return -ENODEV; 7808c2ecf20Sopenharmony_ci } 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_ci /* some BIOSes don't map IMR */ 7838c2ecf20Sopenharmony_ci if (base == 0x55aa55aa || base == 0x0) { 7848c2ecf20Sopenharmony_ci dev_info(sdev->dev, "IMR not set by BIOS. Ignoring\n"); 7858c2ecf20Sopenharmony_ci goto irq; 7868c2ecf20Sopenharmony_ci } 7878c2ecf20Sopenharmony_ci 7888c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, "IMR base at 0x%x size 0x%x", base, size); 7898c2ecf20Sopenharmony_ci sdev->bar[BYT_IMR_BAR] = devm_ioremap(sdev->dev, base, size); 7908c2ecf20Sopenharmony_ci if (!sdev->bar[BYT_IMR_BAR]) { 7918c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: failed to ioremap IMR base 0x%x size 0x%x\n", 7928c2ecf20Sopenharmony_ci base, size); 7938c2ecf20Sopenharmony_ci return -ENODEV; 7948c2ecf20Sopenharmony_ci } 7958c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, "IMR VADDR %p\n", sdev->bar[BYT_IMR_BAR]); 7968c2ecf20Sopenharmony_ci 7978c2ecf20Sopenharmony_ciirq: 7988c2ecf20Sopenharmony_ci /* register our IRQ */ 7998c2ecf20Sopenharmony_ci sdev->ipc_irq = platform_get_irq(pdev, desc->irqindex_host_ipc); 8008c2ecf20Sopenharmony_ci if (sdev->ipc_irq < 0) 8018c2ecf20Sopenharmony_ci return sdev->ipc_irq; 8028c2ecf20Sopenharmony_ci 8038c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, "using IRQ %d\n", sdev->ipc_irq); 8048c2ecf20Sopenharmony_ci ret = devm_request_threaded_irq(sdev->dev, sdev->ipc_irq, 8058c2ecf20Sopenharmony_ci byt_irq_handler, byt_irq_thread, 8068c2ecf20Sopenharmony_ci IRQF_SHARED, "AudioDSP", sdev); 8078c2ecf20Sopenharmony_ci if (ret < 0) { 8088c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: failed to register IRQ %d\n", 8098c2ecf20Sopenharmony_ci sdev->ipc_irq); 8108c2ecf20Sopenharmony_ci return ret; 8118c2ecf20Sopenharmony_ci } 8128c2ecf20Sopenharmony_ci 8138c2ecf20Sopenharmony_ci /* enable BUSY and disable DONE Interrupt by default */ 8148c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits64(sdev, BYT_DSP_BAR, SHIM_IMRX, 8158c2ecf20Sopenharmony_ci SHIM_IMRX_BUSY | SHIM_IMRX_DONE, 8168c2ecf20Sopenharmony_ci SHIM_IMRX_DONE); 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_ci /* set default mailbox offset for FW ready message */ 8198c2ecf20Sopenharmony_ci sdev->dsp_box.offset = MBOX_OFFSET; 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_ci return ret; 8228c2ecf20Sopenharmony_ci} 8238c2ecf20Sopenharmony_ci 8248c2ecf20Sopenharmony_ci/* baytrail ops */ 8258c2ecf20Sopenharmony_ciconst struct snd_sof_dsp_ops sof_byt_ops = { 8268c2ecf20Sopenharmony_ci /* device init */ 8278c2ecf20Sopenharmony_ci .probe = byt_acpi_probe, 8288c2ecf20Sopenharmony_ci .remove = byt_remove, 8298c2ecf20Sopenharmony_ci 8308c2ecf20Sopenharmony_ci /* DSP core boot / reset */ 8318c2ecf20Sopenharmony_ci .run = byt_run, 8328c2ecf20Sopenharmony_ci .reset = byt_reset, 8338c2ecf20Sopenharmony_ci 8348c2ecf20Sopenharmony_ci /* Register IO */ 8358c2ecf20Sopenharmony_ci .write = sof_io_write, 8368c2ecf20Sopenharmony_ci .read = sof_io_read, 8378c2ecf20Sopenharmony_ci .write64 = sof_io_write64, 8388c2ecf20Sopenharmony_ci .read64 = sof_io_read64, 8398c2ecf20Sopenharmony_ci 8408c2ecf20Sopenharmony_ci /* Block IO */ 8418c2ecf20Sopenharmony_ci .block_read = sof_block_read, 8428c2ecf20Sopenharmony_ci .block_write = sof_block_write, 8438c2ecf20Sopenharmony_ci 8448c2ecf20Sopenharmony_ci /* doorbell */ 8458c2ecf20Sopenharmony_ci .irq_handler = byt_irq_handler, 8468c2ecf20Sopenharmony_ci .irq_thread = byt_irq_thread, 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ci /* ipc */ 8498c2ecf20Sopenharmony_ci .send_msg = byt_send_msg, 8508c2ecf20Sopenharmony_ci .fw_ready = sof_fw_ready, 8518c2ecf20Sopenharmony_ci .get_mailbox_offset = byt_get_mailbox_offset, 8528c2ecf20Sopenharmony_ci .get_window_offset = byt_get_window_offset, 8538c2ecf20Sopenharmony_ci 8548c2ecf20Sopenharmony_ci .ipc_msg_data = intel_ipc_msg_data, 8558c2ecf20Sopenharmony_ci .ipc_pcm_params = intel_ipc_pcm_params, 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_ci /* machine driver */ 8588c2ecf20Sopenharmony_ci .machine_select = byt_machine_select, 8598c2ecf20Sopenharmony_ci .machine_register = sof_machine_register, 8608c2ecf20Sopenharmony_ci .machine_unregister = sof_machine_unregister, 8618c2ecf20Sopenharmony_ci .set_mach_params = byt_set_mach_params, 8628c2ecf20Sopenharmony_ci 8638c2ecf20Sopenharmony_ci /* debug */ 8648c2ecf20Sopenharmony_ci .debug_map = byt_debugfs, 8658c2ecf20Sopenharmony_ci .debug_map_count = ARRAY_SIZE(byt_debugfs), 8668c2ecf20Sopenharmony_ci .dbg_dump = byt_dump, 8678c2ecf20Sopenharmony_ci 8688c2ecf20Sopenharmony_ci /* stream callbacks */ 8698c2ecf20Sopenharmony_ci .pcm_open = intel_pcm_open, 8708c2ecf20Sopenharmony_ci .pcm_close = intel_pcm_close, 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_ci /* module loading */ 8738c2ecf20Sopenharmony_ci .load_module = snd_sof_parse_module_memcpy, 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_ci /*Firmware loading */ 8768c2ecf20Sopenharmony_ci .load_firmware = snd_sof_load_firmware_memcpy, 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_ci /* PM */ 8798c2ecf20Sopenharmony_ci .suspend = byt_suspend, 8808c2ecf20Sopenharmony_ci .resume = byt_resume, 8818c2ecf20Sopenharmony_ci 8828c2ecf20Sopenharmony_ci /* DAI drivers */ 8838c2ecf20Sopenharmony_ci .drv = byt_dai, 8848c2ecf20Sopenharmony_ci .num_drv = 3, /* we have only 3 SSPs on byt*/ 8858c2ecf20Sopenharmony_ci 8868c2ecf20Sopenharmony_ci /* ALSA HW info flags */ 8878c2ecf20Sopenharmony_ci .hw_info = SNDRV_PCM_INFO_MMAP | 8888c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_MMAP_VALID | 8898c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_INTERLEAVED | 8908c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_PAUSE | 8918c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_BATCH, 8928c2ecf20Sopenharmony_ci 8938c2ecf20Sopenharmony_ci .arch_ops = &sof_xtensa_arch_ops, 8948c2ecf20Sopenharmony_ci}; 8958c2ecf20Sopenharmony_ciEXPORT_SYMBOL_NS(sof_byt_ops, SND_SOC_SOF_BAYTRAIL); 8968c2ecf20Sopenharmony_ci 8978c2ecf20Sopenharmony_ciconst struct sof_intel_dsp_desc byt_chip_info = { 8988c2ecf20Sopenharmony_ci .cores_num = 1, 8998c2ecf20Sopenharmony_ci .host_managed_cores_mask = 1, 9008c2ecf20Sopenharmony_ci}; 9018c2ecf20Sopenharmony_ciEXPORT_SYMBOL_NS(byt_chip_info, SND_SOC_SOF_BAYTRAIL); 9028c2ecf20Sopenharmony_ci 9038c2ecf20Sopenharmony_ci/* cherrytrail and braswell ops */ 9048c2ecf20Sopenharmony_ciconst struct snd_sof_dsp_ops sof_cht_ops = { 9058c2ecf20Sopenharmony_ci /* device init */ 9068c2ecf20Sopenharmony_ci .probe = byt_acpi_probe, 9078c2ecf20Sopenharmony_ci .remove = byt_remove, 9088c2ecf20Sopenharmony_ci 9098c2ecf20Sopenharmony_ci /* DSP core boot / reset */ 9108c2ecf20Sopenharmony_ci .run = byt_run, 9118c2ecf20Sopenharmony_ci .reset = byt_reset, 9128c2ecf20Sopenharmony_ci 9138c2ecf20Sopenharmony_ci /* Register IO */ 9148c2ecf20Sopenharmony_ci .write = sof_io_write, 9158c2ecf20Sopenharmony_ci .read = sof_io_read, 9168c2ecf20Sopenharmony_ci .write64 = sof_io_write64, 9178c2ecf20Sopenharmony_ci .read64 = sof_io_read64, 9188c2ecf20Sopenharmony_ci 9198c2ecf20Sopenharmony_ci /* Block IO */ 9208c2ecf20Sopenharmony_ci .block_read = sof_block_read, 9218c2ecf20Sopenharmony_ci .block_write = sof_block_write, 9228c2ecf20Sopenharmony_ci 9238c2ecf20Sopenharmony_ci /* doorbell */ 9248c2ecf20Sopenharmony_ci .irq_handler = byt_irq_handler, 9258c2ecf20Sopenharmony_ci .irq_thread = byt_irq_thread, 9268c2ecf20Sopenharmony_ci 9278c2ecf20Sopenharmony_ci /* ipc */ 9288c2ecf20Sopenharmony_ci .send_msg = byt_send_msg, 9298c2ecf20Sopenharmony_ci .fw_ready = sof_fw_ready, 9308c2ecf20Sopenharmony_ci .get_mailbox_offset = byt_get_mailbox_offset, 9318c2ecf20Sopenharmony_ci .get_window_offset = byt_get_window_offset, 9328c2ecf20Sopenharmony_ci 9338c2ecf20Sopenharmony_ci .ipc_msg_data = intel_ipc_msg_data, 9348c2ecf20Sopenharmony_ci .ipc_pcm_params = intel_ipc_pcm_params, 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ci /* machine driver */ 9378c2ecf20Sopenharmony_ci .machine_select = byt_machine_select, 9388c2ecf20Sopenharmony_ci .machine_register = sof_machine_register, 9398c2ecf20Sopenharmony_ci .machine_unregister = sof_machine_unregister, 9408c2ecf20Sopenharmony_ci .set_mach_params = byt_set_mach_params, 9418c2ecf20Sopenharmony_ci 9428c2ecf20Sopenharmony_ci /* debug */ 9438c2ecf20Sopenharmony_ci .debug_map = cht_debugfs, 9448c2ecf20Sopenharmony_ci .debug_map_count = ARRAY_SIZE(cht_debugfs), 9458c2ecf20Sopenharmony_ci .dbg_dump = byt_dump, 9468c2ecf20Sopenharmony_ci 9478c2ecf20Sopenharmony_ci /* stream callbacks */ 9488c2ecf20Sopenharmony_ci .pcm_open = intel_pcm_open, 9498c2ecf20Sopenharmony_ci .pcm_close = intel_pcm_close, 9508c2ecf20Sopenharmony_ci 9518c2ecf20Sopenharmony_ci /* module loading */ 9528c2ecf20Sopenharmony_ci .load_module = snd_sof_parse_module_memcpy, 9538c2ecf20Sopenharmony_ci 9548c2ecf20Sopenharmony_ci /*Firmware loading */ 9558c2ecf20Sopenharmony_ci .load_firmware = snd_sof_load_firmware_memcpy, 9568c2ecf20Sopenharmony_ci 9578c2ecf20Sopenharmony_ci /* PM */ 9588c2ecf20Sopenharmony_ci .suspend = byt_suspend, 9598c2ecf20Sopenharmony_ci .resume = byt_resume, 9608c2ecf20Sopenharmony_ci 9618c2ecf20Sopenharmony_ci /* DAI drivers */ 9628c2ecf20Sopenharmony_ci .drv = byt_dai, 9638c2ecf20Sopenharmony_ci /* all 6 SSPs may be available for cherrytrail */ 9648c2ecf20Sopenharmony_ci .num_drv = ARRAY_SIZE(byt_dai), 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_ci /* ALSA HW info flags */ 9678c2ecf20Sopenharmony_ci .hw_info = SNDRV_PCM_INFO_MMAP | 9688c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_MMAP_VALID | 9698c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_INTERLEAVED | 9708c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_PAUSE | 9718c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_BATCH, 9728c2ecf20Sopenharmony_ci 9738c2ecf20Sopenharmony_ci .arch_ops = &sof_xtensa_arch_ops, 9748c2ecf20Sopenharmony_ci}; 9758c2ecf20Sopenharmony_ciEXPORT_SYMBOL_NS(sof_cht_ops, SND_SOC_SOF_BAYTRAIL); 9768c2ecf20Sopenharmony_ci 9778c2ecf20Sopenharmony_ciconst struct sof_intel_dsp_desc cht_chip_info = { 9788c2ecf20Sopenharmony_ci .cores_num = 1, 9798c2ecf20Sopenharmony_ci .host_managed_cores_mask = 1, 9808c2ecf20Sopenharmony_ci}; 9818c2ecf20Sopenharmony_ciEXPORT_SYMBOL_NS(cht_chip_info, SND_SOC_SOF_BAYTRAIL); 9828c2ecf20Sopenharmony_ci 9838c2ecf20Sopenharmony_ci#endif /* CONFIG_SND_SOC_SOF_BAYTRAIL */ 9848c2ecf20Sopenharmony_ci 9858c2ecf20Sopenharmony_ciMODULE_LICENSE("Dual BSD/GPL"); 9868c2ecf20Sopenharmony_ciMODULE_IMPORT_NS(SND_SOC_SOF_INTEL_HIFI_EP_IPC); 9878c2ecf20Sopenharmony_ciMODULE_IMPORT_NS(SND_SOC_SOF_XTENSA); 988