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