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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
@@ -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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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 <[email protected]>
+ * 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);