xref: /freebsd/sys/arm/freescale/imx/imx6_src.c (revision 83860f69f5847443ea51dd35f8dee3433e0f86f9)
1*83860f69SOleksandr Tymoshenko /*-
2*83860f69SOleksandr Tymoshenko  * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
3*83860f69SOleksandr Tymoshenko  * All rights reserved.
4*83860f69SOleksandr Tymoshenko  *
5*83860f69SOleksandr Tymoshenko  * Redistribution and use in source and binary forms, with or without
6*83860f69SOleksandr Tymoshenko  * modification, are permitted provided that the following conditions
7*83860f69SOleksandr Tymoshenko  * are met:
8*83860f69SOleksandr Tymoshenko  * 1. Redistributions of source code must retain the above copyright
9*83860f69SOleksandr Tymoshenko  *    notice, this list of conditions and the following disclaimer.
10*83860f69SOleksandr Tymoshenko  * 2. Redistributions in binary form must reproduce the above copyright
11*83860f69SOleksandr Tymoshenko  *    notice, this list of conditions and the following disclaimer in the
12*83860f69SOleksandr Tymoshenko  *    documentation and/or other materials provided with the distribution.
13*83860f69SOleksandr Tymoshenko  *
14*83860f69SOleksandr Tymoshenko  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*83860f69SOleksandr Tymoshenko  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*83860f69SOleksandr Tymoshenko  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*83860f69SOleksandr Tymoshenko  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*83860f69SOleksandr Tymoshenko  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*83860f69SOleksandr Tymoshenko  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*83860f69SOleksandr Tymoshenko  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*83860f69SOleksandr Tymoshenko  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*83860f69SOleksandr Tymoshenko  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*83860f69SOleksandr Tymoshenko  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*83860f69SOleksandr Tymoshenko  * SUCH DAMAGE.
25*83860f69SOleksandr Tymoshenko  */
26*83860f69SOleksandr Tymoshenko 
27*83860f69SOleksandr Tymoshenko #include <sys/cdefs.h>
28*83860f69SOleksandr Tymoshenko __FBSDID("$FreeBSD$");
29*83860f69SOleksandr Tymoshenko 
30*83860f69SOleksandr Tymoshenko /*
31*83860f69SOleksandr Tymoshenko  * System Reset Control for iMX6
32*83860f69SOleksandr Tymoshenko  */
33*83860f69SOleksandr Tymoshenko 
34*83860f69SOleksandr Tymoshenko #include <sys/param.h>
35*83860f69SOleksandr Tymoshenko #include <sys/systm.h>
36*83860f69SOleksandr Tymoshenko #include <sys/kernel.h>
37*83860f69SOleksandr Tymoshenko #include <sys/module.h>
38*83860f69SOleksandr Tymoshenko #include <sys/bus.h>
39*83860f69SOleksandr Tymoshenko #include <sys/rman.h>
40*83860f69SOleksandr Tymoshenko 
41*83860f69SOleksandr Tymoshenko #include <dev/ofw/ofw_bus.h>
42*83860f69SOleksandr Tymoshenko #include <dev/ofw/ofw_bus_subr.h>
43*83860f69SOleksandr Tymoshenko 
44*83860f69SOleksandr Tymoshenko #include <machine/bus.h>
45*83860f69SOleksandr Tymoshenko 
46*83860f69SOleksandr Tymoshenko #include <arm/freescale/imx/imx6_src.h>
47*83860f69SOleksandr Tymoshenko 
48*83860f69SOleksandr Tymoshenko #define	SRC_SCR		0
49*83860f69SOleksandr Tymoshenko #define		SW_IPU1_RST	(1 << 3)
50*83860f69SOleksandr Tymoshenko 
51*83860f69SOleksandr Tymoshenko struct src_softc {
52*83860f69SOleksandr Tymoshenko 	device_t	dev;
53*83860f69SOleksandr Tymoshenko 	struct resource	*mem_res;
54*83860f69SOleksandr Tymoshenko };
55*83860f69SOleksandr Tymoshenko 
56*83860f69SOleksandr Tymoshenko static struct src_softc *src_sc;
57*83860f69SOleksandr Tymoshenko 
58*83860f69SOleksandr Tymoshenko static inline uint32_t
59*83860f69SOleksandr Tymoshenko RD4(struct src_softc *sc, bus_size_t off)
60*83860f69SOleksandr Tymoshenko {
61*83860f69SOleksandr Tymoshenko 
62*83860f69SOleksandr Tymoshenko 	return (bus_read_4(sc->mem_res, off));
63*83860f69SOleksandr Tymoshenko }
64*83860f69SOleksandr Tymoshenko 
65*83860f69SOleksandr Tymoshenko static inline void
66*83860f69SOleksandr Tymoshenko WR4(struct src_softc *sc, bus_size_t off, uint32_t val)
67*83860f69SOleksandr Tymoshenko {
68*83860f69SOleksandr Tymoshenko 
69*83860f69SOleksandr Tymoshenko 	bus_write_4(sc->mem_res, off, val);
70*83860f69SOleksandr Tymoshenko }
71*83860f69SOleksandr Tymoshenko 
72*83860f69SOleksandr Tymoshenko int
73*83860f69SOleksandr Tymoshenko src_reset_ipu()
74*83860f69SOleksandr Tymoshenko {
75*83860f69SOleksandr Tymoshenko 	uint32_t reg;
76*83860f69SOleksandr Tymoshenko 	int timeout = 10000;
77*83860f69SOleksandr Tymoshenko 
78*83860f69SOleksandr Tymoshenko 	if (src_sc == NULL)
79*83860f69SOleksandr Tymoshenko 		return (-1);
80*83860f69SOleksandr Tymoshenko 
81*83860f69SOleksandr Tymoshenko 	reg = RD4(src_sc, SRC_SCR);
82*83860f69SOleksandr Tymoshenko 	reg |= SW_IPU1_RST;
83*83860f69SOleksandr Tymoshenko 	WR4(src_sc, SRC_SCR, reg);
84*83860f69SOleksandr Tymoshenko 
85*83860f69SOleksandr Tymoshenko 	while (timeout-- > 0) {
86*83860f69SOleksandr Tymoshenko 		reg = RD4(src_sc, SRC_SCR);
87*83860f69SOleksandr Tymoshenko 		if (reg & SW_IPU1_RST)
88*83860f69SOleksandr Tymoshenko 			DELAY(1);
89*83860f69SOleksandr Tymoshenko 		else
90*83860f69SOleksandr Tymoshenko 			break;
91*83860f69SOleksandr Tymoshenko 	}
92*83860f69SOleksandr Tymoshenko 
93*83860f69SOleksandr Tymoshenko 	if (timeout < 0)
94*83860f69SOleksandr Tymoshenko 		return (-1);
95*83860f69SOleksandr Tymoshenko 	else
96*83860f69SOleksandr Tymoshenko 		return (0);
97*83860f69SOleksandr Tymoshenko }
98*83860f69SOleksandr Tymoshenko 
99*83860f69SOleksandr Tymoshenko static int
100*83860f69SOleksandr Tymoshenko src_detach(device_t dev)
101*83860f69SOleksandr Tymoshenko {
102*83860f69SOleksandr Tymoshenko 	struct src_softc *sc;
103*83860f69SOleksandr Tymoshenko 
104*83860f69SOleksandr Tymoshenko 	sc = device_get_softc(dev);
105*83860f69SOleksandr Tymoshenko 
106*83860f69SOleksandr Tymoshenko 	if (sc->mem_res != NULL)
107*83860f69SOleksandr Tymoshenko 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
108*83860f69SOleksandr Tymoshenko 
109*83860f69SOleksandr Tymoshenko 	return (0);
110*83860f69SOleksandr Tymoshenko }
111*83860f69SOleksandr Tymoshenko 
112*83860f69SOleksandr Tymoshenko static int
113*83860f69SOleksandr Tymoshenko src_attach(device_t dev)
114*83860f69SOleksandr Tymoshenko {
115*83860f69SOleksandr Tymoshenko 	struct src_softc *sc;
116*83860f69SOleksandr Tymoshenko 	int err, rid;
117*83860f69SOleksandr Tymoshenko 
118*83860f69SOleksandr Tymoshenko 	sc = device_get_softc(dev);
119*83860f69SOleksandr Tymoshenko 	err = 0;
120*83860f69SOleksandr Tymoshenko 
121*83860f69SOleksandr Tymoshenko 	/* Allocate bus_space resources. */
122*83860f69SOleksandr Tymoshenko 	rid = 0;
123*83860f69SOleksandr Tymoshenko 	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
124*83860f69SOleksandr Tymoshenko 	    RF_ACTIVE);
125*83860f69SOleksandr Tymoshenko 	if (sc->mem_res == NULL) {
126*83860f69SOleksandr Tymoshenko 		device_printf(dev, "Cannot allocate memory resources\n");
127*83860f69SOleksandr Tymoshenko 		err = ENXIO;
128*83860f69SOleksandr Tymoshenko 		goto out;
129*83860f69SOleksandr Tymoshenko 	}
130*83860f69SOleksandr Tymoshenko 
131*83860f69SOleksandr Tymoshenko 	src_sc = sc;
132*83860f69SOleksandr Tymoshenko 
133*83860f69SOleksandr Tymoshenko 	err = 0;
134*83860f69SOleksandr Tymoshenko 
135*83860f69SOleksandr Tymoshenko out:
136*83860f69SOleksandr Tymoshenko 
137*83860f69SOleksandr Tymoshenko 	if (err != 0)
138*83860f69SOleksandr Tymoshenko 		src_detach(dev);
139*83860f69SOleksandr Tymoshenko 
140*83860f69SOleksandr Tymoshenko 	return (err);
141*83860f69SOleksandr Tymoshenko }
142*83860f69SOleksandr Tymoshenko 
143*83860f69SOleksandr Tymoshenko static int
144*83860f69SOleksandr Tymoshenko src_probe(device_t dev)
145*83860f69SOleksandr Tymoshenko {
146*83860f69SOleksandr Tymoshenko 
147*83860f69SOleksandr Tymoshenko         if ((ofw_bus_is_compatible(dev, "fsl,imx6q-src") == 0) &&
148*83860f69SOleksandr Tymoshenko             (ofw_bus_is_compatible(dev, "fsl,imx6-src") == 0))
149*83860f69SOleksandr Tymoshenko 		return (ENXIO);
150*83860f69SOleksandr Tymoshenko 
151*83860f69SOleksandr Tymoshenko 	device_set_desc(dev, "Freescale i.MX6 System Reset Controller");
152*83860f69SOleksandr Tymoshenko 
153*83860f69SOleksandr Tymoshenko 	return (BUS_PROBE_DEFAULT);
154*83860f69SOleksandr Tymoshenko }
155*83860f69SOleksandr Tymoshenko 
156*83860f69SOleksandr Tymoshenko static device_method_t src_methods[] = {
157*83860f69SOleksandr Tymoshenko 	/* Device interface */
158*83860f69SOleksandr Tymoshenko 	DEVMETHOD(device_probe,  src_probe),
159*83860f69SOleksandr Tymoshenko 	DEVMETHOD(device_attach, src_attach),
160*83860f69SOleksandr Tymoshenko 	DEVMETHOD(device_detach, src_detach),
161*83860f69SOleksandr Tymoshenko 
162*83860f69SOleksandr Tymoshenko 	DEVMETHOD_END
163*83860f69SOleksandr Tymoshenko };
164*83860f69SOleksandr Tymoshenko 
165*83860f69SOleksandr Tymoshenko static driver_t src_driver = {
166*83860f69SOleksandr Tymoshenko 	"src",
167*83860f69SOleksandr Tymoshenko 	src_methods,
168*83860f69SOleksandr Tymoshenko 	sizeof(struct src_softc)
169*83860f69SOleksandr Tymoshenko };
170*83860f69SOleksandr Tymoshenko 
171*83860f69SOleksandr Tymoshenko static devclass_t src_devclass;
172*83860f69SOleksandr Tymoshenko 
173*83860f69SOleksandr Tymoshenko DRIVER_MODULE(src, simplebus, src_driver, src_devclass, 0, 0);
174