1239281Sgonzo/*-
2239281Sgonzo * Copyright (C) 2010 Texas Instruments Incorporated - http://www.ti.com/
3239281Sgonzo * Copyright (c) 2012 Damjan Marion <dmarion@Freebsd.org>
4239281Sgonzo * All rights reserved.
5239281Sgonzo *
6239281Sgonzo * Redistribution and use in source and binary forms, with or without
7239281Sgonzo * modification, are permitted provided that the following conditions
8239281Sgonzo * are met:
9239281Sgonzo * 1. Redistributions of source code must retain the above copyright
10239281Sgonzo *    notice, this list of conditions and the following disclaimer.
11239281Sgonzo * 2. Redistributions in binary form must reproduce the above copyright
12239281Sgonzo *    notice, this list of conditions and the following disclaimer in the
13239281Sgonzo *    documentation and/or other materials provided with the distribution.
14239281Sgonzo * 3. Neither the name of authors nor the names of its contributors may be
15239281Sgonzo *    used to endorse or promote products derived from this software without
16239281Sgonzo *    specific prior written permission.
17239281Sgonzo *
18239281Sgonzo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19239281Sgonzo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20239281Sgonzo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21239281Sgonzo * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22239281Sgonzo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23239281Sgonzo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24239281Sgonzo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25239281Sgonzo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26239281Sgonzo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27239281Sgonzo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28239281Sgonzo * SUCH DAMAGE.
29239281Sgonzo */
30239281Sgonzo
31239281Sgonzo#include <sys/cdefs.h>
32239281Sgonzo__FBSDID("$FreeBSD$");
33239281Sgonzo
34239281Sgonzo#include <sys/param.h>
35239281Sgonzo#include <sys/systm.h>
36239281Sgonzo#include <sys/endian.h>
37239281Sgonzo#include <sys/mbuf.h>
38239281Sgonzo#include <sys/lock.h>
39239281Sgonzo#include <sys/mutex.h>
40239281Sgonzo#include <sys/kernel.h>
41239281Sgonzo#include <sys/module.h>
42239281Sgonzo#include <sys/socket.h>
43239281Sgonzo#include <sys/sysctl.h>
44239281Sgonzo
45239281Sgonzo#include <sys/sockio.h>
46239281Sgonzo#include <sys/bus.h>
47239281Sgonzo#include <machine/bus.h>
48239281Sgonzo#include <sys/rman.h>
49239281Sgonzo#include <machine/resource.h>
50239281Sgonzo
51239281Sgonzo#include <dev/fdt/fdt_common.h>
52239281Sgonzo#include <dev/ofw/ofw_bus.h>
53239281Sgonzo#include <dev/ofw/ofw_bus_subr.h>
54239281Sgonzo
55239281Sgonzo#include <arm/ti/ti_scm.h>
56239281Sgonzo#include <arm/ti/ti_prcm.h>
57239281Sgonzo
58239281Sgonzo#include <arm/ti/ti_edma3.h>
59239281Sgonzo
60239281Sgonzo#define TI_EDMA3_NUM_TCS		3
61239281Sgonzo#define TI_EDMA3_NUM_IRQS		3
62239281Sgonzo#define TI_EDMA3_NUM_DMA_CHS		64
63239281Sgonzo#define TI_EDMA3_NUM_QDMA_CHS		8
64239281Sgonzo
65239281Sgonzo#define TI_EDMA3CC_PID			0x000
66239281Sgonzo#define TI_EDMA3CC_DCHMAP(p)		(0x100 + ((p)*4))
67239281Sgonzo#define TI_EDMA3CC_DMAQNUM(n)		(0x240 + ((n)*4))
68239281Sgonzo#define TI_EDMA3CC_QDMAQNUM		0x260
69239281Sgonzo#define TI_EDMA3CC_EMCR			0x308
70239281Sgonzo#define TI_EDMA3CC_EMCRH		0x30C
71239281Sgonzo#define TI_EDMA3CC_QEMCR		0x314
72239281Sgonzo#define TI_EDMA3CC_CCERR		0x318
73239281Sgonzo#define TI_EDMA3CC_CCERRCLR		0x31C
74239281Sgonzo#define TI_EDMA3CC_DRAE(p)		(0x340 + ((p)*8))
75239281Sgonzo#define TI_EDMA3CC_DRAEH(p)		(0x344 + ((p)*8))
76239281Sgonzo#define TI_EDMA3CC_QRAE(p)		(0x380 + ((p)*4))
77239281Sgonzo#define TI_EDMA3CC_S_ESR(p)		(0x2010 + ((p)*0x200))
78239281Sgonzo#define TI_EDMA3CC_S_ESRH(p)		(0x2014 + ((p)*0x200))
79239281Sgonzo#define TI_EDMA3CC_S_SECR(p)		(0x2040 + ((p)*0x200))
80239281Sgonzo#define TI_EDMA3CC_S_SECRH(p)		(0x2044 + ((p)*0x200))
81239281Sgonzo#define TI_EDMA3CC_S_EESR(p)		(0x2030 + ((p)*0x200))
82239281Sgonzo#define TI_EDMA3CC_S_EESRH(p)		(0x2034 + ((p)*0x200))
83239281Sgonzo#define TI_EDMA3CC_S_IESR(p)		(0x2060 + ((p)*0x200))
84239281Sgonzo#define TI_EDMA3CC_S_IESRH(p)		(0x2064 + ((p)*0x200))
85239281Sgonzo#define TI_EDMA3CC_S_IPR(p)		(0x2068 + ((p)*0x200))
86239281Sgonzo#define TI_EDMA3CC_S_IPRH(p)		(0x206C + ((p)*0x200))
87239281Sgonzo#define TI_EDMA3CC_S_QEESR(p)		(0x208C + ((p)*0x200))
88239281Sgonzo
89239281Sgonzo#define TI_EDMA3CC_PARAM_OFFSET		0x4000
90239281Sgonzo#define TI_EDMA3CC_OPT(p)		(TI_EDMA3CC_PARAM_OFFSET + 0x0 + ((p)*0x20))
91239281Sgonzo
92239281Sgonzo#define TI_EDMA3CC_DMAQNUM_SET(c,q)	((0x7 & (q)) << (((c) % 8) * 4))
93239281Sgonzo#define TI_EDMA3CC_DMAQNUM_CLR(c)	(~(0x7 << (((c) % 8) * 4)))
94239281Sgonzo#define TI_EDMA3CC_QDMAQNUM_SET(c,q)	((0x7 & (q)) << ((c) * 4))
95239281Sgonzo#define TI_EDMA3CC_QDMAQNUM_CLR(c)	(~(0x7 << ((c) * 4)))
96239281Sgonzo
97239281Sgonzo#define TI_EDMA3CC_OPT_TCC_CLR		(~(0x3F000))
98239281Sgonzo#define TI_EDMA3CC_OPT_TCC_SET(p)	(((0x3F000 >> 12) & (p)) << 12)
99239281Sgonzo
100239281Sgonzostruct ti_edma3_softc {
101239281Sgonzo	device_t		sc_dev;
102239281Sgonzo	struct resource *	mem_res[TI_EDMA3_NUM_TCS+1];
103239281Sgonzo	struct resource *	irq_res[TI_EDMA3_NUM_IRQS];
104239281Sgonzo	void			*ih_cookie[TI_EDMA3_NUM_IRQS];
105239281Sgonzo};
106239281Sgonzo
107239281Sgonzostatic struct ti_edma3_softc *ti_edma3_sc = NULL;
108239281Sgonzo
109239281Sgonzostatic struct resource_spec ti_edma3_mem_spec[] = {
110239281Sgonzo	{ SYS_RES_MEMORY,   0,  RF_ACTIVE },
111239281Sgonzo	{ SYS_RES_MEMORY,   1,  RF_ACTIVE },
112239281Sgonzo	{ SYS_RES_MEMORY,   2,  RF_ACTIVE },
113239281Sgonzo	{ SYS_RES_MEMORY,   3,  RF_ACTIVE },
114239281Sgonzo	{ -1,               0,  0 }
115239281Sgonzo};
116239281Sgonzostatic struct resource_spec ti_edma3_irq_spec[] = {
117239281Sgonzo	{ SYS_RES_IRQ,      0,  RF_ACTIVE },
118239281Sgonzo	{ SYS_RES_IRQ,      1,  RF_ACTIVE },
119239281Sgonzo	{ SYS_RES_IRQ,      2,  RF_ACTIVE },
120239281Sgonzo	{ -1,               0,  0 }
121239281Sgonzo};
122239281Sgonzo
123239281Sgonzo/* Read/Write macros */
124239281Sgonzo#define ti_edma3_cc_rd_4(reg)		bus_read_4(ti_edma3_sc->mem_res[0], reg)
125239281Sgonzo#define ti_edma3_cc_wr_4(reg, val)	bus_write_4(ti_edma3_sc->mem_res[0], reg, val)
126239281Sgonzo#define ti_edma3_tc_rd_4(c, reg)	bus_read_4(ti_edma3_sc->mem_res[c+1], reg)
127239281Sgonzo#define ti_edma3_tc_wr_4(c, reg, val)	bus_write_4(ti_edma3_sc->mem_res[c+1], reg, val)
128239281Sgonzo
129239281Sgonzostatic void ti_edma3_intr_comp(void *arg);
130239281Sgonzostatic void ti_edma3_intr_mperr(void *arg);
131239281Sgonzostatic void ti_edma3_intr_err(void *arg);
132239281Sgonzo
133239281Sgonzostatic struct {
134239281Sgonzo	driver_intr_t *handler;
135239281Sgonzo	char * description;
136239281Sgonzo} ti_edma3_intrs[TI_EDMA3_NUM_IRQS] = {
137239281Sgonzo	{ ti_edma3_intr_comp,	"EDMA Completion Interrupt" },
138239281Sgonzo	{ ti_edma3_intr_mperr,	"EDMA Memory Protection Error Interrupt" },
139239281Sgonzo	{ ti_edma3_intr_err,	"EDMA Error Interrupt" },
140239281Sgonzo};
141239281Sgonzo
142239281Sgonzostatic int
143239281Sgonzoti_edma3_probe(device_t dev)
144239281Sgonzo{
145239553Skientzle	if (!ofw_bus_is_compatible(dev, "ti,edma3"))
146239281Sgonzo		return (ENXIO);
147239281Sgonzo
148239281Sgonzo	device_set_desc(dev, "TI EDMA Controller");
149239281Sgonzo	return (0);
150239281Sgonzo}
151239281Sgonzo
152239281Sgonzostatic int
153239281Sgonzoti_edma3_attach(device_t dev)
154239281Sgonzo{
155239281Sgonzo	struct ti_edma3_softc *sc = device_get_softc(dev);
156239281Sgonzo	uint32_t reg;
157239281Sgonzo	int err;
158239281Sgonzo	int i;
159239281Sgonzo
160239281Sgonzo	if (ti_edma3_sc)
161239281Sgonzo		return (ENXIO);
162239281Sgonzo
163239281Sgonzo	ti_edma3_sc = sc;
164239281Sgonzo	sc->sc_dev = dev;
165239281Sgonzo
166239281Sgonzo	/* Request the memory resources */
167239281Sgonzo	err = bus_alloc_resources(dev, ti_edma3_mem_spec, sc->mem_res);
168239281Sgonzo	if (err) {
169239281Sgonzo		device_printf(dev, "Error: could not allocate mem resources\n");
170239281Sgonzo		return (ENXIO);
171239281Sgonzo	}
172239281Sgonzo
173239281Sgonzo	/* Request the IRQ resources */
174239281Sgonzo	err = bus_alloc_resources(dev, ti_edma3_irq_spec, sc->irq_res);
175239281Sgonzo	if (err) {
176239281Sgonzo		device_printf(dev, "Error: could not allocate irq resources\n");
177239281Sgonzo		return (ENXIO);
178239281Sgonzo	}
179239281Sgonzo
180239281Sgonzo	/* Enable Channel Controller */
181239281Sgonzo	ti_prcm_clk_enable(EDMA_TPCC_CLK);
182239281Sgonzo
183239281Sgonzo	reg = ti_edma3_cc_rd_4(TI_EDMA3CC_PID);
184239281Sgonzo
185239281Sgonzo	device_printf(dev, "EDMA revision %08x\n", reg);
186239281Sgonzo
187239281Sgonzo
188239281Sgonzo	/* Attach interrupt handlers */
189239281Sgonzo	for (i = 0; i < TI_EDMA3_NUM_IRQS; ++i) {
190239281Sgonzo		err = bus_setup_intr(dev, sc->irq_res[i], INTR_TYPE_MISC |
191239281Sgonzo		    INTR_MPSAFE, NULL, *ti_edma3_intrs[i].handler,
192239281Sgonzo		    sc, &sc->ih_cookie[i]);
193239281Sgonzo		if (err) {
194239281Sgonzo			device_printf(dev, "could not setup %s\n",
195239281Sgonzo			    ti_edma3_intrs[i].description);
196239281Sgonzo			return (err);
197239281Sgonzo		}
198239281Sgonzo	}
199239281Sgonzo
200239281Sgonzo	return (0);
201239281Sgonzo}
202239281Sgonzo
203239281Sgonzostatic device_method_t ti_edma3_methods[] = {
204239281Sgonzo	DEVMETHOD(device_probe, ti_edma3_probe),
205239281Sgonzo	DEVMETHOD(device_attach, ti_edma3_attach),
206239281Sgonzo	{0, 0},
207239281Sgonzo};
208239281Sgonzo
209239281Sgonzostatic driver_t ti_edma3_driver = {
210239281Sgonzo	"ti_edma3",
211239281Sgonzo	ti_edma3_methods,
212239281Sgonzo	sizeof(struct ti_edma3_softc),
213239281Sgonzo};
214239281Sgonzostatic devclass_t ti_edma3_devclass;
215239281Sgonzo
216239281SgonzoDRIVER_MODULE(ti_edma3, simplebus, ti_edma3_driver, ti_edma3_devclass, 0, 0);
217239281SgonzoMODULE_DEPEND(ti_edma3, ti_prcm, 1, 1, 1);
218239281Sgonzo
219239281Sgonzostatic void
220239281Sgonzoti_edma3_intr_comp(void *arg)
221239281Sgonzo{
222239281Sgonzo	printf("%s: unimplemented\n", __func__);
223239281Sgonzo}
224239281Sgonzo
225239281Sgonzostatic void
226239281Sgonzoti_edma3_intr_mperr(void *arg)
227239281Sgonzo{
228239281Sgonzo	printf("%s: unimplemented\n", __func__);
229239281Sgonzo}
230239281Sgonzo
231239281Sgonzostatic void
232239281Sgonzoti_edma3_intr_err(void *arg)
233239281Sgonzo{
234239281Sgonzo	printf("%s: unimplemented\n", __func__);
235239281Sgonzo}
236239281Sgonzo
237239281Sgonzovoid
238239281Sgonzoti_edma3_init(unsigned int eqn)
239239281Sgonzo{
240239281Sgonzo	uint32_t reg;
241239281Sgonzo	int i;
242239281Sgonzo
243239281Sgonzo	/* on AM335x Event queue 0 is always mapped to Transfer Controller 0,
244239281Sgonzo	 * event queue 1 to TC2, etc. So we are asking PRCM to power on specific
245239281Sgonzo	 * TC based on what event queue we need to initialize */
246239281Sgonzo	ti_prcm_clk_enable(EDMA_TPTC0_CLK + eqn);
247239281Sgonzo
248239281Sgonzo	/* Clear Event Missed Regs */
249239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_EMCR, 0xFFFFFFFF);
250239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_EMCRH, 0xFFFFFFFF);
251239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_QEMCR, 0xFFFFFFFF);
252239281Sgonzo
253239281Sgonzo	/* Clear Error Reg */
254239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_CCERRCLR, 0xFFFFFFFF);
255239281Sgonzo
256239281Sgonzo	/* Enable DMA channels 0-63 */
257239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_DRAE(0), 0xFFFFFFFF);
258239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_DRAEH(0), 0xFFFFFFFF);
259239281Sgonzo
260239281Sgonzo	for (i = 0; i < 64; i++) {
261239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_DCHMAP(i), i<<5);
262239281Sgonzo	}
263239281Sgonzo
264239281Sgonzo	/* Initialize the DMA Queue Number Registers */
265239281Sgonzo	for (i = 0; i < TI_EDMA3_NUM_DMA_CHS; i++) {
266239281Sgonzo		reg = ti_edma3_cc_rd_4(TI_EDMA3CC_DMAQNUM(i>>3));
267239281Sgonzo		reg &= TI_EDMA3CC_DMAQNUM_CLR(i);
268239281Sgonzo		reg |= TI_EDMA3CC_DMAQNUM_SET(i, eqn);
269239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_DMAQNUM(i>>3), reg);
270239281Sgonzo	}
271239281Sgonzo
272239281Sgonzo	/* Enable the QDMA Region access for all channels */
273239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_QRAE(0), (1 << TI_EDMA3_NUM_QDMA_CHS) - 1);
274239281Sgonzo
275239281Sgonzo	/*Initialize QDMA Queue Number Registers */
276239281Sgonzo	for (i = 0; i < TI_EDMA3_NUM_QDMA_CHS; i++) {
277239281Sgonzo		reg = ti_edma3_cc_rd_4(TI_EDMA3CC_QDMAQNUM);
278239281Sgonzo		reg &= TI_EDMA3CC_QDMAQNUM_CLR(i);
279239281Sgonzo		reg |= TI_EDMA3CC_QDMAQNUM_SET(i, eqn);
280239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_QDMAQNUM, reg);
281239281Sgonzo	}
282239281Sgonzo}
283239281Sgonzo
284239281Sgonzo#ifdef notyet
285239281Sgonzoint
286239281Sgonzoti_edma3_enable_event_intr(unsigned int ch)
287239281Sgonzo{
288239281Sgonzo	uint32_t reg;
289239281Sgonzo
290239281Sgonzo	if (ch >= TI_EDMA3_NUM_DMA_CHS)
291239281Sgonzo		return (EINVAL);
292239281Sgonzo
293239281Sgonzo	if (ch < 32) {
294239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_S_IESR(0), 1 << ch);
295239281Sgonzo	} else {
296239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_S_IESRH(0), 1 << (ch - 32));
297239281Sgonzo	}
298239281Sgonzo	return 0;
299239281Sgonzo}
300239281Sgonzo#endif
301239281Sgonzo
302239281Sgonzoint
303239281Sgonzoti_edma3_request_dma_ch(unsigned int ch, unsigned int tccn, unsigned int eqn)
304239281Sgonzo{
305239281Sgonzo	uint32_t reg;
306239281Sgonzo
307239281Sgonzo	if (ch >= TI_EDMA3_NUM_DMA_CHS)
308239281Sgonzo		return (EINVAL);
309239281Sgonzo
310239281Sgonzo	/* Enable the DMA channel in the DRAE/DRAEH registers */
311239281Sgonzo	if (ch < 32) {
312239281Sgonzo		reg = ti_edma3_cc_rd_4(TI_EDMA3CC_DRAE(0));
313239281Sgonzo		reg |= (0x01 << ch);
314239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_DRAE(0), reg);
315239281Sgonzo	} else {
316239281Sgonzo		reg = ti_edma3_cc_rd_4(TI_EDMA3CC_DRAEH(0));
317239281Sgonzo		reg |= (0x01 << (ch - 32));
318239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_DRAEH(0), reg);
319239281Sgonzo	}
320239281Sgonzo
321239281Sgonzo	/* Associate DMA Channel to Event Queue */
322239281Sgonzo	reg = ti_edma3_cc_rd_4(TI_EDMA3CC_DMAQNUM(ch >> 3));
323239281Sgonzo	reg &= TI_EDMA3CC_DMAQNUM_CLR(ch);
324239281Sgonzo	reg |= TI_EDMA3CC_DMAQNUM_SET((ch), eqn);
325239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_DMAQNUM(ch >> 3), reg);
326239281Sgonzo
327239281Sgonzo	/* Set TCC in corresponding PaRAM Entry */
328239281Sgonzo	reg = ti_edma3_cc_rd_4(TI_EDMA3CC_OPT(ch));
329239281Sgonzo	reg &= TI_EDMA3CC_OPT_TCC_CLR;
330239281Sgonzo	reg |= TI_EDMA3CC_OPT_TCC_SET(ch);
331239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_OPT(ch), reg);
332239281Sgonzo
333239281Sgonzo	return 0;
334239281Sgonzo}
335239281Sgonzo
336239281Sgonzoint
337239281Sgonzoti_edma3_request_qdma_ch(unsigned int ch, unsigned int tccn, unsigned int eqn)
338239281Sgonzo{
339239281Sgonzo	uint32_t reg;
340239281Sgonzo
341239281Sgonzo	if (ch >= TI_EDMA3_NUM_DMA_CHS)
342239281Sgonzo		return (EINVAL);
343239281Sgonzo
344239281Sgonzo	/* Enable the QDMA channel in the QRAE registers */
345239281Sgonzo	reg = ti_edma3_cc_rd_4(TI_EDMA3CC_QRAE(0));
346239281Sgonzo	reg |= (0x01 << ch);
347239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_QRAE(0), reg);
348239281Sgonzo
349239281Sgonzo	/* Associate QDMA Channel to Event Queue */
350239281Sgonzo	reg = ti_edma3_cc_rd_4(TI_EDMA3CC_QDMAQNUM);
351239281Sgonzo	reg |= TI_EDMA3CC_QDMAQNUM_SET(ch, eqn);
352239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_QDMAQNUM, reg);
353239281Sgonzo
354239281Sgonzo	/* Set TCC in corresponding PaRAM Entry */
355239281Sgonzo	reg = ti_edma3_cc_rd_4(TI_EDMA3CC_OPT(ch));
356239281Sgonzo	reg &= TI_EDMA3CC_OPT_TCC_CLR;
357239281Sgonzo	reg |= TI_EDMA3CC_OPT_TCC_SET(ch);
358239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_OPT(ch), reg);
359239281Sgonzo
360239281Sgonzo	return 0;
361239281Sgonzo}
362239281Sgonzo
363239281Sgonzoint
364239281Sgonzoti_edma3_enable_transfer_manual(unsigned int ch)
365239281Sgonzo{
366239281Sgonzo	if (ch >= TI_EDMA3_NUM_DMA_CHS)
367239281Sgonzo		return (EINVAL);
368239281Sgonzo
369239281Sgonzo	/* set corresponding bit in ESR/ESRH to set a event */
370239281Sgonzo	if (ch < 32) {
371239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_S_ESR(0), 1 <<  ch);
372239281Sgonzo	} else {
373239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_S_ESRH(0), 1 <<  (ch - 32));
374239281Sgonzo	}
375239281Sgonzo
376239281Sgonzo	return 0;
377239281Sgonzo}
378239281Sgonzo
379239281Sgonzoint
380239281Sgonzoti_edma3_enable_transfer_qdma(unsigned int ch)
381239281Sgonzo{
382239281Sgonzo	if (ch >= TI_EDMA3_NUM_QDMA_CHS)
383239281Sgonzo		return (EINVAL);
384239281Sgonzo
385239281Sgonzo	/* set corresponding bit in QEESR to enable QDMA event */
386239281Sgonzo	ti_edma3_cc_wr_4(TI_EDMA3CC_S_QEESR(0), (1 << ch));
387239281Sgonzo
388239281Sgonzo	return 0;
389239281Sgonzo}
390239281Sgonzo
391239281Sgonzoint
392239281Sgonzoti_edma3_enable_transfer_event(unsigned int ch)
393239281Sgonzo{
394239281Sgonzo	if (ch >= TI_EDMA3_NUM_DMA_CHS)
395239281Sgonzo		return (EINVAL);
396239281Sgonzo
397239281Sgonzo	/* Clear SECR(H) & EMCR(H) to clean any previous NULL request
398239281Sgonzo	 * and set corresponding bit in EESR to enable DMA event */
399239281Sgonzo	if(ch < 32) {
400239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_S_SECR(0), (1 << ch));
401239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_EMCR, (1 << ch));
402239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_S_EESR(0), (1 << ch));
403239281Sgonzo	} else {
404239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_S_SECRH(0), 1 << (ch - 32));
405239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_EMCRH, 1 << (ch - 32));
406239281Sgonzo		ti_edma3_cc_wr_4(TI_EDMA3CC_S_EESRH(0), 1 << (ch - 32));
407239281Sgonzo	}
408239281Sgonzo
409239281Sgonzo	return 0;
410239281Sgonzo}
411239281Sgonzo
412239281Sgonzovoid
413239281Sgonzoti_edma3_param_write(unsigned int ch, struct ti_edma3cc_param_set *prs)
414239281Sgonzo{
415239281Sgonzo	bus_write_region_4(ti_edma3_sc->mem_res[0], TI_EDMA3CC_OPT(ch),
416239281Sgonzo	    (uint32_t *) prs, 8);
417239281Sgonzo}
418239281Sgonzo
419239281Sgonzovoid
420239281Sgonzoti_edma3_param_read(unsigned int ch, struct ti_edma3cc_param_set *prs)
421239281Sgonzo{
422239281Sgonzo	bus_read_region_4(ti_edma3_sc->mem_res[0], TI_EDMA3CC_OPT(ch),
423239281Sgonzo	    (uint32_t *) prs, 8);
424239281Sgonzo}
425