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