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