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// Authors: Liam Girdwood <liam.r.girdwood@linux.intel.com> 98c2ecf20Sopenharmony_ci// Ranjani Sridharan <ranjani.sridharan@linux.intel.com> 108c2ecf20Sopenharmony_ci// Rander Wang <rander.wang@intel.com> 118c2ecf20Sopenharmony_ci// Keyon Jie <yang.jie@linux.intel.com> 128c2ecf20Sopenharmony_ci// 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci/* 158c2ecf20Sopenharmony_ci * Hardware interface for audio DSP on Cannonlake. 168c2ecf20Sopenharmony_ci */ 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#include "../ops.h" 198c2ecf20Sopenharmony_ci#include "hda.h" 208c2ecf20Sopenharmony_ci#include "hda-ipc.h" 218c2ecf20Sopenharmony_ci#include "../sof-audio.h" 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistatic const struct snd_sof_debugfs_map cnl_dsp_debugfs[] = { 248c2ecf20Sopenharmony_ci {"hda", HDA_DSP_HDA_BAR, 0, 0x4000, SOF_DEBUGFS_ACCESS_ALWAYS}, 258c2ecf20Sopenharmony_ci {"pp", HDA_DSP_PP_BAR, 0, 0x1000, SOF_DEBUGFS_ACCESS_ALWAYS}, 268c2ecf20Sopenharmony_ci {"dsp", HDA_DSP_BAR, 0, 0x10000, SOF_DEBUGFS_ACCESS_ALWAYS}, 278c2ecf20Sopenharmony_ci}; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_cistatic void cnl_ipc_host_done(struct snd_sof_dev *sdev); 308c2ecf20Sopenharmony_cistatic void cnl_ipc_dsp_done(struct snd_sof_dev *sdev); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ciirqreturn_t cnl_ipc_irq_thread(int irq, void *context) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci struct snd_sof_dev *sdev = context; 358c2ecf20Sopenharmony_ci u32 hipci; 368c2ecf20Sopenharmony_ci u32 hipcida; 378c2ecf20Sopenharmony_ci u32 hipctdr; 388c2ecf20Sopenharmony_ci u32 hipctdd; 398c2ecf20Sopenharmony_ci u32 msg; 408c2ecf20Sopenharmony_ci u32 msg_ext; 418c2ecf20Sopenharmony_ci bool ipc_irq = false; 428c2ecf20Sopenharmony_ci 438c2ecf20Sopenharmony_ci hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDA); 448c2ecf20Sopenharmony_ci hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDR); 458c2ecf20Sopenharmony_ci hipctdd = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDD); 468c2ecf20Sopenharmony_ci hipci = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci /* reply message from DSP */ 498c2ecf20Sopenharmony_ci if (hipcida & CNL_DSP_REG_HIPCIDA_DONE) { 508c2ecf20Sopenharmony_ci msg_ext = hipci & CNL_DSP_REG_HIPCIDR_MSG_MASK; 518c2ecf20Sopenharmony_ci msg = hipcida & CNL_DSP_REG_HIPCIDA_MSG_MASK; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci dev_vdbg(sdev->dev, 548c2ecf20Sopenharmony_ci "ipc: firmware response, msg:0x%x, msg_ext:0x%x\n", 558c2ecf20Sopenharmony_ci msg, msg_ext); 568c2ecf20Sopenharmony_ci 578c2ecf20Sopenharmony_ci /* mask Done interrupt */ 588c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, 598c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCCTL, 608c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCCTL_DONE, 0); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci spin_lock_irq(&sdev->ipc_lock); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci /* handle immediate reply from DSP core */ 658c2ecf20Sopenharmony_ci hda_dsp_ipc_get_reply(sdev); 668c2ecf20Sopenharmony_ci snd_sof_ipc_reply(sdev, msg); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci cnl_ipc_dsp_done(sdev); 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_ci spin_unlock_irq(&sdev->ipc_lock); 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci ipc_irq = true; 738c2ecf20Sopenharmony_ci } 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci /* new message from DSP */ 768c2ecf20Sopenharmony_ci if (hipctdr & CNL_DSP_REG_HIPCTDR_BUSY) { 778c2ecf20Sopenharmony_ci msg = hipctdr & CNL_DSP_REG_HIPCTDR_MSG_MASK; 788c2ecf20Sopenharmony_ci msg_ext = hipctdd & CNL_DSP_REG_HIPCTDD_MSG_MASK; 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci dev_vdbg(sdev->dev, 818c2ecf20Sopenharmony_ci "ipc: firmware initiated, msg:0x%x, msg_ext:0x%x\n", 828c2ecf20Sopenharmony_ci msg, msg_ext); 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci /* handle messages from DSP */ 858c2ecf20Sopenharmony_ci if ((hipctdr & SOF_IPC_PANIC_MAGIC_MASK) == 868c2ecf20Sopenharmony_ci SOF_IPC_PANIC_MAGIC) { 878c2ecf20Sopenharmony_ci snd_sof_dsp_panic(sdev, HDA_DSP_PANIC_OFFSET(msg_ext)); 888c2ecf20Sopenharmony_ci } else { 898c2ecf20Sopenharmony_ci snd_sof_ipc_msgs_rx(sdev); 908c2ecf20Sopenharmony_ci } 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci cnl_ipc_host_done(sdev); 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_ci ipc_irq = true; 958c2ecf20Sopenharmony_ci } 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci if (!ipc_irq) { 988c2ecf20Sopenharmony_ci /* 998c2ecf20Sopenharmony_ci * This interrupt is not shared so no need to return IRQ_NONE. 1008c2ecf20Sopenharmony_ci */ 1018c2ecf20Sopenharmony_ci dev_dbg_ratelimited(sdev->dev, 1028c2ecf20Sopenharmony_ci "nothing to do in IPC IRQ thread\n"); 1038c2ecf20Sopenharmony_ci } 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci return IRQ_HANDLED; 1068c2ecf20Sopenharmony_ci} 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_cistatic void cnl_ipc_host_done(struct snd_sof_dev *sdev) 1098c2ecf20Sopenharmony_ci{ 1108c2ecf20Sopenharmony_ci /* 1118c2ecf20Sopenharmony_ci * clear busy interrupt to tell dsp controller this 1128c2ecf20Sopenharmony_ci * interrupt has been accepted, not trigger it again 1138c2ecf20Sopenharmony_ci */ 1148c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, 1158c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCTDR, 1168c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCTDR_BUSY, 1178c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCTDR_BUSY); 1188c2ecf20Sopenharmony_ci /* 1198c2ecf20Sopenharmony_ci * set done bit to ack dsp the msg has been 1208c2ecf20Sopenharmony_ci * processed and send reply msg to dsp 1218c2ecf20Sopenharmony_ci */ 1228c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, 1238c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCTDA, 1248c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCTDA_DONE, 1258c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCTDA_DONE); 1268c2ecf20Sopenharmony_ci} 1278c2ecf20Sopenharmony_ci 1288c2ecf20Sopenharmony_cistatic void cnl_ipc_dsp_done(struct snd_sof_dev *sdev) 1298c2ecf20Sopenharmony_ci{ 1308c2ecf20Sopenharmony_ci /* 1318c2ecf20Sopenharmony_ci * set DONE bit - tell DSP we have received the reply msg 1328c2ecf20Sopenharmony_ci * from DSP, and processed it, don't send more reply to host 1338c2ecf20Sopenharmony_ci */ 1348c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits_forced(sdev, HDA_DSP_BAR, 1358c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCIDA, 1368c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCIDA_DONE, 1378c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCIDA_DONE); 1388c2ecf20Sopenharmony_ci 1398c2ecf20Sopenharmony_ci /* unmask Done interrupt */ 1408c2ecf20Sopenharmony_ci snd_sof_dsp_update_bits(sdev, HDA_DSP_BAR, 1418c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCCTL, 1428c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCCTL_DONE, 1438c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCCTL_DONE); 1448c2ecf20Sopenharmony_ci} 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cistatic bool cnl_compact_ipc_compress(struct snd_sof_ipc_msg *msg, 1478c2ecf20Sopenharmony_ci u32 *dr, u32 *dd) 1488c2ecf20Sopenharmony_ci{ 1498c2ecf20Sopenharmony_ci struct sof_ipc_pm_gate *pm_gate; 1508c2ecf20Sopenharmony_ci 1518c2ecf20Sopenharmony_ci if (msg->header == (SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_GATE)) { 1528c2ecf20Sopenharmony_ci pm_gate = msg->msg_data; 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci /* send the compact message via the primary register */ 1558c2ecf20Sopenharmony_ci *dr = HDA_IPC_MSG_COMPACT | HDA_IPC_PM_GATE; 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci /* send payload via the extended data register */ 1588c2ecf20Sopenharmony_ci *dd = pm_gate->flags; 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_ci return true; 1618c2ecf20Sopenharmony_ci } 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci return false; 1648c2ecf20Sopenharmony_ci} 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ciint cnl_ipc_send_msg(struct snd_sof_dev *sdev, struct snd_sof_ipc_msg *msg) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci struct sof_intel_hda_dev *hdev = sdev->pdata->hw_pdata; 1698c2ecf20Sopenharmony_ci struct sof_ipc_cmd_hdr *hdr; 1708c2ecf20Sopenharmony_ci u32 dr = 0; 1718c2ecf20Sopenharmony_ci u32 dd = 0; 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci /* 1748c2ecf20Sopenharmony_ci * Currently the only compact IPC supported is the PM_GATE 1758c2ecf20Sopenharmony_ci * IPC which is used for transitioning the DSP between the 1768c2ecf20Sopenharmony_ci * D0I0 and D0I3 states. And these are sent only during the 1778c2ecf20Sopenharmony_ci * set_power_state() op. Therefore, there will never be a case 1788c2ecf20Sopenharmony_ci * that a compact IPC results in the DSP exiting D0I3 without 1798c2ecf20Sopenharmony_ci * the host and FW being in sync. 1808c2ecf20Sopenharmony_ci */ 1818c2ecf20Sopenharmony_ci if (cnl_compact_ipc_compress(msg, &dr, &dd)) { 1828c2ecf20Sopenharmony_ci /* send the message via IPC registers */ 1838c2ecf20Sopenharmony_ci snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDD, 1848c2ecf20Sopenharmony_ci dd); 1858c2ecf20Sopenharmony_ci snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR, 1868c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCIDR_BUSY | dr); 1878c2ecf20Sopenharmony_ci return 0; 1888c2ecf20Sopenharmony_ci } 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci /* send the message via mailbox */ 1918c2ecf20Sopenharmony_ci sof_mailbox_write(sdev, sdev->host_box.offset, msg->msg_data, 1928c2ecf20Sopenharmony_ci msg->msg_size); 1938c2ecf20Sopenharmony_ci snd_sof_dsp_write(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDR, 1948c2ecf20Sopenharmony_ci CNL_DSP_REG_HIPCIDR_BUSY); 1958c2ecf20Sopenharmony_ci 1968c2ecf20Sopenharmony_ci hdr = msg->msg_data; 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci /* 1998c2ecf20Sopenharmony_ci * Use mod_delayed_work() to schedule the delayed work 2008c2ecf20Sopenharmony_ci * to avoid scheduling multiple workqueue items when 2018c2ecf20Sopenharmony_ci * IPCs are sent at a high-rate. mod_delayed_work() 2028c2ecf20Sopenharmony_ci * modifies the timer if the work is pending. 2038c2ecf20Sopenharmony_ci * Also, a new delayed work should not be queued after the 2048c2ecf20Sopenharmony_ci * CTX_SAVE IPC, which is sent before the DSP enters D3. 2058c2ecf20Sopenharmony_ci */ 2068c2ecf20Sopenharmony_ci if (hdr->cmd != (SOF_IPC_GLB_PM_MSG | SOF_IPC_PM_CTX_SAVE)) 2078c2ecf20Sopenharmony_ci mod_delayed_work(system_wq, &hdev->d0i3_work, 2088c2ecf20Sopenharmony_ci msecs_to_jiffies(SOF_HDA_D0I3_WORK_DELAY_MS)); 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci return 0; 2118c2ecf20Sopenharmony_ci} 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_civoid cnl_ipc_dump(struct snd_sof_dev *sdev) 2148c2ecf20Sopenharmony_ci{ 2158c2ecf20Sopenharmony_ci u32 hipcctl; 2168c2ecf20Sopenharmony_ci u32 hipcida; 2178c2ecf20Sopenharmony_ci u32 hipctdr; 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_ci hda_ipc_irq_dump(sdev); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci /* read IPC status */ 2228c2ecf20Sopenharmony_ci hipcida = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCIDA); 2238c2ecf20Sopenharmony_ci hipcctl = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCCTL); 2248c2ecf20Sopenharmony_ci hipctdr = snd_sof_dsp_read(sdev, HDA_DSP_BAR, CNL_DSP_REG_HIPCTDR); 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci /* dump the IPC regs */ 2278c2ecf20Sopenharmony_ci /* TODO: parse the raw msg */ 2288c2ecf20Sopenharmony_ci dev_err(sdev->dev, 2298c2ecf20Sopenharmony_ci "error: host status 0x%8.8x dsp status 0x%8.8x mask 0x%8.8x\n", 2308c2ecf20Sopenharmony_ci hipcida, hipctdr, hipcctl); 2318c2ecf20Sopenharmony_ci} 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci/* cannonlake ops */ 2348c2ecf20Sopenharmony_ciconst struct snd_sof_dsp_ops sof_cnl_ops = { 2358c2ecf20Sopenharmony_ci /* probe and remove */ 2368c2ecf20Sopenharmony_ci .probe = hda_dsp_probe, 2378c2ecf20Sopenharmony_ci .remove = hda_dsp_remove, 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci /* Register IO */ 2408c2ecf20Sopenharmony_ci .write = sof_io_write, 2418c2ecf20Sopenharmony_ci .read = sof_io_read, 2428c2ecf20Sopenharmony_ci .write64 = sof_io_write64, 2438c2ecf20Sopenharmony_ci .read64 = sof_io_read64, 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci /* Block IO */ 2468c2ecf20Sopenharmony_ci .block_read = sof_block_read, 2478c2ecf20Sopenharmony_ci .block_write = sof_block_write, 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci /* doorbell */ 2508c2ecf20Sopenharmony_ci .irq_thread = cnl_ipc_irq_thread, 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_ci /* ipc */ 2538c2ecf20Sopenharmony_ci .send_msg = cnl_ipc_send_msg, 2548c2ecf20Sopenharmony_ci .fw_ready = sof_fw_ready, 2558c2ecf20Sopenharmony_ci .get_mailbox_offset = hda_dsp_ipc_get_mailbox_offset, 2568c2ecf20Sopenharmony_ci .get_window_offset = hda_dsp_ipc_get_window_offset, 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci .ipc_msg_data = hda_ipc_msg_data, 2598c2ecf20Sopenharmony_ci .ipc_pcm_params = hda_ipc_pcm_params, 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci /* machine driver */ 2628c2ecf20Sopenharmony_ci .machine_select = hda_machine_select, 2638c2ecf20Sopenharmony_ci .machine_register = sof_machine_register, 2648c2ecf20Sopenharmony_ci .machine_unregister = sof_machine_unregister, 2658c2ecf20Sopenharmony_ci .set_mach_params = hda_set_mach_params, 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci /* debug */ 2688c2ecf20Sopenharmony_ci .debug_map = cnl_dsp_debugfs, 2698c2ecf20Sopenharmony_ci .debug_map_count = ARRAY_SIZE(cnl_dsp_debugfs), 2708c2ecf20Sopenharmony_ci .dbg_dump = hda_dsp_dump, 2718c2ecf20Sopenharmony_ci .ipc_dump = cnl_ipc_dump, 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci /* stream callbacks */ 2748c2ecf20Sopenharmony_ci .pcm_open = hda_dsp_pcm_open, 2758c2ecf20Sopenharmony_ci .pcm_close = hda_dsp_pcm_close, 2768c2ecf20Sopenharmony_ci .pcm_hw_params = hda_dsp_pcm_hw_params, 2778c2ecf20Sopenharmony_ci .pcm_hw_free = hda_dsp_stream_hw_free, 2788c2ecf20Sopenharmony_ci .pcm_trigger = hda_dsp_pcm_trigger, 2798c2ecf20Sopenharmony_ci .pcm_pointer = hda_dsp_pcm_pointer, 2808c2ecf20Sopenharmony_ci 2818c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_PROBES) 2828c2ecf20Sopenharmony_ci /* probe callbacks */ 2838c2ecf20Sopenharmony_ci .probe_assign = hda_probe_compr_assign, 2848c2ecf20Sopenharmony_ci .probe_free = hda_probe_compr_free, 2858c2ecf20Sopenharmony_ci .probe_set_params = hda_probe_compr_set_params, 2868c2ecf20Sopenharmony_ci .probe_trigger = hda_probe_compr_trigger, 2878c2ecf20Sopenharmony_ci .probe_pointer = hda_probe_compr_pointer, 2888c2ecf20Sopenharmony_ci#endif 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci /* firmware loading */ 2918c2ecf20Sopenharmony_ci .load_firmware = snd_sof_load_firmware_raw, 2928c2ecf20Sopenharmony_ci 2938c2ecf20Sopenharmony_ci /* pre/post fw run */ 2948c2ecf20Sopenharmony_ci .pre_fw_run = hda_dsp_pre_fw_run, 2958c2ecf20Sopenharmony_ci .post_fw_run = hda_dsp_post_fw_run, 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci /* dsp core power up/down */ 2988c2ecf20Sopenharmony_ci .core_power_up = hda_dsp_enable_core, 2998c2ecf20Sopenharmony_ci .core_power_down = hda_dsp_core_reset_power_down, 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci /* firmware run */ 3028c2ecf20Sopenharmony_ci .run = hda_dsp_cl_boot_firmware, 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci /* trace callback */ 3058c2ecf20Sopenharmony_ci .trace_init = hda_dsp_trace_init, 3068c2ecf20Sopenharmony_ci .trace_release = hda_dsp_trace_release, 3078c2ecf20Sopenharmony_ci .trace_trigger = hda_dsp_trace_trigger, 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci /* DAI drivers */ 3108c2ecf20Sopenharmony_ci .drv = skl_dai, 3118c2ecf20Sopenharmony_ci .num_drv = SOF_SKL_NUM_DAIS, 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci /* PM */ 3148c2ecf20Sopenharmony_ci .suspend = hda_dsp_suspend, 3158c2ecf20Sopenharmony_ci .resume = hda_dsp_resume, 3168c2ecf20Sopenharmony_ci .runtime_suspend = hda_dsp_runtime_suspend, 3178c2ecf20Sopenharmony_ci .runtime_resume = hda_dsp_runtime_resume, 3188c2ecf20Sopenharmony_ci .runtime_idle = hda_dsp_runtime_idle, 3198c2ecf20Sopenharmony_ci .set_hw_params_upon_resume = hda_dsp_set_hw_params_upon_resume, 3208c2ecf20Sopenharmony_ci .set_power_state = hda_dsp_set_power_state, 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci /* ALSA HW info flags */ 3238c2ecf20Sopenharmony_ci .hw_info = SNDRV_PCM_INFO_MMAP | 3248c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_MMAP_VALID | 3258c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_INTERLEAVED | 3268c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_PAUSE | 3278c2ecf20Sopenharmony_ci SNDRV_PCM_INFO_NO_PERIOD_WAKEUP, 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci .arch_ops = &sof_xtensa_arch_ops, 3308c2ecf20Sopenharmony_ci}; 3318c2ecf20Sopenharmony_ciEXPORT_SYMBOL_NS(sof_cnl_ops, SND_SOC_SOF_INTEL_HDA_COMMON); 3328c2ecf20Sopenharmony_ci 3338c2ecf20Sopenharmony_ciconst struct sof_intel_dsp_desc cnl_chip_info = { 3348c2ecf20Sopenharmony_ci /* Cannonlake */ 3358c2ecf20Sopenharmony_ci .cores_num = 4, 3368c2ecf20Sopenharmony_ci .init_core_mask = 1, 3378c2ecf20Sopenharmony_ci .host_managed_cores_mask = GENMASK(3, 0), 3388c2ecf20Sopenharmony_ci .ipc_req = CNL_DSP_REG_HIPCIDR, 3398c2ecf20Sopenharmony_ci .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY, 3408c2ecf20Sopenharmony_ci .ipc_ack = CNL_DSP_REG_HIPCIDA, 3418c2ecf20Sopenharmony_ci .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE, 3428c2ecf20Sopenharmony_ci .ipc_ctl = CNL_DSP_REG_HIPCCTL, 3438c2ecf20Sopenharmony_ci .rom_init_timeout = 300, 3448c2ecf20Sopenharmony_ci .ssp_count = CNL_SSP_COUNT, 3458c2ecf20Sopenharmony_ci .ssp_base_offset = CNL_SSP_BASE_OFFSET, 3468c2ecf20Sopenharmony_ci}; 3478c2ecf20Sopenharmony_ciEXPORT_SYMBOL_NS(cnl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); 3488c2ecf20Sopenharmony_ci 3498c2ecf20Sopenharmony_ciconst struct sof_intel_dsp_desc icl_chip_info = { 3508c2ecf20Sopenharmony_ci /* Icelake */ 3518c2ecf20Sopenharmony_ci .cores_num = 4, 3528c2ecf20Sopenharmony_ci .init_core_mask = 1, 3538c2ecf20Sopenharmony_ci .host_managed_cores_mask = GENMASK(3, 0), 3548c2ecf20Sopenharmony_ci .ipc_req = CNL_DSP_REG_HIPCIDR, 3558c2ecf20Sopenharmony_ci .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY, 3568c2ecf20Sopenharmony_ci .ipc_ack = CNL_DSP_REG_HIPCIDA, 3578c2ecf20Sopenharmony_ci .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE, 3588c2ecf20Sopenharmony_ci .ipc_ctl = CNL_DSP_REG_HIPCCTL, 3598c2ecf20Sopenharmony_ci .rom_init_timeout = 300, 3608c2ecf20Sopenharmony_ci .ssp_count = ICL_SSP_COUNT, 3618c2ecf20Sopenharmony_ci .ssp_base_offset = CNL_SSP_BASE_OFFSET, 3628c2ecf20Sopenharmony_ci}; 3638c2ecf20Sopenharmony_ciEXPORT_SYMBOL_NS(icl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ciconst struct sof_intel_dsp_desc ehl_chip_info = { 3668c2ecf20Sopenharmony_ci /* Elkhartlake */ 3678c2ecf20Sopenharmony_ci .cores_num = 4, 3688c2ecf20Sopenharmony_ci .init_core_mask = 1, 3698c2ecf20Sopenharmony_ci .host_managed_cores_mask = BIT(0), 3708c2ecf20Sopenharmony_ci .ipc_req = CNL_DSP_REG_HIPCIDR, 3718c2ecf20Sopenharmony_ci .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY, 3728c2ecf20Sopenharmony_ci .ipc_ack = CNL_DSP_REG_HIPCIDA, 3738c2ecf20Sopenharmony_ci .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE, 3748c2ecf20Sopenharmony_ci .ipc_ctl = CNL_DSP_REG_HIPCCTL, 3758c2ecf20Sopenharmony_ci .rom_init_timeout = 300, 3768c2ecf20Sopenharmony_ci .ssp_count = ICL_SSP_COUNT, 3778c2ecf20Sopenharmony_ci .ssp_base_offset = CNL_SSP_BASE_OFFSET, 3788c2ecf20Sopenharmony_ci}; 3798c2ecf20Sopenharmony_ciEXPORT_SYMBOL_NS(ehl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); 3808c2ecf20Sopenharmony_ci 3818c2ecf20Sopenharmony_ciconst struct sof_intel_dsp_desc jsl_chip_info = { 3828c2ecf20Sopenharmony_ci /* Jasperlake */ 3838c2ecf20Sopenharmony_ci .cores_num = 2, 3848c2ecf20Sopenharmony_ci .init_core_mask = 1, 3858c2ecf20Sopenharmony_ci .host_managed_cores_mask = GENMASK(1, 0), 3868c2ecf20Sopenharmony_ci .ipc_req = CNL_DSP_REG_HIPCIDR, 3878c2ecf20Sopenharmony_ci .ipc_req_mask = CNL_DSP_REG_HIPCIDR_BUSY, 3888c2ecf20Sopenharmony_ci .ipc_ack = CNL_DSP_REG_HIPCIDA, 3898c2ecf20Sopenharmony_ci .ipc_ack_mask = CNL_DSP_REG_HIPCIDA_DONE, 3908c2ecf20Sopenharmony_ci .ipc_ctl = CNL_DSP_REG_HIPCCTL, 3918c2ecf20Sopenharmony_ci .rom_init_timeout = 300, 3928c2ecf20Sopenharmony_ci .ssp_count = ICL_SSP_COUNT, 3938c2ecf20Sopenharmony_ci .ssp_base_offset = CNL_SSP_BASE_OFFSET, 3948c2ecf20Sopenharmony_ci}; 3958c2ecf20Sopenharmony_ciEXPORT_SYMBOL_NS(jsl_chip_info, SND_SOC_SOF_INTEL_HDA_COMMON); 396