Module Name: src Committed By: jmcneill Date: Fri Aug 25 00:07:03 UTC 2017
Modified Files: src/sys/arch/arm/fdt: fdt_intr.h src/sys/arch/arm/sunxi: files.sunxi sunxi_ccu.h sunxi_ccu_div.c sunxi_ccu_prediv.c sunxi_gpio.c sunxi_gpio.h sunxi_mmc.c sunxi_platform.c sunxi_twi.c sunxi_usbphy.c src/sys/arch/evbarm/conf: SUNXI std.sunxi Added Files: src/sys/arch/arm/sunxi: sun5i_a13_ccu.c sun5i_a13_ccu.h sun5i_a13_gpio.c sunxi_intc.c sunxi_timer.c Log Message: Add initial support for Allwinner A13 and R8 SoCs. To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/fdt/fdt_intr.h cvs rdiff -u -r1.16 -r1.17 src/sys/arch/arm/sunxi/files.sunxi cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/sunxi/sun5i_a13_ccu.c \ src/sys/arch/arm/sunxi/sun5i_a13_ccu.h \ src/sys/arch/arm/sunxi/sun5i_a13_gpio.c \ src/sys/arch/arm/sunxi/sunxi_intc.c src/sys/arch/arm/sunxi/sunxi_timer.c cvs rdiff -u -r1.9 -r1.10 src/sys/arch/arm/sunxi/sunxi_ccu.h cvs rdiff -u -r1.1 -r1.2 src/sys/arch/arm/sunxi/sunxi_ccu_div.c cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/sunxi/sunxi_ccu_prediv.c \ src/sys/arch/arm/sunxi/sunxi_twi.c cvs rdiff -u -r1.10 -r1.11 src/sys/arch/arm/sunxi/sunxi_gpio.c cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/sunxi/sunxi_gpio.h cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/sunxi/sunxi_mmc.c \ src/sys/arch/arm/sunxi/sunxi_usbphy.c cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/sunxi/sunxi_platform.c cvs rdiff -u -r1.22 -r1.23 src/sys/arch/evbarm/conf/SUNXI cvs rdiff -u -r1.3 -r1.4 src/sys/arch/evbarm/conf/std.sunxi Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/fdt/fdt_intr.h diff -u src/sys/arch/arm/fdt/fdt_intr.h:1.1 src/sys/arch/arm/fdt/fdt_intr.h:1.2 --- src/sys/arch/arm/fdt/fdt_intr.h:1.1 Tue May 30 22:00:25 2017 +++ src/sys/arch/arm/fdt/fdt_intr.h Fri Aug 25 00:07:02 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: fdt_intr.h,v 1.1 2017/05/30 22:00:25 jmcneill Exp $ */ +/* $NetBSD: fdt_intr.h,v 1.2 2017/08/25 00:07:02 jmcneill Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -34,6 +34,7 @@ #ifndef _LOCORE #define __HAVE_PIC_SET_PRIORITY +#define __HAVE_PIC_PENDING_INTRS #define PIC_MAXSOURCES 256 #define PIC_MAXMAXSOURCES (PIC_MAXSOURCES + 32) Index: src/sys/arch/arm/sunxi/files.sunxi diff -u src/sys/arch/arm/sunxi/files.sunxi:1.16 src/sys/arch/arm/sunxi/files.sunxi:1.17 --- src/sys/arch/arm/sunxi/files.sunxi:1.16 Sun Aug 6 17:15:45 2017 +++ src/sys/arch/arm/sunxi/files.sunxi Fri Aug 25 00:07:03 2017 @@ -1,4 +1,4 @@ -# $NetBSD: files.sunxi,v 1.16 2017/08/06 17:15:45 jmcneill Exp $ +# $NetBSD: files.sunxi,v 1.17 2017/08/25 00:07:03 jmcneill Exp $ # # Configuration info for Allwinner sunxi family SoCs # @@ -27,6 +27,11 @@ file arch/arm/sunxi/sunxi_ccu_nkmp.c su file arch/arm/sunxi/sunxi_ccu_phase.c sunxi_ccu file arch/arm/sunxi/sunxi_ccu_prediv.c sunxi_ccu +# CCU (A13) +device sun5ia13ccu: sunxi_ccu +attach sun5ia13ccu at fdt with sunxi_a13_ccu +file arch/arm/sunxi/sun5i_a13_ccu.c sunxi_a13_ccu + # CCU (A31) device sun6ia31ccu: sunxi_ccu attach sun6ia31ccu at fdt with sunxi_a31_ccu @@ -52,10 +57,16 @@ device sunxigates attach sunxigates at fdt with sunxi_gates file arch/arm/sunxi/sunxi_gates.c sunxi_gates +# Interrupt controller +device sunxiintc: pic, pic_splfuncs +attach sunxiintc at fdt with sunxi_intc +file arch/arm/sunxi/sunxi_intc.c sunxi_intc + # GPIO device sunxigpio: gpiobus attach sunxigpio at fdt with sunxi_gpio file arch/arm/sunxi/sunxi_gpio.c sunxi_gpio +file arch/arm/sunxi/sun5i_a13_gpio.c sunxi_gpio & soc_sun5i_a13 file arch/arm/sunxi/sun6i_a31_gpio.c sunxi_gpio & soc_sun6i_a31 file arch/arm/sunxi/sun8i_a83t_gpio.c sunxi_gpio & soc_sun8i_a83t file arch/arm/sunxi/sun8i_h3_gpio.c sunxi_gpio & soc_sun8i_h3 @@ -103,6 +114,11 @@ device sunxiemac: arp, ether, ifnet, mii attach sunxiemac at fdt with sunxi_emac file arch/arm/sunxi/sunxi_emac.c sunxi_emac +# Timer +device sunxitimer +attach sunxitimer at fdt with sunxi_timer +file arch/arm/sunxi/sunxi_timer.c sunxi_timer + # Watchdog device sunxiwdt: sysmon_wdog attach sunxiwdt at fdt with sunxi_wdt @@ -125,10 +141,12 @@ file arch/arm/sunxi/sun8i_h3_codec.c h3 # SOC parameters defflag opt_soc.h SOC_SUNXI +defflag opt_soc.h SOC_SUN5I: SOC_SUNXI +defflag opt_soc.h SOC_SUN5I_A13: SOC_SUN5I +defflag opt_soc.h SOC_SUN6I: SOC_SUNXI +defflag opt_soc.h SOC_SUN6I_A31: SOC_SUN6I defflag opt_soc.h SOC_SUN8I: SOC_SUNXI defflag opt_soc.h SOC_SUN8I_A83T: SOC_SUN8I defflag opt_soc.h SOC_SUN8I_H3: SOC_SUN8I -defflag opt_soc.h SOC_SUN6I: SOC_SUNXI -defflag opt_soc.h SOC_SUN6I_A31: SOC_SUN6I defflag opt_soc.h SOC_SUN50I: SOC_SUNXI defflag opt_soc.h SOC_SUN50I_A64: SOC_SUN50I Index: src/sys/arch/arm/sunxi/sunxi_ccu.h diff -u src/sys/arch/arm/sunxi/sunxi_ccu.h:1.9 src/sys/arch/arm/sunxi/sunxi_ccu.h:1.10 --- src/sys/arch/arm/sunxi/sunxi_ccu.h:1.9 Sun Aug 13 19:18:08 2017 +++ src/sys/arch/arm/sunxi/sunxi_ccu.h Fri Aug 25 00:07:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_ccu.h,v 1.9 2017/08/13 19:18:08 jmcneill Exp $ */ +/* $NetBSD: sunxi_ccu.h,v 1.10 2017/08/25 00:07:03 jmcneill Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -237,6 +237,7 @@ struct sunxi_ccu_prediv { u_int nparents; uint32_t prediv; uint32_t prediv_sel; + uint32_t prediv_fixed; uint32_t div; uint32_t sel; uint32_t flags; @@ -256,6 +257,11 @@ const char *sunxi_ccu_prediv_get_parent( #define SUNXI_CCU_PREDIV(_id, _name, _parents, _reg, _prediv, \ _prediv_sel, _div, _sel, _flags) \ + SUNXI_CCU_PREDIV_FIXED(_id, _name, _parents, _reg, _prediv, \ + _prediv_sel, 0, _div, _sel, _flags) + +#define SUNXI_CCU_PREDIV_FIXED(_id, _name, _parents, _reg, _prediv, \ + _prediv_sel, _prediv_fixed, _div, _sel, _flags) \ [_id] = { \ .type = SUNXI_CCU_PREDIV, \ .base.name = (_name), \ @@ -264,6 +270,7 @@ const char *sunxi_ccu_prediv_get_parent( .u.prediv.nparents = __arraycount(_parents), \ .u.prediv.prediv = (_prediv), \ .u.prediv.prediv_sel = (_prediv_sel), \ + .u.prediv.prediv_fixed = (_prediv_fixed), \ .u.prediv.div = (_div), \ .u.prediv.sel = (_sel), \ .u.prediv.flags = (_flags), \ Index: src/sys/arch/arm/sunxi/sunxi_ccu_div.c diff -u src/sys/arch/arm/sunxi/sunxi_ccu_div.c:1.1 src/sys/arch/arm/sunxi/sunxi_ccu_div.c:1.2 --- src/sys/arch/arm/sunxi/sunxi_ccu_div.c:1.1 Sun Jul 2 00:14:09 2017 +++ src/sys/arch/arm/sunxi/sunxi_ccu_div.c Fri Aug 25 00:07:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_ccu_div.c,v 1.1 2017/07/02 00:14:09 jmcneill Exp $ */ +/* $NetBSD: sunxi_ccu_div.c,v 1.2 2017/08/25 00:07:03 jmcneill Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_div.c,v 1.1 2017/07/02 00:14:09 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_div.c,v 1.2 2017/08/25 00:07:03 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -57,7 +57,11 @@ sunxi_ccu_div_get_rate(struct sunxi_ccu_ return 0; val = CCU_READ(sc, div->reg); - ratio = __SHIFTOUT(val, div->div); + if (div->div) + ratio = __SHIFTOUT(val, div->div); + else + ratio = 0; + if ((div->flags & SUNXI_CCU_DIV_ZERO_IS_ONE) != 0 && ratio == 0) ratio = 1; if (div->flags & SUNXI_CCU_DIV_POWER_OF_TWO) Index: src/sys/arch/arm/sunxi/sunxi_ccu_prediv.c diff -u src/sys/arch/arm/sunxi/sunxi_ccu_prediv.c:1.2 src/sys/arch/arm/sunxi/sunxi_ccu_prediv.c:1.3 --- src/sys/arch/arm/sunxi/sunxi_ccu_prediv.c:1.2 Thu Jun 29 17:08:52 2017 +++ src/sys/arch/arm/sunxi/sunxi_ccu_prediv.c Fri Aug 25 00:07:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_ccu_prediv.c,v 1.2 2017/06/29 17:08:52 jmcneill Exp $ */ +/* $NetBSD: sunxi_ccu_prediv.c,v 1.3 2017/08/25 00:07:03 jmcneill Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_prediv.c,v 1.2 2017/06/29 17:08:52 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_prediv.c,v 1.3 2017/08/25 00:07:03 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -72,7 +72,10 @@ sunxi_ccu_prediv_get_rate(struct sunxi_c else div++; - pre++; + if (prediv->prediv_fixed) + pre = prediv->prediv_fixed; + else + pre++; if (prediv->flags & SUNXI_CCU_PREDIV_DIVIDE_BY_TWO) pre *= 2; Index: src/sys/arch/arm/sunxi/sunxi_twi.c diff -u src/sys/arch/arm/sunxi/sunxi_twi.c:1.2 src/sys/arch/arm/sunxi/sunxi_twi.c:1.3 --- src/sys/arch/arm/sunxi/sunxi_twi.c:1.2 Sat Jul 1 22:49:09 2017 +++ src/sys/arch/arm/sunxi/sunxi_twi.c Fri Aug 25 00:07:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_twi.c,v 1.2 2017/07/01 22:49:09 jmcneill Exp $ */ +/* $NetBSD: sunxi_twi.c,v 1.3 2017/08/25 00:07:03 jmcneill Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -28,7 +28,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_twi.c,v 1.2 2017/07/01 22:49:09 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_twi.c,v 1.3 2017/08/25 00:07:03 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -46,6 +46,7 @@ static int sunxi_twi_match(device_t, cfd static void sunxi_twi_attach(device_t, device_t, void *); static const char * const compatible[] = { + "allwinner,sun4i-a10-i2c", "allwinner,sun6i-a31-i2c", NULL }; Index: src/sys/arch/arm/sunxi/sunxi_gpio.c diff -u src/sys/arch/arm/sunxi/sunxi_gpio.c:1.10 src/sys/arch/arm/sunxi/sunxi_gpio.c:1.11 --- src/sys/arch/arm/sunxi/sunxi_gpio.c:1.10 Sat Aug 12 23:42:52 2017 +++ src/sys/arch/arm/sunxi/sunxi_gpio.c Fri Aug 25 00:07:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_gpio.c,v 1.10 2017/08/12 23:42:52 jmcneill Exp $ */ +/* $NetBSD: sunxi_gpio.c,v 1.11 2017/08/25 00:07:03 jmcneill Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -29,7 +29,7 @@ #include "opt_soc.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_gpio.c,v 1.10 2017/08/12 23:42:52 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_gpio.c,v 1.11 2017/08/25 00:07:03 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -58,6 +58,9 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_gpio.c #define SUNXI_GPIO_PULL_PINMASK(pin) (0x3 << (((pin) % 16) * 2)) static const struct of_compat_data compat_data[] = { +#ifdef SOC_SUN5I_A13 + { "allwinner,sun5i-a13-pinctrl", (uintptr_t)&sun5i_a13_padconf }, +#endif #ifdef SOC_SUN6I_A31 { "allwinner,sun6i-a31-pinctrl", (uintptr_t)&sun6i_a31_padconf }, { "allwinner,sun6i-a31-r-pinctrl", (uintptr_t)&sun6i_a31_r_padconf }, Index: src/sys/arch/arm/sunxi/sunxi_gpio.h diff -u src/sys/arch/arm/sunxi/sunxi_gpio.h:1.4 src/sys/arch/arm/sunxi/sunxi_gpio.h:1.5 --- src/sys/arch/arm/sunxi/sunxi_gpio.h:1.4 Sun Jul 23 10:16:08 2017 +++ src/sys/arch/arm/sunxi/sunxi_gpio.h Fri Aug 25 00:07:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_gpio.h,v 1.4 2017/07/23 10:16:08 jmcneill Exp $ */ +/* $NetBSD: sunxi_gpio.h,v 1.5 2017/08/25 00:07:03 jmcneill Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -50,6 +50,10 @@ struct sunxi_gpio_padconf { const struct sunxi_gpio_pins *pins; }; +#ifdef SOC_SUN5I_A13 +extern const struct sunxi_gpio_padconf sun5i_a13_padconf; +#endif + #ifdef SOC_SUN6I_A31 extern const struct sunxi_gpio_padconf sun6i_a31_padconf; extern const struct sunxi_gpio_padconf sun6i_a31_r_padconf; Index: src/sys/arch/arm/sunxi/sunxi_mmc.c diff -u src/sys/arch/arm/sunxi/sunxi_mmc.c:1.3 src/sys/arch/arm/sunxi/sunxi_mmc.c:1.4 --- src/sys/arch/arm/sunxi/sunxi_mmc.c:1.3 Mon Jul 17 23:31:05 2017 +++ src/sys/arch/arm/sunxi/sunxi_mmc.c Fri Aug 25 00:07:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_mmc.c,v 1.3 2017/07/17 23:31:05 jmcneill Exp $ */ +/* $NetBSD: sunxi_mmc.c,v 1.4 2017/08/25 00:07:03 jmcneill Exp $ */ /*- * Copyright (c) 2014-2017 Jared McNeill <jmcne...@invisible.ca> @@ -27,7 +27,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_mmc.c,v 1.3 2017/07/17 23:31:05 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_mmc.c,v 1.4 2017/08/25 00:07:03 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -165,6 +165,7 @@ CFATTACH_DECL_NEW(sunxi_mmc, sizeof(stru bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) static const char * const compatible[] = { + "allwinner,sun5i-a13-mmc", "allwinner,sun7i-a20-mmc", NULL }; Index: src/sys/arch/arm/sunxi/sunxi_usbphy.c diff -u src/sys/arch/arm/sunxi/sunxi_usbphy.c:1.3 src/sys/arch/arm/sunxi/sunxi_usbphy.c:1.4 --- src/sys/arch/arm/sunxi/sunxi_usbphy.c:1.3 Sun Jul 2 00:14:09 2017 +++ src/sys/arch/arm/sunxi/sunxi_usbphy.c Fri Aug 25 00:07:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_usbphy.c,v 1.3 2017/07/02 00:14:09 jmcneill Exp $ */ +/* $NetBSD: sunxi_usbphy.c,v 1.4 2017/08/25 00:07:03 jmcneill Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -28,7 +28,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_usbphy.c,v 1.3 2017/07/02 00:14:09 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_usbphy.c,v 1.4 2017/08/25 00:07:03 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -54,11 +54,13 @@ static int sunxi_usbphy_match(device_t, static void sunxi_usbphy_attach(device_t, device_t, void *); enum sunxi_usbphy_type { + USBPHY_A13, USBPHY_A31, USBPHY_H3, }; static const struct of_compat_data compat_data[] = { + { "allwinner,sun5i-a13-usb-phy", USBPHY_A13 }, { "allwinner,sun6i-a31-usb-phy", USBPHY_A31 }, { "allwinner,sun8i-h3-usb-phy", USBPHY_H3 }, { NULL } Index: src/sys/arch/arm/sunxi/sunxi_platform.c diff -u src/sys/arch/arm/sunxi/sunxi_platform.c:1.6 src/sys/arch/arm/sunxi/sunxi_platform.c:1.7 --- src/sys/arch/arm/sunxi/sunxi_platform.c:1.6 Sun Jul 23 10:16:08 2017 +++ src/sys/arch/arm/sunxi/sunxi_platform.c Fri Aug 25 00:07:03 2017 @@ -1,4 +1,4 @@ -/* $NetBSD: sunxi_platform.c,v 1.6 2017/07/23 10:16:08 jmcneill Exp $ */ +/* $NetBSD: sunxi_platform.c,v 1.7 2017/08/25 00:07:03 jmcneill Exp $ */ /*- * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> @@ -31,7 +31,7 @@ #include "opt_fdt_arm.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.6 2017/07/23 10:16:08 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.7 2017/08/25 00:07:03 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -60,12 +60,25 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_platfo #define SUNXI_REF_FREQ 24000000 +#define SUN4I_TIMER_BASE 0x01c20c00 +#define SUN4I_TIMER_SIZE 0x90 +#define SUN4I_TIMER_0_VAL 0x18 + +#define SUN4I_WDT_BASE 0x01c20c90 +#define SUN4I_WDT_SIZE 0x10 +#define SUN4I_WDT_CTRL 0x00 +#define SUN4I_WDT_CTRL_KEY (0x333 << 1) +#define SUN4I_WDT_CTRL_RESTART __BIT(0) +#define SUN4I_WDT_MODE 0x04 +#define SUN4I_WDT_MODE_RST_EN __BIT(1) +#define SUN4I_WDT_MODE_EN __BIT(0) + #define SUN6I_WDT_BASE 0x01c20ca0 #define SUN6I_WDT_SIZE 0x20 #define SUN6I_WDT_CFG 0x14 -#define SUN6I_WDT_CFG_SYS 1 +#define SUN6I_WDT_CFG_SYS __BIT(0) #define SUN6I_WDT_MODE 0x18 -#define SUN6I_WDT_MODE_EN 1 +#define SUN6I_WDT_MODE_EN __BIT(0) #define DEVMAP_ALIGN(a) ((a) & ~L1_S_OFFSET) @@ -131,6 +144,49 @@ sunxi_platform_uart_freq(void) } static void +sunxi_platform_null_bootstrap(void) +{ +} + +static void +sun4i_platform_reset(void) +{ + bus_space_tag_t bst = &armv7_generic_bs_tag; + bus_space_handle_t bsh; + + bus_space_map(bst, SUN4I_WDT_BASE, SUN4I_WDT_SIZE, 0, &bsh); + + bus_space_write_4(bst, bsh, SUN4I_WDT_CTRL, + SUN4I_WDT_CTRL_KEY | SUN4I_WDT_CTRL_RESTART); + for (;;) { + bus_space_write_4(bst, bsh, SUN4I_WDT_MODE, + SUN4I_WDT_MODE_EN | SUN4I_WDT_MODE_RST_EN); + } +} + +static void +sun4i_platform_delay(u_int n) +{ + static bus_space_tag_t bst = &armv7_generic_bs_tag; + static bus_space_handle_t bsh = 0; + uint32_t cur, prev; + long ticks = n; + + if (bsh == 0) + bus_space_map(bst, SUN4I_TIMER_BASE, SUN4I_TIMER_SIZE, 0, &bsh); + + prev = ~bus_space_read_4(bst, bsh, SUN4I_TIMER_0_VAL); + while (ticks > 0) { + cur = ~bus_space_read_4(bst, bsh, SUN4I_TIMER_0_VAL); + if (cur > prev) + ticks -= (cur - prev); + else + ticks -= (~0U - cur + prev); + prev = cur; + } +} + +static void sun6i_platform_reset(void) { bus_space_tag_t bst = &armv7_generic_bs_tag; @@ -142,14 +198,18 @@ sun6i_platform_reset(void) bus_space_write_4(bst, bsh, SUN6I_WDT_MODE, SUN6I_WDT_MODE_EN); } -static void -sun50i_platform_bootstrap(void) -{ - /* XXX - * This should use psci_fdt_bootstrap, but it hangs - * (at least in aarch32 mode) - */ -} +static const struct arm_platform sun5i_platform = { + .devmap = sunxi_platform_devmap, + .bootstrap = sunxi_platform_null_bootstrap, + .init_attach_args = sunxi_platform_init_attach_args, + .early_putchar = sunxi_platform_early_putchar, + .device_register = sunxi_platform_device_register, + .reset = sun4i_platform_reset, + .delay = sun4i_platform_delay, + .uart_freq = sunxi_platform_uart_freq, +}; + +ARM_PLATFORM(sun5i_a13, "allwinner,sun5i-a13", &sun5i_platform); static const struct arm_platform sun6i_platform = { .devmap = sunxi_platform_devmap, @@ -181,7 +241,7 @@ ARM_PLATFORM(sun8i_a83t, "allwinner,sun8 static const struct arm_platform sun50i_platform = { .devmap = sunxi_platform_devmap, - .bootstrap = sun50i_platform_bootstrap, + .bootstrap = sunxi_platform_null_bootstrap, .init_attach_args = sunxi_platform_init_attach_args, .early_putchar = sunxi_platform_early_putchar, .device_register = sunxi_platform_device_register, Index: src/sys/arch/evbarm/conf/SUNXI diff -u src/sys/arch/evbarm/conf/SUNXI:1.22 src/sys/arch/evbarm/conf/SUNXI:1.23 --- src/sys/arch/evbarm/conf/SUNXI:1.22 Sun Aug 13 18:27:48 2017 +++ src/sys/arch/evbarm/conf/SUNXI Fri Aug 25 00:07:03 2017 @@ -1,5 +1,5 @@ # -# $NetBSD: SUNXI,v 1.22 2017/08/13 18:27:48 jmcneill Exp $ +# $NetBSD: SUNXI,v 1.23 2017/08/25 00:07:03 jmcneill Exp $ # # Allwinner sunxi family # @@ -8,6 +8,22 @@ include "arch/evbarm/conf/std.sunxi" include "arch/evbarm/conf/GENERIC.common" makeoptions DTS=" + sun5i-a13-difrnce-dit4350.dts + sun5i-a13-empire-electronix-d709.dts + sun5i-a13-empire-electronix-m712.dts + sun5i-a13-hsg-h702.dts + sun5i-a13-inet-98v-rev2.dts + sun5i-a13-licheepi-one.dts + sun5i-a13-olinuxino-micro.dts + sun5i-a13-olinuxino.dts + sun5i-a13-q8-tablet.dts + sun5i-a13-utoo-p66.dts + + sun5i-gr8-evb.dts + sun5i-gr8-chip-pro.dts + + sun5i-r8-chip.dts + sun6i-a31-app4-evb1.dts sun6i-a31-colombus.dts sun6i-a31-hummingbird.dts @@ -32,6 +48,8 @@ makeoptions DTS=" " options CPU_CORTEXA7 +options CPU_CORTEXA8 +options SOC_SUN5I_A13 options SOC_SUN6I_A31 options SOC_SUN8I_A83T options SOC_SUN8I_H3 @@ -65,6 +83,7 @@ cpu* at cpus? psci* at fdt? # Clock and reset controllers +sun5ia13ccu* at fdt? pass 4 # A13 CCU sun6ia31ccu* at fdt? pass 4 # A31 CCU sun8ia83tccu* at fdt? pass 4 # A83T CCU sun8ih3ccu* at fdt? pass 4 # H3 CCU @@ -81,6 +100,7 @@ gpioleds* at fdt? # Timer gtmr* at fdt? pass 1 # ARM Generic Timer armgtmr0 at gtmr? +sunxitimer* at fdt? # Allwinner async timer # Watchdog sunxiwdt* at fdt? # Allwinner watchdog @@ -88,6 +108,7 @@ sunxiwdt* at fdt? # Allwinner watchdog # Interrupt controller gic* at fdt? pass 1 # GIC armgic0 at gic? +sunxiintc* at fdt? pass 1 # Allwinner INTC # Memory controller Index: src/sys/arch/evbarm/conf/std.sunxi diff -u src/sys/arch/evbarm/conf/std.sunxi:1.3 src/sys/arch/evbarm/conf/std.sunxi:1.4 --- src/sys/arch/evbarm/conf/std.sunxi:1.3 Wed Jul 5 01:08:44 2017 +++ src/sys/arch/evbarm/conf/std.sunxi Fri Aug 25 00:07:03 2017 @@ -1,4 +1,4 @@ -# $NetBSD: std.sunxi,v 1.3 2017/07/05 01:08:44 jmcneill Exp $ +# $NetBSD: std.sunxi,v 1.4 2017/08/25 00:07:03 jmcneill Exp $ # machine evbarm arm @@ -20,6 +20,7 @@ options TPIDRPRW_IS_CURCPU options KERNEL_BASE_EXT=0x80000000 options FPU_VFP options __BUS_SPACE_HAS_STREAM_METHODS +options __HAVE_GENERIC_CPU_INITCLOCKS makeoptions KERNEL_BASE_PHYS="0x40008000" makeoptions KERNEL_BASE_VIRT="0x80008000" Added files: Index: src/sys/arch/arm/sunxi/sun5i_a13_ccu.c diff -u /dev/null src/sys/arch/arm/sunxi/sun5i_a13_ccu.c:1.1 --- /dev/null Fri Aug 25 00:07:03 2017 +++ src/sys/arch/arm/sunxi/sun5i_a13_ccu.c Fri Aug 25 00:07:03 2017 @@ -0,0 +1,263 @@ +/* $NetBSD: sun5i_a13_ccu.c,v 1.1 2017/08/25 00:07:03 jmcneill Exp $ */ + +/*- + * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> + * 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 ``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 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> + +__KERNEL_RCSID(1, "$NetBSD: sun5i_a13_ccu.c,v 1.1 2017/08/25 00:07:03 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/systm.h> + +#include <dev/fdt/fdtvar.h> + +#include <arm/sunxi/sunxi_ccu.h> +#include <arm/sunxi/sun5i_a13_ccu.h> + +#define PLL1_CFG_REG 0x000 +#define PLL6_CFG_REG 0x028 +#define OSC24M_CFG_REG 0x050 +#define CPU_AHB_APB0_CFG_REG 0x054 +#define APB1_CLK_DIV_REG 0x058 +#define AHB_GATING_REG0 0x060 +#define AHB_GATING_REG1 0x064 +#define APB0_GATING_REG 0x068 +#define APB1_GATING_REG 0x06c +#define USBPHY_CFG_REG 0x0cc +#define BE_CFG_REG 0x104 +#define FE_CFG_REG 0x10c +#define CSI_CFG_REG 0x134 +#define VE_CFG_REG 0x13c +#define MALI_CLOCK_CFG_REG 0x154 +#define IEP_SCLK_CFG_REG 0x160 + +static int sun5i_a13_ccu_match(device_t, cfdata_t, void *); +static void sun5i_a13_ccu_attach(device_t, device_t, void *); + +static const char * const compatible[] = { + "allwinner,sun5i-a13-ccu", + NULL +}; + +CFATTACH_DECL_NEW(sunxi_a13_ccu, sizeof(struct sunxi_ccu_softc), + sun5i_a13_ccu_match, sun5i_a13_ccu_attach, NULL, NULL); + +static struct sunxi_ccu_reset sun5i_a13_ccu_resets[] = { + SUNXI_CCU_RESET(A13_RST_USB_PHY0, USBPHY_CFG_REG, 0), + SUNXI_CCU_RESET(A13_RST_USB_PHY1, USBPHY_CFG_REG, 1), + + /* Missing: GPS */ + + SUNXI_CCU_RESET(A13_RST_DE_BE, BE_CFG_REG, 30), + + SUNXI_CCU_RESET(A13_RST_DE_FE, FE_CFG_REG, 30), + + /* Missing: TVE */ + + /* Missing: LCD */ + + SUNXI_CCU_RESET(A13_RST_CSI, CSI_CFG_REG, 30), + + SUNXI_CCU_RESET(A13_RST_VE, VE_CFG_REG, 0), + + SUNXI_CCU_RESET(A13_RST_GPU, MALI_CLOCK_CFG_REG, 30), + + SUNXI_CCU_RESET(A13_RST_IEP, IEP_SCLK_CFG_REG, 30), +}; + +static const char *cpu_parents[] = { "losc", "osc24m", "pll_core", "pll_periph" }; +static const char *axi_parents[] = { "cpu" }; +static const char *ahb_parents[] = { "axi", "cpu", "pll_periph", NULL }; +static const char *apb0_parents[] = { "ahb" }; +static const char *apb1_parents[] = { "osc24m", "pll_periph", "losc", NULL }; + +static struct sunxi_ccu_clk sun5i_a13_ccu_clks[] = { + SUNXI_CCU_GATE(A13_CLK_HOSC, "osc24m", "hosc", + OSC24M_CFG_REG, 0), + + SUNXI_CCU_NKMP(A13_CLK_PLL_CORE, "pll_core", "osc24m", + PLL1_CFG_REG, /* reg */ + __BITS(12,8), /* n */ + __BITS(5,4), /* k */ + __BITS(1,0), /* m */ + __BITS(17,16), /* p */ + __BIT(31), /* enable */ + SUNXI_CCU_NKMP_FACTOR_P_POW2 | SUNXI_CCU_NKMP_FACTOR_N_EXACT), + + SUNXI_CCU_NKMP(A13_CLK_PERIPH, "pll_periph", "osc24m", + PLL6_CFG_REG, /* reg */ + __BITS(12,8), /* n */ + __BITS(5,4), /* k */ + __BITS(1,0), /* m */ + 0, /* p */ + __BIT(31), /* enable */ + SUNXI_CCU_NKMP_DIVIDE_BY_TWO | SUNXI_CCU_NKMP_FACTOR_N_EXACT), + + SUNXI_CCU_PREDIV_FIXED(A13_CLK_CPU, "cpu", cpu_parents, + CPU_AHB_APB0_CFG_REG, /* reg */ + 0, /* prediv */ + __BIT(3), /* prediv_sel */ + 6, /* prediv_fixed */ + 0, /* div */ + __BITS(17,16), /* sel */ + 0), + + SUNXI_CCU_DIV(A13_CLK_AXI, "axi", axi_parents, + CPU_AHB_APB0_CFG_REG, /* reg */ + __BITS(1,0), /* div */ + 0, /* sel */ + 0), + + SUNXI_CCU_DIV(A13_CLK_AHB, "ahb", ahb_parents, + CPU_AHB_APB0_CFG_REG, /* reg */ + 0, /* div */ + __BITS(5,4), /* sel */ + SUNXI_CCU_DIV_POWER_OF_TWO), + + SUNXI_CCU_DIV(A13_CLK_APB0, "apb0", apb0_parents, + CPU_AHB_APB0_CFG_REG, /* reg */ + __BITS(9,8), /* div */ + 0, /* sel */ + SUNXI_CCU_DIV_ZERO_IS_ONE | SUNXI_CCU_DIV_POWER_OF_TWO), + + SUNXI_CCU_NM(A13_CLK_APB1, "apb1", apb1_parents, + APB1_CLK_DIV_REG, /* reg */ + __BITS(17,16), /* n */ + __BITS(4,0), /* m */ + __BITS(25,24), /* sel */ + 0, /* enable */ + SUNXI_CCU_NM_POWER_OF_TWO), + + /* AHB_GATING_REG0. Missing: SS, EMAC, TS, GPS */ + SUNXI_CCU_GATE(A13_CLK_AHB_OTG, "ahb-otg", "ahb", + AHB_GATING_REG0, 0), + SUNXI_CCU_GATE(A13_CLK_AHB_EHCI, "ahb-ehci", "ahb", + AHB_GATING_REG0, 1), + SUNXI_CCU_GATE(A13_CLK_AHB_OHCI, "ahb-ohci", "ahb", + AHB_GATING_REG0, 2), + SUNXI_CCU_GATE(A13_CLK_AHB_DMA, "ahb-dma", "ahb", + AHB_GATING_REG0, 6), + SUNXI_CCU_GATE(A13_CLK_AHB_BIST, "ahb-bist", "ahb", + AHB_GATING_REG0, 7), + SUNXI_CCU_GATE(A13_CLK_AHB_MMC0, "ahb-mmc0", "ahb", + AHB_GATING_REG0, 8), + SUNXI_CCU_GATE(A13_CLK_AHB_MMC1, "ahb-mmc1", "ahb", + AHB_GATING_REG0, 9), + SUNXI_CCU_GATE(A13_CLK_AHB_MMC2, "ahb-mmc2", "ahb", + AHB_GATING_REG0, 10), + SUNXI_CCU_GATE(A13_CLK_AHB_NAND, "ahb-nand", "ahb", + AHB_GATING_REG0, 13), + SUNXI_CCU_GATE(A13_CLK_AHB_SDRAM, "ahb-sdram", "ahb", + AHB_GATING_REG0, 14), + SUNXI_CCU_GATE(A13_CLK_AHB_SPI0, "ahb-spi0", "ahb", + AHB_GATING_REG0, 20), + SUNXI_CCU_GATE(A13_CLK_AHB_SPI1, "ahb-spi1", "ahb", + AHB_GATING_REG0, 21), + SUNXI_CCU_GATE(A13_CLK_AHB_SPI2, "ahb-spi2", "ahb", + AHB_GATING_REG0, 22), + SUNXI_CCU_GATE(A13_CLK_AHB_HSTIMER, "ahb-hstimer", "ahb", + AHB_GATING_REG0, 28), + + /* AHB_GATING_REG1. Missing: TVE, HDMI */ + SUNXI_CCU_GATE(A13_CLK_AHB_VE, "ahb-ve", "ahb", + AHB_GATING_REG1, 0), + SUNXI_CCU_GATE(A13_CLK_AHB_LCD, "ahb-lcd", "ahb", + AHB_GATING_REG1, 4), + SUNXI_CCU_GATE(A13_CLK_AHB_CSI, "ahb-csi", "ahb", + AHB_GATING_REG1, 8), + SUNXI_CCU_GATE(A13_CLK_AHB_DE_BE, "ahb-de_be", "ahb", + AHB_GATING_REG1, 12), + SUNXI_CCU_GATE(A13_CLK_AHB_DE_FE, "ahb-de_fe", "ahb", + AHB_GATING_REG1, 14), + SUNXI_CCU_GATE(A13_CLK_AHB_IEP, "ahb-iep", "ahb", + AHB_GATING_REG1, 19), + SUNXI_CCU_GATE(A13_CLK_AHB_GPU, "ahb-gpu", "ahb", + AHB_GATING_REG1, 20), + + /* APB0_GATING_REG. Missing: SPDIF, I2S, KEYPAD */ + SUNXI_CCU_GATE(A13_CLK_APB0_CODEC, "apb0-codec", "apb0", + APB0_GATING_REG, 0), + SUNXI_CCU_GATE(A13_CLK_APB0_PIO, "apb0-pio", "apb0", + APB0_GATING_REG, 5), + SUNXI_CCU_GATE(A13_CLK_APB0_IR, "apb0-ir", "apb0", + APB0_GATING_REG, 6), + + /* APB1_GATING_REG. Missing: UART0, UART2 */ + SUNXI_CCU_GATE(A13_CLK_APB1_I2C0, "apb1-i2c0", "apb1", + APB1_GATING_REG, 0), + SUNXI_CCU_GATE(A13_CLK_APB1_I2C1, "apb1-i2c1", "apb1", + APB1_GATING_REG, 1), + SUNXI_CCU_GATE(A13_CLK_APB1_I2C2, "apb1-i2c2", "apb1", + APB1_GATING_REG, 2), + SUNXI_CCU_GATE(A13_CLK_APB1_UART1, "apb1-uart1", "apb1", + APB1_GATING_REG, 17), + SUNXI_CCU_GATE(A13_CLK_APB1_UART3, "apb1-uart3", "apb1", + APB1_GATING_REG, 19), + + /* USBPHY_CFG_REG */ + SUNXI_CCU_GATE(A13_CLK_USB_OHCI, "usb-ohci", "osc24m", + USBPHY_CFG_REG, 6), + SUNXI_CCU_GATE(A13_CLK_USB_PHY0, "usb-phy0", "osc24m", + USBPHY_CFG_REG, 8), + SUNXI_CCU_GATE(A13_CLK_USB_PHY1, "usb-phy1", "osc24m", + USBPHY_CFG_REG, 9), +}; + +static int +sun5i_a13_ccu_match(device_t parent, cfdata_t cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +sun5i_a13_ccu_attach(device_t parent, device_t self, void *aux) +{ + struct sunxi_ccu_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + + sc->sc_dev = self; + sc->sc_phandle = faa->faa_phandle; + sc->sc_bst = faa->faa_bst; + + sc->sc_resets = sun5i_a13_ccu_resets; + sc->sc_nresets = __arraycount(sun5i_a13_ccu_resets); + + sc->sc_clks = sun5i_a13_ccu_clks; + sc->sc_nclks = __arraycount(sun5i_a13_ccu_clks); + + if (sunxi_ccu_attach(sc) != 0) + return; + + aprint_naive("\n"); + aprint_normal(": A13 CCU\n"); + + sunxi_ccu_print(sc); +} Index: src/sys/arch/arm/sunxi/sun5i_a13_ccu.h diff -u /dev/null src/sys/arch/arm/sunxi/sun5i_a13_ccu.h:1.1 --- /dev/null Fri Aug 25 00:07:03 2017 +++ src/sys/arch/arm/sunxi/sun5i_a13_ccu.h Fri Aug 25 00:07:03 2017 @@ -0,0 +1,145 @@ +/* $NetBSD: sun5i_a13_ccu.h,v 1.1 2017/08/25 00:07:03 jmcneill Exp $ */ + +/*- + * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> + * 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 ``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 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. + */ + +#ifndef _SUN5I_A13_CCU_H +#define _SUN5I_A13_CCU_H + +#define A13_RST_USB_PHY0 0 +#define A13_RST_USB_PHY1 1 +#define A13_RST_GPS 2 +#define A13_RST_DE_BE 3 +#define A13_RST_DE_FE 4 +#define A13_RST_TVE 5 +#define A13_RST_LCD 6 +#define A13_RST_CSI 7 +#define A13_RST_VE 8 +#define A13_RST_GPU 9 +#define A13_RST_IEP 10 + +#define A13_CLK_HOSC 1 +#define A13_CLK_PLL_CORE 2 +#define A13_CLK_PLL_AUDIO_BASE 3 +#define A13_CLK_PLL_AUDIO 4 +#define A13_CLK_PLL_AUDIO_2X 5 +#define A13_CLK_PLL_AUDIO_4X 6 +#define A13_CLK_PLL_AUDIO_8X 7 +#define A13_CLK_PLL_VIDEO0 8 +#define A13_CLK_PLL_VIDEO0_2X 9 +#define A13_CLK_PLL_VE 10 +#define A13_CLK_PLL_DDR_BASE 11 +#define A13_CLK_PLL_DDR 12 +#define A13_CLK_PLL_DDR_OTHER 13 +#define A13_CLK_PERIPH 14 +#define A13_CLK_VIDEO1 15 +#define A13_CLK_VIDEO1_2X 16 +#define A13_CLK_CPU 17 +#define A13_CLK_AXI 18 +#define A13_CLK_AHB 19 +#define A13_CLK_APB0 20 +#define A13_CLK_APB1 21 +#define A13_CLK_DRAM_AXI 22 +#define A13_CLK_AHB_OTG 23 +#define A13_CLK_AHB_EHCI 24 +#define A13_CLK_AHB_OHCI 25 +#define A13_CLK_AHB_SS 26 +#define A13_CLK_AHB_DMA 27 +#define A13_CLK_AHB_BIST 28 +#define A13_CLK_AHB_MMC0 29 +#define A13_CLK_AHB_MMC1 30 +#define A13_CLK_AHB_MMC2 31 +#define A13_CLK_AHB_NAND 32 +#define A13_CLK_AHB_SDRAM 33 +#define A13_CLK_AHB_EMAC 34 +#define A13_CLK_AHB_TS 35 +#define A13_CLK_AHB_SPI0 36 +#define A13_CLK_AHB_SPI1 37 +#define A13_CLK_AHB_SPI2 38 +#define A13_CLK_AHB_GPS 39 +#define A13_CLK_AHB_HSTIMER 40 +#define A13_CLK_AHB_VE 41 +#define A13_CLK_AHB_TVE 42 +#define A13_CLK_AHB_LCD 43 +#define A13_CLK_AHB_CSI 44 +#define A13_CLK_AHB_HDMI 45 +#define A13_CLK_AHB_DE_BE 46 +#define A13_CLK_AHB_DE_FE 47 +#define A13_CLK_AHB_IEP 48 +#define A13_CLK_AHB_GPU 49 +#define A13_CLK_APB0_CODEC 50 +#define A13_CLK_APB0_SPDIF 51 +#define A13_CLK_APB0_I2S 52 +#define A13_CLK_APB0_PIO 53 +#define A13_CLK_APB0_IR 54 +#define A13_CLK_APB0_KEYPAD 55 +#define A13_CLK_APB1_I2C0 56 +#define A13_CLK_APB1_I2C1 57 +#define A13_CLK_APB1_I2C2 58 +#define A13_CLK_APB1_UART0 59 +#define A13_CLK_APB1_UART1 60 +#define A13_CLK_APB1_UART2 61 +#define A13_CLK_APB1_UART3 62 +#define A13_CLK_NAND 63 +#define A13_CLK_MMC0 64 +#define A13_CLK_MMC1 65 +#define A13_CLK_MMC2 66 +#define A13_CLK_TS 67 +#define A13_CLK_SS 68 +#define A13_CLK_SPI0 69 +#define A13_CLK_SPI1 70 +#define A13_CLK_SPI2 71 +#define A13_CLK_IR 72 +#define A13_CLK_I2S 73 +#define A13_CLK_SPDIF 74 +#define A13_CLK_KEYPAD 75 +#define A13_CLK_USB_OHCI 76 +#define A13_CLK_USB_PHY0 77 +#define A13_CLK_USB_PHY1 78 +#define A13_CLK_GPS 79 +#define A13_CLK_DRAM_VE 80 +#define A13_CLK_DRAM_CSI 81 +#define A13_CLK_DRAM_TS 82 +#define A13_CLK_DRAM_TVE 83 +#define A13_CLK_DRAM_DE_FE 84 +#define A13_CLK_DRAM_DE_BE 85 +#define A13_CLK_DRAM_ACE 86 +#define A13_CLK_DRAM_IEP 87 +#define A13_CLK_DE_BE 88 +#define A13_CLK_DE_FE 89 +#define A13_CLK_TCON_CH0 90 +#define A13_CLK_TCON_CH1_SCLK 91 +#define A13_CLK_TCON_CH1 92 +#define A13_CLK_CSI 93 +#define A13_CLK_VE 94 +#define A13_CLK_CODEC 95 +#define A13_CLK_AVS 96 +#define A13_CLK_HDMI 97 +#define A13_CLK_GPU 98 +#define A13_CLK_MBUS 99 +#define A13_CLK_IEP 100 + +#endif /* !_SUN5I_A13_CCU_H */ Index: src/sys/arch/arm/sunxi/sun5i_a13_gpio.c diff -u /dev/null src/sys/arch/arm/sunxi/sun5i_a13_gpio.c:1.1 --- /dev/null Fri Aug 25 00:07:03 2017 +++ src/sys/arch/arm/sunxi/sun5i_a13_gpio.c Fri Aug 25 00:07:03 2017 @@ -0,0 +1,128 @@ +/* $NetBSD: sun5i_a13_gpio.c,v 1.1 2017/08/25 00:07:03 jmcneill Exp $ */ + +/*- + * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> + * 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 ``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 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$ + */ + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: sun5i_a13_gpio.c,v 1.1 2017/08/25 00:07:03 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/types.h> + +#include <arm/sunxi/sunxi_gpio.h> + +static const struct sunxi_gpio_pins a13_pins[] = { + { "PB0", 1, 0, { "gpio_in", "gpio_out", "i2c0" } }, + { "PB1", 1, 1, { "gpio_in", "gpio_out", "i2c0" } }, + { "PB2", 1, 2, { "gpio_in", "gpio_out", "pwm", NULL, NULL, NULL, "eint" } }, + { "PB3", 1, 3, { "gpio_in", "gpio_out", "ir0", NULL, NULL, NULL, "eint" } }, + { "PB4", 1, 4, { "gpio_in", "gpio_out", "ir0", NULL, NULL, NULL, "eint" } }, + { "PB10", 1, 10, { "gpio_in", "gpio_out", "spi2", NULL, NULL, NULL, "eint" } }, + { "PB15", 1, 15, { "gpio_in", "gpio_out", "i2c1" } }, + { "PB16", 1, 16, { "gpio_in", "gpio_out", "i2c1" } }, + { "PB17", 1, 17, { "gpio_in", "gpio_out", "i2c2" } }, + { "PB18", 1, 18, { "gpio_in", "gpio_out", "i2c2" } }, + + { "PC0", 2, 0, { "gpio_in", "gpio_out", "nand0", "spi0" } }, + { "PC1", 2, 1, { "gpio_in", "gpio_out", "nand0", "spi0" } }, + { "PC2", 2, 2, { "gpio_in", "gpio_out", "nand0", "spi0" } }, + { "PC3", 2, 3, { "gpio_in", "gpio_out", "nand0", "spi0" } }, + { "PC4", 2, 4, { "gpio_in", "gpio_out", "nand0" } }, + { "PC5", 2, 5, { "gpio_in", "gpio_out", "nand0" } }, + { "PC6", 2, 6, { "gpio_in", "gpio_out", "nand0", "mmc2" } }, + { "PC7", 2, 7, { "gpio_in", "gpio_out", "nand0", "mmc2" } }, + { "PC8", 2, 8, { "gpio_in", "gpio_out", "nand0", "mmc2" } }, + { "PC9", 2, 9, { "gpio_in", "gpio_out", "nand0", "mmc2" } }, + { "PC10", 2, 10, { "gpio_in", "gpio_out", "nand0", "mmc2" } }, + { "PC11", 2, 11, { "gpio_in", "gpio_out", "nand0", "mmc2" } }, + { "PC12", 2, 12, { "gpio_in", "gpio_out", "nand0", "mmc2" } }, + { "PC13", 2, 13, { "gpio_in", "gpio_out", "nand0", "mmc2" } }, + { "PC14", 2, 14, { "gpio_in", "gpio_out", "nand0", "mmc2" } }, + { "PC15", 2, 15, { "gpio_in", "gpio_out", "nand0", "mmc2" } }, + { "PC19", 2, 19, { "gpio_in", "gpio_out", "nand0" } }, + + { "PD2", 3, 2, { "gpio_in", "gpio_out", "lcd0", "uart2" } }, + { "PD3", 3, 3, { "gpio_in", "gpio_out", "lcd0", "uart2" } }, + { "PD4", 3, 4, { "gpio_in", "gpio_out", "lcd0", "uart2" } }, + { "PD5", 3, 5, { "gpio_in", "gpio_out", "lcd0", "uart2" } }, + { "PD6", 3, 6, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD7", 3, 7, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD10", 3, 10, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD11", 3, 11, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD12", 3, 12, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD13", 3, 13, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD14", 3, 14, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD15", 3, 15, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD18", 3, 18, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD19", 3, 19, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD20", 3, 20, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD21", 3, 21, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD22", 3, 22, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD23", 3, 23, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD24", 3, 24, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD25", 3, 25, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD26", 3, 26, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + { "PD27", 3, 27, { "gpio_in", "gpio_out", "lcd0", "emac" } }, + + { "PE0", 4, 0, { "gpio_in", NULL, "ts0", "csi0", "spi2", NULL, "eint" } }, + { "PE1", 4, 1, { "gpio_in", NULL, "ts0", "csi0", "spi2", NULL, "eint" } }, + { "PE2", 4, 2, { "gpio_in", NULL, "ts0", "csi0", "spi2" } }, + { "PE3", 4, 3, { "gpio_in", "gpio_out", "ts0", "csi0", "spi2" } }, + { "PE4", 4, 4, { "gpio_in", "gpio_out", "ts0", "csi0", "mmc2" } }, + { "PE5", 4, 5, { "gpio_in", "gpio_out", "ts0", "csi0", "mmc2" } }, + { "PE6", 4, 6, { "gpio_in", "gpio_out", "ts0", "csi0", "mmc2" } }, + { "PE7", 4, 7, { "gpio_in", "gpio_out", "ts0", "csi0", "mmc2" } }, + { "PE8", 4, 8, { "gpio_in", "gpio_out", "ts0", "csi0", "mmc2" } }, + { "PE9", 4, 9, { "gpio_in", "gpio_out", "ts0", "csi0", "mmc2" } }, + { "PE10", 4, 10, { "gpio_in", "gpio_out", "ts0", "csi0", "uart1" } }, + { "PE11", 4, 11, { "gpio_in", "gpio_out", "ts0", "csi0", "uart1" } }, + + { "PF0", 5, 0, { "gpio_in", "gpio_out", "mmc0", "jtag" } }, + { "PF1", 5, 1, { "gpio_in", "gpio_out", "mmc0", "jtag" } }, + { "PF2", 5, 2, { "gpio_in", "gpio_out", "mmc0", "uart0" } }, + { "PF3", 5, 3, { "gpio_in", "gpio_out", "mmc0", "jtag" } }, + { "PF4", 5, 4, { "gpio_in", "gpio_out", "mmc0", "uart0" } }, + { "PF5", 5, 5, { "gpio_in", "gpio_out", "mmc0", "jtag" } }, + + { "PG0", 6, 0, { "gpio_in", NULL, "gps", NULL, NULL, NULL, "eint" } }, + { "PG1", 6, 1, { "gpio_in", NULL, "gps", NULL, NULL, NULL, "eint" } }, + { "PG2", 6, 2, { "gpio_in", NULL, "gps", NULL, NULL, NULL, "eint" } }, + { "PG3", 6, 3, { "gpio_in", "gpio_out", NULL, NULL, "uart1", NULL, "eint" } }, + { "PG4", 6, 4, { "gpio_in", "gpio_out", NULL, NULL, "uart1", NULL, "eint" } }, + { "PG9", 6, 9, { "gpio_in", "gpio_out", "spi1", "uart3", NULL, NULL, "eint" } }, + { "PG10", 6, 10, { "gpio_in", "gpio_out", "spi1", "uart3", NULL, NULL, "eint" } }, + { "PG11", 6, 11, { "gpio_in", "gpio_out", "spi1", "uart3", NULL, NULL, "eint" } }, + { "PG12", 6, 12, { "gpio_in", "gpio_out", "spi1", "uart3", NULL, NULL, "eint" } }, +}; + +const struct sunxi_gpio_padconf sun5i_a13_padconf = { + .npins = __arraycount(a13_pins), + .pins = a13_pins, +}; Index: src/sys/arch/arm/sunxi/sunxi_intc.c diff -u /dev/null src/sys/arch/arm/sunxi/sunxi_intc.c:1.1 --- /dev/null Fri Aug 25 00:07:03 2017 +++ src/sys/arch/arm/sunxi/sunxi_intc.c Fri Aug 25 00:07:03 2017 @@ -0,0 +1,272 @@ +/* $NetBSD: sunxi_intc.c,v 1.1 2017/08/25 00:07:03 jmcneill Exp $ */ + +/*- + * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> + * 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 ``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 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. + */ + +#define _INTR_PRIVATE + +#include <sys/cdefs.h> +__KERNEL_RCSID(0, "$NetBSD: sunxi_intc.c,v 1.1 2017/08/25 00:07:03 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/intr.h> +#include <sys/systm.h> + +#include <dev/fdt/fdtvar.h> + +#include <arm/cpu.h> +#include <arm/pic/picvar.h> +#include <arm/fdt/arm_fdtvar.h> + +#define INTC_MAX_SOURCES 96 +#define INTC_MAX_GROUPS 3 + +#define INTC_VECTOR_REG 0x00 +#define INTC_BASE_ADDR_REG 0x04 +#define INTC_PROTECT_REG 0x08 +#define INTC_PROTECT_EN __BIT(0) +#define INTC_NMII_CTRL_REG 0x0c +#define INTC_IRQ_PEND_REG(n) (0x10 + ((n) * 4)) +#define INTC_FIQ_PEND_REG(n) (0x20 + ((n) * 4)) +#define INTC_SEL_REG(n) (0x30 + ((n) * 4)) +#define INTC_EN_REG(n) (0x40 + ((n) * 4)) +#define INTC_MASK_REG(n) (0x50 + ((n) * 4)) +#define INTC_RESP_REG(n) (0x60 + ((n) * 4)) +#define INTC_FORCE_REG(n) (0x70 + ((n) * 4)) +#define INTC_SRC_PRIO_REG(n) (0x80 + ((n) * 4)) + +static const char * const compatible[] = { + "allwinner,sun4i-a10-ic", + NULL +}; + +struct sunxi_intc_softc { + device_t sc_dev; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + int sc_phandle; + + uint32_t sc_enabled_irqs[INTC_MAX_GROUPS]; + + struct pic_softc sc_pic; +}; + +static struct sunxi_intc_softc *intc_softc; + +#define PICTOSOFTC(pic) \ + ((void *)((uintptr_t)(pic) - offsetof(struct sunxi_intc_softc, sc_pic))) + +#define INTC_READ(sc, reg) \ + bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) +#define INTC_WRITE(sc, reg, val) \ + bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) + +static void +sunxi_intc_unblock_irqs(struct pic_softc *pic, size_t irqbase, uint32_t mask) +{ + struct sunxi_intc_softc * const sc = PICTOSOFTC(pic); + const u_int group = irqbase / 32; + + KASSERT((mask & sc->sc_enabled_irqs[group]) == 0); + sc->sc_enabled_irqs[group] |= mask; + INTC_WRITE(sc, INTC_EN_REG(group), sc->sc_enabled_irqs[group]); +} + +static void +sunxi_intc_block_irqs(struct pic_softc *pic, size_t irqbase, uint32_t mask) +{ + struct sunxi_intc_softc * const sc = PICTOSOFTC(pic); + const u_int group = irqbase / 32; + + sc->sc_enabled_irqs[group] &= ~mask; + INTC_WRITE(sc, INTC_EN_REG(group), sc->sc_enabled_irqs[group]); +} + +static void +sunxi_intc_establish_irq(struct pic_softc *pic, struct intrsource *is) +{ + KASSERT(is->is_irq < INTC_MAX_SOURCES); + KASSERT(is->is_type == IST_LEVEL); +} + +static void +sunxi_intc_set_priority(struct pic_softc *pic, int ipl) +{ +} + +static const struct pic_ops sunxi_intc_picops = { + .pic_unblock_irqs = sunxi_intc_unblock_irqs, + .pic_block_irqs = sunxi_intc_block_irqs, + .pic_establish_irq = sunxi_intc_establish_irq, + .pic_set_priority = sunxi_intc_set_priority, +}; + +static void * +sunxi_intc_fdt_establish(device_t dev, u_int *specifier, int ipl, int flags, + int (*func)(void *), void *arg) +{ + /* 1st cell is the interrupt number */ + const u_int irq = be32toh(specifier[0]); + + if (irq >= INTC_MAX_SOURCES) { +#ifdef DIAGNOSTIC + device_printf(dev, "IRQ %u is invalid\n", irq); +#endif + return NULL; + } + + const u_int mpsafe = (flags & FDT_INTR_MPSAFE) ? IST_MPSAFE : 0; + + return intr_establish(irq, ipl, IST_LEVEL | mpsafe, func, arg); +} + +static void +sunxi_intc_fdt_disestablish(device_t dev, void *ih) +{ + intr_disestablish(ih); +} + +static bool +sunxi_intc_fdt_intrstr(device_t dev, u_int *specifier, char *buf, size_t buflen) +{ + /* 1st cell is the interrupt number */ + if (!specifier) + return false; + const u_int irq = be32toh(specifier[0]); + + snprintf(buf, buflen, "INTC irq %d", irq); + + return true; +} + +static const struct fdtbus_interrupt_controller_func sunxi_intc_fdt_funcs = { + .establish = sunxi_intc_fdt_establish, + .disestablish = sunxi_intc_fdt_disestablish, + .intrstr = sunxi_intc_fdt_intrstr, +}; + +static int +sunxi_intc_find_pending_irqs(struct sunxi_intc_softc *sc, u_int group) +{ + uint32_t pend; + + pend = INTC_READ(sc, INTC_IRQ_PEND_REG(group)); + + KASSERT((sc->sc_enabled_irqs[group] & pend) == pend); + + if (pend == 0) + return 0; + + return pic_mark_pending_sources(&sc->sc_pic, group * 32, pend); +} + +static void +sunxi_intc_irq_handler(void *frame) +{ + struct cpu_info * const ci = curcpu(); + struct sunxi_intc_softc * const sc = intc_softc; + const int oldipl = ci->ci_cpl; + const uint32_t oldipl_mask = __BIT(oldipl); + int ipl_mask = 0; + + ci->ci_data.cpu_nintr++; + + if (sc->sc_enabled_irqs[0]) + ipl_mask |= sunxi_intc_find_pending_irqs(sc, 0); + if (sc->sc_enabled_irqs[1]) + ipl_mask |= sunxi_intc_find_pending_irqs(sc, 1); + if (sc->sc_enabled_irqs[2]) + ipl_mask |= sunxi_intc_find_pending_irqs(sc, 2); + + if ((ipl_mask & ~oldipl_mask) > oldipl_mask) + pic_do_pending_ints(I32_bit, oldipl, frame); +} + +static int +sunxi_intc_match(device_t parent, cfdata_t cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +sunxi_intc_attach(device_t parent, device_t self, void *aux) +{ + struct sunxi_intc_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + const int phandle = faa->faa_phandle; + bus_addr_t addr; + bus_size_t size; + int error, i; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + sc->sc_dev = self; + sc->sc_phandle = phandle; + sc->sc_bst = faa->faa_bst; + if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { + aprint_error(": couldn't map registers\n"); + return; + } + + aprint_naive("\n"); + aprint_normal(": Interrupt Controller\n"); + + /* Disable IRQs */ + for (i = 0; i < INTC_MAX_GROUPS; i++) { + INTC_WRITE(sc, INTC_EN_REG(i), 0); + INTC_WRITE(sc, INTC_MASK_REG(i), 0); + } + /* Disable user mode access to intc registers */ + INTC_WRITE(sc, INTC_PROTECT_REG, INTC_PROTECT_EN); + + sc->sc_pic.pic_ops = &sunxi_intc_picops; + sc->sc_pic.pic_maxsources = INTC_MAX_SOURCES; + snprintf(sc->sc_pic.pic_name, sizeof(sc->sc_pic.pic_name), "intc"); + pic_add(&sc->sc_pic, 0); + + error = fdtbus_register_interrupt_controller(self, phandle, + &sunxi_intc_fdt_funcs); + if (error) { + aprint_error_dev(self, "couldn't register with fdtbus: %d\n", + error); + return; + } + + KASSERT(intc_softc == NULL); + intc_softc = sc; + arm_fdt_irq_set_handler(sunxi_intc_irq_handler); +} + +CFATTACH_DECL_NEW(sunxi_intc, sizeof(struct sunxi_intc_softc), + sunxi_intc_match, sunxi_intc_attach, NULL, NULL); Index: src/sys/arch/arm/sunxi/sunxi_timer.c diff -u /dev/null src/sys/arch/arm/sunxi/sunxi_timer.c:1.1 --- /dev/null Fri Aug 25 00:07:03 2017 +++ src/sys/arch/arm/sunxi/sunxi_timer.c Fri Aug 25 00:07:03 2017 @@ -0,0 +1,200 @@ +/* $NetBSD: sunxi_timer.c,v 1.1 2017/08/25 00:07:03 jmcneill Exp $ */ + +/*- + * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca> + * 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 ``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 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> +__KERNEL_RCSID(0, "$NetBSD: sunxi_timer.c,v 1.1 2017/08/25 00:07:03 jmcneill Exp $"); + +#include <sys/param.h> +#include <sys/kernel.h> +#include <sys/bus.h> +#include <sys/device.h> +#include <sys/intr.h> +#include <sys/systm.h> +#include <sys/timetc.h> + +#include <arm/locore.h> + +#include <dev/fdt/fdtvar.h> + +#include <arm/fdt/arm_fdtvar.h> + +#define TMR_IRQ_EN_REG 0x00 +#define TMR_IRQ_EN(n) __BIT(n) +#define TMR_IRQ_STAS_REG 0x04 +#define TMR_IRQ_STAS_PEND(n) __BIT(n) +#define TMR0_CTRL_REG 0x10 +#define TMR0_CTRL_MODE __BIT(7) +#define TMR0_CTRL_CLK_PRESCALE __BITS(6,4) +#define TMR0_CTRL_CLK_SRC __BITS(3,2) +#define TMR0_CTRL_CLK_SRC_OSC24M 1 +#define TMR0_CTRL_CLK_SRC_PLL6_6 2 +#define TMR0_CTRL_RELOAD __BIT(1) +#define TMR0_CTRL_EN __BIT(0) +#define TMR0_INTV_VALUE_REG 0x14 +#define TMR0_CURNT_VALUE_REG 0x18 + +static const char * const compatible[] = { + "allwinner,sun4i-a10-timer", + NULL +}; + +struct sunxi_timer_softc { + device_t sc_dev; + bus_space_tag_t sc_bst; + bus_space_handle_t sc_bsh; + int sc_phandle; + struct clk *sc_clk; + + struct timecounter sc_tc; +}; + +#define TIMER_READ(sc, reg) \ + bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg)) +#define TIMER_WRITE(sc, reg, val) \ + bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val)) + +static struct sunxi_timer_softc *timer_softc; + +static int +sunxi_timer_intr(void *arg) +{ + struct sunxi_timer_softc * const sc = timer_softc; + struct clockframe *frame = arg; + uint32_t stas; + + stas = TIMER_READ(sc, TMR_IRQ_STAS_REG); + if (stas == 0) + return 0; + TIMER_WRITE(sc, TMR_IRQ_STAS_REG, stas); + + if ((stas & TMR_IRQ_STAS_PEND(0)) != 0) + hardclock(frame); + + return 1; +} + +static void +sunxi_timer_cpu_initclocks(void) +{ + struct sunxi_timer_softc * const sc = timer_softc; + char intrstr[128]; + void *ih; + + KASSERT(sc != NULL); + + if (!fdtbus_intr_str(sc->sc_phandle, 0, intrstr, sizeof(intrstr))) + panic("%s: failed to decode interrupt", __func__); + + ih = fdtbus_intr_establish(sc->sc_phandle, 0, IPL_CLOCK, + FDT_INTR_MPSAFE, sunxi_timer_intr, NULL); + if (ih == NULL) + panic("%s: failed to establish timer interrupt", __func__); + + aprint_normal_dev(sc->sc_dev, "interrupting on %s\n", intrstr); + + /* Enable Timer 0 IRQ */ + const uint32_t irq_en = TIMER_READ(sc, TMR_IRQ_EN_REG); + TIMER_WRITE(sc, TMR_IRQ_EN_REG, irq_en | TMR_IRQ_EN(0)); +} + +static u_int +sunxi_timer_get_timecount(struct timecounter *tc) +{ + struct sunxi_timer_softc * const sc = tc->tc_priv; + + return ~TIMER_READ(sc, TMR0_CURNT_VALUE_REG); +} + +static int +sunxi_timer_match(device_t parent, cfdata_t cf, void *aux) +{ + struct fdt_attach_args * const faa = aux; + + return of_match_compatible(faa->faa_phandle, compatible); +} + +static void +sunxi_timer_attach(device_t parent, device_t self, void *aux) +{ + struct sunxi_timer_softc * const sc = device_private(self); + struct fdt_attach_args * const faa = aux; + struct timecounter *tc = &sc->sc_tc; + const int phandle = faa->faa_phandle; + bus_addr_t addr; + bus_size_t size; + + if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) { + aprint_error(": couldn't get registers\n"); + return; + } + + if ((sc->sc_clk = fdtbus_clock_get_index(phandle, 0)) == NULL) { + aprint_error(": couldn't get clock\n"); + return; + } + + sc->sc_dev = self; + sc->sc_phandle = phandle; + sc->sc_bst = faa->faa_bst; + if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) { + aprint_error(": couldn't map registers\n"); + return; + } + + aprint_naive("\n"); + aprint_normal(": Timer\n"); + + const u_int rate = clk_get_rate(sc->sc_clk); + + /* Disable IRQs and all timers */ + TIMER_WRITE(sc, TMR_IRQ_EN_REG, 0); + TIMER_WRITE(sc, TMR_IRQ_STAS_REG, TIMER_READ(sc, TMR_IRQ_STAS_REG)); + /* Enable Timer 0 */ + TIMER_WRITE(sc, TMR0_INTV_VALUE_REG, rate / hz); + TIMER_WRITE(sc, TMR0_CTRL_REG, + __SHIFTIN(TMR0_CTRL_CLK_SRC_OSC24M, TMR0_CTRL_CLK_SRC) | + TMR0_CTRL_RELOAD | TMR0_CTRL_EN); + + /* Timecounter setup */ + tc->tc_get_timecount = sunxi_timer_get_timecount; + tc->tc_counter_mask = ~0u, + tc->tc_frequency = clk_get_rate(sc->sc_clk); + tc->tc_name = device_xname(self); + tc->tc_quality = 100; + tc->tc_priv = sc; + tc_init(tc); + + /* Use this as the OS timer in UP configurations */ + if (!arm_has_mpext_p) { + timer_softc = sc; + arm_fdt_timer_register(sunxi_timer_cpu_initclocks); + } +} + +CFATTACH_DECL_NEW(sunxi_timer, sizeof(struct sunxi_timer_softc), + sunxi_timer_match, sunxi_timer_attach, NULL, NULL);