1 /* SPDX-License-Identifier: BSD-3-Clause
2  *
3  * Copyright(c) 2016 Intel Corporation. All rights reserved.
4  *
5  * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
6  *         Keyon Jie <yang.jie@linux.intel.com>
7  */
8 
9 #ifndef __SOF_DRIVERS_DW_DMA_H__
10 #define __SOF_DRIVERS_DW_DMA_H__
11 
12 #include <platform/drivers/dw-dma.h>
13 #include <sof/bit.h>
14 #include <sof/common.h>
15 #include <sof/lib/dma.h>
16 #include <sof/trace/trace.h>
17 #include <user/trace.h>
18 #include <stdint.h>
19 
20 /* channel registers */
21 #define DW_MAX_CHAN		8
22 #define DW_FIFO_SIZE		0x80
23 #define DW_CHAN_SIZE		0x58
24 #define DW_CHAN_OFFSET(chan)	(DW_CHAN_SIZE * (chan))
25 
26 #define DW_SAR(chan)		(0x00 + DW_CHAN_OFFSET(chan))
27 #define DW_DAR(chan)		(0x08 + DW_CHAN_OFFSET(chan))
28 #define DW_LLP(chan)		(0x10 + DW_CHAN_OFFSET(chan))
29 #define DW_CTRL_LOW(chan)	(0x18 + DW_CHAN_OFFSET(chan))
30 #define DW_CTRL_HIGH(chan)	(0x1C + DW_CHAN_OFFSET(chan))
31 #define DW_CFG_LOW(chan)	(0x40 + DW_CHAN_OFFSET(chan))
32 #define DW_CFG_HIGH(chan)	(0x44 + DW_CHAN_OFFSET(chan))
33 #define DW_DSR(chan)		(0x50 + DW_CHAN_OFFSET(chan))
34 
35 /* common registers */
36 #define DW_RAW_TFR		0x2C0
37 #define DW_RAW_BLOCK		0x2C8
38 #define DW_RAW_SRC_TRAN		0x2D0
39 #define DW_RAW_DST_TRAN		0x2D8
40 #define DW_RAW_ERR		0x2E0
41 #define DW_STATUS_TFR		0x2E8
42 #define DW_STATUS_BLOCK		0x2F0
43 #define DW_STATUS_SRC_TRAN	0x2F8
44 #define DW_STATUS_DST_TRAN	0x300
45 #define DW_STATUS_ERR		0x308
46 #define DW_MASK_TFR		0x310
47 #define DW_MASK_BLOCK		0x318
48 #define DW_MASK_SRC_TRAN	0x320
49 #define DW_MASK_DST_TRAN	0x328
50 #define DW_MASK_ERR		0x330
51 #define DW_CLEAR_TFR		0x338
52 #define DW_CLEAR_BLOCK		0x340
53 #define DW_CLEAR_SRC_TRAN	0x348
54 #define DW_CLEAR_DST_TRAN	0x350
55 #define DW_CLEAR_ERR		0x358
56 #define DW_INTR_STATUS		0x360
57 #define DW_DMA_CFG		0x398
58 #define DW_DMA_CHAN_EN		0x3A0
59 #define DW_FIFO_PART0_LO	0x400
60 #define DW_FIFO_PART0_HI	0x404
61 #define DW_FIFO_PART1_LO	0x408
62 #define DW_FIFO_PART1_HI	0x40C
63 
64 /* channel bits */
65 #define DW_CHAN_WRITE_EN_ALL	MASK(2 * DW_MAX_CHAN - 1, DW_MAX_CHAN)
66 #define DW_CHAN_WRITE_EN(chan)	BIT((chan) + DW_MAX_CHAN)
67 #define DW_CHAN_ALL		MASK(DW_MAX_CHAN - 1, 0)
68 #define DW_CHAN(chan)		BIT(chan)
69 #define DW_CHAN_MASK_ALL	DW_CHAN_WRITE_EN_ALL
70 #define DW_CHAN_MASK(chan)	DW_CHAN_WRITE_EN(chan)
71 #define DW_CHAN_UNMASK_ALL	(DW_CHAN_WRITE_EN_ALL | DW_CHAN_ALL)
72 #define DW_CHAN_UNMASK(chan)	(DW_CHAN_WRITE_EN(chan) | DW_CHAN(chan))
73 
74 /* CFG_LO */
75 #define DW_CFGL_DRAIN		BIT(10)
76 #define DW_CFGL_FIFO_EMPTY	BIT(9)
77 #define DW_CFGL_SUSPEND		BIT(8)
78 
79 /* CTL_LO */
80 #define DW_CTLL_RELOAD_DST	BIT(31)
81 #define DW_CTLL_RELOAD_SRC	BIT(30)
82 #define DW_CTLL_LLP_S_EN	BIT(28)
83 #define DW_CTLL_LLP_D_EN	BIT(27)
84 #define DW_CTLL_SMS(x)		SET_BIT(25, x)
85 #define DW_CTLL_DMS(x)		SET_BIT(23, x)
86 #define DW_CTLL_FC_P2P		SET_BITS(21, 20, 3)
87 #define DW_CTLL_FC_P2M		SET_BITS(21, 20, 2)
88 #define DW_CTLL_FC_M2P		SET_BITS(21, 20, 1)
89 #define DW_CTLL_FC_M2M		SET_BITS(21, 20, 0)
90 #define DW_CTLL_D_SCAT_EN	BIT(18)
91 #define DW_CTLL_S_GATH_EN	BIT(17)
92 #define DW_CTLL_SRC_MSIZE(x)	SET_BITS(16, 14, x)
93 #define DW_CTLL_DST_MSIZE(x)	SET_BITS(13, 11, x)
94 #define DW_CTLL_SRC_FIX		SET_BITS(10, 9, 2)
95 #define DW_CTLL_SRC_DEC		SET_BITS(10, 9, 1)
96 #define DW_CTLL_SRC_INC		SET_BITS(10, 9, 0)
97 #define DW_CTLL_DST_FIX		SET_BITS(8, 7, 2)
98 #define DW_CTLL_DST_DEC		SET_BITS(8, 7, 1)
99 #define DW_CTLL_DST_INC		SET_BITS(8, 7, 0)
100 #define DW_CTLL_SRC_WIDTH(x)	SET_BITS(6, 4, x)
101 #define DW_CTLL_DST_WIDTH(x)	SET_BITS(3, 1, x)
102 #define DW_CTLL_INT_EN		BIT(0)
103 #define DW_CTLL_SRC_WIDTH_MASK	MASK(6, 4)
104 #define DW_CTLL_SRC_WIDTH_SHIFT	4
105 #define DW_CTLL_DST_WIDTH_MASK	MASK(3, 1)
106 #define DW_CTLL_DST_WIDTH_SHIFT	1
107 
108 /* DSR */
109 #define DW_DSR_DSC(x)		SET_BITS(31, 20, x)
110 #define DW_DSR_DSI(x)		SET_BITS(19, 0, x)
111 
112 /* FIFO_PART */
113 #define DW_FIFO_UPD		BIT(26)
114 #define DW_FIFO_CHx(x)		SET_BITS(25, 13, x)
115 #define DW_FIFO_CHy(x)		SET_BITS(12, 0, x)
116 
117 /* number of tries to wait for reset */
118 #define DW_DMA_CFG_TRIES	10000
119 
120 /* channel drain timeout in microseconds */
121 #define DW_DMA_TIMEOUT	1333
122 
123 /* min number of elems for config with irq disabled */
124 #define DW_DMA_CFG_NO_IRQ_MIN_ELEMS	3
125 
126 /* linked list item address */
127 #define DW_DMA_LLI_ADDRESS(lli, dir) \
128 	(((dir) == DMA_DIR_MEM_TO_DEV) ? ((lli)->sar) : ((lli)->dar))
129 
130 #define DW_DMA_BUFFER_ALIGNMENT 0x4
131 #define DW_DMA_COPY_ALIGNMENT	0x4
132 
133 /* LLI address alignment, in Bytes */
134 #ifndef DW_DMA_LLI_ALIGN
135 #define DW_DMA_LLI_ALIGN	32
136 #endif
137 
138 /* TODO: add FIFO sizes */
139 struct dw_chan_data {
140 	uint16_t class;
141 	uint16_t weight;
142 };
143 
144 struct dw_drv_plat_data {
145 	struct dw_chan_data chan[DW_MAX_CHAN];
146 };
147 
148 /* DMA descriptor used by HW */
149 struct dw_lli {
150 	uint32_t sar;
151 	uint32_t dar;
152 	uint32_t llp;
153 	uint32_t ctrl_lo;
154 	uint32_t ctrl_hi;
155 	uint32_t sstat;
156 	uint32_t dstat;
157 
158 	/* align to required bytes to make sure every item
159 	 * is aligned in case of more than two items
160 	 */
161 	uint8_t reserved[DW_DMA_LLI_ALIGN - sizeof(uint32_t) * 7];
162 } __packed;
163 
164 extern const struct dma_ops dw_dma_ops;
165 
166 #endif /* __SOF_DRIVERS_DW_DMA_H__ */
167