xref: /freebsd/sys/arm/freescale/vybrid/vf_dmamux.c (revision f3a72e40)
1f3a72e40SRuslan Bukin /*-
2f3a72e40SRuslan Bukin  * Copyright (c) 2014 Ruslan Bukin <br@bsdpad.com>
3f3a72e40SRuslan Bukin  * All rights reserved.
4f3a72e40SRuslan Bukin  *
5f3a72e40SRuslan Bukin  * Redistribution and use in source and binary forms, with or without
6f3a72e40SRuslan Bukin  * modification, are permitted provided that the following conditions
7f3a72e40SRuslan Bukin  * are met:
8f3a72e40SRuslan Bukin  * 1. Redistributions of source code must retain the above copyright
9f3a72e40SRuslan Bukin  *    notice, this list of conditions and the following disclaimer.
10f3a72e40SRuslan Bukin  * 2. Redistributions in binary form must reproduce the above copyright
11f3a72e40SRuslan Bukin  *    notice, this list of conditions and the following disclaimer in the
12f3a72e40SRuslan Bukin  *    documentation and/or other materials provided with the distribution.
13f3a72e40SRuslan Bukin  *
14f3a72e40SRuslan Bukin  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15f3a72e40SRuslan Bukin  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16f3a72e40SRuslan Bukin  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17f3a72e40SRuslan Bukin  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18f3a72e40SRuslan Bukin  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19f3a72e40SRuslan Bukin  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20f3a72e40SRuslan Bukin  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21f3a72e40SRuslan Bukin  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22f3a72e40SRuslan Bukin  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23f3a72e40SRuslan Bukin  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24f3a72e40SRuslan Bukin  * SUCH DAMAGE.
25f3a72e40SRuslan Bukin  */
26f3a72e40SRuslan Bukin 
27f3a72e40SRuslan Bukin /*
28f3a72e40SRuslan Bukin  * Vybrid Family Direct Memory Access Multiplexer (DMAMUX)
29f3a72e40SRuslan Bukin  * Chapter 22, Vybrid Reference Manual, Rev. 5, 07/2013
30f3a72e40SRuslan Bukin  */
31f3a72e40SRuslan Bukin 
32f3a72e40SRuslan Bukin #include <sys/cdefs.h>
33f3a72e40SRuslan Bukin __FBSDID("$FreeBSD$");
34f3a72e40SRuslan Bukin 
35f3a72e40SRuslan Bukin #include <sys/param.h>
36f3a72e40SRuslan Bukin #include <sys/systm.h>
37f3a72e40SRuslan Bukin #include <sys/bus.h>
38f3a72e40SRuslan Bukin #include <sys/kernel.h>
39f3a72e40SRuslan Bukin #include <sys/module.h>
40f3a72e40SRuslan Bukin #include <sys/malloc.h>
41f3a72e40SRuslan Bukin #include <sys/rman.h>
42f3a72e40SRuslan Bukin #include <sys/timeet.h>
43f3a72e40SRuslan Bukin #include <sys/timetc.h>
44f3a72e40SRuslan Bukin #include <sys/watchdog.h>
45f3a72e40SRuslan Bukin 
46f3a72e40SRuslan Bukin #include <dev/fdt/fdt_common.h>
47f3a72e40SRuslan Bukin #include <dev/ofw/openfirm.h>
48f3a72e40SRuslan Bukin #include <dev/ofw/ofw_bus.h>
49f3a72e40SRuslan Bukin #include <dev/ofw/ofw_bus_subr.h>
50f3a72e40SRuslan Bukin 
51f3a72e40SRuslan Bukin #include <machine/bus.h>
52f3a72e40SRuslan Bukin #include <machine/fdt.h>
53f3a72e40SRuslan Bukin #include <machine/cpu.h>
54f3a72e40SRuslan Bukin #include <machine/intr.h>
55f3a72e40SRuslan Bukin 
56f3a72e40SRuslan Bukin #include <arm/freescale/vybrid/vf_common.h>
57f3a72e40SRuslan Bukin #include <arm/freescale/vybrid/vf_dmamux.h>
58f3a72e40SRuslan Bukin 
59f3a72e40SRuslan Bukin #define	DMAMUX_CHCFG(n)		(0x1 * n)	/* Channels 0-15 Cfg Reg */
60f3a72e40SRuslan Bukin #define	CHCFG_ENBL		(1 << 7)	/* Channel Enable */
61f3a72e40SRuslan Bukin #define	CHCFG_TRIG		(1 << 6)	/* Channel Trigger Enable */
62f3a72e40SRuslan Bukin #define	CHCFG_SOURCE_MASK	0x3f		/* Channel Source (Slot) */
63f3a72e40SRuslan Bukin #define	CHCFG_SOURCE_SHIFT	0
64f3a72e40SRuslan Bukin 
65f3a72e40SRuslan Bukin struct dmamux_softc {
66f3a72e40SRuslan Bukin 	struct resource		*res[4];
67f3a72e40SRuslan Bukin 	bus_space_tag_t		bst[4];
68f3a72e40SRuslan Bukin 	bus_space_handle_t	bsh[4];
69f3a72e40SRuslan Bukin };
70f3a72e40SRuslan Bukin 
71f3a72e40SRuslan Bukin struct dmamux_softc *dmamux_sc;
72f3a72e40SRuslan Bukin 
73f3a72e40SRuslan Bukin static struct resource_spec dmamux_spec[] = {
74f3a72e40SRuslan Bukin 	{ SYS_RES_MEMORY,	0,	RF_ACTIVE }, /* DMAMUX0 */
75f3a72e40SRuslan Bukin 	{ SYS_RES_MEMORY,	1,	RF_ACTIVE }, /* DMAMUX1 */
76f3a72e40SRuslan Bukin 	{ SYS_RES_MEMORY,	2,	RF_ACTIVE }, /* DMAMUX2 */
77f3a72e40SRuslan Bukin 	{ SYS_RES_MEMORY,	3,	RF_ACTIVE }, /* DMAMUX3 */
78f3a72e40SRuslan Bukin 	{ -1, 0 }
79f3a72e40SRuslan Bukin };
80f3a72e40SRuslan Bukin 
81f3a72e40SRuslan Bukin static int
82f3a72e40SRuslan Bukin dmamux_probe(device_t dev)
83f3a72e40SRuslan Bukin {
84f3a72e40SRuslan Bukin 
85f3a72e40SRuslan Bukin 	if (!ofw_bus_status_okay(dev))
86f3a72e40SRuslan Bukin 		return (ENXIO);
87f3a72e40SRuslan Bukin 
88f3a72e40SRuslan Bukin 	if (!ofw_bus_is_compatible(dev, "fsl,mvf600-dmamux"))
89f3a72e40SRuslan Bukin 		return (ENXIO);
90f3a72e40SRuslan Bukin 
91f3a72e40SRuslan Bukin 	device_set_desc(dev, "Vybrid Family Direct Memory Access Multiplexer");
92f3a72e40SRuslan Bukin 	return (BUS_PROBE_DEFAULT);
93f3a72e40SRuslan Bukin }
94f3a72e40SRuslan Bukin 
95f3a72e40SRuslan Bukin int
96f3a72e40SRuslan Bukin dmamux_configure(int mux, int source, int channel, int enable)
97f3a72e40SRuslan Bukin {
98f3a72e40SRuslan Bukin 	struct dmamux_softc *sc;
99f3a72e40SRuslan Bukin 	int reg;
100f3a72e40SRuslan Bukin 
101f3a72e40SRuslan Bukin 	sc = dmamux_sc;
102f3a72e40SRuslan Bukin 
103f3a72e40SRuslan Bukin 	MUX_WRITE1(sc, mux, DMAMUX_CHCFG(channel), 0x0);
104f3a72e40SRuslan Bukin 
105f3a72e40SRuslan Bukin 	reg = 0;
106f3a72e40SRuslan Bukin 	if (enable)
107f3a72e40SRuslan Bukin 		reg |= (CHCFG_ENBL);
108f3a72e40SRuslan Bukin 
109f3a72e40SRuslan Bukin 	reg &= ~(CHCFG_SOURCE_MASK << CHCFG_SOURCE_SHIFT);
110f3a72e40SRuslan Bukin 	reg |= (source << CHCFG_SOURCE_SHIFT);
111f3a72e40SRuslan Bukin 
112f3a72e40SRuslan Bukin 	MUX_WRITE1(sc, mux, DMAMUX_CHCFG(channel), reg);
113f3a72e40SRuslan Bukin 
114f3a72e40SRuslan Bukin 	return (0);
115f3a72e40SRuslan Bukin }
116f3a72e40SRuslan Bukin 
117f3a72e40SRuslan Bukin static int
118f3a72e40SRuslan Bukin dmamux_attach(device_t dev)
119f3a72e40SRuslan Bukin {
120f3a72e40SRuslan Bukin 	struct dmamux_softc *sc;
121f3a72e40SRuslan Bukin 	int i;
122f3a72e40SRuslan Bukin 
123f3a72e40SRuslan Bukin 	sc = device_get_softc(dev);
124f3a72e40SRuslan Bukin 
125f3a72e40SRuslan Bukin 	if (bus_alloc_resources(dev, dmamux_spec, sc->res)) {
126f3a72e40SRuslan Bukin 		device_printf(dev, "could not allocate resources\n");
127f3a72e40SRuslan Bukin 		return (ENXIO);
128f3a72e40SRuslan Bukin 	}
129f3a72e40SRuslan Bukin 
130f3a72e40SRuslan Bukin 	/* Memory interface */
131f3a72e40SRuslan Bukin 	for (i = 0; i < 4; i++) {
132f3a72e40SRuslan Bukin 		sc->bst[i] = rman_get_bustag(sc->res[i]);
133f3a72e40SRuslan Bukin 		sc->bsh[i] = rman_get_bushandle(sc->res[i]);
134f3a72e40SRuslan Bukin 	}
135f3a72e40SRuslan Bukin 
136f3a72e40SRuslan Bukin 	dmamux_sc = sc;
137f3a72e40SRuslan Bukin 
138f3a72e40SRuslan Bukin 	return (0);
139f3a72e40SRuslan Bukin }
140f3a72e40SRuslan Bukin 
141f3a72e40SRuslan Bukin static device_method_t dmamux_methods[] = {
142f3a72e40SRuslan Bukin 	DEVMETHOD(device_probe,		dmamux_probe),
143f3a72e40SRuslan Bukin 	DEVMETHOD(device_attach,	dmamux_attach),
144f3a72e40SRuslan Bukin 	{ 0, 0 }
145f3a72e40SRuslan Bukin };
146f3a72e40SRuslan Bukin 
147f3a72e40SRuslan Bukin static driver_t dmamux_driver = {
148f3a72e40SRuslan Bukin 	"dmamux",
149f3a72e40SRuslan Bukin 	dmamux_methods,
150f3a72e40SRuslan Bukin 	sizeof(struct dmamux_softc),
151f3a72e40SRuslan Bukin };
152f3a72e40SRuslan Bukin 
153f3a72e40SRuslan Bukin static devclass_t dmamux_devclass;
154f3a72e40SRuslan Bukin 
155f3a72e40SRuslan Bukin DRIVER_MODULE(dmamux, simplebus, dmamux_driver, dmamux_devclass, 0, 0);
156