diff options
author | ian <ian@FreeBSD.org> | 2013-12-13 19:17:09 +0000 |
---|---|---|
committer | ian <ian@FreeBSD.org> | 2013-12-13 19:17:09 +0000 |
commit | 733bb57871c94bbe4ac830be91cd5f3c62c9a75f (patch) | |
tree | 3fcda676348876ab9da1fee7e136ad83a3d5541d /sys/arm | |
parent | 180cdddb9524b6e0bc4aeec1d5629683275af232 (diff) | |
download | FreeBSD-src-733bb57871c94bbe4ac830be91cd5f3c62c9a75f.zip FreeBSD-src-733bb57871c94bbe4ac830be91cd5f3c62c9a75f.tar.gz |
MFC r256949: Import basic support for Rockchip RK3188 SoC.
Diffstat (limited to 'sys/arm')
-rw-r--r-- | sys/arm/rockchip/bus_space.c | 113 | ||||
-rw-r--r-- | sys/arm/rockchip/common.c | 64 | ||||
-rw-r--r-- | sys/arm/rockchip/files.rk30xx | 21 | ||||
-rw-r--r-- | sys/arm/rockchip/rk30xx_gpio.c | 528 | ||||
-rw-r--r-- | sys/arm/rockchip/rk30xx_grf.c | 130 | ||||
-rw-r--r-- | sys/arm/rockchip/rk30xx_grf.h | 141 | ||||
-rw-r--r-- | sys/arm/rockchip/rk30xx_machdep.c | 122 | ||||
-rw-r--r-- | sys/arm/rockchip/rk30xx_pmu.c | 130 | ||||
-rw-r--r-- | sys/arm/rockchip/rk30xx_pmu.h | 60 | ||||
-rw-r--r-- | sys/arm/rockchip/std.rk30xx | 27 |
10 files changed, 1336 insertions, 0 deletions
diff --git a/sys/arm/rockchip/bus_space.c b/sys/arm/rockchip/bus_space.c new file mode 100644 index 0000000..4cce820 --- /dev/null +++ b/sys/arm/rockchip/bus_space.c @@ -0,0 +1,113 @@ +/*- + * Copyright (C) 2012 FreeBSD Foundation + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of MARVELL nor the names of contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/malloc.h> + +#include <machine/bus.h> + +/* Prototypes for all the bus_space structure functions */ +bs_protos(generic); +bs_protos(generic_armv4); + +struct bus_space _base_tag = { + /* cookie */ + .bs_cookie = (void *) 0, + + /* mapping/unmapping */ + .bs_map = generic_bs_map, + .bs_unmap = generic_bs_unmap, + .bs_subregion = generic_bs_subregion, + + /* allocation/deallocation */ + .bs_alloc = generic_bs_alloc, + .bs_free = generic_bs_free, + + /* barrier */ + .bs_barrier = generic_bs_barrier, + + /* read (single) */ + .bs_r_1 = generic_bs_r_1, + .bs_r_2 = generic_armv4_bs_r_2, + .bs_r_4 = generic_bs_r_4, + .bs_r_8 = NULL, + + /* read multiple */ + .bs_rm_1 = generic_bs_rm_1, + .bs_rm_2 = generic_armv4_bs_rm_2, + .bs_rm_4 = generic_bs_rm_4, + .bs_rm_8 = NULL, + + /* read region */ + .bs_rr_1 = generic_bs_rr_1, + .bs_rr_2 = generic_armv4_bs_rr_2, + .bs_rr_4 = generic_bs_rr_4, + .bs_rr_8 = NULL, + + /* write (single) */ + .bs_w_1 = generic_bs_w_1, + .bs_w_2 = generic_armv4_bs_w_2, + .bs_w_4 = generic_bs_w_4, + .bs_w_8 = NULL, + + /* write multiple */ + .bs_wm_1 = generic_bs_wm_1, + .bs_wm_2 = generic_armv4_bs_wm_2, + .bs_wm_4 = generic_bs_wm_4, + .bs_wm_8 = NULL, + + /* write region */ + .bs_wr_1 = generic_bs_wr_1, + .bs_wr_2 = generic_armv4_bs_wr_2, + .bs_wr_4 = generic_bs_wr_4, + .bs_wr_8 = NULL, + + /* set multiple */ + /* XXX not implemented */ + + /* set region */ + .bs_sr_1 = NULL, + .bs_sr_2 = generic_armv4_bs_sr_2, + .bs_sr_4 = generic_bs_sr_4, + .bs_sr_8 = NULL, + + /* copy */ + .bs_c_1 = NULL, + .bs_c_2 = generic_armv4_bs_c_2, + .bs_c_4 = NULL, + .bs_c_8 = NULL, +}; + +bus_space_tag_t fdtbus_bs_tag = &_base_tag; diff --git a/sys/arm/rockchip/common.c b/sys/arm/rockchip/common.c new file mode 100644 index 0000000..0653184 --- /dev/null +++ b/sys/arm/rockchip/common.c @@ -0,0 +1,64 @@ +/*- + * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> + +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/openfirm.h> + +#include <machine/bus.h> +#include <machine/fdt.h> +#include <machine/vmparam.h> + +struct fdt_fixup_entry fdt_fixup_table[] = { + { NULL, NULL } +}; + +static int +fdt_aintc_decode_ic(phandle_t node, pcell_t *intr, int *interrupt, int *trig, + int *pol) +{ + + if (!fdt_is_compatible(node, "arm,gic")) + return (ENXIO); + + *interrupt = fdt32_to_cpu(intr[0]); + *trig = INTR_TRIGGER_CONFORM; + *pol = INTR_POLARITY_CONFORM; + + return (0); +} + +fdt_pic_decode_t fdt_pic_table[] = { + &fdt_aintc_decode_ic, + NULL +}; diff --git a/sys/arm/rockchip/files.rk30xx b/sys/arm/rockchip/files.rk30xx new file mode 100644 index 0000000..d6db873 --- /dev/null +++ b/sys/arm/rockchip/files.rk30xx @@ -0,0 +1,21 @@ +# $FreeBSD$ +kern/kern_clocksource.c standard + +arm/arm/bus_space_asm_generic.S standard +arm/arm/bus_space_generic.c standard +arm/arm/cpufunc_asm_armv5.S standard +arm/arm/cpufunc_asm_arm10.S standard +arm/arm/cpufunc_asm_arm11.S standard +arm/arm/cpufunc_asm_armv7.S standard +arm/arm/irq_dispatch.S standard + +arm/arm/gic.c standard +arm/arm/mpcore_timer.c standard + +arm/rockchip/bus_space.c standard +arm/rockchip/common.c standard +arm/rockchip/rk30xx_machdep.c standard +arm/rockchip/rk30xx_pmu.c standard +arm/rockchip/rk30xx_grf.c standard +arm/rockchip/rk30xx_gpio.c optional gpio +dev/usb/controller/dwc_otg_fdt.c optional dwcotg diff --git a/sys/arm/rockchip/rk30xx_gpio.c b/sys/arm/rockchip/rk30xx_gpio.c new file mode 100644 index 0000000..903ffbd --- /dev/null +++ b/sys/arm/rockchip/rk30xx_gpio.c @@ -0,0 +1,528 @@ +/*- + * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@gmail.com> + * Copyright (c) 2012 Oleksandr Tymoshenko <gonzo@freebsd.org> + * Copyright (c) 2012 Luiz Otavio O Souza. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> + +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/rman.h> +#include <sys/lock.h> +#include <sys/mutex.h> +#include <sys/gpio.h> + +#include <machine/bus.h> +#include <machine/cpu.h> +#include <machine/cpufunc.h> +#include <machine/resource.h> +#include <machine/fdt.h> +#include <machine/frame.h> +#include <machine/intr.h> + +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#include "gpio_if.h" + +#include "rk30xx_grf.h" +#include "rk30xx_pmu.h" + +/* + * RK3188 has 4 banks of gpio. + * 32 pins per bank + * PA0 - PA7 | PB0 - PB7 + * PC0 - PC7 | PD0 - PD7 + */ + +#define RK30_GPIO_PINS 128 +#define RK30_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \ + GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN) + +#define RK30_GPIO_NONE 0 +#define RK30_GPIO_PULLUP 1 +#define RK30_GPIO_PULLDOWN 2 + +#define RK30_GPIO_INPUT 0 +#define RK30_GPIO_OUTPUT 1 + +struct rk30_gpio_softc { + device_t sc_dev; + struct mtx sc_mtx; + struct resource * sc_mem_res; + struct resource * sc_irq_res; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + void * sc_intrhand; + int sc_gpio_npins; + struct gpio_pin sc_gpio_pins[RK30_GPIO_PINS]; +}; + +#define RK30_GPIO_LOCK(_sc) mtx_lock(&_sc->sc_mtx) +#define RK30_GPIO_UNLOCK(_sc) mtx_unlock(&_sc->sc_mtx) +#define RK30_GPIO_LOCK_ASSERT(_sc) mtx_assert(&_sc->sc_mtx, MA_OWNED) + +#define RK30_GPIO_SWPORT_DR 0x00 +#define RK30_GPIO_SWPORT_DDR 0x04 +#define RK30_GPIO_INTEN 0x30 +#define RK30_GPIO_INTMASK 0x34 +#define RK30_GPIO_INTTYPE_LEVEL 0x38 +#define RK30_GPIO_INT_POLARITY 0x3c +#define RK30_GPIO_INT_STATUS 0x40 +#define RK30_GPIO_INT_RAWSTATUS 0x44 +#define RK30_GPIO_DEBOUNCE 0x48 +#define RK30_GPIO_PORTS_EOI 0x4c +#define RK30_GPIO_EXT_PORT 0x50 +#define RK30_GPIO_LS_SYNC 0x60 + +#define RK30_GPIO_WRITE(_sc, _off, _val) \ + bus_space_write_4(_sc->sc_bst, _sc->sc_bsh, _off, _val) +#define RK30_GPIO_READ(_sc, _off) \ + bus_space_read_4(_sc->sc_bst, _sc->sc_bsh, _off) + +static uint32_t +rk30_gpio_get_function(struct rk30_gpio_softc *sc, uint32_t pin) +{ + uint32_t bank, func, offset; + + bank = pin / 32; + pin = pin % 32; + offset = 1 << pin; + + func = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); + func &= offset; + + return (func); +} + +static uint32_t +rk30_gpio_func_flag(uint32_t nfunc) +{ + + switch (nfunc) { + case RK30_GPIO_INPUT: + return (GPIO_PIN_INPUT); + case RK30_GPIO_OUTPUT: + return (GPIO_PIN_OUTPUT); + } + return (0); +} + +static void +rk30_gpio_set_function(struct rk30_gpio_softc *sc, uint32_t pin, uint32_t f) +{ + uint32_t bank, data, offset; + + /* Must be called with lock held. */ + RK30_GPIO_LOCK_ASSERT(sc); + + bank = pin / 32; + pin = pin % 32; + offset = 1 << pin; + + data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); + if (f) + data |= offset; + else + data &= ~offset; + RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data); +} + +static void +rk30_gpio_set_pud(struct rk30_gpio_softc *sc, uint32_t pin, uint32_t state) +{ + uint32_t bank; + + bank = pin / 32; + + /* Must be called with lock held. */ + RK30_GPIO_LOCK_ASSERT(sc); + + if (bank == 0 && pin < 12) + rk30_pmu_gpio_pud(pin, state); + else + rk30_grf_gpio_pud(bank, pin, state); +} + +static void +rk30_gpio_pin_configure(struct rk30_gpio_softc *sc, struct gpio_pin *pin, + unsigned int flags) +{ + + RK30_GPIO_LOCK(sc); + + /* + * Manage input/output. + */ + if (flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) { + pin->gp_flags &= ~(GPIO_PIN_INPUT|GPIO_PIN_OUTPUT); + if (flags & GPIO_PIN_OUTPUT) { + pin->gp_flags |= GPIO_PIN_OUTPUT; + rk30_gpio_set_function(sc, pin->gp_pin, + RK30_GPIO_OUTPUT); + } else { + pin->gp_flags |= GPIO_PIN_INPUT; + rk30_gpio_set_function(sc, pin->gp_pin, + RK30_GPIO_INPUT); + } + } + + /* Manage Pull-up/pull-down. */ + pin->gp_flags &= ~(GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN); + if (flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) { + if (flags & GPIO_PIN_PULLUP) { + pin->gp_flags |= GPIO_PIN_PULLUP; + rk30_gpio_set_pud(sc, pin->gp_pin, + RK30_GPIO_PULLUP); + } else { + pin->gp_flags |= GPIO_PIN_PULLDOWN; + rk30_gpio_set_pud(sc, pin->gp_pin, + RK30_GPIO_PULLDOWN); + } + } else + rk30_gpio_set_pud(sc, pin->gp_pin, RK30_GPIO_NONE); + + RK30_GPIO_UNLOCK(sc); +} + +static int +rk30_gpio_pin_max(device_t dev, int *maxpin) +{ + + *maxpin = RK30_GPIO_PINS - 1; + return (0); +} + +static int +rk30_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps) +{ + struct rk30_gpio_softc *sc = device_get_softc(dev); + int i; + + for (i = 0; i < sc->sc_gpio_npins; i++) { + if (sc->sc_gpio_pins[i].gp_pin == pin) + break; + } + + if (i >= sc->sc_gpio_npins) + return (EINVAL); + + RK30_GPIO_LOCK(sc); + *caps = sc->sc_gpio_pins[i].gp_caps; + RK30_GPIO_UNLOCK(sc); + + return (0); +} + +static int +rk30_gpio_pin_getflags(device_t dev, uint32_t pin, uint32_t *flags) +{ + struct rk30_gpio_softc *sc = device_get_softc(dev); + int i; + + for (i = 0; i < sc->sc_gpio_npins; i++) { + if (sc->sc_gpio_pins[i].gp_pin == pin) + break; + } + + if (i >= sc->sc_gpio_npins) + return (EINVAL); + + RK30_GPIO_LOCK(sc); + *flags = sc->sc_gpio_pins[i].gp_flags; + RK30_GPIO_UNLOCK(sc); + + return (0); +} + +static int +rk30_gpio_pin_getname(device_t dev, uint32_t pin, char *name) +{ + struct rk30_gpio_softc *sc = device_get_softc(dev); + int i; + + for (i = 0; i < sc->sc_gpio_npins; i++) { + if (sc->sc_gpio_pins[i].gp_pin == pin) + break; + } + + if (i >= sc->sc_gpio_npins) + return (EINVAL); + + RK30_GPIO_LOCK(sc); + memcpy(name, sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME); + RK30_GPIO_UNLOCK(sc); + + return (0); +} + +static int +rk30_gpio_pin_setflags(device_t dev, uint32_t pin, uint32_t flags) +{ + struct rk30_gpio_softc *sc = device_get_softc(dev); + int i; + + for (i = 0; i < sc->sc_gpio_npins; i++) { + if (sc->sc_gpio_pins[i].gp_pin == pin) + break; + } + + if (i >= sc->sc_gpio_npins) + return (EINVAL); + + /* Check for unwanted flags. */ + if ((flags & sc->sc_gpio_pins[i].gp_caps) != flags) + return (EINVAL); + + /* Can't mix input/output together. */ + if ((flags & (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) == + (GPIO_PIN_INPUT|GPIO_PIN_OUTPUT)) + return (EINVAL); + + /* Can't mix pull-up/pull-down together. */ + if ((flags & (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) == + (GPIO_PIN_PULLUP|GPIO_PIN_PULLDOWN)) + return (EINVAL); + + rk30_gpio_pin_configure(sc, &sc->sc_gpio_pins[i], flags); + + return (0); +} + +static int +rk30_gpio_pin_set(device_t dev, uint32_t pin, unsigned int value) +{ + struct rk30_gpio_softc *sc = device_get_softc(dev); + uint32_t bank, offset, data; + int i; + + for (i = 0; i < sc->sc_gpio_npins; i++) { + if (sc->sc_gpio_pins[i].gp_pin == pin) + break; + } + + if (i >= sc->sc_gpio_npins) + return (EINVAL); + + bank = pin / 32; + pin = pin % 32; + offset = 1 << pin; + + RK30_GPIO_LOCK(sc); + data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); + data |= offset; + RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data); + + data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR); + if (value) + data |= offset; + else + data &= ~offset; + RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data); + RK30_GPIO_UNLOCK(sc); + + return (0); +} + +static int +rk30_gpio_pin_get(device_t dev, uint32_t pin, unsigned int *val) +{ + struct rk30_gpio_softc *sc = device_get_softc(dev); + uint32_t bank, offset, reg_data; + int i; + + for (i = 0; i < sc->sc_gpio_npins; i++) { + if (sc->sc_gpio_pins[i].gp_pin == pin) + break; + } + + if (i >= sc->sc_gpio_npins) + return (EINVAL); + + bank = pin / 32; + pin = pin % 32; + offset = 1 << pin; + + RK30_GPIO_LOCK(sc); + reg_data = RK30_GPIO_READ(sc, RK30_GPIO_EXT_PORT); + RK30_GPIO_UNLOCK(sc); + *val = (reg_data & offset) ? 1 : 0; + + return (0); +} + +static int +rk30_gpio_pin_toggle(device_t dev, uint32_t pin) +{ + struct rk30_gpio_softc *sc = device_get_softc(dev); + uint32_t bank, data, offset; + int i; + + for (i = 0; i < sc->sc_gpio_npins; i++) { + if (sc->sc_gpio_pins[i].gp_pin == pin) + break; + } + + if (i >= sc->sc_gpio_npins) + return (EINVAL); + + bank = pin / 32; + pin = pin % 32; + offset = 1 << pin; + + RK30_GPIO_LOCK(sc); + data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DDR); + if (data & offset) + data &= ~offset; + else + data |= offset; + RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DDR, data); + + data = RK30_GPIO_READ(sc, RK30_GPIO_SWPORT_DR); + if (data & offset) + data &= ~offset; + else + data |= offset; + RK30_GPIO_WRITE(sc, RK30_GPIO_SWPORT_DR, data); + RK30_GPIO_UNLOCK(sc); + + return (0); +} + +static int +rk30_gpio_probe(device_t dev) +{ + + if (!ofw_bus_is_compatible(dev, "rockchip,rk30xx-gpio")) + return (ENXIO); + + device_set_desc(dev, "Rockchip RK30XX GPIO controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +rk30_gpio_attach(device_t dev) +{ + struct rk30_gpio_softc *sc = device_get_softc(dev); + uint32_t func; + int i, rid; + phandle_t gpio; + + sc->sc_dev = dev; + + mtx_init(&sc->sc_mtx, "rk30 gpio", "gpio", MTX_DEF); + + rid = 0; + sc->sc_mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, + RF_ACTIVE); + if (!sc->sc_mem_res) { + device_printf(dev, "cannot allocate memory window\n"); + return (ENXIO); + } + + sc->sc_bst = rman_get_bustag(sc->sc_mem_res); + sc->sc_bsh = rman_get_bushandle(sc->sc_mem_res); + + rid = 0; + sc->sc_irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid, + RF_ACTIVE); + if (!sc->sc_irq_res) { + bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); + device_printf(dev, "cannot allocate interrupt\n"); + return (ENXIO); + } + + /* Find our node. */ + gpio = ofw_bus_get_node(sc->sc_dev); + + if (!OF_hasprop(gpio, "gpio-controller")) + /* Node is not a GPIO controller. */ + goto fail; + + /* Initialize the software controlled pins. */ + for (i = 0; i < RK30_GPIO_PINS; i++) { + snprintf(sc->sc_gpio_pins[i].gp_name, GPIOMAXNAME, + "pin %d", i); + func = rk30_gpio_get_function(sc, i); + sc->sc_gpio_pins[i].gp_pin = i; + sc->sc_gpio_pins[i].gp_caps = RK30_GPIO_DEFAULT_CAPS; + sc->sc_gpio_pins[i].gp_flags = rk30_gpio_func_flag(func); + } + sc->sc_gpio_npins = i; + + device_add_child(dev, "gpioc", device_get_unit(dev)); + device_add_child(dev, "gpiobus", device_get_unit(dev)); + return (bus_generic_attach(dev)); + +fail: + if (sc->sc_irq_res) + bus_release_resource(dev, SYS_RES_IRQ, 0, sc->sc_irq_res); + if (sc->sc_mem_res) + bus_release_resource(dev, SYS_RES_MEMORY, 0, sc->sc_mem_res); + return (ENXIO); +} + +static int +rk30_gpio_detach(device_t dev) +{ + + return (EBUSY); +} + +static device_method_t rk30_gpio_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, rk30_gpio_probe), + DEVMETHOD(device_attach, rk30_gpio_attach), + DEVMETHOD(device_detach, rk30_gpio_detach), + + /* GPIO protocol */ + DEVMETHOD(gpio_pin_max, rk30_gpio_pin_max), + DEVMETHOD(gpio_pin_getname, rk30_gpio_pin_getname), + DEVMETHOD(gpio_pin_getflags, rk30_gpio_pin_getflags), + DEVMETHOD(gpio_pin_getcaps, rk30_gpio_pin_getcaps), + DEVMETHOD(gpio_pin_setflags, rk30_gpio_pin_setflags), + DEVMETHOD(gpio_pin_get, rk30_gpio_pin_get), + DEVMETHOD(gpio_pin_set, rk30_gpio_pin_set), + DEVMETHOD(gpio_pin_toggle, rk30_gpio_pin_toggle), + + DEVMETHOD_END +}; + +static devclass_t rk30_gpio_devclass; + +static driver_t rk30_gpio_driver = { + "gpio", + rk30_gpio_methods, + sizeof(struct rk30_gpio_softc), +}; + +DRIVER_MODULE(rk30_gpio, simplebus, rk30_gpio_driver, rk30_gpio_devclass, 0, 0); diff --git a/sys/arm/rockchip/rk30xx_grf.c b/sys/arm/rockchip/rk30xx_grf.c new file mode 100644 index 0000000..f5b83a9 --- /dev/null +++ b/sys/arm/rockchip/rk30xx_grf.c @@ -0,0 +1,130 @@ +/*- + * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* General Register File for Rockchip RK30xx */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/malloc.h> +#include <sys/rman.h> +#include <sys/timeet.h> +#include <sys/timetc.h> +#include <sys/watchdog.h> +#include <machine/bus.h> +#include <machine/cpu.h> +#include <machine/frame.h> +#include <machine/intr.h> + +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#include <machine/bus.h> +#include <machine/fdt.h> + +#include "rk30xx_grf.h" + +struct rk30_grf_softc { + struct resource *res; + bus_space_tag_t bst; + bus_space_handle_t bsh; +}; + +static struct rk30_grf_softc *rk30_grf_sc = NULL; + +#define grf_read_4(sc, reg) \ + bus_space_read_4((sc)->bst, (sc)->bsh, (reg)) +#define grf_write_4(sc, reg, val) \ + bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val)) + +static int +rk30_grf_probe(device_t dev) +{ + + if (ofw_bus_is_compatible(dev, "rockchip,rk30xx-grf")) { + device_set_desc(dev, "RK30XX General Register File"); + return(BUS_PROBE_DEFAULT); + } + + return (ENXIO); +} + +static int +rk30_grf_attach(device_t dev) +{ + struct rk30_grf_softc *sc = device_get_softc(dev); + int rid = 0; + + if (rk30_grf_sc) + return (ENXIO); + + sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (!sc->res) { + device_printf(dev, "could not allocate resource\n"); + return (ENXIO); + } + + sc->bst = rman_get_bustag(sc->res); + sc->bsh = rman_get_bushandle(sc->res); + + rk30_grf_sc = sc; + + return (0); +} + +static device_method_t rk30_grf_methods[] = { + DEVMETHOD(device_probe, rk30_grf_probe), + DEVMETHOD(device_attach, rk30_grf_attach), + { 0, 0 } +}; + +static driver_t rk30_grf_driver = { + "rk30_grf", + rk30_grf_methods, + sizeof(struct rk30_grf_softc), +}; + +static devclass_t rk30_grf_devclass; + +DRIVER_MODULE(rk30_grf, simplebus, rk30_grf_driver, rk30_grf_devclass, 0, 0); + +void +rk30_grf_gpio_pud(uint32_t bank, uint32_t pin, uint32_t state) +{ + uint32_t offset; + + offset = GRF_GPIO0B_PULL - 4 + (bank * 16) + ((pin / 8) * 4); + pin = (7 - (pin % 8)) * 2; + grf_write_4(rk30_grf_sc, offset, (0x3 << (16 + pin)) | (state << pin)); +} + diff --git a/sys/arm/rockchip/rk30xx_grf.h b/sys/arm/rockchip/rk30xx_grf.h new file mode 100644 index 0000000..a26716b --- /dev/null +++ b/sys/arm/rockchip/rk30xx_grf.h @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _RK30_GRF_H_ +#define _RK30_GRF_H_ + +#define RK30_GRF_BASE 0xF0008000 + +#define GRF_GPIO0L_DIR 0x0000 +#define GRF_GPIO0H_DIR 0x0004 +#define GRF_GPIO1L_DIR 0x0008 +#define GRF_GPIO1H_DIR 0x000c +#define GRF_GPIO2L_DIR 0x0010 +#define GRF_GPIO2H_DIR 0x0014 +#define GRF_GPIO3L_DIR 0x0018 +#define GRF_GPIO3H_DIR 0x001c +#define GRF_GPIO0L_DO 0x0020 +#define GRF_GPIO0H_DO 0x0024 +#define GRF_GPIO1L_DO 0x0028 +#define GRF_GPIO1H_DO 0x002c +#define GRF_GPIO2L_DO 0x0030 +#define GRF_GPIO2H_DO 0x0034 +#define GRF_GPIO3L_DO 0x0038 +#define GRF_GPIO3H_DO 0x003c +#define GRF_GPIO0L_EN 0x0040 +#define GRF_GPIO0H_EN 0x0044 +#define GRF_GPIO1L_EN 0x0048 +#define GRF_GPIO1H_EN 0x004c +#define GRF_GPIO2L_EN 0x0050 +#define GRF_GPIO2H_EN 0x0054 +#define GRF_GPIO3L_EN 0x0058 +#define GRF_GPIO3H_EN 0x005c + +#define GRF_GPIO0C_IOMUX 0x0068 +#define GRF_GPIO0D_IOMUX 0x006c +#define GRF_GPIO1A_IOMUX 0x0070 +#define GRF_GPIO1B_IOMUX 0x0074 +#define GRF_GPIO1C_IOMUX 0x0078 +#define GRF_GPIO1D_IOMUX 0x007c +#define GRF_GPIO2A_IOMUX 0x0080 +#define GRF_GPIO2B_IOMUX 0x0084 +#define GRF_GPIO2C_IOMUX 0x0088 +#define GRF_GPIO2D_IOMUX 0x008c +#define GRF_GPIO3A_IOMUX 0x0090 +#define GRF_GPIO3B_IOMUX 0x0094 +#define GRF_GPIO3C_IOMUX 0x0098 +#define GRF_GPIO3D_IOMUX 0x009c +#define GRF_SOC_CON0 0x00a0 +#define GRF_SOC_CON1 0x00a4 +#define GRF_SOC_CON2 0x00a8 +#define GRF_SOC_STATUS0 0x00ac +#define GRF_DMAC1_CON0 0x00b0 +#define GRF_DMAC1_CON1 0x00b4 +#define GRF_DMAC1_CON2 0x00b8 +#define GRF_DMAC2_CON0 0x00bc +#define GRF_DMAC2_CON1 0x00c0 +#define GRF_DMAC2_CON2 0x00c4 +#define GRF_DMAC2_CON3 0x00c8 +#define GRF_CPU_CON0 0x00cc +#define GRF_CPU_CON1 0x00d0 +#define GRF_CPU_CON2 0x00d4 +#define GRF_CPU_CON3 0x00d8 +#define GRF_CPU_CON4 0x00dc +#define GRF_CPU_CON5 0x00e0 + +#define GRF_DDRC_CON0 0x00ec +#define GRF_DDRC_STAT 0x00f0 +#define GRF_IO_CON0 0x00f4 +#define GRF_IO_CON1 0x00f8 +#define GRF_IO_CON2 0x00fc +#define GRF_IO_CON3 0x0100 +#define GRF_IO_CON4 0x0104 +#define GRF_SOC_STATUS1 0x0108 +#define GRF_UOC0_CON0 0x010c +#define GRF_UOC0_CON1 0x0110 +#define GRF_UOC0_CON2 0x0114 +#define GRF_UOC0_CON3 0x0118 +#define GRF_UOC1_CON0 0x011c +#define GRF_UOC1_CON1 0x0120 +#define GRF_UOC1_CON2 0x0124 +#define GRF_UOC1_CON3 0x0128 +#define GRF_UOC2_CON0 0x012c +#define GRF_UOC2_CON1 0x0130 + +#define GRF_UOC3_CON0 0x0138 +#define GRF_UOC3_CON1 0x013c +#define GRF_HSIC_STAT 0x0140 +#define GRF_OS_REG0 0x0144 +#define GRF_OS_REG1 0x0148 +#define GRF_OS_REG2 0x014c +#define GRF_OS_REG3 0x0150 +#define GRF_OS_REG4 0x0154 +#define GRF_OS_REG5 0x0158 +#define GRF_OS_REG6 0x015c +#define GRF_OS_REG7 0x0160 +#define GRF_GPIO0B_PULL 0x0164 +#define GRF_GPIO0C_PULL 0x0168 +#define GRF_GPIO0D_PULL 0x016c +#define GRF_GPIO1A_PULL 0x0170 +#define GRF_GPIO1B_PULL 0x0174 +#define GRF_GPIO1C_PULL 0x0178 +#define GRF_GPIO1D_PULL 0x017c +#define GRF_GPIO2A_PULL 0x0180 +#define GRF_GPIO2B_PULL 0x0184 +#define GRF_GPIO2C_PULL 0x0188 +#define GRF_GPIO2D_PULL 0x018c +#define GRF_GPIO3A_PULL 0x0190 +#define GRF_GPIO3B_PULL 0x0194 +#define GRF_GPIO3C_PULL 0x0198 +#define GRF_GPIO3D_PULL 0x019c +#define GRF_FLASH_DATA_PULL 0x01a0 +#define GRF_FLASH_CMD_PULL 0x01a4 + +void rk30_grf_gpio_pud(uint32_t bank, uint32_t pin, uint32_t state); + +#endif /* _RK30_GRF_H_ */ diff --git a/sys/arm/rockchip/rk30xx_machdep.c b/sys/arm/rockchip/rk30xx_machdep.c new file mode 100644 index 0000000..0b315a1 --- /dev/null +++ b/sys/arm/rockchip/rk30xx_machdep.c @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@gmail.com> + * All rights reserved. + * + * This code is derived from software written for Brini by Mark Brinicombe + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * from: FreeBSD: //depot/projects/arm/src/sys/arm/ti/ti_machdep.c + */ + +#include "opt_ddb.h" +#include "opt_platform.h" + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#define _ARM32_BUS_DMA_PRIVATE +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> + +#include <vm/vm.h> +#include <vm/pmap.h> + +#include <machine/armreg.h> +#include <machine/bus.h> +#include <machine/frame.h> /* For trapframe_t, used in <machine/machdep.h> */ +#include <machine/machdep.h> +#include <machine/pmap.h> + +#include <dev/fdt/fdt_common.h> + +/* Start of address space used for bootstrap map */ +#define DEVMAP_BOOTSTRAP_MAP_START 0xF0000000 + +vm_offset_t +initarm_lastaddr(void) +{ + + return (DEVMAP_BOOTSTRAP_MAP_START - ARM_NOCACHE_KVA_SIZE); +} + +void +initarm_gpio_init(void) +{ +} + +void +initarm_late_init(void) +{ + + /* Enable cache */ + cpufunc_control(CPU_CONTROL_DC_ENABLE|CPU_CONTROL_IC_ENABLE, + CPU_CONTROL_DC_ENABLE|CPU_CONTROL_IC_ENABLE); +} + +#define FDT_DEVMAP_MAX (1 + 2 + 1 + 1) +static struct pmap_devmap fdt_devmap[FDT_DEVMAP_MAX] = { + { 0, 0, 0, 0, 0, } +}; + +/* + * Construct pmap_devmap[] with DT-derived config data. + */ +int +platform_devmap_init(void) +{ + int i = 0; + + fdt_devmap[i].pd_va = 0xF0000000; + fdt_devmap[i].pd_pa = 0x20000000; + fdt_devmap[i].pd_size = 0x100000; + fdt_devmap[i].pd_prot = VM_PROT_READ | VM_PROT_WRITE; + fdt_devmap[i].pd_cache = PTE_DEVICE; + i++; + + pmap_devmap_bootstrap_table = &fdt_devmap[0]; + + return (0); +} + +struct arm32_dma_range * +bus_dma_get_range(void) +{ + + return (NULL); +} + +int +bus_dma_get_range_nb(void) +{ + + return (0); +} + +void +cpu_reset() +{ + + printf("No cpu_reset implementation!\n"); + while (1); +} diff --git a/sys/arm/rockchip/rk30xx_pmu.c b/sys/arm/rockchip/rk30xx_pmu.c new file mode 100644 index 0000000..55a7fdc --- /dev/null +++ b/sys/arm/rockchip/rk30xx_pmu.c @@ -0,0 +1,130 @@ +/*- + * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* PMU for Rockchip RK30xx */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/bus.h> +#include <sys/kernel.h> +#include <sys/module.h> +#include <sys/malloc.h> +#include <sys/rman.h> +#include <sys/timeet.h> +#include <sys/timetc.h> +#include <sys/watchdog.h> +#include <machine/bus.h> +#include <machine/cpu.h> +#include <machine/frame.h> +#include <machine/intr.h> + +#include <dev/fdt/fdt_common.h> +#include <dev/ofw/openfirm.h> +#include <dev/ofw/ofw_bus.h> +#include <dev/ofw/ofw_bus_subr.h> + +#include <machine/bus.h> +#include <machine/fdt.h> + +#include "rk30xx_pmu.h" + +struct rk30_pmu_softc { + struct resource *res; + bus_space_tag_t bst; + bus_space_handle_t bsh; +}; + +static struct rk30_pmu_softc *rk30_pmu_sc = NULL; + +#define pmu_read_4(sc, reg) \ + bus_space_read_4((sc)->bst, (sc)->bsh, (reg)) +#define pmu_write_4(sc, reg, val) \ + bus_space_write_4((sc)->bst, (sc)->bsh, (reg), (val)) + +static int +rk30_pmu_probe(device_t dev) +{ + + if (ofw_bus_is_compatible(dev, "rockchip,rk30xx-pmu")) { + device_set_desc(dev, "RK30XX PMU"); + return(BUS_PROBE_DEFAULT); + } + + return (ENXIO); +} + +static int +rk30_pmu_attach(device_t dev) +{ + struct rk30_pmu_softc *sc = device_get_softc(dev); + int rid = 0; + + if (rk30_pmu_sc) + return (ENXIO); + + sc->res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (!sc->res) { + device_printf(dev, "could not allocate resource\n"); + return (ENXIO); + } + + sc->bst = rman_get_bustag(sc->res); + sc->bsh = rman_get_bushandle(sc->res); + + rk30_pmu_sc = sc; + + return (0); +} + +static device_method_t rk30_pmu_methods[] = { + DEVMETHOD(device_probe, rk30_pmu_probe), + DEVMETHOD(device_attach, rk30_pmu_attach), + { 0, 0 } +}; + +static driver_t rk30_pmu_driver = { + "rk30_pmu", + rk30_pmu_methods, + sizeof(struct rk30_pmu_softc), +}; + +static devclass_t rk30_pmu_devclass; + +DRIVER_MODULE(rk30_pmu, simplebus, rk30_pmu_driver, rk30_pmu_devclass, 0, 0); + +void +rk30_pmu_gpio_pud(uint32_t pin, uint32_t state) +{ + uint32_t offset; + + offset = PMU_GPIO0A_PULL + ((pin / 8) * 4); + pin = (pin % 8) * 2; + pmu_write_4(rk30_pmu_sc, offset, (0x3 << (16 + pin)) | (state << pin)); +} + diff --git a/sys/arm/rockchip/rk30xx_pmu.h b/sys/arm/rockchip/rk30xx_pmu.h new file mode 100644 index 0000000..7bdec94 --- /dev/null +++ b/sys/arm/rockchip/rk30xx_pmu.h @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 2013 Ganbold Tsagaankhuu <ganbold@gmail.com> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef _RK30_PMU_H_ +#define _RK30_PMU_H_ + +#define RK30_PMU_BASE 0xF0004000 + +#define PMU_WAKEUP_CFG0 0x00 +#define PMU_WAKEUP_CFG1 0x04 +#define PMU_PWRDN_CON 0x08 +#define PMU_PWRDN_ST 0x0c +#define PMU_INT_CON 0x10 +#define PMU_INT_ST 0x14 +#define PMU_MISC_CON 0x18 +#define PMU_OSC_CNT 0x1c +#define PMU_PLL_CNT 0x20 +#define PMU_PMU_CNT 0x24 +#define PMU_DDRIO_PWRON_CNT 0x28 +#define PMU_WAKEUP_RST_CLR_CNT 0x2c +#define PMU_SCU_PWRDWN_CNT 0x30 +#define PMU_SCU_PWRUP_CNT 0x34 +#define PMU_MISC_CON1 0x38 +#define PMU_GPIO0_CON 0x3c +#define PMU_SYS_REG0 0x40 +#define PMU_SYS_REG1 0x44 +#define PMU_SYS_REG2 0x48 +#define PMU_SYS_REG3 0x4c +#define PMU_STOP_INT_DLY 0x60 +#define PMU_GPIO0A_PULL 0x64 +#define PMU_GPIO0B_PULL 0x68 + +void rk30_pmu_gpio_pud(uint32_t pin, uint32_t state); + +#endif /* _RK30_PMU_H_ */ diff --git a/sys/arm/rockchip/std.rk30xx b/sys/arm/rockchip/std.rk30xx new file mode 100644 index 0000000..7b714bb --- /dev/null +++ b/sys/arm/rockchip/std.rk30xx @@ -0,0 +1,27 @@ +# Rockchip rk30xx common options +#$FreeBSD$ + +cpu CPU_CORTEXA +machine arm armv6 +makeoption ARM_LITTLE_ENDIAN + +# Physical memory starts at 0x60400000. We assume images are loaded at +# 0x60400000. +# +# +options PHYSADDR=0x60000000 + +makeoptions KERNPHYSADDR=0x60400000 +options KERNPHYSADDR=0x60400000 + +makeoptions KERNVIRTADDR=0xc0400000 +options KERNVIRTADDR=0xc0400000 + +options STARTUP_PAGETABLE_ADDR=0x60200000 + +options ARM_L2_PIPT + +options IPI_IRQ_START=0 +options IPI_IRQ_END=15 + +files "../rockchip/files.rk30xx" |