From owner-svn-src-all@FreeBSD.ORG Tue Jan 15 08:26:18 2013 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id 85B84E80; Tue, 15 Jan 2013 08:26:18 +0000 (UTC) (envelope-from ganbold@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 5DCF136B; Tue, 15 Jan 2013 08:26:18 +0000 (UTC) Received: from svn.freebsd.org (svn.FreeBSD.org [8.8.178.70]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id r0F8QIpm044612; Tue, 15 Jan 2013 08:26:18 GMT (envelope-from ganbold@svn.freebsd.org) Received: (from ganbold@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id r0F8QGJr044600; Tue, 15 Jan 2013 08:26:16 GMT (envelope-from ganbold@svn.freebsd.org) Message-Id: <201301150826.r0F8QGJr044600@svn.freebsd.org> From: Ganbold Tsagaankhuu Date: Tue, 15 Jan 2013 08:26:16 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r245450 - in head/sys: arm/allwinner arm/conf boot/fdt/dts X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 15 Jan 2013 08:26:18 -0000 Author: ganbold (doc committer) Date: Tue Jan 15 08:26:16 2013 New Revision: 245450 URL: http://svnweb.freebsd.org/changeset/base/245450 Log: Initial support for Allwinner A10 SoC (Cubieboard) Add simple console driver Add interrupt handling and timer codes Add kernel config file Add dts file Approved by: gonzo Added: head/sys/arm/allwinner/ head/sys/arm/allwinner/a10_machdep.c (contents, props changed) head/sys/arm/allwinner/aintc.c (contents, props changed) head/sys/arm/allwinner/bus_space.c (contents, props changed) head/sys/arm/allwinner/common.c (contents, props changed) head/sys/arm/allwinner/console.c (contents, props changed) head/sys/arm/allwinner/files.a10 (contents, props changed) head/sys/arm/allwinner/std.a10 (contents, props changed) head/sys/arm/allwinner/timer.c (contents, props changed) head/sys/arm/conf/CUBIEBOARD (contents, props changed) head/sys/boot/fdt/dts/cubieboard.dts (contents, props changed) Added: head/sys/arm/allwinner/a10_machdep.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/allwinner/a10_machdep.c Tue Jan 15 08:26:16 2013 (r245450) @@ -0,0 +1,122 @@ +/*- + * Copyright (c) 2012 Ganbold Tsagaankhuu. + * 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 +__FBSDID("$FreeBSD$"); + +#define _ARM32_BUS_DMA_PRIVATE +#include +#include +#include + +#include +#include + +#include +#include /* For trapframe_t, used in */ +#include +#include + +#include + +/* Start of address space used for bootstrap map */ +#define DEVMAP_BOOTSTRAP_MAP_START 0xE0000000 + +void (*a10_cpu_reset)(void); + +vm_offset_t +initarm_lastaddr(void) +{ + + a10_cpu_reset = NULL; + return (DEVMAP_BOOTSTRAP_MAP_START - ARM_NOCACHE_KVA_SIZE); +} + +void +initarm_gpio_init(void) +{ +} + +void +initarm_late_init(void) +{ +} + +#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 = 0xE1C00000; + fdt_devmap[i].pd_pa = 0x01C00000; + fdt_devmap[i].pd_size = 0x00400000; /* 4 MB */ + 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() +{ + if (a10_cpu_reset) + (*a10_cpu_reset)(); + else + printf("no cpu_reset implementation\n"); + printf("Reset failed!\n"); + while (1); +} Added: head/sys/arm/allwinner/aintc.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/allwinner/aintc.c Tue Jan 15 08:26:16 2013 (r245450) @@ -0,0 +1,211 @@ +/*- + * Copyright (c) 2012 Ganbold Tsagaankhuu + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/** + * Interrupt controller registers + * + */ +#define SW_INT_VECTOR_REG 0x00 +#define SW_INT_BASE_ADR_REG 0x04 +#define SW_INT_PROTECTION_REG 0x08 +#define SW_INT_NMI_CTRL_REG 0x0c + +#define SW_INT_IRQ_PENDING_REG0 0x10 +#define SW_INT_IRQ_PENDING_REG1 0x14 +#define SW_INT_IRQ_PENDING_REG2 0x18 + +#define SW_INT_FIQ_PENDING_REG0 0x20 +#define SW_INT_FIQ_PENDING_REG1 0x24 +#define SW_INT_FIQ_PENDING_REG2 0x28 + +#define SW_INT_SELECT_REG0 0x30 +#define SW_INT_SELECT_REG1 0x34 +#define SW_INT_SELECT_REG2 0x38 + +#define SW_INT_ENABLE_REG0 0x40 +#define SW_INT_ENABLE_REG1 0x44 +#define SW_INT_ENABLE_REG2 0x48 + +#define SW_INT_MASK_REG0 0x50 +#define SW_INT_MASK_REG1 0x54 +#define SW_INT_MASK_REG2 0x58 + +#define SW_INT_IRQNO_ENMI 0 + +#define SW_INT_IRQ_PENDING_REG(_b) (0x10 + ((_b) * 4)) +#define SW_INT_FIQ_PENDING_REG(_b) (0x20 + ((_b) * 4)) +#define SW_INT_SELECT_REG(_b) (0x30 + ((_b) * 4)) +#define SW_INT_ENABLE_REG(_b) (0x40 + ((_b) * 4)) +#define SW_INT_MASK_REG(_b) (0x50 + ((_b) * 4)) + +struct a10_aintc_softc { + device_t sc_dev; + struct resource * aintc_res; + bus_space_tag_t aintc_bst; + bus_space_handle_t aintc_bsh; + uint8_t ver; +}; + +static struct a10_aintc_softc *a10_aintc_sc = NULL; + +#define aintc_read_4(reg) \ + bus_space_read_4(a10_aintc_sc->aintc_bst, a10_aintc_sc->aintc_bsh, reg) +#define aintc_write_4(reg, val) \ + bus_space_write_4(a10_aintc_sc->aintc_bst, a10_aintc_sc->aintc_bsh, reg, val) + +static int +a10_aintc_probe(device_t dev) +{ + if (!ofw_bus_is_compatible(dev, "a10,aintc")) + return (ENXIO); + device_set_desc(dev, "A10 AINTC Interrupt Controller"); + return (BUS_PROBE_DEFAULT); +} + +static int +a10_aintc_attach(device_t dev) +{ + struct a10_aintc_softc *sc = device_get_softc(dev); + int rid = 0; + int i; + + sc->sc_dev = dev; + + if (a10_aintc_sc) + return (ENXIO); + + sc->aintc_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); + if (!sc->aintc_res) { + device_printf(dev, "could not allocate resource\n"); + return (ENXIO); + } + + sc->aintc_bst = rman_get_bustag(sc->aintc_res); + sc->aintc_bsh = rman_get_bushandle(sc->aintc_res); + + a10_aintc_sc = sc; + + /* Disable & clear all interrupts */ + for (i = 0; i < 3; i++) { + aintc_write_4(SW_INT_ENABLE_REG(i), 0); + aintc_write_4(SW_INT_MASK_REG(i), 0xffffffff); + } + /* enable protection mode*/ + aintc_write_4(SW_INT_PROTECTION_REG, 0x01); + + /* config the external interrupt source type*/ + aintc_write_4(SW_INT_NMI_CTRL_REG, 0x00); + + return (0); +} + +static device_method_t a10_aintc_methods[] = { + DEVMETHOD(device_probe, a10_aintc_probe), + DEVMETHOD(device_attach, a10_aintc_attach), + { 0, 0 } +}; + +static driver_t a10_aintc_driver = { + "aintc", + a10_aintc_methods, + sizeof(struct a10_aintc_softc), +}; + +static devclass_t a10_aintc_devclass; + +DRIVER_MODULE(aintc, simplebus, a10_aintc_driver, a10_aintc_devclass, 0, 0); + +int +arm_get_next_irq(int last_irq) +{ + uint32_t value; + int i, b; + + for (i = 0; i < 3; i++) { + value = aintc_read_4(SW_INT_IRQ_PENDING_REG(i)); + for (b = 0; b < 32; b++) + if (value & (1 << b)) { + return (i * 32 + b); + } + } + + return (-1); +} + +void +arm_mask_irq(uintptr_t nb) +{ + uint32_t bit, block, value; + + bit = (nb % 32); + block = (nb / 32); + + value = aintc_read_4(SW_INT_ENABLE_REG(block)); + value &= ~(1 << bit); + aintc_write_4(SW_INT_ENABLE_REG(block), value); + + value = aintc_read_4(SW_INT_MASK_REG(block)); + value |= (1 << bit); + aintc_write_4(SW_INT_MASK_REG(block), value); +} + +void +arm_unmask_irq(uintptr_t nb) +{ + uint32_t bit, block, value; + + bit = (nb % 32); + block = (nb / 32); + + value = aintc_read_4(SW_INT_ENABLE_REG(block)); + value |= (1 << bit); + aintc_write_4(SW_INT_ENABLE_REG(block), value); + + value = aintc_read_4(SW_INT_MASK_REG(block)); + value &= ~(1 << bit); + aintc_write_4(SW_INT_MASK_REG(block), value); + + if(nb == SW_INT_IRQNO_ENMI) /* must clear pending bit when enabled */ + aintc_write_4(SW_INT_IRQ_PENDING_REG(0), (1 << SW_INT_IRQNO_ENMI)); +} Added: head/sys/arm/allwinner/bus_space.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/allwinner/bus_space.c Tue Jan 15 08:26:16 2013 (r245450) @@ -0,0 +1,113 @@ +/*- + * Copyright (C) 2012 Ganbold Tsagaankhuu + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include + +#include + +/* 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; Added: head/sys/arm/allwinner/common.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/allwinner/common.c Tue Jan 15 08:26:16 2013 (r245450) @@ -0,0 +1,65 @@ +/*- + * Copyright (c) 2012 Ganbold Tsagaankhuu + * All rights reserved. + * + * Developed by Ganbold Tsagaankhuu + * + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +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, "a10,aintc")) + 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 +}; Added: head/sys/arm/allwinner/console.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/allwinner/console.c Tue Jan 15 08:26:16 2013 (r245450) @@ -0,0 +1,146 @@ +/*- + * Copyright (c) 2012 Ganbold Tsagaankhuu + * 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. + */ + +/* Simple UART console driver for Allwinner A10 */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include + +#ifndef A10_UART_BASE +#define A10_UART_BASE 0xe1c28000 /* UART0 */ +#endif + +int reg_shift = 2; + +#define UART_DLL 0 /* Out: Divisor Latch Low */ +#define UART_DLM 1 /* Out: Divisor Latch High */ +#define UART_FCR 2 /* Out: FIFO Control Register */ +#define UART_LCR 3 /* Out: Line Control Register */ +#define UART_MCR 4 /* Out: Modem Control Register */ +#define UART_LSR 5 /* In: Line Status Register */ +#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ +#define UART_LSR_DR 0x01 /* Receiver data ready */ +#define UART_MSR 6 /* In: Modem Status Register */ +#define UART_SCR 7 /* I/O: Scratch Register */ + + +/* + * uart related funcs + */ +static u_int32_t +uart_getreg(u_int32_t *bas) +{ + return *((volatile u_int32_t *)(bas)) & 0xff; +} + +static void +uart_setreg(u_int32_t *bas, u_int32_t val) +{ + *((volatile u_int32_t *)(bas)) = (u_int32_t)val; +} + +static int +ub_getc(void) +{ + while ((uart_getreg((u_int32_t *)(A10_UART_BASE + + (UART_LSR << reg_shift))) & UART_LSR_DR) == 0); + __asm __volatile("nop"); + + return (uart_getreg((u_int32_t *)A10_UART_BASE) & 0xff); +} + +static void +ub_putc(unsigned char c) +{ + if (c == '\n') + ub_putc('\r'); + + while ((uart_getreg((u_int32_t *)(A10_UART_BASE + + (UART_LSR << reg_shift))) & UART_LSR_THRE) == 0) + __asm __volatile("nop"); + + uart_setreg((u_int32_t *)A10_UART_BASE, c); +} + +static cn_probe_t uart_cnprobe; +static cn_init_t uart_cninit; +static cn_term_t uart_cnterm; +static cn_getc_t uart_cngetc; +static cn_putc_t uart_cnputc; +static cn_grab_t uart_cngrab; +static cn_ungrab_t uart_cnungrab; + +static void +uart_cngrab(struct consdev *cp) +{ +} + +static void +uart_cnungrab(struct consdev *cp) +{ +} + + +static void +uart_cnprobe(struct consdev *cp) +{ + sprintf(cp->cn_name, "uart"); + cp->cn_pri = CN_NORMAL; +} + +static void +uart_cninit(struct consdev *cp) +{ + uart_setreg((u_int32_t *)(A10_UART_BASE + + (UART_FCR << reg_shift)), 0x06); +} + +void +uart_cnputc(struct consdev *cp, int c) +{ + ub_putc(c); +} + +int +uart_cngetc(struct consdev * cp) +{ + return ub_getc(); +} + +static void +uart_cnterm(struct consdev * cp) +{ +} + +CONSOLE_DRIVER(uart); + Added: head/sys/arm/allwinner/files.a10 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/allwinner/files.a10 Tue Jan 15 08:26:16 2013 (r245450) @@ -0,0 +1,17 @@ +# $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/allwinner/timer.c standard +arm/allwinner/aintc.c standard +arm/allwinner/bus_space.c standard +arm/allwinner/common.c standard +arm/allwinner/console.c standard +arm/allwinner/a10_machdep.c standard Added: head/sys/arm/allwinner/std.a10 ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/allwinner/std.a10 Tue Jan 15 08:26:16 2013 (r245450) @@ -0,0 +1,21 @@ +# Allwinner A10 common options +#$FreeBSD$ + +cpu CPU_CORTEXA +machine arm armv6 +makeoption ARM_LITTLE_ENDIAN + +# Physical memory starts at 0x40200000. We assume images are loaded at +# 0x40200000, e.g. from u-boot with 'fatload mmc 0 0x40200000 kernel' +# +# +options PHYSADDR=0x40000000 + +makeoptions KERNPHYSADDR=0x40200000 +options KERNPHYSADDR=0x40200000 +makeoptions KERNVIRTADDR=0xc0200000 +options KERNVIRTADDR=0xc0200000 + +options STARTUP_PAGETABLE_ADDR=0x48000000 + +files "../allwinner/files.a10" Added: head/sys/arm/allwinner/timer.c ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ head/sys/arm/allwinner/timer.c Tue Jan 15 08:26:16 2013 (r245450) @@ -0,0 +1,341 @@ +/*- + * Copyright (c) 2012 Ganbold Tsagaankhuu + * 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 +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#include + +/** + * Timer registers addr + * + */ +#define SW_TIMER_IRQ_EN_REG 0x00 +#define SW_TIMER_IRQ_STA_REG 0x04 +#define SW_TIMER0_CTRL_REG 0x10 +#define SW_TIMER0_INT_VALUE_REG 0x14 +#define SW_TIMER0_CUR_VALUE_REG 0x18 + +#define SYS_TIMER_SCAL 16 /* timer clock source pre-divsion */ +#define SYS_TIMER_CLKSRC 24000000 /* timer clock source */ +#define TMR_INTER_VAL SYS_TIMER_CLKSRC/(SYS_TIMER_SCAL * 1000) + +#define CLOCK_TICK_RATE TMR_INTER_VAL +#define INITIAL_TIMECOUNTER (0xffffffff) + +struct a10_timer_softc { + device_t sc_dev; + struct resource *res[2]; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + void *sc_ih; /* interrupt handler */ + uint32_t sc_period; + uint32_t clkfreq; + struct eventtimer et; +}; + +int a10_timer_get_timerfreq(struct a10_timer_softc *); + +#define timer_read_4(sc, reg) \ + bus_space_read_4(sc->sc_bst, sc->sc_bsh, reg) +#define timer_write_4(sc, reg, val) \ + bus_space_write_4(sc->sc_bst, sc->sc_bsh, reg, val) + +static u_int a10_timer_get_timecount(struct timecounter *); +static int a10_timer_timer_start(struct eventtimer *, + struct bintime *, struct bintime *); +static int a10_timer_timer_stop(struct eventtimer *); + +static int a10_timer_initialized = 0; +static int a10_timer_intr(void *); +static int a10_timer_probe(device_t); +static int a10_timer_attach(device_t); + +static struct timecounter a10_timer_timecounter = { + .tc_name = "a10_timer timer0", + .tc_get_timecount = a10_timer_get_timecount, + .tc_counter_mask = ~0u, + .tc_frequency = 0, + .tc_quality = 1000, +}; + +struct a10_timer_softc *a10_timer_sc = NULL; + +static struct resource_spec a10_timer_spec[] = { + { SYS_RES_MEMORY, 0, RF_ACTIVE }, + { SYS_RES_IRQ, 0, RF_ACTIVE }, + { -1, 0 } +}; + +static int +a10_timer_probe(device_t dev) +{ + + if (!ofw_bus_is_compatible(dev, "a10,timers")) + return (ENXIO); + + device_set_desc(dev, "Allwinner A10 timer"); + return (BUS_PROBE_DEFAULT); +} + +static int +a10_timer_attach(device_t dev) +{ + struct a10_timer_softc *sc; + int err; + uint32_t val; + uint32_t freq; + + sc = device_get_softc(dev); + + if (bus_alloc_resources(dev, a10_timer_spec, sc->res)) { + device_printf(dev, "could not allocate resources\n"); + return (ENXIO); + } + + sc->sc_dev = dev; + sc->sc_bst = rman_get_bustag(sc->res[0]); + sc->sc_bsh = rman_get_bushandle(sc->res[0]); + + /* set interval */ + timer_write_4(sc, SW_TIMER0_INT_VALUE_REG, TMR_INTER_VAL); + + /* set clock source to HOSC, 16 pre-division */ + val = timer_read_4(sc, SW_TIMER0_CTRL_REG); + val &= ~(0x07<<4); + val &= ~(0x03<<2); + val |= (4<<4) | (1<<2); + timer_write_4(sc, SW_TIMER0_CTRL_REG, val); + + /* set mode to auto reload */ + val = timer_read_4(sc, SW_TIMER0_CTRL_REG); + val |= (1<<1); + timer_write_4(sc, SW_TIMER0_CTRL_REG, val); + + /* Enable timer0 */ + val = timer_read_4(sc, SW_TIMER_IRQ_EN_REG); + val |= (1<<0); + timer_write_4(sc, SW_TIMER_IRQ_EN_REG, val); + + /* Setup and enable the timer interrupt */ + err = bus_setup_intr(dev, sc->res[1], INTR_TYPE_CLK, a10_timer_intr, + NULL, sc, &sc->sc_ih); + if (err != 0) { + bus_release_resources(dev, a10_timer_spec, sc->res); + device_printf(dev, "Unable to setup the clock irq handler, " + "err = %d\n", err); + return (ENXIO); + } + freq = SYS_TIMER_CLKSRC; + + /* Set desired frequency in event timer and timecounter */ + sc->et.et_frequency = (uint64_t)freq; + sc->clkfreq = (uint64_t)freq; + sc->et.et_name = "a10_timer Eventtimer"; + sc->et.et_flags = ET_FLAGS_ONESHOT | ET_FLAGS_PERIODIC; + sc->et.et_quality = 1000; + sc->et.et_min_period.sec = 0; + sc->et.et_min_period.frac = + ((0x00000002LLU << 32) / sc->et.et_frequency) << 32; + sc->et.et_max_period.sec = 0xfffffff0U / sc->et.et_frequency; + sc->et.et_max_period.frac = + ((0xfffffffeLLU << 32) / sc->et.et_frequency) << 32; + sc->et.et_start = a10_timer_timer_start; + sc->et.et_stop = a10_timer_timer_stop; + sc->et.et_priv = sc; + et_register(&sc->et); + + if (device_get_unit(dev) == 0) + a10_timer_sc = sc; + + a10_timer_timecounter.tc_frequency = (uint64_t)freq; + tc_init(&a10_timer_timecounter); + + printf("clock: hz=%d stathz = %d\n", hz, stathz); + + device_printf(sc->sc_dev, "timer clock frequency %d\n", sc->clkfreq); + + a10_timer_initialized = 1; + + return (0); +} + +static int +a10_timer_timer_start(struct eventtimer *et, struct bintime *first, + struct bintime *period) +{ + struct a10_timer_softc *sc; + uint32_t clo, count; + + sc = (struct a10_timer_softc *)et->et_priv; + + if (first != NULL) { + count = (sc->et.et_frequency * (first->frac >> 32)) >> 32; + if (first->sec != 0) + count += sc->et.et_frequency * first->sec; + + /* clear */ + timer_write_4(sc, SW_TIMER0_CUR_VALUE_REG, 0); + clo = timer_read_4(sc, SW_TIMER0_CUR_VALUE_REG); + clo += count; + timer_write_4(sc, SW_TIMER0_CUR_VALUE_REG, clo); + + return (0); + } + + return (EINVAL); +} + +static int +a10_timer_timer_stop(struct eventtimer *et) +{ + struct a10_timer_softc *sc; + uint32_t val; + + sc = (struct a10_timer_softc *)et->et_priv; + + /* clear */ + timer_write_4(sc, SW_TIMER0_CUR_VALUE_REG, 0); + + /* disable */ + val = timer_read_4(sc, SW_TIMER0_CTRL_REG); + val &= ~(1<<0); /* Disable timer0 */ + timer_write_4(sc, SW_TIMER0_CTRL_REG, val); + + sc->sc_period = 0; + + return (0); +} + +int +a10_timer_get_timerfreq(struct a10_timer_softc *sc) +{ + + return (sc->clkfreq); +} + +void +cpu_initclocks(void) +{ + cpu_initclocks_bsp(); +} + +static int +a10_timer_intr(void *arg) +{ + struct a10_timer_softc *sc; + + sc = (struct a10_timer_softc *)arg; + + if (sc->et.et_active) + sc->et.et_event_cb(&sc->et, sc->et.et_arg); + + /* pending */ + timer_write_4(sc, SW_TIMER_IRQ_STA_REG, 0x1); + *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***