xref: /freebsd/sys/arm/freescale/imx/imx6_src.c (revision 59249a516a69e3a4055393f0975cdd8a848f5ce8)
183860f69SOleksandr Tymoshenko /*-
283860f69SOleksandr Tymoshenko  * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org>
383860f69SOleksandr Tymoshenko  * All rights reserved.
483860f69SOleksandr Tymoshenko  *
583860f69SOleksandr Tymoshenko  * Redistribution and use in source and binary forms, with or without
683860f69SOleksandr Tymoshenko  * modification, are permitted provided that the following conditions
783860f69SOleksandr Tymoshenko  * are met:
883860f69SOleksandr Tymoshenko  * 1. Redistributions of source code must retain the above copyright
983860f69SOleksandr Tymoshenko  *    notice, this list of conditions and the following disclaimer.
1083860f69SOleksandr Tymoshenko  * 2. Redistributions in binary form must reproduce the above copyright
1183860f69SOleksandr Tymoshenko  *    notice, this list of conditions and the following disclaimer in the
1283860f69SOleksandr Tymoshenko  *    documentation and/or other materials provided with the distribution.
1383860f69SOleksandr Tymoshenko  *
1483860f69SOleksandr Tymoshenko  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1583860f69SOleksandr Tymoshenko  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1683860f69SOleksandr Tymoshenko  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1783860f69SOleksandr Tymoshenko  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1883860f69SOleksandr Tymoshenko  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1983860f69SOleksandr Tymoshenko  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2083860f69SOleksandr Tymoshenko  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2183860f69SOleksandr Tymoshenko  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2283860f69SOleksandr Tymoshenko  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2383860f69SOleksandr Tymoshenko  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2483860f69SOleksandr Tymoshenko  * SUCH DAMAGE.
2583860f69SOleksandr Tymoshenko  */
2683860f69SOleksandr Tymoshenko 
2783860f69SOleksandr Tymoshenko #include <sys/cdefs.h>
2883860f69SOleksandr Tymoshenko __FBSDID("$FreeBSD$");
2983860f69SOleksandr Tymoshenko 
3083860f69SOleksandr Tymoshenko /*
3183860f69SOleksandr Tymoshenko  * System Reset Control for iMX6
3283860f69SOleksandr Tymoshenko  */
3383860f69SOleksandr Tymoshenko 
3483860f69SOleksandr Tymoshenko #include <sys/param.h>
3583860f69SOleksandr Tymoshenko #include <sys/systm.h>
3683860f69SOleksandr Tymoshenko #include <sys/kernel.h>
3783860f69SOleksandr Tymoshenko #include <sys/module.h>
3883860f69SOleksandr Tymoshenko #include <sys/bus.h>
3983860f69SOleksandr Tymoshenko #include <sys/rman.h>
4083860f69SOleksandr Tymoshenko 
4183860f69SOleksandr Tymoshenko #include <dev/ofw/ofw_bus.h>
4283860f69SOleksandr Tymoshenko #include <dev/ofw/ofw_bus_subr.h>
4383860f69SOleksandr Tymoshenko 
4483860f69SOleksandr Tymoshenko #include <machine/bus.h>
4583860f69SOleksandr Tymoshenko 
4683860f69SOleksandr Tymoshenko #include <arm/freescale/imx/imx6_src.h>
4783860f69SOleksandr Tymoshenko 
4883860f69SOleksandr Tymoshenko #define	SRC_SCR		0
4983860f69SOleksandr Tymoshenko #define		SW_IPU1_RST	(1 << 3)
5083860f69SOleksandr Tymoshenko 
5183860f69SOleksandr Tymoshenko struct src_softc {
5283860f69SOleksandr Tymoshenko 	device_t	dev;
5383860f69SOleksandr Tymoshenko 	struct resource	*mem_res;
5483860f69SOleksandr Tymoshenko };
5583860f69SOleksandr Tymoshenko 
5683860f69SOleksandr Tymoshenko static struct src_softc *src_sc;
5783860f69SOleksandr Tymoshenko 
5883860f69SOleksandr Tymoshenko static inline uint32_t
5983860f69SOleksandr Tymoshenko RD4(struct src_softc *sc, bus_size_t off)
6083860f69SOleksandr Tymoshenko {
6183860f69SOleksandr Tymoshenko 
6283860f69SOleksandr Tymoshenko 	return (bus_read_4(sc->mem_res, off));
6383860f69SOleksandr Tymoshenko }
6483860f69SOleksandr Tymoshenko 
6583860f69SOleksandr Tymoshenko static inline void
6683860f69SOleksandr Tymoshenko WR4(struct src_softc *sc, bus_size_t off, uint32_t val)
6783860f69SOleksandr Tymoshenko {
6883860f69SOleksandr Tymoshenko 
6983860f69SOleksandr Tymoshenko 	bus_write_4(sc->mem_res, off, val);
7083860f69SOleksandr Tymoshenko }
7183860f69SOleksandr Tymoshenko 
7283860f69SOleksandr Tymoshenko int
73*59249a51SAndrew Turner src_reset_ipu(void)
7483860f69SOleksandr Tymoshenko {
7583860f69SOleksandr Tymoshenko 	uint32_t reg;
7683860f69SOleksandr Tymoshenko 	int timeout = 10000;
7783860f69SOleksandr Tymoshenko 
7883860f69SOleksandr Tymoshenko 	if (src_sc == NULL)
7983860f69SOleksandr Tymoshenko 		return (-1);
8083860f69SOleksandr Tymoshenko 
8183860f69SOleksandr Tymoshenko 	reg = RD4(src_sc, SRC_SCR);
8283860f69SOleksandr Tymoshenko 	reg |= SW_IPU1_RST;
8383860f69SOleksandr Tymoshenko 	WR4(src_sc, SRC_SCR, reg);
8483860f69SOleksandr Tymoshenko 
8583860f69SOleksandr Tymoshenko 	while (timeout-- > 0) {
8683860f69SOleksandr Tymoshenko 		reg = RD4(src_sc, SRC_SCR);
8783860f69SOleksandr Tymoshenko 		if (reg & SW_IPU1_RST)
8883860f69SOleksandr Tymoshenko 			DELAY(1);
8983860f69SOleksandr Tymoshenko 		else
9083860f69SOleksandr Tymoshenko 			break;
9183860f69SOleksandr Tymoshenko 	}
9283860f69SOleksandr Tymoshenko 
9383860f69SOleksandr Tymoshenko 	if (timeout < 0)
9483860f69SOleksandr Tymoshenko 		return (-1);
9583860f69SOleksandr Tymoshenko 	else
9683860f69SOleksandr Tymoshenko 		return (0);
9783860f69SOleksandr Tymoshenko }
9883860f69SOleksandr Tymoshenko 
9983860f69SOleksandr Tymoshenko static int
10083860f69SOleksandr Tymoshenko src_detach(device_t dev)
10183860f69SOleksandr Tymoshenko {
10283860f69SOleksandr Tymoshenko 	struct src_softc *sc;
10383860f69SOleksandr Tymoshenko 
10483860f69SOleksandr Tymoshenko 	sc = device_get_softc(dev);
10583860f69SOleksandr Tymoshenko 
10683860f69SOleksandr Tymoshenko 	if (sc->mem_res != NULL)
10783860f69SOleksandr Tymoshenko 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
10883860f69SOleksandr Tymoshenko 
10983860f69SOleksandr Tymoshenko 	return (0);
11083860f69SOleksandr Tymoshenko }
11183860f69SOleksandr Tymoshenko 
11283860f69SOleksandr Tymoshenko static int
11383860f69SOleksandr Tymoshenko src_attach(device_t dev)
11483860f69SOleksandr Tymoshenko {
11583860f69SOleksandr Tymoshenko 	struct src_softc *sc;
11683860f69SOleksandr Tymoshenko 	int err, rid;
11783860f69SOleksandr Tymoshenko 
11883860f69SOleksandr Tymoshenko 	sc = device_get_softc(dev);
11983860f69SOleksandr Tymoshenko 	err = 0;
12083860f69SOleksandr Tymoshenko 
12183860f69SOleksandr Tymoshenko 	/* Allocate bus_space resources. */
12283860f69SOleksandr Tymoshenko 	rid = 0;
12383860f69SOleksandr Tymoshenko 	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
12483860f69SOleksandr Tymoshenko 	    RF_ACTIVE);
12583860f69SOleksandr Tymoshenko 	if (sc->mem_res == NULL) {
12683860f69SOleksandr Tymoshenko 		device_printf(dev, "Cannot allocate memory resources\n");
12783860f69SOleksandr Tymoshenko 		err = ENXIO;
12883860f69SOleksandr Tymoshenko 		goto out;
12983860f69SOleksandr Tymoshenko 	}
13083860f69SOleksandr Tymoshenko 
13183860f69SOleksandr Tymoshenko 	src_sc = sc;
13283860f69SOleksandr Tymoshenko 
13383860f69SOleksandr Tymoshenko 	err = 0;
13483860f69SOleksandr Tymoshenko 
13583860f69SOleksandr Tymoshenko out:
13683860f69SOleksandr Tymoshenko 
13783860f69SOleksandr Tymoshenko 	if (err != 0)
13883860f69SOleksandr Tymoshenko 		src_detach(dev);
13983860f69SOleksandr Tymoshenko 
14083860f69SOleksandr Tymoshenko 	return (err);
14183860f69SOleksandr Tymoshenko }
14283860f69SOleksandr Tymoshenko 
14383860f69SOleksandr Tymoshenko static int
14483860f69SOleksandr Tymoshenko src_probe(device_t dev)
14583860f69SOleksandr Tymoshenko {
14683860f69SOleksandr Tymoshenko 
14783860f69SOleksandr Tymoshenko         if ((ofw_bus_is_compatible(dev, "fsl,imx6q-src") == 0) &&
14883860f69SOleksandr Tymoshenko             (ofw_bus_is_compatible(dev, "fsl,imx6-src") == 0))
14983860f69SOleksandr Tymoshenko 		return (ENXIO);
15083860f69SOleksandr Tymoshenko 
15183860f69SOleksandr Tymoshenko 	device_set_desc(dev, "Freescale i.MX6 System Reset Controller");
15283860f69SOleksandr Tymoshenko 
15383860f69SOleksandr Tymoshenko 	return (BUS_PROBE_DEFAULT);
15483860f69SOleksandr Tymoshenko }
15583860f69SOleksandr Tymoshenko 
15683860f69SOleksandr Tymoshenko static device_method_t src_methods[] = {
15783860f69SOleksandr Tymoshenko 	/* Device interface */
15883860f69SOleksandr Tymoshenko 	DEVMETHOD(device_probe,  src_probe),
15983860f69SOleksandr Tymoshenko 	DEVMETHOD(device_attach, src_attach),
16083860f69SOleksandr Tymoshenko 	DEVMETHOD(device_detach, src_detach),
16183860f69SOleksandr Tymoshenko 
16283860f69SOleksandr Tymoshenko 	DEVMETHOD_END
16383860f69SOleksandr Tymoshenko };
16483860f69SOleksandr Tymoshenko 
16583860f69SOleksandr Tymoshenko static driver_t src_driver = {
16683860f69SOleksandr Tymoshenko 	"src",
16783860f69SOleksandr Tymoshenko 	src_methods,
16883860f69SOleksandr Tymoshenko 	sizeof(struct src_softc)
16983860f69SOleksandr Tymoshenko };
17083860f69SOleksandr Tymoshenko 
17183860f69SOleksandr Tymoshenko static devclass_t src_devclass;
17283860f69SOleksandr Tymoshenko 
17383860f69SOleksandr Tymoshenko DRIVER_MODULE(src, simplebus, src_driver, src_devclass, 0, 0);
174