xref: /freebsd/sys/arm/freescale/vybrid/vf_edma.h (revision 40a8ac8f62b535d30349faf28cf47106b7041b83)
1 /*-
2  * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28 
29 #define	DMA_CR		0x000	/* Control */
30 #define	DMA_ES		0x004	/* Error Status */
31 #define	DMA_ERQ		0x00C	/* Enable Request */
32 #define	DMA_EEI		0x014	/* Enable Error Interrupt */
33 #define	DMA_CEEI	0x018	/* Clear Enable Error Interrupt */
34 #define	DMA_SEEI	0x019	/* Set Enable Error Interrupt */
35 #define	DMA_CERQ	0x01A	/* Clear Enable Request */
36 #define	DMA_SERQ	0x01B	/* Set Enable Request */
37 #define	DMA_CDNE	0x01C	/* Clear DONE Status Bit */
38 #define	DMA_SSRT	0x01D	/* Set START Bit */
39 #define	DMA_CERR	0x01E	/* Clear Error */
40 #define	 CERR_CAEI	(1 << 6) /* Clear All Error Indicators */
41 #define	DMA_CINT	0x01F	/* Clear Interrupt Request */
42 #define	 CINT_CAIR	(1 << 6) /* Clear All Interrupt Requests */
43 #define	DMA_INT		0x024	/* Interrupt Request */
44 #define	DMA_ERR		0x02C	/* Error */
45 #define	DMA_HRS		0x034	/* Hardware Request Status */
46 #define	DMA_EARS	0x044	/* Enable Asynchronous Request in Stop */
47 #define	DMA_DCHPRI3	0x100	/* Channel n Priority */
48 #define	DMA_DCHPRI2	0x101	/* Channel n Priority */
49 #define	DMA_DCHPRI1	0x102	/* Channel n Priority */
50 #define	DMA_DCHPRI0	0x103	/* Channel n Priority */
51 #define	DMA_DCHPRI7	0x104	/* Channel n Priority */
52 #define	DMA_DCHPRI6	0x105	/* Channel n Priority */
53 #define	DMA_DCHPRI5	0x106	/* Channel n Priority */
54 #define	DMA_DCHPRI4	0x107	/* Channel n Priority */
55 #define	DMA_DCHPRI11	0x108	/* Channel n Priority */
56 #define	DMA_DCHPRI10	0x109	/* Channel n Priority */
57 #define	DMA_DCHPRI9	0x10A	/* Channel n Priority */
58 #define	DMA_DCHPRI8	0x10B	/* Channel n Priority */
59 #define	DMA_DCHPRI15	0x10C	/* Channel n Priority */
60 #define	DMA_DCHPRI14	0x10D	/* Channel n Priority */
61 #define	DMA_DCHPRI13	0x10E	/* Channel n Priority */
62 #define	DMA_DCHPRI12	0x10F	/* Channel n Priority */
63 #define	DMA_DCHPRI19	0x110	/* Channel n Priority */
64 #define	DMA_DCHPRI18	0x111	/* Channel n Priority */
65 #define	DMA_DCHPRI17	0x112	/* Channel n Priority */
66 #define	DMA_DCHPRI16	0x113	/* Channel n Priority */
67 #define	DMA_DCHPRI23	0x114	/* Channel n Priority */
68 #define	DMA_DCHPRI22	0x115	/* Channel n Priority */
69 #define	DMA_DCHPRI21	0x116	/* Channel n Priority */
70 #define	DMA_DCHPRI20	0x117	/* Channel n Priority */
71 #define	DMA_DCHPRI27	0x118	/* Channel n Priority */
72 #define	DMA_DCHPRI26	0x119	/* Channel n Priority */
73 #define	DMA_DCHPRI25	0x11A	/* Channel n Priority */
74 #define	DMA_DCHPRI24	0x11B	/* Channel n Priority */
75 #define	DMA_DCHPRI31	0x11C	/* Channel n Priority */
76 #define	DMA_DCHPRI30	0x11D	/* Channel n Priority */
77 #define	DMA_DCHPRI29	0x11E	/* Channel n Priority */
78 #define	DMA_DCHPRI28	0x11F	/* Channel n Priority */
79 
80 #define	DMA_TCDn_SADDR(n)		(0x00 + 0x20 * n)	/* Source Address */
81 #define	DMA_TCDn_SOFF(n)		(0x04 + 0x20 * n)	/* Signed Source Address Offset */
82 #define	DMA_TCDn_ATTR(n)		(0x06 + 0x20 * n)	/* Transfer Attributes */
83 #define	DMA_TCDn_NBYTES_MLNO(n)		(0x08 + 0x20 * n)	/* Minor Byte Count */
84 #define	DMA_TCDn_NBYTES_MLOFFNO(n)	(0x08 + 0x20 * n)	/* Signed Minor Loop Offset */
85 #define	DMA_TCDn_NBYTES_MLOFFYES(n)	(0x08 + 0x20 * n)	/* Signed Minor Loop Offset */
86 #define	DMA_TCDn_SLAST(n)		(0x0C + 0x20 * n)	/* Last Source Address Adjustment */
87 #define	DMA_TCDn_DADDR(n)		(0x10 + 0x20 * n)	/* Destination Address */
88 #define	DMA_TCDn_DOFF(n)		(0x14 + 0x20 * n)	/* Signed Destination Address Offset */
89 #define	DMA_TCDn_CITER_ELINKYES(n)	(0x16 + 0x20 * n)	/* Current Minor Loop Link, Major Loop Count */
90 #define	DMA_TCDn_CITER_ELINKNO(n)	(0x16 + 0x20 * n)
91 #define	DMA_TCDn_DLASTSGA(n)		(0x18 + 0x20 * n)	/* Last Dst Addr Adjustment/Scatter Gather Address */
92 #define	DMA_TCDn_CSR(n)			(0x1C + 0x20 * n)	/* Control and Status */
93 #define	DMA_TCDn_BITER_ELINKYES(n)	(0x1E + 0x20 * n)	/* Beginning Minor Loop Link, Major Loop Count */
94 #define	DMA_TCDn_BITER_ELINKNO(n)	(0x1E + 0x20 * n)	/* Beginning Minor Loop Link, Major Loop Count */
95 
96 #define TCD_CSR_START			(1 << 0)
97 #define	TCD_CSR_INTMAJOR		(1 << 1)
98 #define	TCD_CSR_INTHALF			(1 << 2)
99 #define	TCD_CSR_DREQ			(1 << 3)
100 #define	TCD_CSR_ESG			(1 << 4)
101 #define	TCD_CSR_MAJORELINK		(1 << 5)
102 #define	TCD_CSR_ACTIVE			(1 << 6)
103 #define	TCD_CSR_DONE			(1 << 7)
104 #define	TCD_CSR_MAJORELINKCH_SHIFT	8
105 
106 #define	TCD_ATTR_SMOD_SHIFT		11	/* Source Address Modulo */
107 #define	TCD_ATTR_SSIZE_SHIFT		8	/* Source Data Transfer Size */
108 #define	TCD_ATTR_DMOD_SHIFT		3	/* Dst Address Modulo */
109 #define	TCD_ATTR_DSIZE_SHIFT		0	/* Dst Data Transfer Size */
110 
111 #define	TCD_READ4(_sc, _reg)		\
112 	bus_space_read_4(_sc->bst_tcd, _sc->bsh_tcd, _reg)
113 #define	TCD_WRITE4(_sc, _reg, _val)	\
114 	bus_space_write_4(_sc->bst_tcd, _sc->bsh_tcd, _reg, _val)
115 #define	TCD_READ2(_sc, _reg)		\
116 	bus_space_read_2(_sc->bst_tcd, _sc->bsh_tcd, _reg)
117 #define	TCD_WRITE2(_sc, _reg, _val)	\
118 	bus_space_write_2(_sc->bst_tcd, _sc->bsh_tcd, _reg, _val)
119 #define	TCD_READ1(_sc, _reg)		\
120 	bus_space_read_1(_sc->bst_tcd, _sc->bsh_tcd, _reg)
121 #define	TCD_WRITE1(_sc, _reg, _val)	\
122 	bus_space_write_1(_sc->bst_tcd, _sc->bsh_tcd, _reg, _val)
123 
124 #define	EDMA_NUM_DEVICES	2
125 #define	EDMA_NUM_CHANNELS	32
126 #define	NCHAN_PER_MUX		16
127 
128 struct tcd_conf {
129 	bus_addr_t	saddr;
130 	bus_addr_t	daddr;
131 	uint32_t	nbytes;
132 	uint32_t	nmajor;
133 	uint32_t	majorelink;
134 	uint32_t	majorelinkch;
135 	uint32_t	esg;
136 	uint32_t	smod;
137 	uint32_t	dmod;
138 	uint32_t	soff;
139 	uint32_t	doff;
140 	uint32_t	ssize;
141 	uint32_t	dsize;
142 	uint32_t	slast;
143 	uint32_t	dlast_sga;
144 	uint32_t	channel;
145 	uint32_t	(*ih)(void *, int);
146 	void		*ih_user;
147 };
148 
149 /*
150  * TCD struct is described at
151  * Vybrid Reference Manual, Rev. 5, 07/2013
152  *
153  * Should be used for Scatter/Gathering feature.
154  */
155 
156 struct TCD {
157 	uint32_t	saddr;
158 	uint16_t	attr;
159 	uint16_t	soff;
160 	uint32_t	nbytes;
161 	uint32_t	slast;
162 	uint32_t	daddr;
163 	uint16_t	citer;
164 	uint16_t	doff;
165 	uint32_t	dlast_sga;
166 	uint16_t	biter;
167 	uint16_t	csr;
168 } __packed;
169 
170 struct edma_softc {
171 	device_t		dev;
172 	struct resource		*res[4];
173 	bus_space_tag_t		bst;
174 	bus_space_handle_t	bsh;
175 	bus_space_tag_t		bst_tcd;
176 	bus_space_handle_t	bsh_tcd;
177 	void			*tc_ih;
178 	void			*err_ih;
179 	uint32_t		device_id;
180 
181 	int	(*channel_configure) (struct edma_softc *, int, int);
182 	int	(*channel_free) (struct edma_softc *, int);
183 	int	(*dma_request) (struct edma_softc *, int);
184 	int	(*dma_setup) (struct edma_softc *, struct tcd_conf *);
185 	int	(*dma_stop) (struct edma_softc *, int);
186 };
187