162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Intel Code Loader DMA support
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2015, Intel Corporation.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifndef SKL_SST_CLDMA_H_
962306a36Sopenharmony_ci#define SKL_SST_CLDMA_H_
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#define FW_CL_STREAM_NUMBER		0x1
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#define DMA_ADDRESS_128_BITS_ALIGNMENT	7
1462306a36Sopenharmony_ci#define BDL_ALIGN(x)			(x >> DMA_ADDRESS_128_BITS_ALIGNMENT)
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define SKL_ADSPIC_CL_DMA			0x2
1762306a36Sopenharmony_ci#define SKL_ADSPIS_CL_DMA			0x2
1862306a36Sopenharmony_ci#define SKL_CL_DMA_SD_INT_DESC_ERR		0x10 /* Descriptor error interrupt */
1962306a36Sopenharmony_ci#define SKL_CL_DMA_SD_INT_FIFO_ERR		0x08 /* FIFO error interrupt */
2062306a36Sopenharmony_ci#define SKL_CL_DMA_SD_INT_COMPLETE		0x04 /* Buffer completion interrupt */
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/* Intel HD Audio Code Loader DMA Registers */
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#define HDA_ADSP_LOADER_BASE		0x80
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci/* Stream Registers */
2762306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_CTL			(HDA_ADSP_LOADER_BASE + 0x00)
2862306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_STS			(HDA_ADSP_LOADER_BASE + 0x03)
2962306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_LPIB			(HDA_ADSP_LOADER_BASE + 0x04)
3062306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_CBL			(HDA_ADSP_LOADER_BASE + 0x08)
3162306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_LVI			(HDA_ADSP_LOADER_BASE + 0x0c)
3262306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_FIFOW		(HDA_ADSP_LOADER_BASE + 0x0e)
3362306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_FIFOSIZE		(HDA_ADSP_LOADER_BASE + 0x10)
3462306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_FORMAT		(HDA_ADSP_LOADER_BASE + 0x12)
3562306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_FIFOL		(HDA_ADSP_LOADER_BASE + 0x14)
3662306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_BDLPL		(HDA_ADSP_LOADER_BASE + 0x18)
3762306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SD_BDLPU		(HDA_ADSP_LOADER_BASE + 0x1c)
3862306a36Sopenharmony_ci
3962306a36Sopenharmony_ci/* CL: Software Position Based FIFO Capability Registers */
4062306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SPBFIFO			(HDA_ADSP_LOADER_BASE + 0x20)
4162306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SPBFIFO_SPBFCH		(SKL_ADSP_REG_CL_SPBFIFO + 0x0)
4262306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SPBFIFO_SPBFCCTL	(SKL_ADSP_REG_CL_SPBFIFO + 0x4)
4362306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SPBFIFO_SPIB		(SKL_ADSP_REG_CL_SPBFIFO + 0x8)
4462306a36Sopenharmony_ci#define SKL_ADSP_REG_CL_SPBFIFO_MAXFIFOS	(SKL_ADSP_REG_CL_SPBFIFO + 0xc)
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/* CL: Stream Descriptor x Control */
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci/* Stream Reset */
4962306a36Sopenharmony_ci#define CL_SD_CTL_SRST_SHIFT		0
5062306a36Sopenharmony_ci#define CL_SD_CTL_SRST_MASK		(1 << CL_SD_CTL_SRST_SHIFT)
5162306a36Sopenharmony_ci#define CL_SD_CTL_SRST(x)		\
5262306a36Sopenharmony_ci			((x << CL_SD_CTL_SRST_SHIFT) & CL_SD_CTL_SRST_MASK)
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_ci/* Stream Run */
5562306a36Sopenharmony_ci#define CL_SD_CTL_RUN_SHIFT		1
5662306a36Sopenharmony_ci#define CL_SD_CTL_RUN_MASK		(1 << CL_SD_CTL_RUN_SHIFT)
5762306a36Sopenharmony_ci#define CL_SD_CTL_RUN(x)		\
5862306a36Sopenharmony_ci			((x << CL_SD_CTL_RUN_SHIFT) & CL_SD_CTL_RUN_MASK)
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci/* Interrupt On Completion Enable */
6162306a36Sopenharmony_ci#define CL_SD_CTL_IOCE_SHIFT		2
6262306a36Sopenharmony_ci#define CL_SD_CTL_IOCE_MASK		(1 << CL_SD_CTL_IOCE_SHIFT)
6362306a36Sopenharmony_ci#define CL_SD_CTL_IOCE(x)		\
6462306a36Sopenharmony_ci			((x << CL_SD_CTL_IOCE_SHIFT) & CL_SD_CTL_IOCE_MASK)
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci/* FIFO Error Interrupt Enable */
6762306a36Sopenharmony_ci#define CL_SD_CTL_FEIE_SHIFT		3
6862306a36Sopenharmony_ci#define CL_SD_CTL_FEIE_MASK		(1 << CL_SD_CTL_FEIE_SHIFT)
6962306a36Sopenharmony_ci#define CL_SD_CTL_FEIE(x)		\
7062306a36Sopenharmony_ci			((x << CL_SD_CTL_FEIE_SHIFT) & CL_SD_CTL_FEIE_MASK)
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci/* Descriptor Error Interrupt Enable */
7362306a36Sopenharmony_ci#define CL_SD_CTL_DEIE_SHIFT		4
7462306a36Sopenharmony_ci#define CL_SD_CTL_DEIE_MASK		(1 << CL_SD_CTL_DEIE_SHIFT)
7562306a36Sopenharmony_ci#define CL_SD_CTL_DEIE(x)		\
7662306a36Sopenharmony_ci			((x << CL_SD_CTL_DEIE_SHIFT) & CL_SD_CTL_DEIE_MASK)
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci/* FIFO Limit Change */
7962306a36Sopenharmony_ci#define CL_SD_CTL_FIFOLC_SHIFT		5
8062306a36Sopenharmony_ci#define CL_SD_CTL_FIFOLC_MASK		(1 << CL_SD_CTL_FIFOLC_SHIFT)
8162306a36Sopenharmony_ci#define CL_SD_CTL_FIFOLC(x)		\
8262306a36Sopenharmony_ci			((x << CL_SD_CTL_FIFOLC_SHIFT) & CL_SD_CTL_FIFOLC_MASK)
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci/* Stripe Control */
8562306a36Sopenharmony_ci#define CL_SD_CTL_STRIPE_SHIFT		16
8662306a36Sopenharmony_ci#define CL_SD_CTL_STRIPE_MASK		(0x3 << CL_SD_CTL_STRIPE_SHIFT)
8762306a36Sopenharmony_ci#define CL_SD_CTL_STRIPE(x)		\
8862306a36Sopenharmony_ci			((x << CL_SD_CTL_STRIPE_SHIFT) & CL_SD_CTL_STRIPE_MASK)
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci/* Traffic Priority */
9162306a36Sopenharmony_ci#define CL_SD_CTL_TP_SHIFT		18
9262306a36Sopenharmony_ci#define CL_SD_CTL_TP_MASK		(1 << CL_SD_CTL_TP_SHIFT)
9362306a36Sopenharmony_ci#define CL_SD_CTL_TP(x)			\
9462306a36Sopenharmony_ci			((x << CL_SD_CTL_TP_SHIFT) & CL_SD_CTL_TP_MASK)
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci/* Bidirectional Direction Control */
9762306a36Sopenharmony_ci#define CL_SD_CTL_DIR_SHIFT		19
9862306a36Sopenharmony_ci#define CL_SD_CTL_DIR_MASK		(1 << CL_SD_CTL_DIR_SHIFT)
9962306a36Sopenharmony_ci#define CL_SD_CTL_DIR(x)		\
10062306a36Sopenharmony_ci			((x << CL_SD_CTL_DIR_SHIFT) & CL_SD_CTL_DIR_MASK)
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* Stream Number */
10362306a36Sopenharmony_ci#define CL_SD_CTL_STRM_SHIFT		20
10462306a36Sopenharmony_ci#define CL_SD_CTL_STRM_MASK		(0xf << CL_SD_CTL_STRM_SHIFT)
10562306a36Sopenharmony_ci#define CL_SD_CTL_STRM(x)		\
10662306a36Sopenharmony_ci			((x << CL_SD_CTL_STRM_SHIFT) & CL_SD_CTL_STRM_MASK)
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci/* CL: Stream Descriptor x Status */
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci/* Buffer Completion Interrupt Status */
11162306a36Sopenharmony_ci#define CL_SD_STS_BCIS(x)		CL_SD_CTL_IOCE(x)
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci/* FIFO Error */
11462306a36Sopenharmony_ci#define CL_SD_STS_FIFOE(x)		CL_SD_CTL_FEIE(x)
11562306a36Sopenharmony_ci
11662306a36Sopenharmony_ci/* Descriptor Error */
11762306a36Sopenharmony_ci#define CL_SD_STS_DESE(x)		CL_SD_CTL_DEIE(x)
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci/* FIFO Ready */
12062306a36Sopenharmony_ci#define CL_SD_STS_FIFORDY(x)	CL_SD_CTL_FIFOLC(x)
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_ci/* CL: Stream Descriptor x Last Valid Index */
12462306a36Sopenharmony_ci#define CL_SD_LVI_SHIFT			0
12562306a36Sopenharmony_ci#define CL_SD_LVI_MASK			(0xff << CL_SD_LVI_SHIFT)
12662306a36Sopenharmony_ci#define CL_SD_LVI(x)			((x << CL_SD_LVI_SHIFT) & CL_SD_LVI_MASK)
12762306a36Sopenharmony_ci
12862306a36Sopenharmony_ci/* CL: Stream Descriptor x FIFO Eviction Watermark */
12962306a36Sopenharmony_ci#define CL_SD_FIFOW_SHIFT		0
13062306a36Sopenharmony_ci#define CL_SD_FIFOW_MASK		(0x7 << CL_SD_FIFOW_SHIFT)
13162306a36Sopenharmony_ci#define CL_SD_FIFOW(x)			\
13262306a36Sopenharmony_ci			((x << CL_SD_FIFOW_SHIFT) & CL_SD_FIFOW_MASK)
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ci/* CL: Stream Descriptor x Buffer Descriptor List Pointer Lower Base Address */
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci/* Protect Bits */
13762306a36Sopenharmony_ci#define CL_SD_BDLPLBA_PROT_SHIFT	0
13862306a36Sopenharmony_ci#define CL_SD_BDLPLBA_PROT_MASK		(1 << CL_SD_BDLPLBA_PROT_SHIFT)
13962306a36Sopenharmony_ci#define CL_SD_BDLPLBA_PROT(x)		\
14062306a36Sopenharmony_ci		((x << CL_SD_BDLPLBA_PROT_SHIFT) & CL_SD_BDLPLBA_PROT_MASK)
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci/* Buffer Descriptor List Lower Base Address */
14362306a36Sopenharmony_ci#define CL_SD_BDLPLBA_SHIFT		7
14462306a36Sopenharmony_ci#define CL_SD_BDLPLBA_MASK		(0x1ffffff << CL_SD_BDLPLBA_SHIFT)
14562306a36Sopenharmony_ci#define CL_SD_BDLPLBA(x)		\
14662306a36Sopenharmony_ci	((BDL_ALIGN(lower_32_bits(x)) << CL_SD_BDLPLBA_SHIFT) & CL_SD_BDLPLBA_MASK)
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_ci/* Buffer Descriptor List Upper Base Address */
14962306a36Sopenharmony_ci#define CL_SD_BDLPUBA_SHIFT		0
15062306a36Sopenharmony_ci#define CL_SD_BDLPUBA_MASK		(0xffffffff << CL_SD_BDLPUBA_SHIFT)
15162306a36Sopenharmony_ci#define CL_SD_BDLPUBA(x)		\
15262306a36Sopenharmony_ci		((upper_32_bits(x) << CL_SD_BDLPUBA_SHIFT) & CL_SD_BDLPUBA_MASK)
15362306a36Sopenharmony_ci
15462306a36Sopenharmony_ci/*
15562306a36Sopenharmony_ci * Code Loader - Software Position Based FIFO
15662306a36Sopenharmony_ci * Capability Registers x Software Position Based FIFO Header
15762306a36Sopenharmony_ci */
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci/* Next Capability Pointer */
16062306a36Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_PTR_SHIFT	0
16162306a36Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_PTR_MASK	(0xff << CL_SPBFIFO_SPBFCH_PTR_SHIFT)
16262306a36Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_PTR(x)	\
16362306a36Sopenharmony_ci		((x << CL_SPBFIFO_SPBFCH_PTR_SHIFT) & CL_SPBFIFO_SPBFCH_PTR_MASK)
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci/* Capability Identifier */
16662306a36Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_ID_SHIFT	16
16762306a36Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_ID_MASK	(0xfff << CL_SPBFIFO_SPBFCH_ID_SHIFT)
16862306a36Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_ID(x)		\
16962306a36Sopenharmony_ci		((x << CL_SPBFIFO_SPBFCH_ID_SHIFT) & CL_SPBFIFO_SPBFCH_ID_MASK)
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci/* Capability Version */
17262306a36Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_VER_SHIFT	28
17362306a36Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_VER_MASK	(0xf << CL_SPBFIFO_SPBFCH_VER_SHIFT)
17462306a36Sopenharmony_ci#define CL_SPBFIFO_SPBFCH_VER(x)	\
17562306a36Sopenharmony_ci	((x << CL_SPBFIFO_SPBFCH_VER_SHIFT) & CL_SPBFIFO_SPBFCH_VER_MASK)
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci/* Software Position in Buffer Enable */
17862306a36Sopenharmony_ci#define CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT	0
17962306a36Sopenharmony_ci#define CL_SPBFIFO_SPBFCCTL_SPIBE_MASK	(1 << CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT)
18062306a36Sopenharmony_ci#define CL_SPBFIFO_SPBFCCTL_SPIBE(x)	\
18162306a36Sopenharmony_ci	((x << CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT) & CL_SPBFIFO_SPBFCCTL_SPIBE_MASK)
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci/* SST IPC SKL defines */
18462306a36Sopenharmony_ci#define SKL_WAIT_TIMEOUT		500	/* 500 msec */
18562306a36Sopenharmony_ci#define SKL_MAX_BUFFER_SIZE		(32 * PAGE_SIZE)
18662306a36Sopenharmony_ci
18762306a36Sopenharmony_cienum skl_cl_dma_wake_states {
18862306a36Sopenharmony_ci	SKL_CL_DMA_STATUS_NONE = 0,
18962306a36Sopenharmony_ci	SKL_CL_DMA_BUF_COMPLETE,
19062306a36Sopenharmony_ci	SKL_CL_DMA_ERR,	/* TODO: Expand the error states */
19162306a36Sopenharmony_ci};
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_cistruct sst_dsp;
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_cistruct skl_cl_dev_ops {
19662306a36Sopenharmony_ci	void (*cl_setup_bdle)(struct sst_dsp *ctx,
19762306a36Sopenharmony_ci			struct snd_dma_buffer *dmab_data,
19862306a36Sopenharmony_ci			__le32 **bdlp, int size, int with_ioc);
19962306a36Sopenharmony_ci	void (*cl_setup_controller)(struct sst_dsp *ctx,
20062306a36Sopenharmony_ci			struct snd_dma_buffer *dmab_bdl,
20162306a36Sopenharmony_ci			unsigned int max_size, u32 page_count);
20262306a36Sopenharmony_ci	void (*cl_setup_spb)(struct sst_dsp  *ctx,
20362306a36Sopenharmony_ci			unsigned int size, bool enable);
20462306a36Sopenharmony_ci	void (*cl_cleanup_spb)(struct sst_dsp  *ctx);
20562306a36Sopenharmony_ci	void (*cl_trigger)(struct sst_dsp  *ctx, bool enable);
20662306a36Sopenharmony_ci	void (*cl_cleanup_controller)(struct sst_dsp  *ctx);
20762306a36Sopenharmony_ci	int (*cl_copy_to_dmabuf)(struct sst_dsp *ctx,
20862306a36Sopenharmony_ci			const void *bin, u32 size, bool wait);
20962306a36Sopenharmony_ci	void (*cl_stop_dma)(struct sst_dsp *ctx);
21062306a36Sopenharmony_ci};
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci/**
21362306a36Sopenharmony_ci * skl_cl_dev - holds information for code loader dma transfer
21462306a36Sopenharmony_ci *
21562306a36Sopenharmony_ci * @dmab_data: buffer pointer
21662306a36Sopenharmony_ci * @dmab_bdl: buffer descriptor list
21762306a36Sopenharmony_ci * @bufsize: ring buffer size
21862306a36Sopenharmony_ci * @frags: Last valid buffer descriptor index in the BDL
21962306a36Sopenharmony_ci * @curr_spib_pos: Current position in ring buffer
22062306a36Sopenharmony_ci * @dma_buffer_offset: dma buffer offset
22162306a36Sopenharmony_ci * @ops: operations supported on CL dma
22262306a36Sopenharmony_ci * @wait_queue: wait queue to wake for wake event
22362306a36Sopenharmony_ci * @wake_status: DMA wake status
22462306a36Sopenharmony_ci * @wait_condition: condition to wait on wait queue
22562306a36Sopenharmony_ci * @cl_dma_lock: for synchronized access to cldma
22662306a36Sopenharmony_ci */
22762306a36Sopenharmony_cistruct skl_cl_dev {
22862306a36Sopenharmony_ci	struct snd_dma_buffer dmab_data;
22962306a36Sopenharmony_ci	struct snd_dma_buffer dmab_bdl;
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci	unsigned int bufsize;
23262306a36Sopenharmony_ci	unsigned int frags;
23362306a36Sopenharmony_ci
23462306a36Sopenharmony_ci	unsigned int curr_spib_pos;
23562306a36Sopenharmony_ci	unsigned int dma_buffer_offset;
23662306a36Sopenharmony_ci	struct skl_cl_dev_ops ops;
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci	wait_queue_head_t wait_queue;
23962306a36Sopenharmony_ci	int wake_status;
24062306a36Sopenharmony_ci	bool wait_condition;
24162306a36Sopenharmony_ci};
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci#endif /* SKL_SST_CLDMA_H_ */
244