1290807Sgonzo/*- 2290807Sgonzo * Copyright (c) 2015 Oleksandr Tymoshenko <gonzo@freebsd.org> 3290807Sgonzo * All rights reserved. 4290807Sgonzo * 5290807Sgonzo * Redistribution and use in source and binary forms, with or without 6290807Sgonzo * modification, are permitted provided that the following conditions 7290807Sgonzo * are met: 8290807Sgonzo * 1. Redistributions of source code must retain the above copyright 9290807Sgonzo * notice, this list of conditions and the following disclaimer. 10290807Sgonzo * 2. Redistributions in binary form must reproduce the above copyright 11290807Sgonzo * notice, this list of conditions and the following disclaimer in the 12290807Sgonzo * documentation and/or other materials provided with the distribution. 13290807Sgonzo * 14290807Sgonzo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15290807Sgonzo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16290807Sgonzo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17290807Sgonzo * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18290807Sgonzo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19290807Sgonzo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20290807Sgonzo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21290807Sgonzo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22290807Sgonzo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23290807Sgonzo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24290807Sgonzo * SUCH DAMAGE. 25290807Sgonzo */ 26290807Sgonzo 27290807Sgonzo#include <sys/cdefs.h> 28290807Sgonzo__FBSDID("$FreeBSD: stable/11/sys/arm/freescale/imx/imx6_src.c 314506 2017-03-01 19:55:04Z ian $"); 29290807Sgonzo 30290807Sgonzo/* 31290807Sgonzo * System Reset Control for iMX6 32290807Sgonzo */ 33290807Sgonzo 34290807Sgonzo#include <sys/param.h> 35290807Sgonzo#include <sys/systm.h> 36290807Sgonzo#include <sys/kernel.h> 37290807Sgonzo#include <sys/module.h> 38290807Sgonzo#include <sys/bus.h> 39290807Sgonzo#include <sys/rman.h> 40290807Sgonzo 41290807Sgonzo#include <dev/ofw/ofw_bus.h> 42290807Sgonzo#include <dev/ofw/ofw_bus_subr.h> 43290807Sgonzo 44290807Sgonzo#include <machine/bus.h> 45290807Sgonzo 46290807Sgonzo#include <arm/freescale/imx/imx6_src.h> 47290807Sgonzo 48290807Sgonzo#define SRC_SCR 0 49290807Sgonzo#define SW_IPU1_RST (1 << 3) 50290807Sgonzo 51290807Sgonzostruct src_softc { 52290807Sgonzo device_t dev; 53290807Sgonzo struct resource *mem_res; 54290807Sgonzo}; 55290807Sgonzo 56290807Sgonzostatic struct src_softc *src_sc; 57290807Sgonzo 58290807Sgonzostatic inline uint32_t 59290807SgonzoRD4(struct src_softc *sc, bus_size_t off) 60290807Sgonzo{ 61290807Sgonzo 62290807Sgonzo return (bus_read_4(sc->mem_res, off)); 63290807Sgonzo} 64290807Sgonzo 65290807Sgonzostatic inline void 66290807SgonzoWR4(struct src_softc *sc, bus_size_t off, uint32_t val) 67290807Sgonzo{ 68290807Sgonzo 69290807Sgonzo bus_write_4(sc->mem_res, off, val); 70290807Sgonzo} 71290807Sgonzo 72290807Sgonzoint 73314506Siansrc_reset_ipu(void) 74290807Sgonzo{ 75290807Sgonzo uint32_t reg; 76290807Sgonzo int timeout = 10000; 77290807Sgonzo 78290807Sgonzo if (src_sc == NULL) 79290807Sgonzo return (-1); 80290807Sgonzo 81290807Sgonzo reg = RD4(src_sc, SRC_SCR); 82290807Sgonzo reg |= SW_IPU1_RST; 83290807Sgonzo WR4(src_sc, SRC_SCR, reg); 84290807Sgonzo 85290807Sgonzo while (timeout-- > 0) { 86290807Sgonzo reg = RD4(src_sc, SRC_SCR); 87290807Sgonzo if (reg & SW_IPU1_RST) 88290807Sgonzo DELAY(1); 89290807Sgonzo else 90290807Sgonzo break; 91290807Sgonzo } 92290807Sgonzo 93290807Sgonzo if (timeout < 0) 94290807Sgonzo return (-1); 95290807Sgonzo else 96290807Sgonzo return (0); 97290807Sgonzo} 98290807Sgonzo 99290807Sgonzostatic int 100290807Sgonzosrc_detach(device_t dev) 101290807Sgonzo{ 102290807Sgonzo struct src_softc *sc; 103290807Sgonzo 104290807Sgonzo sc = device_get_softc(dev); 105290807Sgonzo 106290807Sgonzo if (sc->mem_res != NULL) 107290807Sgonzo bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->mem_res); 108290807Sgonzo 109290807Sgonzo return (0); 110290807Sgonzo} 111290807Sgonzo 112290807Sgonzostatic int 113290807Sgonzosrc_attach(device_t dev) 114290807Sgonzo{ 115290807Sgonzo struct src_softc *sc; 116290807Sgonzo int err, rid; 117290807Sgonzo 118290807Sgonzo sc = device_get_softc(dev); 119290807Sgonzo err = 0; 120290807Sgonzo 121290807Sgonzo /* Allocate bus_space resources. */ 122290807Sgonzo rid = 0; 123290807Sgonzo sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, 124290807Sgonzo RF_ACTIVE); 125290807Sgonzo if (sc->mem_res == NULL) { 126290807Sgonzo device_printf(dev, "Cannot allocate memory resources\n"); 127290807Sgonzo err = ENXIO; 128290807Sgonzo goto out; 129290807Sgonzo } 130290807Sgonzo 131290807Sgonzo src_sc = sc; 132290807Sgonzo 133290807Sgonzo err = 0; 134290807Sgonzo 135290807Sgonzoout: 136290807Sgonzo 137290807Sgonzo if (err != 0) 138290807Sgonzo src_detach(dev); 139290807Sgonzo 140290807Sgonzo return (err); 141290807Sgonzo} 142290807Sgonzo 143290807Sgonzostatic int 144290807Sgonzosrc_probe(device_t dev) 145290807Sgonzo{ 146290807Sgonzo 147290807Sgonzo if ((ofw_bus_is_compatible(dev, "fsl,imx6q-src") == 0) && 148290807Sgonzo (ofw_bus_is_compatible(dev, "fsl,imx6-src") == 0)) 149290807Sgonzo return (ENXIO); 150290807Sgonzo 151290807Sgonzo device_set_desc(dev, "Freescale i.MX6 System Reset Controller"); 152290807Sgonzo 153290807Sgonzo return (BUS_PROBE_DEFAULT); 154290807Sgonzo} 155290807Sgonzo 156290807Sgonzostatic device_method_t src_methods[] = { 157290807Sgonzo /* Device interface */ 158290807Sgonzo DEVMETHOD(device_probe, src_probe), 159290807Sgonzo DEVMETHOD(device_attach, src_attach), 160290807Sgonzo DEVMETHOD(device_detach, src_detach), 161290807Sgonzo 162290807Sgonzo DEVMETHOD_END 163290807Sgonzo}; 164290807Sgonzo 165290807Sgonzostatic driver_t src_driver = { 166290807Sgonzo "src", 167290807Sgonzo src_methods, 168290807Sgonzo sizeof(struct src_softc) 169290807Sgonzo}; 170290807Sgonzo 171290807Sgonzostatic devclass_t src_devclass; 172290807Sgonzo 173290807SgonzoDRIVER_MODULE(src, simplebus, src_driver, src_devclass, 0, 0); 174