rk30xx_pmu.c revision 256949
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 256949 2013-10-23 00:39:43Z ganbold $"); 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/frame.h> 45256949Sganbold#include <machine/intr.h> 46256949Sganbold 47256949Sganbold#include <dev/fdt/fdt_common.h> 48256949Sganbold#include <dev/ofw/openfirm.h> 49256949Sganbold#include <dev/ofw/ofw_bus.h> 50256949Sganbold#include <dev/ofw/ofw_bus_subr.h> 51256949Sganbold 52256949Sganbold#include <machine/bus.h> 53256949Sganbold#include <machine/fdt.h> 54256949Sganbold 55256949Sganbold#include "rk30xx_pmu.h" 56256949Sganbold 57256949Sganboldstruct rk30_pmu_softc { 58256949Sganbold struct resource *res; 59256949Sganbold bus_space_tag_t bst; 60256949Sganbold bus_space_handle_t bsh; 61256949Sganbold}; 62256949Sganbold 63256949Sganboldstatic struct rk30_pmu_softc *rk30_pmu_sc = NULL; 64256949Sganbold 65256949Sganbold#define pmu_read_4(sc, reg) \ 66256949Sganbold bus_space_read_4((sc)->bst, (sc)->bsh, (reg)) 67256949Sganbold#define pmu_write_4(sc, reg, val) \ 68256949Sganbold bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val)) 69256949Sganbold 70256949Sganboldstatic int 71256949Sganboldrk30_pmu_probe(device_t dev) 72256949Sganbold{ 73256949Sganbold 74256949Sganbold if (ofw_bus_is_compatible(dev, "rockchip,rk30xx-pmu")) { 75256949Sganbold device_set_desc(dev, "RK30XX PMU"); 76256949Sganbold return(BUS_PROBE_DEFAULT); 77256949Sganbold } 78256949Sganbold 79256949Sganbold return (ENXIO); 80256949Sganbold} 81256949Sganbold 82256949Sganboldstatic int 83256949Sganboldrk30_pmu_attach(device_t dev) 84256949Sganbold{ 85256949Sganbold struct rk30_pmu_softc *sc = device_get_softc(dev); 86256949Sganbold int rid = 0; 87256949Sganbold 88256949Sganbold if (rk30_pmu_sc) 89256949Sganbold return (ENXIO); 90256949Sganbold 91256949Sganbold sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 92256949Sganbold if (!sc->res) { 93256949Sganbold device_printf(dev, "could not allocate resource\n"); 94256949Sganbold return (ENXIO); 95256949Sganbold } 96256949Sganbold 97256949Sganbold sc->bst = rman_get_bustag(sc->res); 98256949Sganbold sc->bsh = rman_get_bushandle(sc->res); 99256949Sganbold 100256949Sganbold rk30_pmu_sc = sc; 101256949Sganbold 102256949Sganbold return (0); 103256949Sganbold} 104256949Sganbold 105256949Sganboldstatic device_method_t rk30_pmu_methods[] = { 106256949Sganbold DEVMETHOD(device_probe, rk30_pmu_probe), 107256949Sganbold DEVMETHOD(device_attach, rk30_pmu_attach), 108256949Sganbold { 0, 0 } 109256949Sganbold}; 110256949Sganbold 111256949Sganboldstatic driver_t rk30_pmu_driver = { 112256949Sganbold "rk30_pmu", 113256949Sganbold rk30_pmu_methods, 114256949Sganbold sizeof(struct rk30_pmu_softc), 115256949Sganbold}; 116256949Sganbold 117256949Sganboldstatic devclass_t rk30_pmu_devclass; 118256949Sganbold 119256949SganboldDRIVER_MODULE(rk30_pmu, simplebus, rk30_pmu_driver, rk30_pmu_devclass, 0, 0); 120256949Sganbold 121256949Sganboldvoid 122256949Sganboldrk30_pmu_gpio_pud(uint32_t pin, uint32_t state) 123256949Sganbold{ 124256949Sganbold uint32_t offset; 125256949Sganbold 126256949Sganbold offset = PMU_GPIO0A_PULL + ((pin / 8) * 4); 127256949Sganbold pin = (pin % 8) * 2; 128256949Sganbold pmu_write_4(rk30_pmu_sc, offset, (0x3 << (16 + pin)) | (state << pin)); 129256949Sganbold} 130256949Sganbold 131