rk30xx_pmu.c revision 261410
1256949Sganbold/*- 2256949Sganbold * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@gmail.com> 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: head/sys/arm/rockchip/rk30xx_pmu.c 261410 2014-02-02 19:17:28Z ian $"); 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#include <machine/fdt.h> 53256949Sganbold 54256949Sganbold#include "rk30xx_pmu.h" 55256949Sganbold 56256949Sganboldstruct rk30_pmu_softc { 57256949Sganbold struct resource *res; 58256949Sganbold bus_space_tag_t bst; 59256949Sganbold bus_space_handle_t bsh; 60256949Sganbold}; 61256949Sganbold 62256949Sganboldstatic struct rk30_pmu_softc *rk30_pmu_sc = NULL; 63256949Sganbold 64256949Sganbold#define pmu_read_4(sc, reg) \ 65256949Sganbold bus_space_read_4((sc)->bst, (sc)->bsh, (reg)) 66256949Sganbold#define pmu_write_4(sc, reg, val) \ 67256949Sganbold bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val)) 68256949Sganbold 69256949Sganboldstatic int 70256949Sganboldrk30_pmu_probe(device_t dev) 71256949Sganbold{ 72256949Sganbold 73261410Sian if (!ofw_bus_status_okay(dev)) 74261410Sian return (ENXIO); 75261410Sian 76256949Sganbold if (ofw_bus_is_compatible(dev, "rockchip,rk30xx-pmu")) { 77256949Sganbold device_set_desc(dev, "RK30XX PMU"); 78256949Sganbold return(BUS_PROBE_DEFAULT); 79256949Sganbold } 80256949Sganbold 81256949Sganbold return (ENXIO); 82256949Sganbold} 83256949Sganbold 84256949Sganboldstatic int 85256949Sganboldrk30_pmu_attach(device_t dev) 86256949Sganbold{ 87256949Sganbold struct rk30_pmu_softc *sc = device_get_softc(dev); 88256949Sganbold int rid = 0; 89256949Sganbold 90256949Sganbold if (rk30_pmu_sc) 91256949Sganbold return (ENXIO); 92256949Sganbold 93256949Sganbold sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 94256949Sganbold if (!sc->res) { 95256949Sganbold device_printf(dev, "could not allocate resource\n"); 96256949Sganbold return (ENXIO); 97256949Sganbold } 98256949Sganbold 99256949Sganbold sc->bst = rman_get_bustag(sc->res); 100256949Sganbold sc->bsh = rman_get_bushandle(sc->res); 101256949Sganbold 102256949Sganbold rk30_pmu_sc = sc; 103256949Sganbold 104256949Sganbold return (0); 105256949Sganbold} 106256949Sganbold 107256949Sganboldstatic device_method_t rk30_pmu_methods[] = { 108256949Sganbold DEVMETHOD(device_probe, rk30_pmu_probe), 109256949Sganbold DEVMETHOD(device_attach, rk30_pmu_attach), 110256949Sganbold { 0, 0 } 111256949Sganbold}; 112256949Sganbold 113256949Sganboldstatic driver_t rk30_pmu_driver = { 114256949Sganbold "rk30_pmu", 115256949Sganbold rk30_pmu_methods, 116256949Sganbold sizeof(struct rk30_pmu_softc), 117256949Sganbold}; 118256949Sganbold 119256949Sganboldstatic devclass_t rk30_pmu_devclass; 120256949Sganbold 121256949SganboldDRIVER_MODULE(rk30_pmu, simplebus, rk30_pmu_driver, rk30_pmu_devclass, 0, 0); 122256949Sganbold 123256949Sganboldvoid 124256949Sganboldrk30_pmu_gpio_pud(uint32_t pin, uint32_t state) 125256949Sganbold{ 126256949Sganbold uint32_t offset; 127256949Sganbold 128256949Sganbold offset = PMU_GPIO0A_PULL + ((pin / 8) * 4); 129256949Sganbold pin = (pin % 8) * 2; 130256949Sganbold pmu_write_4(rk30_pmu_sc, offset, (0x3 << (16 + pin)) | (state << pin)); 131256949Sganbold} 132256949Sganbold 133