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