147d7195dSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
2e3090387SVinod Koul /*
3e3090387SVinod Koul  * Intel Code Loader DMA support
4e3090387SVinod Koul  *
5e3090387SVinod Koul  * Copyright (C) 2015, Intel Corporation.
6e3090387SVinod Koul  */
7e3090387SVinod Koul 
8e3090387SVinod Koul #ifndef SKL_SST_CLDMA_H_
9e3090387SVinod Koul #define SKL_SST_CLDMA_H_
10e3090387SVinod Koul 
11e3090387SVinod Koul #define FW_CL_STREAM_NUMBER		0x1
12e3090387SVinod Koul 
13e3090387SVinod Koul #define DMA_ADDRESS_128_BITS_ALIGNMENT	7
14e3090387SVinod Koul #define BDL_ALIGN(x)			(x >> DMA_ADDRESS_128_BITS_ALIGNMENT)
15e3090387SVinod Koul 
16e3090387SVinod Koul #define SKL_ADSPIC_CL_DMA			0x2
17e3090387SVinod Koul #define SKL_ADSPIS_CL_DMA			0x2
18e3090387SVinod Koul #define SKL_CL_DMA_SD_INT_DESC_ERR		0x10 /* Descriptor error interrupt */
19e3090387SVinod Koul #define SKL_CL_DMA_SD_INT_FIFO_ERR		0x08 /* FIFO error interrupt */
20e3090387SVinod Koul #define SKL_CL_DMA_SD_INT_COMPLETE		0x04 /* Buffer completion interrupt */
21e3090387SVinod Koul 
22e3090387SVinod Koul /* Intel HD Audio Code Loader DMA Registers */
23e3090387SVinod Koul 
24e3090387SVinod Koul #define HDA_ADSP_LOADER_BASE		0x80
25e3090387SVinod Koul 
26e3090387SVinod Koul /* Stream Registers */
27e3090387SVinod Koul #define SKL_ADSP_REG_CL_SD_CTL			(HDA_ADSP_LOADER_BASE + 0x00)
28e3090387SVinod Koul #define SKL_ADSP_REG_CL_SD_STS			(HDA_ADSP_LOADER_BASE + 0x03)
29e3090387SVinod Koul #define SKL_ADSP_REG_CL_SD_LPIB			(HDA_ADSP_LOADER_BASE + 0x04)
30e3090387SVinod Koul #define SKL_ADSP_REG_CL_SD_CBL			(HDA_ADSP_LOADER_BASE + 0x08)
31e3090387SVinod Koul #define SKL_ADSP_REG_CL_SD_LVI			(HDA_ADSP_LOADER_BASE + 0x0c)
32e3090387SVinod Koul #define SKL_ADSP_REG_CL_SD_FIFOW		(HDA_ADSP_LOADER_BASE + 0x0e)
33e3090387SVinod Koul #define SKL_ADSP_REG_CL_SD_FIFOSIZE		(HDA_ADSP_LOADER_BASE + 0x10)
34e3090387SVinod Koul #define SKL_ADSP_REG_CL_SD_FORMAT		(HDA_ADSP_LOADER_BASE + 0x12)
35e3090387SVinod Koul #define SKL_ADSP_REG_CL_SD_FIFOL		(HDA_ADSP_LOADER_BASE + 0x14)
36e3090387SVinod Koul #define SKL_ADSP_REG_CL_SD_BDLPL		(HDA_ADSP_LOADER_BASE + 0x18)
37e3090387SVinod Koul #define SKL_ADSP_REG_CL_SD_BDLPU		(HDA_ADSP_LOADER_BASE + 0x1c)
38e3090387SVinod Koul 
39e3090387SVinod Koul /* CL: Software Position Based FIFO Capability Registers */
40e3090387SVinod Koul #define SKL_ADSP_REG_CL_SPBFIFO			(HDA_ADSP_LOADER_BASE + 0x20)
41e3090387SVinod Koul #define SKL_ADSP_REG_CL_SPBFIFO_SPBFCH		(SKL_ADSP_REG_CL_SPBFIFO + 0x0)
42e3090387SVinod Koul #define SKL_ADSP_REG_CL_SPBFIFO_SPBFCCTL	(SKL_ADSP_REG_CL_SPBFIFO + 0x4)
43e3090387SVinod Koul #define SKL_ADSP_REG_CL_SPBFIFO_SPIB		(SKL_ADSP_REG_CL_SPBFIFO + 0x8)
44e3090387SVinod Koul #define SKL_ADSP_REG_CL_SPBFIFO_MAXFIFOS	(SKL_ADSP_REG_CL_SPBFIFO + 0xc)
45e3090387SVinod Koul 
46e3090387SVinod Koul /* CL: Stream Descriptor x Control */
47e3090387SVinod Koul 
48e3090387SVinod Koul /* Stream Reset */
49e3090387SVinod Koul #define CL_SD_CTL_SRST_SHIFT		0
50e3090387SVinod Koul #define CL_SD_CTL_SRST_MASK		(1 << CL_SD_CTL_SRST_SHIFT)
51e3090387SVinod Koul #define CL_SD_CTL_SRST(x)		\
52e3090387SVinod Koul 			((x << CL_SD_CTL_SRST_SHIFT) & CL_SD_CTL_SRST_MASK)
53e3090387SVinod Koul 
54e3090387SVinod Koul /* Stream Run */
55e3090387SVinod Koul #define CL_SD_CTL_RUN_SHIFT		1
56e3090387SVinod Koul #define CL_SD_CTL_RUN_MASK		(1 << CL_SD_CTL_RUN_SHIFT)
57e3090387SVinod Koul #define CL_SD_CTL_RUN(x)		\
58e3090387SVinod Koul 			((x << CL_SD_CTL_RUN_SHIFT) & CL_SD_CTL_RUN_MASK)
59e3090387SVinod Koul 
60e3090387SVinod Koul /* Interrupt On Completion Enable */
61e3090387SVinod Koul #define CL_SD_CTL_IOCE_SHIFT		2
62e3090387SVinod Koul #define CL_SD_CTL_IOCE_MASK		(1 << CL_SD_CTL_IOCE_SHIFT)
63e3090387SVinod Koul #define CL_SD_CTL_IOCE(x)		\
64e3090387SVinod Koul 			((x << CL_SD_CTL_IOCE_SHIFT) & CL_SD_CTL_IOCE_MASK)
65e3090387SVinod Koul 
66e3090387SVinod Koul /* FIFO Error Interrupt Enable */
67e3090387SVinod Koul #define CL_SD_CTL_FEIE_SHIFT		3
68e3090387SVinod Koul #define CL_SD_CTL_FEIE_MASK		(1 << CL_SD_CTL_FEIE_SHIFT)
69e3090387SVinod Koul #define CL_SD_CTL_FEIE(x)		\
70e3090387SVinod Koul 			((x << CL_SD_CTL_FEIE_SHIFT) & CL_SD_CTL_FEIE_MASK)
71e3090387SVinod Koul 
72e3090387SVinod Koul /* Descriptor Error Interrupt Enable */
73e3090387SVinod Koul #define CL_SD_CTL_DEIE_SHIFT		4
74e3090387SVinod Koul #define CL_SD_CTL_DEIE_MASK		(1 << CL_SD_CTL_DEIE_SHIFT)
75e3090387SVinod Koul #define CL_SD_CTL_DEIE(x)		\
76e3090387SVinod Koul 			((x << CL_SD_CTL_DEIE_SHIFT) & CL_SD_CTL_DEIE_MASK)
77e3090387SVinod Koul 
78e3090387SVinod Koul /* FIFO Limit Change */
79e3090387SVinod Koul #define CL_SD_CTL_FIFOLC_SHIFT		5
80e3090387SVinod Koul #define CL_SD_CTL_FIFOLC_MASK		(1 << CL_SD_CTL_FIFOLC_SHIFT)
81e3090387SVinod Koul #define CL_SD_CTL_FIFOLC(x)		\
82e3090387SVinod Koul 			((x << CL_SD_CTL_FIFOLC_SHIFT) & CL_SD_CTL_FIFOLC_MASK)
83e3090387SVinod Koul 
84e3090387SVinod Koul /* Stripe Control */
85e3090387SVinod Koul #define CL_SD_CTL_STRIPE_SHIFT		16
86e3090387SVinod Koul #define CL_SD_CTL_STRIPE_MASK		(0x3 << CL_SD_CTL_STRIPE_SHIFT)
87e3090387SVinod Koul #define CL_SD_CTL_STRIPE(x)		\
88e3090387SVinod Koul 			((x << CL_SD_CTL_STRIPE_SHIFT) & CL_SD_CTL_STRIPE_MASK)
89e3090387SVinod Koul 
90e3090387SVinod Koul /* Traffic Priority */
91e3090387SVinod Koul #define CL_SD_CTL_TP_SHIFT		18
92e3090387SVinod Koul #define CL_SD_CTL_TP_MASK		(1 << CL_SD_CTL_TP_SHIFT)
93e3090387SVinod Koul #define CL_SD_CTL_TP(x)			\
94e3090387SVinod Koul 			((x << CL_SD_CTL_TP_SHIFT) & CL_SD_CTL_TP_MASK)
95e3090387SVinod Koul 
96e3090387SVinod Koul /* Bidirectional Direction Control */
97e3090387SVinod Koul #define CL_SD_CTL_DIR_SHIFT		19
98e3090387SVinod Koul #define CL_SD_CTL_DIR_MASK		(1 << CL_SD_CTL_DIR_SHIFT)
99e3090387SVinod Koul #define CL_SD_CTL_DIR(x)		\
100e3090387SVinod Koul 			((x << CL_SD_CTL_DIR_SHIFT) & CL_SD_CTL_DIR_MASK)
101e3090387SVinod Koul 
102e3090387SVinod Koul /* Stream Number */
103e3090387SVinod Koul #define CL_SD_CTL_STRM_SHIFT		20
104e3090387SVinod Koul #define CL_SD_CTL_STRM_MASK		(0xf << CL_SD_CTL_STRM_SHIFT)
105e3090387SVinod Koul #define CL_SD_CTL_STRM(x)		\
106e3090387SVinod Koul 			((x << CL_SD_CTL_STRM_SHIFT) & CL_SD_CTL_STRM_MASK)
107e3090387SVinod Koul 
108e3090387SVinod Koul /* CL: Stream Descriptor x Status */
109e3090387SVinod Koul 
110e3090387SVinod Koul /* Buffer Completion Interrupt Status */
111e3090387SVinod Koul #define CL_SD_STS_BCIS(x)		CL_SD_CTL_IOCE(x)
112e3090387SVinod Koul 
113e3090387SVinod Koul /* FIFO Error */
114e3090387SVinod Koul #define CL_SD_STS_FIFOE(x)		CL_SD_CTL_FEIE(x)
115e3090387SVinod Koul 
116e3090387SVinod Koul /* Descriptor Error */
117e3090387SVinod Koul #define CL_SD_STS_DESE(x)		CL_SD_CTL_DEIE(x)
118e3090387SVinod Koul 
119e3090387SVinod Koul /* FIFO Ready */
120e3090387SVinod Koul #define CL_SD_STS_FIFORDY(x)	CL_SD_CTL_FIFOLC(x)
121e3090387SVinod Koul 
122e3090387SVinod Koul 
123e3090387SVinod Koul /* CL: Stream Descriptor x Last Valid Index */
124e3090387SVinod Koul #define CL_SD_LVI_SHIFT			0
125e3090387SVinod Koul #define CL_SD_LVI_MASK			(0xff << CL_SD_LVI_SHIFT)
126e3090387SVinod Koul #define CL_SD_LVI(x)			((x << CL_SD_LVI_SHIFT) & CL_SD_LVI_MASK)
127e3090387SVinod Koul 
128e3090387SVinod Koul /* CL: Stream Descriptor x FIFO Eviction Watermark */
129e3090387SVinod Koul #define CL_SD_FIFOW_SHIFT		0
130e3090387SVinod Koul #define CL_SD_FIFOW_MASK		(0x7 << CL_SD_FIFOW_SHIFT)
131e3090387SVinod Koul #define CL_SD_FIFOW(x)			\
132e3090387SVinod Koul 			((x << CL_SD_FIFOW_SHIFT) & CL_SD_FIFOW_MASK)
133e3090387SVinod Koul 
134e3090387SVinod Koul /* CL: Stream Descriptor x Buffer Descriptor List Pointer Lower Base Address */
135e3090387SVinod Koul 
136e3090387SVinod Koul /* Protect Bits */
137e3090387SVinod Koul #define CL_SD_BDLPLBA_PROT_SHIFT	0
138e3090387SVinod Koul #define CL_SD_BDLPLBA_PROT_MASK		(1 << CL_SD_BDLPLBA_PROT_SHIFT)
139e3090387SVinod Koul #define CL_SD_BDLPLBA_PROT(x)		\
140e3090387SVinod Koul 		((x << CL_SD_BDLPLBA_PROT_SHIFT) & CL_SD_BDLPLBA_PROT_MASK)
141e3090387SVinod Koul 
142e3090387SVinod Koul /* Buffer Descriptor List Lower Base Address */
143e3090387SVinod Koul #define CL_SD_BDLPLBA_SHIFT		7
144e3090387SVinod Koul #define CL_SD_BDLPLBA_MASK		(0x1ffffff << CL_SD_BDLPLBA_SHIFT)
145e3090387SVinod Koul #define CL_SD_BDLPLBA(x)		\
146e3090387SVinod Koul 	((BDL_ALIGN(lower_32_bits(x)) << CL_SD_BDLPLBA_SHIFT) & CL_SD_BDLPLBA_MASK)
147e3090387SVinod Koul 
148e3090387SVinod Koul /* Buffer Descriptor List Upper Base Address */
149e3090387SVinod Koul #define CL_SD_BDLPUBA_SHIFT		0
150e3090387SVinod Koul #define CL_SD_BDLPUBA_MASK		(0xffffffff << CL_SD_BDLPUBA_SHIFT)
151e3090387SVinod Koul #define CL_SD_BDLPUBA(x)		\
152e3090387SVinod Koul 		((upper_32_bits(x) << CL_SD_BDLPUBA_SHIFT) & CL_SD_BDLPUBA_MASK)
153e3090387SVinod Koul 
154e3090387SVinod Koul /*
155e3090387SVinod Koul  * Code Loader - Software Position Based FIFO
156e3090387SVinod Koul  * Capability Registers x Software Position Based FIFO Header
157e3090387SVinod Koul  */
158e3090387SVinod Koul 
159e3090387SVinod Koul /* Next Capability Pointer */
160e3090387SVinod Koul #define CL_SPBFIFO_SPBFCH_PTR_SHIFT	0
161e3090387SVinod Koul #define CL_SPBFIFO_SPBFCH_PTR_MASK	(0xff << CL_SPBFIFO_SPBFCH_PTR_SHIFT)
162e3090387SVinod Koul #define CL_SPBFIFO_SPBFCH_PTR(x)	\
163e3090387SVinod Koul 		((x << CL_SPBFIFO_SPBFCH_PTR_SHIFT) & CL_SPBFIFO_SPBFCH_PTR_MASK)
164e3090387SVinod Koul 
165e3090387SVinod Koul /* Capability Identifier */
166e3090387SVinod Koul #define CL_SPBFIFO_SPBFCH_ID_SHIFT	16
167e3090387SVinod Koul #define CL_SPBFIFO_SPBFCH_ID_MASK	(0xfff << CL_SPBFIFO_SPBFCH_ID_SHIFT)
168e3090387SVinod Koul #define CL_SPBFIFO_SPBFCH_ID(x)		\
169e3090387SVinod Koul 		((x << CL_SPBFIFO_SPBFCH_ID_SHIFT) & CL_SPBFIFO_SPBFCH_ID_MASK)
170e3090387SVinod Koul 
171e3090387SVinod Koul /* Capability Version */
172e3090387SVinod Koul #define CL_SPBFIFO_SPBFCH_VER_SHIFT	28
173e3090387SVinod Koul #define CL_SPBFIFO_SPBFCH_VER_MASK	(0xf << CL_SPBFIFO_SPBFCH_VER_SHIFT)
174e3090387SVinod Koul #define CL_SPBFIFO_SPBFCH_VER(x)	\
175e3090387SVinod Koul 	((x << CL_SPBFIFO_SPBFCH_VER_SHIFT) & CL_SPBFIFO_SPBFCH_VER_MASK)
176e3090387SVinod Koul 
177e3090387SVinod Koul /* Software Position in Buffer Enable */
178e3090387SVinod Koul #define CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT	0
179e3090387SVinod Koul #define CL_SPBFIFO_SPBFCCTL_SPIBE_MASK	(1 << CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT)
180e3090387SVinod Koul #define CL_SPBFIFO_SPBFCCTL_SPIBE(x)	\
181e3090387SVinod Koul 	((x << CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT) & CL_SPBFIFO_SPBFCCTL_SPIBE_MASK)
182e3090387SVinod Koul 
183914426c8SVinod Koul /* SST IPC SKL defines */
184914426c8SVinod Koul #define SKL_WAIT_TIMEOUT		500	/* 500 msec */
185914426c8SVinod Koul #define SKL_MAX_BUFFER_SIZE		(32 * PAGE_SIZE)
186914426c8SVinod Koul 
187914426c8SVinod Koul enum skl_cl_dma_wake_states {
188914426c8SVinod Koul 	SKL_CL_DMA_STATUS_NONE = 0,
189914426c8SVinod Koul 	SKL_CL_DMA_BUF_COMPLETE,
190914426c8SVinod Koul 	SKL_CL_DMA_ERR,	/* TODO: Expand the error states */
191914426c8SVinod Koul };
192914426c8SVinod Koul 
193914426c8SVinod Koul struct sst_dsp;
194914426c8SVinod Koul 
195914426c8SVinod Koul struct skl_cl_dev_ops {
196914426c8SVinod Koul 	void (*cl_setup_bdle)(struct sst_dsp *ctx,
197914426c8SVinod Koul 			struct snd_dma_buffer *dmab_data,
19886efd35eSPierre-Louis Bossart 			__le32 **bdlp, int size, int with_ioc);
199914426c8SVinod Koul 	void (*cl_setup_controller)(struct sst_dsp *ctx,
200914426c8SVinod Koul 			struct snd_dma_buffer *dmab_bdl,
201914426c8SVinod Koul 			unsigned int max_size, u32 page_count);
202914426c8SVinod Koul 	void (*cl_setup_spb)(struct sst_dsp  *ctx,
203914426c8SVinod Koul 			unsigned int size, bool enable);
204914426c8SVinod Koul 	void (*cl_cleanup_spb)(struct sst_dsp  *ctx);
205914426c8SVinod Koul 	void (*cl_trigger)(struct sst_dsp  *ctx, bool enable);
206914426c8SVinod Koul 	void (*cl_cleanup_controller)(struct sst_dsp  *ctx);
207914426c8SVinod Koul 	int (*cl_copy_to_dmabuf)(struct sst_dsp *ctx,
208b7d0254cSJeeja KP 			const void *bin, u32 size, bool wait);
209914426c8SVinod Koul 	void (*cl_stop_dma)(struct sst_dsp *ctx);
210914426c8SVinod Koul };
211914426c8SVinod Koul 
212914426c8SVinod Koul /**
213914426c8SVinod Koul  * skl_cl_dev - holds information for code loader dma transfer
214914426c8SVinod Koul  *
215914426c8SVinod Koul  * @dmab_data: buffer pointer
216914426c8SVinod Koul  * @dmab_bdl: buffer descriptor list
217914426c8SVinod Koul  * @bufsize: ring buffer size
218914426c8SVinod Koul  * @frags: Last valid buffer descriptor index in the BDL
219914426c8SVinod Koul  * @curr_spib_pos: Current position in ring buffer
220914426c8SVinod Koul  * @dma_buffer_offset: dma buffer offset
221914426c8SVinod Koul  * @ops: operations supported on CL dma
222914426c8SVinod Koul  * @wait_queue: wait queue to wake for wake event
223914426c8SVinod Koul  * @wake_status: DMA wake status
224914426c8SVinod Koul  * @wait_condition: condition to wait on wait queue
225914426c8SVinod Koul  * @cl_dma_lock: for synchronized access to cldma
226914426c8SVinod Koul  */
227914426c8SVinod Koul struct skl_cl_dev {
228914426c8SVinod Koul 	struct snd_dma_buffer dmab_data;
229914426c8SVinod Koul 	struct snd_dma_buffer dmab_bdl;
230914426c8SVinod Koul 
231914426c8SVinod Koul 	unsigned int bufsize;
232914426c8SVinod Koul 	unsigned int frags;
233914426c8SVinod Koul 
234914426c8SVinod Koul 	unsigned int curr_spib_pos;
235914426c8SVinod Koul 	unsigned int dma_buffer_offset;
236914426c8SVinod Koul 	struct skl_cl_dev_ops ops;
237914426c8SVinod Koul 
238914426c8SVinod Koul 	wait_queue_head_t wait_queue;
239914426c8SVinod Koul 	int wake_status;
240914426c8SVinod Koul 	bool wait_condition;
241914426c8SVinod Koul };
242914426c8SVinod Koul 
243e3090387SVinod Koul #endif /* SKL_SST_CLDMA_H_ */
244