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