skl-sst-cldma.h 8.1 KB
Newer Older
1
/* SPDX-License-Identifier: GPL-2.0-only */
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
/*
 * Intel Code Loader DMA support
 *
 * Copyright (C) 2015, Intel Corporation.
 */

#ifndef SKL_SST_CLDMA_H_
#define SKL_SST_CLDMA_H_

#define FW_CL_STREAM_NUMBER		0x1

#define DMA_ADDRESS_128_BITS_ALIGNMENT	7
#define BDL_ALIGN(x)			(x >> DMA_ADDRESS_128_BITS_ALIGNMENT)

#define SKL_ADSPIC_CL_DMA			0x2
#define SKL_ADSPIS_CL_DMA			0x2
#define SKL_CL_DMA_SD_INT_DESC_ERR		0x10 /* Descriptor error interrupt */
#define SKL_CL_DMA_SD_INT_FIFO_ERR		0x08 /* FIFO error interrupt */
#define SKL_CL_DMA_SD_INT_COMPLETE		0x04 /* Buffer completion interrupt */

/* Intel HD Audio Code Loader DMA Registers */

#define HDA_ADSP_LOADER_BASE		0x80

/* Stream Registers */
#define SKL_ADSP_REG_CL_SD_CTL			(HDA_ADSP_LOADER_BASE + 0x00)
#define SKL_ADSP_REG_CL_SD_STS			(HDA_ADSP_LOADER_BASE + 0x03)
#define SKL_ADSP_REG_CL_SD_LPIB			(HDA_ADSP_LOADER_BASE + 0x04)
#define SKL_ADSP_REG_CL_SD_CBL			(HDA_ADSP_LOADER_BASE + 0x08)
#define SKL_ADSP_REG_CL_SD_LVI			(HDA_ADSP_LOADER_BASE + 0x0c)
#define SKL_ADSP_REG_CL_SD_FIFOW		(HDA_ADSP_LOADER_BASE + 0x0e)
#define SKL_ADSP_REG_CL_SD_FIFOSIZE		(HDA_ADSP_LOADER_BASE + 0x10)
#define SKL_ADSP_REG_CL_SD_FORMAT		(HDA_ADSP_LOADER_BASE + 0x12)
#define SKL_ADSP_REG_CL_SD_FIFOL		(HDA_ADSP_LOADER_BASE + 0x14)
#define SKL_ADSP_REG_CL_SD_BDLPL		(HDA_ADSP_LOADER_BASE + 0x18)
#define SKL_ADSP_REG_CL_SD_BDLPU		(HDA_ADSP_LOADER_BASE + 0x1c)

/* CL: Software Position Based FIFO Capability Registers */
#define SKL_ADSP_REG_CL_SPBFIFO			(HDA_ADSP_LOADER_BASE + 0x20)
#define SKL_ADSP_REG_CL_SPBFIFO_SPBFCH		(SKL_ADSP_REG_CL_SPBFIFO + 0x0)
#define SKL_ADSP_REG_CL_SPBFIFO_SPBFCCTL	(SKL_ADSP_REG_CL_SPBFIFO + 0x4)
#define SKL_ADSP_REG_CL_SPBFIFO_SPIB		(SKL_ADSP_REG_CL_SPBFIFO + 0x8)
#define SKL_ADSP_REG_CL_SPBFIFO_MAXFIFOS	(SKL_ADSP_REG_CL_SPBFIFO + 0xc)

/* CL: Stream Descriptor x Control */

/* Stream Reset */
#define CL_SD_CTL_SRST_SHIFT		0
#define CL_SD_CTL_SRST_MASK		(1 << CL_SD_CTL_SRST_SHIFT)
#define CL_SD_CTL_SRST(x)		\
			((x << CL_SD_CTL_SRST_SHIFT) & CL_SD_CTL_SRST_MASK)

/* Stream Run */
#define CL_SD_CTL_RUN_SHIFT		1
#define CL_SD_CTL_RUN_MASK		(1 << CL_SD_CTL_RUN_SHIFT)
#define CL_SD_CTL_RUN(x)		\
			((x << CL_SD_CTL_RUN_SHIFT) & CL_SD_CTL_RUN_MASK)

/* Interrupt On Completion Enable */
#define CL_SD_CTL_IOCE_SHIFT		2
#define CL_SD_CTL_IOCE_MASK		(1 << CL_SD_CTL_IOCE_SHIFT)
#define CL_SD_CTL_IOCE(x)		\
			((x << CL_SD_CTL_IOCE_SHIFT) & CL_SD_CTL_IOCE_MASK)

/* FIFO Error Interrupt Enable */
#define CL_SD_CTL_FEIE_SHIFT		3
#define CL_SD_CTL_FEIE_MASK		(1 << CL_SD_CTL_FEIE_SHIFT)
#define CL_SD_CTL_FEIE(x)		\
			((x << CL_SD_CTL_FEIE_SHIFT) & CL_SD_CTL_FEIE_MASK)

/* Descriptor Error Interrupt Enable */
#define CL_SD_CTL_DEIE_SHIFT		4
#define CL_SD_CTL_DEIE_MASK		(1 << CL_SD_CTL_DEIE_SHIFT)
#define CL_SD_CTL_DEIE(x)		\
			((x << CL_SD_CTL_DEIE_SHIFT) & CL_SD_CTL_DEIE_MASK)

/* FIFO Limit Change */
#define CL_SD_CTL_FIFOLC_SHIFT		5
#define CL_SD_CTL_FIFOLC_MASK		(1 << CL_SD_CTL_FIFOLC_SHIFT)
#define CL_SD_CTL_FIFOLC(x)		\
			((x << CL_SD_CTL_FIFOLC_SHIFT) & CL_SD_CTL_FIFOLC_MASK)

/* Stripe Control */
#define CL_SD_CTL_STRIPE_SHIFT		16
#define CL_SD_CTL_STRIPE_MASK		(0x3 << CL_SD_CTL_STRIPE_SHIFT)
#define CL_SD_CTL_STRIPE(x)		\
			((x << CL_SD_CTL_STRIPE_SHIFT) & CL_SD_CTL_STRIPE_MASK)

/* Traffic Priority */
#define CL_SD_CTL_TP_SHIFT		18
#define CL_SD_CTL_TP_MASK		(1 << CL_SD_CTL_TP_SHIFT)
#define CL_SD_CTL_TP(x)			\
			((x << CL_SD_CTL_TP_SHIFT) & CL_SD_CTL_TP_MASK)

/* Bidirectional Direction Control */
#define CL_SD_CTL_DIR_SHIFT		19
#define CL_SD_CTL_DIR_MASK		(1 << CL_SD_CTL_DIR_SHIFT)
#define CL_SD_CTL_DIR(x)		\
			((x << CL_SD_CTL_DIR_SHIFT) & CL_SD_CTL_DIR_MASK)

/* Stream Number */
#define CL_SD_CTL_STRM_SHIFT		20
#define CL_SD_CTL_STRM_MASK		(0xf << CL_SD_CTL_STRM_SHIFT)
#define CL_SD_CTL_STRM(x)		\
			((x << CL_SD_CTL_STRM_SHIFT) & CL_SD_CTL_STRM_MASK)

/* CL: Stream Descriptor x Status */

/* Buffer Completion Interrupt Status */
#define CL_SD_STS_BCIS(x)		CL_SD_CTL_IOCE(x)

/* FIFO Error */
#define CL_SD_STS_FIFOE(x)		CL_SD_CTL_FEIE(x)

/* Descriptor Error */
#define CL_SD_STS_DESE(x)		CL_SD_CTL_DEIE(x)

/* FIFO Ready */
#define CL_SD_STS_FIFORDY(x)	CL_SD_CTL_FIFOLC(x)


/* CL: Stream Descriptor x Last Valid Index */
#define CL_SD_LVI_SHIFT			0
#define CL_SD_LVI_MASK			(0xff << CL_SD_LVI_SHIFT)
#define CL_SD_LVI(x)			((x << CL_SD_LVI_SHIFT) & CL_SD_LVI_MASK)

/* CL: Stream Descriptor x FIFO Eviction Watermark */
#define CL_SD_FIFOW_SHIFT		0
#define CL_SD_FIFOW_MASK		(0x7 << CL_SD_FIFOW_SHIFT)
#define CL_SD_FIFOW(x)			\
			((x << CL_SD_FIFOW_SHIFT) & CL_SD_FIFOW_MASK)

/* CL: Stream Descriptor x Buffer Descriptor List Pointer Lower Base Address */

/* Protect Bits */
#define CL_SD_BDLPLBA_PROT_SHIFT	0
#define CL_SD_BDLPLBA_PROT_MASK		(1 << CL_SD_BDLPLBA_PROT_SHIFT)
#define CL_SD_BDLPLBA_PROT(x)		\
		((x << CL_SD_BDLPLBA_PROT_SHIFT) & CL_SD_BDLPLBA_PROT_MASK)

/* Buffer Descriptor List Lower Base Address */
#define CL_SD_BDLPLBA_SHIFT		7
#define CL_SD_BDLPLBA_MASK		(0x1ffffff << CL_SD_BDLPLBA_SHIFT)
#define CL_SD_BDLPLBA(x)		\
	((BDL_ALIGN(lower_32_bits(x)) << CL_SD_BDLPLBA_SHIFT) & CL_SD_BDLPLBA_MASK)

/* Buffer Descriptor List Upper Base Address */
#define CL_SD_BDLPUBA_SHIFT		0
#define CL_SD_BDLPUBA_MASK		(0xffffffff << CL_SD_BDLPUBA_SHIFT)
#define CL_SD_BDLPUBA(x)		\
		((upper_32_bits(x) << CL_SD_BDLPUBA_SHIFT) & CL_SD_BDLPUBA_MASK)

/*
 * Code Loader - Software Position Based FIFO
 * Capability Registers x Software Position Based FIFO Header
 */

/* Next Capability Pointer */
#define CL_SPBFIFO_SPBFCH_PTR_SHIFT	0
#define CL_SPBFIFO_SPBFCH_PTR_MASK	(0xff << CL_SPBFIFO_SPBFCH_PTR_SHIFT)
#define CL_SPBFIFO_SPBFCH_PTR(x)	\
		((x << CL_SPBFIFO_SPBFCH_PTR_SHIFT) & CL_SPBFIFO_SPBFCH_PTR_MASK)

/* Capability Identifier */
#define CL_SPBFIFO_SPBFCH_ID_SHIFT	16
#define CL_SPBFIFO_SPBFCH_ID_MASK	(0xfff << CL_SPBFIFO_SPBFCH_ID_SHIFT)
#define CL_SPBFIFO_SPBFCH_ID(x)		\
		((x << CL_SPBFIFO_SPBFCH_ID_SHIFT) & CL_SPBFIFO_SPBFCH_ID_MASK)

/* Capability Version */
#define CL_SPBFIFO_SPBFCH_VER_SHIFT	28
#define CL_SPBFIFO_SPBFCH_VER_MASK	(0xf << CL_SPBFIFO_SPBFCH_VER_SHIFT)
#define CL_SPBFIFO_SPBFCH_VER(x)	\
	((x << CL_SPBFIFO_SPBFCH_VER_SHIFT) & CL_SPBFIFO_SPBFCH_VER_MASK)

/* Software Position in Buffer Enable */
#define CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT	0
#define CL_SPBFIFO_SPBFCCTL_SPIBE_MASK	(1 << CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT)
#define CL_SPBFIFO_SPBFCCTL_SPIBE(x)	\
	((x << CL_SPBFIFO_SPBFCCTL_SPIBE_SHIFT) & CL_SPBFIFO_SPBFCCTL_SPIBE_MASK)

183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
/* SST IPC SKL defines */
#define SKL_WAIT_TIMEOUT		500	/* 500 msec */
#define SKL_MAX_BUFFER_SIZE		(32 * PAGE_SIZE)

enum skl_cl_dma_wake_states {
	SKL_CL_DMA_STATUS_NONE = 0,
	SKL_CL_DMA_BUF_COMPLETE,
	SKL_CL_DMA_ERR,	/* TODO: Expand the error states */
};

struct sst_dsp;

struct skl_cl_dev_ops {
	void (*cl_setup_bdle)(struct sst_dsp *ctx,
			struct snd_dma_buffer *dmab_data,
198
			__le32 **bdlp, int size, int with_ioc);
199 200 201 202 203 204 205 206 207
	void (*cl_setup_controller)(struct sst_dsp *ctx,
			struct snd_dma_buffer *dmab_bdl,
			unsigned int max_size, u32 page_count);
	void (*cl_setup_spb)(struct sst_dsp  *ctx,
			unsigned int size, bool enable);
	void (*cl_cleanup_spb)(struct sst_dsp  *ctx);
	void (*cl_trigger)(struct sst_dsp  *ctx, bool enable);
	void (*cl_cleanup_controller)(struct sst_dsp  *ctx);
	int (*cl_copy_to_dmabuf)(struct sst_dsp *ctx,
208
			const void *bin, u32 size, bool wait);
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242
	void (*cl_stop_dma)(struct sst_dsp *ctx);
};

/**
 * skl_cl_dev - holds information for code loader dma transfer
 *
 * @dmab_data: buffer pointer
 * @dmab_bdl: buffer descriptor list
 * @bufsize: ring buffer size
 * @frags: Last valid buffer descriptor index in the BDL
 * @curr_spib_pos: Current position in ring buffer
 * @dma_buffer_offset: dma buffer offset
 * @ops: operations supported on CL dma
 * @wait_queue: wait queue to wake for wake event
 * @wake_status: DMA wake status
 * @wait_condition: condition to wait on wait queue
 * @cl_dma_lock: for synchronized access to cldma
 */
struct skl_cl_dev {
	struct snd_dma_buffer dmab_data;
	struct snd_dma_buffer dmab_bdl;

	unsigned int bufsize;
	unsigned int frags;

	unsigned int curr_spib_pos;
	unsigned int dma_buffer_offset;
	struct skl_cl_dev_ops ops;

	wait_queue_head_t wait_queue;
	int wake_status;
	bool wait_condition;
};

243
#endif /* SKL_SST_CLDMA_H_ */