xref: /freebsd/sys/arm/freescale/imx/imx6_src.c (revision 685dc743dc3b5645e34836464128e1c0558b404b)
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 /*
2983860f69SOleksandr Tymoshenko  * System Reset Control for iMX6
3083860f69SOleksandr Tymoshenko  */
3183860f69SOleksandr Tymoshenko 
3283860f69SOleksandr Tymoshenko #include <sys/param.h>
3383860f69SOleksandr Tymoshenko #include <sys/systm.h>
3483860f69SOleksandr Tymoshenko #include <sys/kernel.h>
3583860f69SOleksandr Tymoshenko #include <sys/module.h>
3683860f69SOleksandr Tymoshenko #include <sys/bus.h>
3783860f69SOleksandr Tymoshenko #include <sys/rman.h>
3883860f69SOleksandr Tymoshenko 
3983860f69SOleksandr Tymoshenko #include <dev/ofw/ofw_bus.h>
4083860f69SOleksandr Tymoshenko #include <dev/ofw/ofw_bus_subr.h>
4183860f69SOleksandr Tymoshenko 
4283860f69SOleksandr Tymoshenko #include <machine/bus.h>
4383860f69SOleksandr Tymoshenko 
4483860f69SOleksandr Tymoshenko #include <arm/freescale/imx/imx6_src.h>
4583860f69SOleksandr Tymoshenko 
4683860f69SOleksandr Tymoshenko #define	SRC_SCR		0
4783860f69SOleksandr Tymoshenko #define		SW_IPU1_RST	(1 << 3)
4883860f69SOleksandr Tymoshenko 
4983860f69SOleksandr Tymoshenko struct src_softc {
5083860f69SOleksandr Tymoshenko 	device_t	dev;
5183860f69SOleksandr Tymoshenko 	struct resource	*mem_res;
5283860f69SOleksandr Tymoshenko };
5383860f69SOleksandr Tymoshenko 
5483860f69SOleksandr Tymoshenko static struct src_softc *src_sc;
5583860f69SOleksandr Tymoshenko 
5683860f69SOleksandr Tymoshenko static inline uint32_t
RD4(struct src_softc * sc,bus_size_t off)5783860f69SOleksandr Tymoshenko RD4(struct src_softc *sc, bus_size_t off)
5883860f69SOleksandr Tymoshenko {
5983860f69SOleksandr Tymoshenko 
6083860f69SOleksandr Tymoshenko 	return (bus_read_4(sc->mem_res, off));
6183860f69SOleksandr Tymoshenko }
6283860f69SOleksandr Tymoshenko 
6383860f69SOleksandr Tymoshenko static inline void
WR4(struct src_softc * sc,bus_size_t off,uint32_t val)6483860f69SOleksandr Tymoshenko WR4(struct src_softc *sc, bus_size_t off, uint32_t val)
6583860f69SOleksandr Tymoshenko {
6683860f69SOleksandr Tymoshenko 
6783860f69SOleksandr Tymoshenko 	bus_write_4(sc->mem_res, off, val);
6883860f69SOleksandr Tymoshenko }
6983860f69SOleksandr Tymoshenko 
7083860f69SOleksandr Tymoshenko int
src_reset_ipu(void)7159249a51SAndrew Turner src_reset_ipu(void)
7283860f69SOleksandr Tymoshenko {
7383860f69SOleksandr Tymoshenko 	uint32_t reg;
7483860f69SOleksandr Tymoshenko 	int timeout = 10000;
7583860f69SOleksandr Tymoshenko 
7683860f69SOleksandr Tymoshenko 	if (src_sc == NULL)
7783860f69SOleksandr Tymoshenko 		return (-1);
7883860f69SOleksandr Tymoshenko 
7983860f69SOleksandr Tymoshenko 	reg = RD4(src_sc, SRC_SCR);
8083860f69SOleksandr Tymoshenko 	reg |= SW_IPU1_RST;
8183860f69SOleksandr Tymoshenko 	WR4(src_sc, SRC_SCR, reg);
8283860f69SOleksandr Tymoshenko 
8383860f69SOleksandr Tymoshenko 	while (timeout-- > 0) {
8483860f69SOleksandr Tymoshenko 		reg = RD4(src_sc, SRC_SCR);
8583860f69SOleksandr Tymoshenko 		if (reg & SW_IPU1_RST)
8683860f69SOleksandr Tymoshenko 			DELAY(1);
8783860f69SOleksandr Tymoshenko 		else
8883860f69SOleksandr Tymoshenko 			break;
8983860f69SOleksandr Tymoshenko 	}
9083860f69SOleksandr Tymoshenko 
9183860f69SOleksandr Tymoshenko 	if (timeout < 0)
9283860f69SOleksandr Tymoshenko 		return (-1);
9383860f69SOleksandr Tymoshenko 	else
9483860f69SOleksandr Tymoshenko 		return (0);
9583860f69SOleksandr Tymoshenko }
9683860f69SOleksandr Tymoshenko 
9783860f69SOleksandr Tymoshenko static int
src_detach(device_t dev)9883860f69SOleksandr Tymoshenko src_detach(device_t dev)
9983860f69SOleksandr Tymoshenko {
10083860f69SOleksandr Tymoshenko 	struct src_softc *sc;
10183860f69SOleksandr Tymoshenko 
10283860f69SOleksandr Tymoshenko 	sc = device_get_softc(dev);
10383860f69SOleksandr Tymoshenko 
10483860f69SOleksandr Tymoshenko 	if (sc->mem_res != NULL)
10583860f69SOleksandr Tymoshenko 		bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res);
10683860f69SOleksandr Tymoshenko 
10783860f69SOleksandr Tymoshenko 	return (0);
10883860f69SOleksandr Tymoshenko }
10983860f69SOleksandr Tymoshenko 
11083860f69SOleksandr Tymoshenko static int
src_attach(device_t dev)11183860f69SOleksandr Tymoshenko src_attach(device_t dev)
11283860f69SOleksandr Tymoshenko {
11383860f69SOleksandr Tymoshenko 	struct src_softc *sc;
11483860f69SOleksandr Tymoshenko 	int err, rid;
11583860f69SOleksandr Tymoshenko 
11683860f69SOleksandr Tymoshenko 	sc = device_get_softc(dev);
11783860f69SOleksandr Tymoshenko 	err = 0;
11883860f69SOleksandr Tymoshenko 
11983860f69SOleksandr Tymoshenko 	/* Allocate bus_space resources. */
12083860f69SOleksandr Tymoshenko 	rid = 0;
12183860f69SOleksandr Tymoshenko 	sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
12283860f69SOleksandr Tymoshenko 	    RF_ACTIVE);
12383860f69SOleksandr Tymoshenko 	if (sc->mem_res == NULL) {
12483860f69SOleksandr Tymoshenko 		device_printf(dev, "Cannot allocate memory resources\n");
12583860f69SOleksandr Tymoshenko 		err = ENXIO;
12683860f69SOleksandr Tymoshenko 		goto out;
12783860f69SOleksandr Tymoshenko 	}
12883860f69SOleksandr Tymoshenko 
12983860f69SOleksandr Tymoshenko 	src_sc = sc;
13083860f69SOleksandr Tymoshenko 
13183860f69SOleksandr Tymoshenko 	err = 0;
13283860f69SOleksandr Tymoshenko 
13383860f69SOleksandr Tymoshenko out:
13483860f69SOleksandr Tymoshenko 
13583860f69SOleksandr Tymoshenko 	if (err != 0)
13683860f69SOleksandr Tymoshenko 		src_detach(dev);
13783860f69SOleksandr Tymoshenko 
13883860f69SOleksandr Tymoshenko 	return (err);
13983860f69SOleksandr Tymoshenko }
14083860f69SOleksandr Tymoshenko 
14183860f69SOleksandr Tymoshenko static int
src_probe(device_t dev)14283860f69SOleksandr Tymoshenko src_probe(device_t dev)
14383860f69SOleksandr Tymoshenko {
14483860f69SOleksandr Tymoshenko 
14583860f69SOleksandr Tymoshenko         if ((ofw_bus_is_compatible(dev, "fsl,imx6q-src") == 0) &&
14683860f69SOleksandr Tymoshenko             (ofw_bus_is_compatible(dev, "fsl,imx6-src") == 0))
14783860f69SOleksandr Tymoshenko 		return (ENXIO);
14883860f69SOleksandr Tymoshenko 
14983860f69SOleksandr Tymoshenko 	device_set_desc(dev, "Freescale i.MX6 System Reset Controller");
15083860f69SOleksandr Tymoshenko 
15183860f69SOleksandr Tymoshenko 	return (BUS_PROBE_DEFAULT);
15283860f69SOleksandr Tymoshenko }
15383860f69SOleksandr Tymoshenko 
15483860f69SOleksandr Tymoshenko static device_method_t src_methods[] = {
15583860f69SOleksandr Tymoshenko 	/* Device interface */
15683860f69SOleksandr Tymoshenko 	DEVMETHOD(device_probe,  src_probe),
15783860f69SOleksandr Tymoshenko 	DEVMETHOD(device_attach, src_attach),
15883860f69SOleksandr Tymoshenko 	DEVMETHOD(device_detach, src_detach),
15983860f69SOleksandr Tymoshenko 
16083860f69SOleksandr Tymoshenko 	DEVMETHOD_END
16183860f69SOleksandr Tymoshenko };
16283860f69SOleksandr Tymoshenko 
16383860f69SOleksandr Tymoshenko static driver_t src_driver = {
16483860f69SOleksandr Tymoshenko 	"src",
16583860f69SOleksandr Tymoshenko 	src_methods,
16683860f69SOleksandr Tymoshenko 	sizeof(struct src_softc)
16783860f69SOleksandr Tymoshenko };
16883860f69SOleksandr Tymoshenko 
169*ea538dabSJohn Baldwin DRIVER_MODULE(src, simplebus, src_driver, 0, 0);
170