1256949Sganbold/*- 2263711Sganbold * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org> 3256949Sganbold * All rights reserved. 4256949Sganbold * 5256949Sganbold * Redistribution and use in source and binary forms, with or without 6256949Sganbold * modification, are permitted provided that the following conditions 7256949Sganbold * are met: 8256949Sganbold * 1. Redistributions of source code must retain the above copyright 9256949Sganbold * notice, this list of conditions and the following disclaimer. 10256949Sganbold * 2. Redistributions in binary form must reproduce the above copyright 11256949Sganbold * notice, this list of conditions and the following disclaimer in the 12256949Sganbold * documentation and/or other materials provided with the distribution. 13256949Sganbold * 14256949Sganbold * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15256949Sganbold * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16256949Sganbold * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17256949Sganbold * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18256949Sganbold * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19256949Sganbold * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20256949Sganbold * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21256949Sganbold * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22256949Sganbold * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23256949Sganbold * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24256949Sganbold * SUCH DAMAGE. 25256949Sganbold */ 26256949Sganbold 27256949Sganbold/* PMU for Rockchip RK30xx */ 28256949Sganbold 29256949Sganbold#include <sys/cdefs.h> 30256949Sganbold__FBSDID("$FreeBSD$"); 31256949Sganbold 32256949Sganbold#include <sys/param.h> 33256949Sganbold#include <sys/systm.h> 34256949Sganbold#include <sys/bus.h> 35256949Sganbold#include <sys/kernel.h> 36256949Sganbold#include <sys/module.h> 37256949Sganbold#include <sys/malloc.h> 38256949Sganbold#include <sys/rman.h> 39256949Sganbold#include <sys/timeet.h> 40256949Sganbold#include <sys/timetc.h> 41256949Sganbold#include <sys/watchdog.h> 42256949Sganbold#include <machine/bus.h> 43256949Sganbold#include <machine/cpu.h> 44256949Sganbold#include <machine/intr.h> 45256949Sganbold 46256949Sganbold#include <dev/fdt/fdt_common.h> 47256949Sganbold#include <dev/ofw/openfirm.h> 48256949Sganbold#include <dev/ofw/ofw_bus.h> 49256949Sganbold#include <dev/ofw/ofw_bus_subr.h> 50256949Sganbold 51256949Sganbold#include <machine/bus.h> 52256949Sganbold 53256949Sganbold#include "rk30xx_pmu.h" 54256949Sganbold 55256949Sganboldstruct rk30_pmu_softc { 56256949Sganbold struct resource *res; 57256949Sganbold bus_space_tag_t bst; 58256949Sganbold bus_space_handle_t bsh; 59256949Sganbold}; 60256949Sganbold 61256949Sganboldstatic struct rk30_pmu_softc *rk30_pmu_sc = NULL; 62256949Sganbold 63256949Sganbold#define pmu_read_4(sc, reg) \ 64256949Sganbold bus_space_read_4((sc)->bst, (sc)->bsh, (reg)) 65256949Sganbold#define pmu_write_4(sc, reg, val) \ 66256949Sganbold bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val)) 67256949Sganbold 68256949Sganboldstatic int 69256949Sganboldrk30_pmu_probe(device_t dev) 70256949Sganbold{ 71256949Sganbold 72261410Sian if (!ofw_bus_status_okay(dev)) 73261410Sian return (ENXIO); 74261410Sian 75256949Sganbold if (ofw_bus_is_compatible(dev, "rockchip,rk30xx-pmu")) { 76256949Sganbold device_set_desc(dev, "RK30XX PMU"); 77256949Sganbold return(BUS_PROBE_DEFAULT); 78256949Sganbold } 79256949Sganbold 80256949Sganbold return (ENXIO); 81256949Sganbold} 82256949Sganbold 83256949Sganboldstatic int 84256949Sganboldrk30_pmu_attach(device_t dev) 85256949Sganbold{ 86256949Sganbold struct rk30_pmu_softc *sc = device_get_softc(dev); 87256949Sganbold int rid = 0; 88256949Sganbold 89256949Sganbold if (rk30_pmu_sc) 90256949Sganbold return (ENXIO); 91256949Sganbold 92256949Sganbold sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 93256949Sganbold if (!sc->res) { 94256949Sganbold device_printf(dev, "could not allocate resource\n"); 95256949Sganbold return (ENXIO); 96256949Sganbold } 97256949Sganbold 98256949Sganbold sc->bst = rman_get_bustag(sc->res); 99256949Sganbold sc->bsh = rman_get_bushandle(sc->res); 100256949Sganbold 101256949Sganbold rk30_pmu_sc = sc; 102256949Sganbold 103256949Sganbold return (0); 104256949Sganbold} 105256949Sganbold 106256949Sganboldstatic device_method_t rk30_pmu_methods[] = { 107256949Sganbold DEVMETHOD(device_probe, rk30_pmu_probe), 108256949Sganbold DEVMETHOD(device_attach, rk30_pmu_attach), 109256949Sganbold { 0, 0 } 110256949Sganbold}; 111256949Sganbold 112256949Sganboldstatic driver_t rk30_pmu_driver = { 113256949Sganbold "rk30_pmu", 114256949Sganbold rk30_pmu_methods, 115256949Sganbold sizeof(struct rk30_pmu_softc), 116256949Sganbold}; 117256949Sganbold 118256949Sganboldstatic devclass_t rk30_pmu_devclass; 119256949Sganbold 120256949SganboldDRIVER_MODULE(rk30_pmu, simplebus, rk30_pmu_driver, rk30_pmu_devclass, 0, 0); 121256949Sganbold 122256949Sganboldvoid 123256949Sganboldrk30_pmu_gpio_pud(uint32_t pin, uint32_t state) 124256949Sganbold{ 125256949Sganbold uint32_t offset; 126256949Sganbold 127256949Sganbold offset = PMU_GPIO0A_PULL + ((pin / 8) * 4); 128256949Sganbold pin = (pin % 8) * 2; 129256949Sganbold pmu_write_4(rk30_pmu_sc, offset, (0x3 << (16 + pin)) | (state << pin)); 130256949Sganbold} 131256949Sganbold 132