1198892Srdivacky/*- 2198892Srdivacky * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@freebsd.org> 3198892Srdivacky * All rights reserved. 4198892Srdivacky * 5198892Srdivacky * Redistribution and use in source and binary forms, with or without 6198892Srdivacky * modification, are permitted provided that the following conditions 7198892Srdivacky * are met: 8198892Srdivacky * 1. Redistributions of source code must retain the above copyright 9198892Srdivacky * notice, this list of conditions and the following disclaimer. 10198892Srdivacky * 2. Redistributions in binary form must reproduce the above copyright 11198892Srdivacky * notice, this list of conditions and the following disclaimer in the 12198892Srdivacky * documentation and/or other materials provided with the distribution. 13198892Srdivacky * 14198892Srdivacky * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15198892Srdivacky * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16198892Srdivacky * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17198892Srdivacky * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18198892Srdivacky * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19198892Srdivacky * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20198892Srdivacky * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21210299Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22198892Srdivacky * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23198892Srdivacky * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24198892Srdivacky * SUCH DAMAGE. 25198892Srdivacky */ 26198892Srdivacky 27198892Srdivacky/* PMU for Rockchip RK30xx */ 28198892Srdivacky 29198892Srdivacky#include <sys/cdefs.h> 30224145Sdim__FBSDID("$FreeBSD: releng/10.2/sys/arm/rockchip/rk30xx_pmu.c 266337 2014-05-17 18:53:36Z ian $"); 31198892Srdivacky 32198892Srdivacky#include <sys/param.h> 33210299Sed#include <sys/systm.h> 34198892Srdivacky#include <sys/bus.h> 35224145Sdim#include <sys/kernel.h> 36212904Sdim#include <sys/module.h> 37212904Sdim#include <sys/malloc.h> 38234353Sdim#include <sys/rman.h> 39234353Sdim#include <sys/timeet.h> 40198892Srdivacky#include <sys/timetc.h> 41198892Srdivacky#include <sys/watchdog.h> 42198892Srdivacky#include <machine/bus.h> 43198892Srdivacky#include <machine/cpu.h> 44198892Srdivacky#include <machine/intr.h> 45212904Sdim 46212904Sdim#include <dev/fdt/fdt_common.h> 47212904Sdim#include <dev/ofw/openfirm.h> 48212904Sdim#include <dev/ofw/ofw_bus.h> 49198892Srdivacky#include <dev/ofw/ofw_bus_subr.h> 50212904Sdim 51200581Srdivacky#include <machine/bus.h> 52200581Srdivacky#include <machine/fdt.h> 53200581Srdivacky 54198892Srdivacky#include "rk30xx_pmu.h" 55198892Srdivacky 56234353Sdimstruct rk30_pmu_softc { 57198892Srdivacky struct resource *res; 58234353Sdim bus_space_tag_t bst; 59198892Srdivacky bus_space_handle_t bsh; 60198892Srdivacky}; 61198892Srdivacky 62198892Srdivackystatic struct rk30_pmu_softc *rk30_pmu_sc = NULL; 63198892Srdivacky 64198892Srdivacky#define pmu_read_4(sc, reg) \ 65239462Sdim bus_space_read_4((sc)->bst, (sc)->bsh, (reg)) 66239462Sdim#define pmu_write_4(sc, reg, val) \ 67239462Sdim bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val)) 68239462Sdim 69239462Sdimstatic int 70198892Srdivackyrk30_pmu_probe(device_t dev) 71198892Srdivacky{ 72210299Sed 73210299Sed if (!ofw_bus_status_okay(dev)) 74210299Sed return (ENXIO); 75210299Sed 76210299Sed if (ofw_bus_is_compatible(dev, "rockchip,rk30xx-pmu")) { 77210299Sed device_set_desc(dev, "RK30XX PMU"); 78198892Srdivacky return(BUS_PROBE_DEFAULT); 79210299Sed } 80198892Srdivacky 81239462Sdim return (ENXIO); 82239462Sdim} 83239462Sdim 84239462Sdimstatic int 85239462Sdimrk30_pmu_attach(device_t dev) 86198892Srdivacky{ 87210299Sed struct rk30_pmu_softc *sc = device_get_softc(dev); 88198892Srdivacky int rid = 0; 89198892Srdivacky 90198892Srdivacky if (rk30_pmu_sc) 91198892Srdivacky return (ENXIO); 92198892Srdivacky 93198892Srdivacky sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); 94234353Sdim if (!sc->res) { 95239462Sdim device_printf(dev, "could not allocate resource\n"); 96239462Sdim return (ENXIO); 97239462Sdim } 98239462Sdim 99239462Sdim sc->bst = rman_get_bustag(sc->res); 100239462Sdim sc->bsh = rman_get_bushandle(sc->res); 101198892Srdivacky 102198892Srdivacky rk30_pmu_sc = sc; 103198892Srdivacky 104198892Srdivacky return (0); 105198892Srdivacky} 106198892Srdivacky 107234353Sdimstatic device_method_t rk30_pmu_methods[] = { 108198892Srdivacky DEVMETHOD(device_probe, rk30_pmu_probe), 109198892Srdivacky DEVMETHOD(device_attach, rk30_pmu_attach), 110198892Srdivacky { 0, 0 } 111198892Srdivacky}; 112204792Srdivacky 113204792Srdivackystatic driver_t rk30_pmu_driver = { 114198892Srdivacky "rk30_pmu", 115198892Srdivacky rk30_pmu_methods, 116218893Sdim sizeof(struct rk30_pmu_softc), 117218893Sdim}; 118218893Sdim 119218893Sdimstatic devclass_t rk30_pmu_devclass; 120218893Sdim 121198892SrdivackyDRIVER_MODULE(rk30_pmu, simplebus, rk30_pmu_driver, rk30_pmu_devclass, 0, 0); 122218893Sdim 123218893Sdimvoid 124218893Sdimrk30_pmu_gpio_pud(uint32_t pin, uint32_t state) 125218893Sdim{ 126218893Sdim uint32_t offset; 127218893Sdim 128218893Sdim offset = PMU_GPIO0A_PULL + ((pin / 8) * 4); 129212904Sdim pin = (pin % 8) * 2; 130198892Srdivacky pmu_write_4(rk30_pmu_sc, offset, (0x3 << (16 + pin)) | (state << pin)); 131198892Srdivacky} 132198892Srdivacky 133198892Srdivacky