18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Intel Code Loader DMA support
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (C) 2015, Intel Corporation.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef SKL_SST_CLDMA_H_
98c2ecf20Sopenharmony_ci#define SKL_SST_CLDMA_H_
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#define FW_CL_STREAM_NUMBER		0x1
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#define DMA_ADDRESS_128_BITS_ALIGNMENT	7
148c2ecf20Sopenharmony_ci#define BDL_ALIGN(x)			(x >> DMA_ADDRESS_128_BITS_ALIGNMENT)
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#define SKL_ADSPIC_CL_DMA			0x2
178c2ecf20Sopenharmony_ci#define SKL_ADSPIS_CL_DMA			0x2
188c2ecf20Sopenharmony_ci#define SKL_CL_DMA_SD_INT_DESC_ERR		0x10 /* Descriptor error interrupt */
198c2ecf20Sopenharmony_ci#define SKL_CL_DMA_SD_INT_FIFO_ERR		0x08 /* FIFO error interrupt */
208c2ecf20Sopenharmony_ci#define SKL_CL_DMA_SD_INT_COMPLETE		0x04 /* Buffer completion interrupt */
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci/* Intel HD Audio Code Loader DMA Registers */
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_ci#define HDA_ADSP_LOADER_BASE		0x80
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ci/* Stream Registers */
278c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_CTL			(HDA_ADSP_LOADER_BASE + 0x00)
288c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_STS			(HDA_ADSP_LOADER_BASE + 0x03)
298c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_LPIB			(HDA_ADSP_LOADER_BASE + 0x04)
308c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_CBL			(HDA_ADSP_LOADER_BASE + 0x08)
318c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_LVI			(HDA_ADSP_LOADER_BASE + 0x0c)
328c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_FIFOW		(HDA_ADSP_LOADER_BASE + 0x0e)
338c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_FIFOSIZE		(HDA_ADSP_LOADER_BASE + 0x10)
348c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_FORMAT		(HDA_ADSP_LOADER_BASE + 0x12)
358c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_FIFOL		(HDA_ADSP_LOADER_BASE + 0x14)
368c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_BDLPL		(HDA_ADSP_LOADER_BASE + 0x18)
378c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_BDLPU		(HDA_ADSP_LOADER_BASE + 0x1c)
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci/* CL: Software Position Based FIFO Capability Registers */
408c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SPBFIFO			(HDA_ADSP_LOADER_BASE + 0x20)
418c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SPBFIFO_SPBFCH		(SKL_ADSP_REG_CL_SPBFIFO + 0x0)
428c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SPBFIFO_SPBFCCTL	(SKL_ADSP_REG_CL_SPBFIFO + 0x4)
438c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SPBFIFO_SPIB		(SKL_ADSP_REG_CL_SPBFIFO + 0x8)
448c2ecf20Sopenharmony_ci#define SKL_ADSP_REG_CL_SPBFIFO_MAXFIFOS	(SKL_ADSP_REG_CL_SPBFIFO + 0xc)
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci/* CL: Stream Descriptor x Control */
478c2ecf20Sopenharmony_ci
488c2ecf20Sopenharmony_ci/* Stream Reset */
498c2ecf20Sopenharmony_ci#define CL_SD_CTL_SRST_SHIFT		0
508c2ecf20Sopenharmony_ci#define CL_SD_CTL_SRST_MASK		(1 << CL_SD_CTL_SRST_SHIFT)
518c2ecf20Sopenharmony_ci#define CL_SD_CTL_SRST(x)		\
528c2ecf20Sopenharmony_ci			((x << CL_SD_CTL_SRST_SHIFT) & CL_SD_CTL_SRST_MASK)
538c2ecf20Sopenharmony_ci
548c2ecf20Sopenharmony_ci/* Stream Run */
558c2ecf20Sopenharmony_ci#define CL_SD_CTL_RUN_SHIFT		1
568c2ecf20Sopenharmony_ci#define CL_SD_CTL_RUN_MASK		(1 << CL_SD_CTL_RUN_SHIFT)
578c2ecf20Sopenharmony_ci#define CL_SD_CTL_RUN(x)		\
588c2ecf20Sopenharmony_ci			((x << CL_SD_CTL_RUN_SHIFT) & CL_SD_CTL_RUN_MASK)
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci/* Interrupt On Completion Enable */
618c2ecf20Sopenharmony_ci#define CL_SD_CTL_IOCE_SHIFT		2
628c2ecf20Sopenharmony_ci#define CL_SD_CTL_IOCE_MASK		(1 << CL_SD_CTL_IOCE_SHIFT)
638c2ecf20Sopenharmony_ci#define CL_SD_CTL_IOCE(x)		\
648c2ecf20Sopenharmony_ci			((x << CL_SD_CTL_IOCE_SHIFT) & CL_SD_CTL_IOCE_MASK)
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci/* FIFO Error Interrupt Enable */
678c2ecf20Sopenharmony_ci#define CL_SD_CTL_FEIE_SHIFT		3
688c2ecf20Sopenharmony_ci#define CL_SD_CTL_FEIE_MASK		(1 << CL_SD_CTL_FEIE_SHIFT)
698c2ecf20Sopenharmony_ci#define CL_SD_CTL_FEIE(x)		\
708c2ecf20Sopenharmony_ci			((x << CL_SD_CTL_FEIE_SHIFT) & CL_SD_CTL_FEIE_MASK)
718c2ecf20Sopenharmony_ci
728c2ecf20Sopenharmony_ci/* Descriptor Error Interrupt Enable */
738c2ecf20Sopenharmony_ci#define CL_SD_CTL_DEIE_SHIFT		4
748c2ecf20Sopenharmony_ci#define CL_SD_CTL_DEIE_MASK		(1 << CL_SD_CTL_DEIE_SHIFT)
758c2ecf20Sopenharmony_ci#define CL_SD_CTL_DEIE(x)		\
768c2ecf20Sopenharmony_ci			((x << CL_SD_CTL_DEIE_SHIFT) & CL_SD_CTL_DEIE_MASK)
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci/* FIFO Limit Change */
798c2ecf20Sopenharmony_ci#define CL_SD_CTL_FIFOLC_SHIFT		5
808c2ecf20Sopenharmony_ci#define CL_SD_CTL_FIFOLC_MASK		(1 << CL_SD_CTL_FIFOLC_SHIFT)
818c2ecf20Sopenharmony_ci#define CL_SD_CTL_FIFOLC(x)		\
828c2ecf20Sopenharmony_ci			((x << CL_SD_CTL_FIFOLC_SHIFT) & CL_SD_CTL_FIFOLC_MASK)
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci/* Stripe Control */
858c2ecf20Sopenharmony_ci#define CL_SD_CTL_STRIPE_SHIFT		16
868c2ecf20Sopenharmony_ci#define CL_SD_CTL_STRIPE_MASK		(0x3 << CL_SD_CTL_STRIPE_SHIFT)
878c2ecf20Sopenharmony_ci#define CL_SD_CTL_STRIPE(x)		\
888c2ecf20Sopenharmony_ci			((x << CL_SD_CTL_STRIPE_SHIFT) & CL_SD_CTL_STRIPE_MASK)
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci/* Traffic Priority */
918c2ecf20Sopenharmony_ci#define CL_SD_CTL_TP_SHIFT		18
928c2ecf20Sopenharmony_ci#define CL_SD_CTL_TP_MASK		(1 << CL_SD_CTL_TP_SHIFT)
938c2ecf20Sopenharmony_ci#define CL_SD_CTL_TP(x)			\
948c2ecf20Sopenharmony_ci			((x << CL_SD_CTL_TP_SHIFT) & CL_SD_CTL_TP_MASK)
958c2ecf20Sopenharmony_ci
968c2ecf20Sopenharmony_ci/* Bidirectional Direction Control */
978c2ecf20Sopenharmony_ci#define CL_SD_CTL_DIR_SHIFT		19
988c2ecf20Sopenharmony_ci#define CL_SD_CTL_DIR_MASK		(1 << CL_SD_CTL_DIR_SHIFT)
998c2ecf20Sopenharmony_ci#define CL_SD_CTL_DIR(x)		\
1008c2ecf20Sopenharmony_ci			((x << CL_SD_CTL_DIR_SHIFT) & CL_SD_CTL_DIR_MASK)
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci/* Stream Number */
1038c2ecf20Sopenharmony_ci#define CL_SD_CTL_STRM_SHIFT		20
1048c2ecf20Sopenharmony_ci#define CL_SD_CTL_STRM_MASK		(0xf << CL_SD_CTL_STRM_SHIFT)
1058c2ecf20Sopenharmony_ci#define CL_SD_CTL_STRM(x)		\
1068c2ecf20Sopenharmony_ci			((x << CL_SD_CTL_STRM_SHIFT) & CL_SD_CTL_STRM_MASK)
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci/* CL: Stream Descriptor x Status */
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci/* Buffer Completion Interrupt Status */
1118c2ecf20Sopenharmony_ci#define CL_SD_STS_BCIS(x)		CL_SD_CTL_IOCE(x)
1128c2ecf20Sopenharmony_ci
1138c2ecf20Sopenharmony_ci/* FIFO Error */
1148c2ecf20Sopenharmony_ci#define CL_SD_STS_FIFOE(x)		CL_SD_CTL_FEIE(x)
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci/* Descriptor Error */
1178c2ecf20Sopenharmony_ci#define CL_SD_STS_DESE(x)		CL_SD_CTL_DEIE(x)
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci/* FIFO Ready */
1208c2ecf20Sopenharmony_ci#define CL_SD_STS_FIFORDY(x)	CL_SD_CTL_FIFOLC(x)
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci/* CL: Stream Descriptor x Last Valid Index */
1248c2ecf20Sopenharmony_ci#define CL_SD_LVI_SHIFT			0
1258c2ecf20Sopenharmony_ci#define CL_SD_LVI_MASK			(0xff << CL_SD_LVI_SHIFT)
1268c2ecf20Sopenharmony_ci#define CL_SD_LVI(x)			((x << CL_SD_LVI_SHIFT) & CL_SD_LVI_MASK)
1278c2ecf20Sopenharmony_ci
1288c2ecf20Sopenharmony_ci/* CL: Stream Descriptor x FIFO Eviction Watermark */
1298c2ecf20Sopenharmony_ci#define CL_SD_FIFOW_SHIFT		0
1308c2ecf20Sopenharmony_ci#define CL_SD_FIFOW_MASK		(0x7 << CL_SD_FIFOW_SHIFT)
1318c2ecf20Sopenharmony_ci#define CL_SD_FIFOW(x)			\
1328c2ecf20Sopenharmony_ci			((x << CL_SD_FIFOW_SHIFT) & CL_SD_FIFOW_MASK)
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci/* CL: Stream Descriptor x Buffer Descriptor List Pointer Lower Base Address */
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci/* Protect Bits */
1378c2ecf20Sopenharmony_ci#define CL_SD_BDLPLBA_PROT_SHIFT	0
1388c2ecf20Sopenharmony_ci#define CL_SD_BDLPLBA_PROT_MASK		(1 << CL_SD_BDLPLBA_PROT_SHIFT)
1398c2ecf20Sopenharmony_ci#define CL_SD_BDLPLBA_PROT(x)		\
1408c2ecf20Sopenharmony_ci		((x << CL_SD_BDLPLBA_PROT_SHIFT) & CL_SD_BDLPLBA_PROT_MASK)
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci/* Buffer Descriptor List Lower Base Address */
1438c2ecf20Sopenharmony_ci#define CL_SD_BDLPLBA_SHIFT		7
1448c2ecf20Sopenharmony_ci#define CL_SD_BDLPLBA_MASK		(0x1ffffff << CL_SD_BDLPLBA_SHIFT)
1458c2ecf20Sopenharmony_ci#define CL_SD_BDLPLBA(x)		\
1468c2ecf20Sopenharmony_ci	((BDL_ALIGN(lower_32_bits(x)) << CL_SD_BDLPLBA_SHIFT) & CL_SD_BDLPLBA_MASK)
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci/* Buffer Descriptor List Upper Base Address */
1498c2ecf20Sopenharmony_ci#define CL_SD_BDLPUBA_SHIFT		0
1508c2ecf20Sopenharmony_ci#define CL_SD_BDLPUBA_MASK		(0xffffffff << CL_SD_BDLPUBA_SHIFT)
1518c2ecf20Sopenharmony_ci#define CL_SD_BDLPUBA(x)		\
1528c2ecf20Sopenharmony_ci		((upper_32_bits(x) << CL_SD_BDLPUBA_SHIFT) & CL_SD_BDLPUBA_MASK)
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci/*
1558c2ecf20Sopenharmony_ci * Code Loader - Software Position Based FIFO
1568c2ecf20Sopenharmony_ci * Capability Registers x Software Position Based FIFO Header
1578c2ecf20Sopenharmony_ci */
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ci/* Next Capability Pointer */
1608c2ecf20Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_PTR_SHIFT	0
1618c2ecf20Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_PTR_MASK	(0xff << CL_SPBFIFO_SPBFCH_PTR_SHIFT)
1628c2ecf20Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_PTR(x)	\
1638c2ecf20Sopenharmony_ci		((x << CL_SPBFIFO_SPBFCH_PTR_SHIFT) & CL_SPBFIFO_SPBFCH_PTR_MASK)
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci/* Capability Identifier */
1668c2ecf20Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_ID_SHIFT	16
1678c2ecf20Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_ID_MASK	(0xfff << CL_SPBFIFO_SPBFCH_ID_SHIFT)
1688c2ecf20Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_ID(x)		\
1698c2ecf20Sopenharmony_ci		((x << CL_SPBFIFO_SPBFCH_ID_SHIFT) & CL_SPBFIFO_SPBFCH_ID_MASK)
1708c2ecf20Sopenharmony_ci
1718c2ecf20Sopenharmony_ci/* Capability Version */
1728c2ecf20Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_VER_SHIFT	28
1738c2ecf20Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_VER_MASK	(0xf << CL_SPBFIFO_SPBFCH_VER_SHIFT)
1748c2ecf20Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_VER(x)	\
1758c2ecf20Sopenharmony_ci	((x << CL_SPBFIFO_SPBFCH_VER_SHIFT) & CL_SPBFIFO_SPBFCH_VER_MASK)
1768c2ecf20Sopenharmony_ci
1778c2ecf20Sopenharmony_ci/* Software Position in Buffer Enable */
1788c2ecf20Sopenharmony_ci#define CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT	0
1798c2ecf20Sopenharmony_ci#define CL_SPBFIFO_SPBFCCTL_SPIBE_MASK	(1 << CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT)
1808c2ecf20Sopenharmony_ci#define CL_SPBFIFO_SPBFCCTL_SPIBE(x)	\
1818c2ecf20Sopenharmony_ci	((x << CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT) & CL_SPBFIFO_SPBFCCTL_SPIBE_MASK)
1828c2ecf20Sopenharmony_ci
1838c2ecf20Sopenharmony_ci/* SST IPC SKL defines */
1848c2ecf20Sopenharmony_ci#define SKL_WAIT_TIMEOUT		500	/* 500 msec */
1858c2ecf20Sopenharmony_ci#define SKL_MAX_BUFFER_SIZE		(32 * PAGE_SIZE)
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_cienum skl_cl_dma_wake_states {
1888c2ecf20Sopenharmony_ci	SKL_CL_DMA_STATUS_NONE = 0,
1898c2ecf20Sopenharmony_ci	SKL_CL_DMA_BUF_COMPLETE,
1908c2ecf20Sopenharmony_ci	SKL_CL_DMA_ERR,	/* TODO: Expand the error states */
1918c2ecf20Sopenharmony_ci};
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_cistruct sst_dsp;
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_cistruct skl_cl_dev_ops {
1968c2ecf20Sopenharmony_ci	void (*cl_setup_bdle)(struct sst_dsp *ctx,
1978c2ecf20Sopenharmony_ci			struct snd_dma_buffer *dmab_data,
1988c2ecf20Sopenharmony_ci			__le32 **bdlp, int size, int with_ioc);
1998c2ecf20Sopenharmony_ci	void (*cl_setup_controller)(struct sst_dsp *ctx,
2008c2ecf20Sopenharmony_ci			struct snd_dma_buffer *dmab_bdl,
2018c2ecf20Sopenharmony_ci			unsigned int max_size, u32 page_count);
2028c2ecf20Sopenharmony_ci	void (*cl_setup_spb)(struct sst_dsp  *ctx,
2038c2ecf20Sopenharmony_ci			unsigned int size, bool enable);
2048c2ecf20Sopenharmony_ci	void (*cl_cleanup_spb)(struct sst_dsp  *ctx);
2058c2ecf20Sopenharmony_ci	void (*cl_trigger)(struct sst_dsp  *ctx, bool enable);
2068c2ecf20Sopenharmony_ci	void (*cl_cleanup_controller)(struct sst_dsp  *ctx);
2078c2ecf20Sopenharmony_ci	int (*cl_copy_to_dmabuf)(struct sst_dsp *ctx,
2088c2ecf20Sopenharmony_ci			const void *bin, u32 size, bool wait);
2098c2ecf20Sopenharmony_ci	void (*cl_stop_dma)(struct sst_dsp *ctx);
2108c2ecf20Sopenharmony_ci};
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ci/**
2138c2ecf20Sopenharmony_ci * skl_cl_dev - holds information for code loader dma transfer
2148c2ecf20Sopenharmony_ci *
2158c2ecf20Sopenharmony_ci * @dmab_data: buffer pointer
2168c2ecf20Sopenharmony_ci * @dmab_bdl: buffer descriptor list
2178c2ecf20Sopenharmony_ci * @bufsize: ring buffer size
2188c2ecf20Sopenharmony_ci * @frags: Last valid buffer descriptor index in the BDL
2198c2ecf20Sopenharmony_ci * @curr_spib_pos: Current position in ring buffer
2208c2ecf20Sopenharmony_ci * @dma_buffer_offset: dma buffer offset
2218c2ecf20Sopenharmony_ci * @ops: operations supported on CL dma
2228c2ecf20Sopenharmony_ci * @wait_queue: wait queue to wake for wake event
2238c2ecf20Sopenharmony_ci * @wake_status: DMA wake status
2248c2ecf20Sopenharmony_ci * @wait_condition: condition to wait on wait queue
2258c2ecf20Sopenharmony_ci * @cl_dma_lock: for synchronized access to cldma
2268c2ecf20Sopenharmony_ci */
2278c2ecf20Sopenharmony_cistruct skl_cl_dev {
2288c2ecf20Sopenharmony_ci	struct snd_dma_buffer dmab_data;
2298c2ecf20Sopenharmony_ci	struct snd_dma_buffer dmab_bdl;
2308c2ecf20Sopenharmony_ci
2318c2ecf20Sopenharmony_ci	unsigned int bufsize;
2328c2ecf20Sopenharmony_ci	unsigned int frags;
2338c2ecf20Sopenharmony_ci
2348c2ecf20Sopenharmony_ci	unsigned int curr_spib_pos;
2358c2ecf20Sopenharmony_ci	unsigned int dma_buffer_offset;
2368c2ecf20Sopenharmony_ci	struct skl_cl_dev_ops ops;
2378c2ecf20Sopenharmony_ci
2388c2ecf20Sopenharmony_ci	wait_queue_head_t wait_queue;
2398c2ecf20Sopenharmony_ci	int wake_status;
2408c2ecf20Sopenharmony_ci	bool wait_condition;
2418c2ecf20Sopenharmony_ci};
2428c2ecf20Sopenharmony_ci
2438c2ecf20Sopenharmony_ci#endif /* SKL_SST_CLDMA_H_ */
244