Module Name:    src
Committed By:   jmcneill
Date:           Wed Jun 28 23:51:29 UTC 2017

Added Files:
        src/sys/arch/arm/sunxi: files.sunxi sun8i_h3_ccu.c sun8i_h3_ccu.h
            sunxi_ccu.c sunxi_ccu.h sunxi_ccu_gate.c sunxi_ccu_nm.c sunxi_com.c
            sunxi_platform.c sunxi_platform.h
        src/sys/arch/evbarm/conf: SUNXI files.sunxi mk.sunxi std.sunxi
        src/sys/arch/evbarm/sunxi: genassym.cf sunxi_start.S

Log Message:
Add initial support for Allwinner H3 SoC.


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/sunxi/files.sunxi \
    src/sys/arch/arm/sunxi/sun8i_h3_ccu.c \
    src/sys/arch/arm/sunxi/sun8i_h3_ccu.h src/sys/arch/arm/sunxi/sunxi_ccu.c \
    src/sys/arch/arm/sunxi/sunxi_ccu.h \
    src/sys/arch/arm/sunxi/sunxi_ccu_gate.c \
    src/sys/arch/arm/sunxi/sunxi_ccu_nm.c src/sys/arch/arm/sunxi/sunxi_com.c \
    src/sys/arch/arm/sunxi/sunxi_platform.c \
    src/sys/arch/arm/sunxi/sunxi_platform.h
cvs rdiff -u -r0 -r1.1 src/sys/arch/evbarm/conf/SUNXI \
    src/sys/arch/evbarm/conf/files.sunxi src/sys/arch/evbarm/conf/mk.sunxi \
    src/sys/arch/evbarm/conf/std.sunxi
cvs rdiff -u -r0 -r1.1 src/sys/arch/evbarm/sunxi/genassym.cf \
    src/sys/arch/evbarm/sunxi/sunxi_start.S

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Added files:

Index: src/sys/arch/arm/sunxi/files.sunxi
diff -u /dev/null src/sys/arch/arm/sunxi/files.sunxi:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/arm/sunxi/files.sunxi	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,37 @@
+#	$NetBSD: files.sunxi,v 1.1 2017/06/28 23:51:29 jmcneill Exp $
+#
+# Configuration info for Allwinner sunxi family SoCs
+#
+#
+
+include	"arch/arm/pic/files.pic"
+include	"arch/arm/cortex/files.cortex"
+
+file	arch/arm/arm32/arm32_boot.c
+file	arch/arm/arm32/arm32_kvminit.c
+file	arch/arm/arm32/arm32_reboot.c
+file	arch/arm/arm32/irq_dispatch.S
+file	arch/arm/arm32/armv7_generic_space.c
+file	arch/arm/arm32/armv7_generic_dma.c
+file	arch/arm/arm/bus_space_a4x.S
+
+file	arch/arm/sunxi/sunxi_platform.c		soc_sunxi
+
+# CCU
+define	sunxi_ccu
+file	arch/arm/sunxi/sunxi_ccu.c		sunxi_ccu
+file	arch/arm/sunxi/sunxi_ccu_gate.c		sunxi_ccu
+file	arch/arm/sunxi/sunxi_ccu_nm.c		sunxi_ccu
+
+device	sun8ih3ccu: sunxi_ccu
+attach	sun8ih3ccu at fdt with sunxi_h3_ccu
+file	arch/arm/sunxi/sun8i_h3_ccu.c		sunxi_h3_ccu
+
+# UART
+attach	com at fdt with sunxi_com
+file	arch/arm/sunxi/sunxi_com.c		sunxi_com needs-flag
+
+# SOC parameters
+defflag	opt_soc.h			SOC_SUNXI
+defflag	opt_soc.h			SOC_SUN8I: SOC_SUNXI
+defflag	opt_soc.h			SOC_SUN8I_H3: SOC_SUN8I
Index: src/sys/arch/arm/sunxi/sun8i_h3_ccu.c
diff -u /dev/null src/sys/arch/arm/sunxi/sun8i_h3_ccu.c:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/arm/sunxi/sun8i_h3_ccu.c	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,171 @@
+/* $NetBSD: sun8i_h3_ccu.c,v 1.1 2017/06/28 23:51:29 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2017 Jared McNeill <jmcne...@invisible.ca>
+ * Copyright (c) 2017 Emmanuel Vadot <m...@freebsd.org>
+ * 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: sun8i_h3_ccu.c,v 1.1 2017/06/28 23:51:29 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/sun8i_h3_ccu.h>
+
+#define	USBPHY_CFG_REG		0x0cc
+#define	MBUS_RST_REG		0x0fc
+#define	BUS_SOFT_RST_REG0	0x2c0
+#define	BUS_SOFT_RST_REG1	0x2c4
+#define	BUS_SOFT_RST_REG2	0x2c8
+#define	BUS_SOFT_RST_REG3	0x2d0
+#define	BUS_SOFT_RST_REG4	0x2d8
+
+#define	APB2_CFG_REG		0x058
+#define	BUS_CLK_GATING_REG3	0x06c
+
+static int sun8i_h3_ccu_match(device_t, cfdata_t, void *);
+static void sun8i_h3_ccu_attach(device_t, device_t, void *);
+
+static const char * const compatible[] = {
+	"allwinner,sun8i-h3-ccu",
+	NULL
+};
+
+CFATTACH_DECL_NEW(sunxi_h3_ccu, sizeof(struct sunxi_ccu_softc),
+	sun8i_h3_ccu_match, sun8i_h3_ccu_attach, NULL, NULL);
+
+static struct sunxi_ccu_reset sun8i_h3_ccu_resets[] = {
+	SUNXI_CCU_RESET(H3_RST_USB_PHY0, USBPHY_CFG_REG, 0),
+	SUNXI_CCU_RESET(H3_RST_USB_PHY1, USBPHY_CFG_REG, 1),
+	SUNXI_CCU_RESET(H3_RST_USB_PHY2, USBPHY_CFG_REG, 2),
+	SUNXI_CCU_RESET(H3_RST_USB_PHY3, USBPHY_CFG_REG, 3),
+
+	SUNXI_CCU_RESET(H3_RST_MBUS, MBUS_RST_REG, 31),
+
+	SUNXI_CCU_RESET(H3_RST_BUS_CE, BUS_SOFT_RST_REG0, 5),
+	SUNXI_CCU_RESET(H3_RST_BUS_DMA, BUS_SOFT_RST_REG0, 6),
+	SUNXI_CCU_RESET(H3_RST_BUS_MMC0, BUS_SOFT_RST_REG0, 8),
+	SUNXI_CCU_RESET(H3_RST_BUS_MMC1, BUS_SOFT_RST_REG0, 9),
+	SUNXI_CCU_RESET(H3_RST_BUS_MMC2, BUS_SOFT_RST_REG0, 10),
+	SUNXI_CCU_RESET(H3_RST_BUS_NAND, BUS_SOFT_RST_REG0, 13),
+	SUNXI_CCU_RESET(H3_RST_BUS_DRAM, BUS_SOFT_RST_REG0, 14),
+	SUNXI_CCU_RESET(H3_RST_BUS_EMAC, BUS_SOFT_RST_REG0, 17),
+	SUNXI_CCU_RESET(H3_RST_BUS_TS, BUS_SOFT_RST_REG0, 18),
+	SUNXI_CCU_RESET(H3_RST_BUS_HSTIMER, BUS_SOFT_RST_REG0, 19),
+	SUNXI_CCU_RESET(H3_RST_BUS_SPI0, BUS_SOFT_RST_REG0, 20),
+	SUNXI_CCU_RESET(H3_RST_BUS_SPI1, BUS_SOFT_RST_REG0, 21),
+	SUNXI_CCU_RESET(H3_RST_BUS_OTG, BUS_SOFT_RST_REG0, 23),
+	SUNXI_CCU_RESET(H3_RST_BUS_EHCI0, BUS_SOFT_RST_REG0, 24),
+	SUNXI_CCU_RESET(H3_RST_BUS_EHCI1, BUS_SOFT_RST_REG0, 25),
+	SUNXI_CCU_RESET(H3_RST_BUS_EHCI2, BUS_SOFT_RST_REG0, 26),
+	SUNXI_CCU_RESET(H3_RST_BUS_EHCI3, BUS_SOFT_RST_REG0, 27),
+	SUNXI_CCU_RESET(H3_RST_BUS_OHCI0, BUS_SOFT_RST_REG0, 28),
+	SUNXI_CCU_RESET(H3_RST_BUS_OHCI1, BUS_SOFT_RST_REG0, 29),
+	SUNXI_CCU_RESET(H3_RST_BUS_OHCI2, BUS_SOFT_RST_REG0, 30),
+	SUNXI_CCU_RESET(H3_RST_BUS_OHCI3, BUS_SOFT_RST_REG0, 31),
+        
+	SUNXI_CCU_RESET(H3_RST_BUS_VE, BUS_SOFT_RST_REG1, 0),
+	SUNXI_CCU_RESET(H3_RST_BUS_TCON0, BUS_SOFT_RST_REG1, 3),
+	SUNXI_CCU_RESET(H3_RST_BUS_TCON1, BUS_SOFT_RST_REG1, 4),
+	SUNXI_CCU_RESET(H3_RST_BUS_DEINTERLACE, BUS_SOFT_RST_REG1, 5),
+	SUNXI_CCU_RESET(H3_RST_BUS_CSI, BUS_SOFT_RST_REG1, 8),
+	SUNXI_CCU_RESET(H3_RST_BUS_TVE, BUS_SOFT_RST_REG1, 9),
+	SUNXI_CCU_RESET(H3_RST_BUS_HDMI0, BUS_SOFT_RST_REG1, 10),
+	SUNXI_CCU_RESET(H3_RST_BUS_HDMI1, BUS_SOFT_RST_REG1, 11),
+	SUNXI_CCU_RESET(H3_RST_BUS_DE, BUS_SOFT_RST_REG1, 12),
+	SUNXI_CCU_RESET(H3_RST_BUS_GPU, BUS_SOFT_RST_REG1, 20),
+	SUNXI_CCU_RESET(H3_RST_BUS_MSGBOX, BUS_SOFT_RST_REG1, 21),
+	SUNXI_CCU_RESET(H3_RST_BUS_SPINLOCK, BUS_SOFT_RST_REG1, 22),
+	SUNXI_CCU_RESET(H3_RST_BUS_DBG, BUS_SOFT_RST_REG1, 31),
+
+	SUNXI_CCU_RESET(H3_RST_BUS_EPHY, BUS_SOFT_RST_REG2, 2),
+
+	SUNXI_CCU_RESET(H3_RST_BUS_CODEC, BUS_SOFT_RST_REG3, 0),
+	SUNXI_CCU_RESET(H3_RST_BUS_SPDIF, BUS_SOFT_RST_REG3, 1),
+	SUNXI_CCU_RESET(H3_RST_BUS_THS, BUS_SOFT_RST_REG3, 8),
+	SUNXI_CCU_RESET(H3_RST_BUS_I2S0, BUS_SOFT_RST_REG3, 12),
+	SUNXI_CCU_RESET(H3_RST_BUS_I2S1, BUS_SOFT_RST_REG3, 13),
+	SUNXI_CCU_RESET(H3_RST_BUS_I2S2, BUS_SOFT_RST_REG3, 14),
+
+	SUNXI_CCU_RESET(H3_RST_BUS_I2C0, BUS_SOFT_RST_REG4, 0),
+	SUNXI_CCU_RESET(H3_RST_BUS_I2C1, BUS_SOFT_RST_REG4, 1),
+	SUNXI_CCU_RESET(H3_RST_BUS_I2C2, BUS_SOFT_RST_REG4, 2),
+	SUNXI_CCU_RESET(H3_RST_BUS_UART0, BUS_SOFT_RST_REG4, 16),
+	SUNXI_CCU_RESET(H3_RST_BUS_UART1, BUS_SOFT_RST_REG4, 17),
+	SUNXI_CCU_RESET(H3_RST_BUS_UART2, BUS_SOFT_RST_REG4, 18),
+	SUNXI_CCU_RESET(H3_RST_BUS_UART3, BUS_SOFT_RST_REG4, 19),
+	SUNXI_CCU_RESET(H3_RST_BUS_SCR, BUS_SOFT_RST_REG4, 20),
+};
+
+static const char *apb2_parents[] = { "losc", "hosc", "pll_periph0" };
+
+static struct sunxi_ccu_clk sun8i_h3_ccu_clks[] = {
+	SUNXI_CCU_NM(H3_CLK_APB2, "apb2", apb2_parents,
+	    APB2_CFG_REG, __BITS(17,16), __BITS(4,0), __BITS(25,24),
+	    SUNXI_CCU_NM_POWER_OF_TWO),
+
+	SUNXI_CCU_GATE(H3_CLK_BUS_UART0, "bus-uart0", "apb2",
+	    BUS_CLK_GATING_REG3, 19),
+};
+
+static int
+sun8i_h3_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
+sun8i_h3_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 = sun8i_h3_ccu_resets;
+	sc->sc_nresets = __arraycount(sun8i_h3_ccu_resets);
+
+	sc->sc_clks = sun8i_h3_ccu_clks;
+	sc->sc_nclks = __arraycount(sun8i_h3_ccu_clks);
+
+	if (sunxi_ccu_attach(sc) != 0)
+		return;
+
+	aprint_naive("\n");
+	aprint_normal(": H3 CCU\n");
+
+	sunxi_ccu_print(sc);
+}
Index: src/sys/arch/arm/sunxi/sun8i_h3_ccu.h
diff -u /dev/null src/sys/arch/arm/sunxi/sun8i_h3_ccu.h:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/arm/sunxi/sun8i_h3_ccu.h	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,205 @@
+/* $NetBSD: sun8i_h3_ccu.h,v 1.1 2017/06/28 23:51:29 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2017 Emmanuel Vadot <m...@freebsd.org>
+ * 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$
+ */
+
+#ifndef __CCU_H3_H__
+#define __CCU_H3_H__
+
+#define	H3_RST_USB_PHY0		0
+#define	H3_RST_USB_PHY1		1
+#define	H3_RST_USB_PHY2		2
+#define	H3_RST_USB_PHY3		3
+#define	H3_RST_MBUS		4
+#define	H3_RST_BUS_CE		5
+#define	H3_RST_BUS_DMA		6
+#define	H3_RST_BUS_MMC0		7
+#define	H3_RST_BUS_MMC1		8
+#define	H3_RST_BUS_MMC2		9
+#define	H3_RST_BUS_NAND		10
+#define	H3_RST_BUS_DRAM		11
+#define	H3_RST_BUS_EMAC		12
+#define	H3_RST_BUS_TS		13
+#define	H3_RST_BUS_HSTIMER	14
+#define	H3_RST_BUS_SPI0		15
+#define	H3_RST_BUS_SPI1		16
+#define	H3_RST_BUS_OTG		17
+#define	H3_RST_BUS_EHCI0	18
+#define	H3_RST_BUS_EHCI1	19
+#define	H3_RST_BUS_EHCI2	20
+#define	H3_RST_BUS_EHCI3	21
+#define	H3_RST_BUS_OHCI0	22
+#define	H3_RST_BUS_OHCI1	23
+#define	H3_RST_BUS_OHCI2	24
+#define	H3_RST_BUS_OHCI3	25
+#define	H3_RST_BUS_VE		26
+#define	H3_RST_BUS_TCON0	27
+#define	H3_RST_BUS_TCON1	28
+#define	H3_RST_BUS_DEINTERLACE	29
+#define	H3_RST_BUS_CSI		30
+#define	H3_RST_BUS_TVE		31
+#define	H3_RST_BUS_HDMI0	32
+#define	H3_RST_BUS_HDMI1	33
+#define	H3_RST_BUS_DE		34
+#define	H3_RST_BUS_GPU		35
+#define	H3_RST_BUS_MSGBOX	36
+#define	H3_RST_BUS_SPINLOCK	37
+#define	H3_RST_BUS_DBG		38
+#define	H3_RST_BUS_EPHY		39
+#define	H3_RST_BUS_CODEC	40
+#define	H3_RST_BUS_SPDIF	41
+#define	H3_RST_BUS_THS		42
+#define	H3_RST_BUS_I2S0		43
+#define	H3_RST_BUS_I2S1		44
+#define	H3_RST_BUS_I2S2		45
+#define	H3_RST_BUS_I2C0		46
+#define	H3_RST_BUS_I2C1		47
+#define	H3_RST_BUS_I2C2		48
+#define	H3_RST_BUS_UART0	49
+#define	H3_RST_BUS_UART1	50
+#define	H3_RST_BUS_UART2	51
+#define	H3_RST_BUS_UART3	52
+#define	H3_RST_BUS_SCR		53
+
+#define	H3_CLK_PLL_CPUX		0
+#define	H3_CLK_PLL_AUDIO_BASE	1
+#define	H3_CLK_PLL_AUDIO	2
+#define	H3_CLK_PLL_AUDIO_2X	3
+#define	H3_CLK_PLL_AUDIO_4X	4
+#define	H3_CLK_PLL_AUDIO_8X	5
+#define	H3_CLK_PLL_VIDEO	6
+#define	H3_CLK_PLL_VE		7
+#define	H3_CLK_PLL_DDR		8
+#define	H3_CLK_PLL_PERIPH0	9
+#define	H3_CLK_PLL_PERIPH0_2X	10
+#define	H3_CLK_PLL_GPU		11
+#define	H3_CLK_PLL_PERIPH1	12
+#define	H3_CLK_PLL_DE		13
+#define	H3_CLK_CPUX		14
+#define	H3_CLK_AXI		15
+#define	H3_CLK_AHB1		16
+#define	H3_CLK_APB1		17
+#define	H3_CLK_APB2		18
+#define	H3_CLK_AHB2		19
+#define	H3_CLK_BUS_CE		20
+#define	H3_CLK_BUS_DMA		21
+#define	H3_CLK_BUS_MMC0		22
+#define	H3_CLK_BUS_MMC1		23
+#define	H3_CLK_BUS_MMC2		24
+#define	H3_CLK_BUS_NAND		25
+#define	H3_CLK_BUS_DRAM		26
+#define	H3_CLK_BUS_EMAC		27
+#define	H3_CLK_BUS_TS		28
+#define	H3_CLK_BUS_HSTIMER	29
+#define	H3_CLK_BUS_SPI0		30
+#define	H3_CLK_BUS_SPI1		31
+#define	H3_CLK_BUS_OTG		32
+#define	H3_CLK_BUS_EHCI0	33
+#define	H3_CLK_BUS_EHCI1	34
+#define	H3_CLK_BUS_EHCI2	35
+#define	H3_CLK_BUS_EHCI3	36
+#define	H3_CLK_BUS_OHCI0	37
+#define	H3_CLK_BUS_OHCI1	38
+#define	H3_CLK_BUS_OHCI2	39
+#define	H3_CLK_BUS_OHCI3	40
+#define	H3_CLK_BUS_VE		41
+#define	H3_CLK_BUS_TCON0	42
+#define	H3_CLK_BUS_TCON1	43
+#define	H3_CLK_BUS_DEINTERLACE	44
+#define	H3_CLK_BUS_CSI		45
+#define	H3_CLK_BUS_TVE		46
+#define	H3_CLK_BUS_HDMI		47
+#define	H3_CLK_BUS_DE		48
+#define	H3_CLK_BUS_GPU		49
+#define	H3_CLK_BUS_MSGBOX	50
+#define	H3_CLK_BUS_SPINLOCK	51
+#define	H3_CLK_BUS_CODEC	52
+#define	H3_CLK_BUS_SPDIF	53
+#define	H3_CLK_BUS_PIO		54
+#define	H3_CLK_BUS_THS		55
+#define	H3_CLK_BUS_I2S0		56
+#define	H3_CLK_BUS_I2S1		57
+#define	H3_CLK_BUS_I2S2		58
+#define	H3_CLK_BUS_I2C0		59
+#define	H3_CLK_BUS_I2C1		60
+#define	H3_CLK_BUS_I2C2		61
+#define	H3_CLK_BUS_UART0	62
+#define	H3_CLK_BUS_UART1	63
+#define	H3_CLK_BUS_UART2	64
+#define	H3_CLK_BUS_UART3	65
+#define	H3_CLK_BUS_SCR		66
+#define	H3_CLK_BUS_EPHY		67
+#define	H3_CLK_BUS_DBG		68
+#define	H3_CLK_THS		69
+#define	H3_CLK_NAND		70
+#define	H3_CLK_MMC0		71
+#define	H3_CLK_MMC0_SAMPLE	72
+#define	H3_CLK_MMC0_OUTPUT	73
+#define	H3_CLK_MMC1		74
+#define	H3_CLK_MMC1_SAMPLE	75
+#define	H3_CLK_MMC1_OUTPUT	76
+#define	H3_CLK_MMC2		77
+#define	H3_CLK_MMC2_SAMPLE	78
+#define	H3_CLK_MMC2_OUTPUT	79
+#define	H3_CLK_TS		80
+#define	H3_CLK_CE		81
+#define	H3_CLK_SPI0		82
+#define	H3_CLK_SPI1		83
+#define	H3_CLK_I2S0		84
+#define	H3_CLK_I2S1		85
+#define	H3_CLK_I2S2		86
+#define	H3_CLK_SPDIF		87
+#define	H3_CLK_USBPHY0		88
+#define	H3_CLK_USBPHY1		89
+#define	H3_CLK_USBPHY2		90
+#define	H3_CLK_USBPHY3		91
+#define	H3_CLK_USBOHCI0		92
+#define	H3_CLK_USBOHCI1		93
+#define	H3_CLK_USBOHCI2		94
+#define	H3_CLK_USBOHCI3		95
+#define	H3_CLK_DRAM		96
+#define	H3_CLK_DRAM_VE		97
+#define	H3_CLK_DRAM_CSI		98
+#define	H3_CLK_DRAM_DEINTERLACE	99
+#define	H3_CLK_DRAM_TS		100
+#define	H3_CLK_DE		101
+#define	H3_CLK_TCON0		102
+#define	H3_CLK_TVE		103
+#define	H3_CLK_DEINTERLACE	104
+#define	H3_CLK_CSI_MISC		105
+#define	H3_CLK_CSI_SCLK		106
+#define	H3_CLK_CSI_MCLK		107
+#define	H3_CLK_VE		108
+#define	H3_CLK_AC_DIG		109
+#define	H3_CLK_AVS		110
+#define	H3_CLK_HDMI		111
+#define	H3_CLK_HDMI_DDC		112
+#define	H3_CLK_MBUS		113
+#define	H3_CLK_GPU		114
+
+#endif /* __CCU_H3_H__ */
Index: src/sys/arch/arm/sunxi/sunxi_ccu.c
diff -u /dev/null src/sys/arch/arm/sunxi/sunxi_ccu.c:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/arm/sunxi/sunxi_ccu.c	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,338 @@
+/* $NetBSD: sunxi_ccu.c,v 1.1 2017/06/28 23:51:29 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 "opt_soc.h"
+#include "opt_multiprocessor.h"
+#include "opt_fdt_arm.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu.c,v 1.1 2017/06/28 23:51:29 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/device.h>
+
+#include <dev/fdt/fdtvar.h>
+
+#include <dev/clk/clk_backend.h>
+
+#include <arm/sunxi/sunxi_ccu.h>
+
+static void *
+sunxi_ccu_reset_acquire(device_t dev, const void *data, size_t len)
+{
+	struct sunxi_ccu_softc * const sc = device_private(dev);
+	struct sunxi_ccu_reset *reset;
+
+	if (len != 4)
+		return NULL;
+
+	const u_int reset_id = be32dec(data);
+
+	if (reset_id >= sc->sc_nresets)
+		return NULL;
+
+	reset = &sc->sc_resets[reset_id];
+	if (reset->mask == 0)
+		return NULL;
+
+	return reset;
+}
+
+static void
+sunxi_ccu_reset_release(device_t dev, void *priv)
+{
+}
+
+static int
+sunxi_ccu_reset_assert(device_t dev, void *priv)
+{
+	struct sunxi_ccu_softc * const sc = device_private(dev);
+	struct sunxi_ccu_reset * const reset = priv;
+
+	const uint32_t val = CCU_READ(sc, reset->reg);
+	CCU_WRITE(sc, reset->reg, val & ~reset->mask);
+
+	return 0;
+}
+
+static int
+sunxi_ccu_reset_deassert(device_t dev, void *priv)
+{
+	struct sunxi_ccu_softc * const sc = device_private(dev);
+	struct sunxi_ccu_reset * const reset = priv;
+
+	const uint32_t val = CCU_READ(sc, reset->reg);
+	CCU_WRITE(sc, reset->reg, val | reset->mask);
+
+	return 0;
+}
+
+static const struct fdtbus_reset_controller_func sunxi_ccu_fdtreset_funcs = {
+	.acquire = sunxi_ccu_reset_acquire,
+	.release = sunxi_ccu_reset_release,
+	.reset_assert = sunxi_ccu_reset_assert,
+	.reset_deassert = sunxi_ccu_reset_deassert,
+};
+
+static struct clk *
+sunxi_ccu_clock_decode(device_t dev, const void *data, size_t len)
+{
+	struct sunxi_ccu_softc * const sc = device_private(dev);
+	struct sunxi_ccu_clk *clk;
+
+	if (len != 4)
+		return NULL;
+
+	const u_int clock_id = be32dec(data);
+	if (clock_id >= sc->sc_nclks)
+		return NULL;
+
+	clk = &sc->sc_clks[clock_id];
+	if (clk->type == SUNXI_CCU_UNKNOWN)
+		return NULL;
+
+	return &clk->base;
+}
+
+static const struct fdtbus_clock_controller_func sunxi_ccu_fdtclock_funcs = {
+	.decode = sunxi_ccu_clock_decode,
+};
+
+static struct clk *
+sunxi_ccu_clock_get(void *priv, const char *name)
+{
+	struct sunxi_ccu_softc * const sc = priv;
+	struct sunxi_ccu_clk *clk;
+
+	clk = sunxi_ccu_clock_find(sc, name);
+	if (clk == NULL)
+		return NULL;
+
+	return &clk->base;
+}
+
+static void
+sunxi_ccu_clock_put(void *priv, struct clk *clk)
+{
+}
+
+static u_int
+sunxi_ccu_clock_get_rate(void *priv, struct clk *clkp)
+{
+	struct sunxi_ccu_softc * const sc = priv;
+	struct sunxi_ccu_clk *clk = (struct sunxi_ccu_clk *)clkp;
+	struct clk *clkp_parent;
+
+	if (clk->get_rate)
+		return clk->get_rate(sc, clk);
+
+	clkp_parent = clk_get_parent(clkp);
+	if (clkp_parent == NULL) {
+		aprint_error("%s: no parent for %s\n", __func__, clk->base.name);
+		return 0;
+	}
+
+	return clk_get_rate(clkp_parent);
+}
+
+static int
+sunxi_ccu_clock_set_rate(void *priv, struct clk *clkp, u_int rate)
+{
+	struct sunxi_ccu_softc * const sc = priv;
+	struct sunxi_ccu_clk *clk = (struct sunxi_ccu_clk *)clkp;
+	struct clk *clkp_parent;
+
+	if (clkp->flags & CLK_SET_RATE_PARENT) {
+		clkp_parent = clk_get_parent(clkp);
+		if (clkp_parent == NULL) {
+			aprint_error("%s: no parent for %s\n", __func__, clk->base.name);
+			return ENXIO;
+		}
+		return clk_set_rate(clkp_parent, rate);
+	}
+
+	if (clk->set_rate)
+		return clk->set_rate(sc, clk, rate);
+
+	return ENXIO;
+}
+
+static int
+sunxi_ccu_clock_enable(void *priv, struct clk *clkp)
+{
+	struct sunxi_ccu_softc * const sc = priv;
+	struct sunxi_ccu_clk *clk = (struct sunxi_ccu_clk *)clkp;
+	struct clk *clkp_parent;
+	int error = 0;
+
+	clkp_parent = clk_get_parent(clkp);
+	if (clkp_parent != NULL) {
+		error = clk_enable(clkp_parent);
+		if (error != 0)
+			return error;
+	}
+
+	if (clk->enable)
+		error = clk->enable(sc, clk, 1);
+
+	return error;
+}
+
+static int
+sunxi_ccu_clock_disable(void *priv, struct clk *clkp)
+{
+	struct sunxi_ccu_softc * const sc = priv;
+	struct sunxi_ccu_clk *clk = (struct sunxi_ccu_clk *)clkp;
+	int error = EINVAL;
+
+	if (clk->enable)
+		error = clk->enable(sc, clk, 0);
+
+	return error;
+}
+
+static int
+sunxi_ccu_clock_set_parent(void *priv, struct clk *clkp,
+    struct clk *clkp_parent)
+{
+	struct sunxi_ccu_softc * const sc = priv;
+	struct sunxi_ccu_clk *clk = (struct sunxi_ccu_clk *)clkp;
+
+	if (clk->set_parent == NULL)
+		return EINVAL;
+
+	return clk->set_parent(sc, clk, clkp_parent->name);
+}
+
+static struct clk *
+sunxi_ccu_clock_get_parent(void *priv, struct clk *clkp)
+{
+	struct sunxi_ccu_softc * const sc = priv;
+	struct sunxi_ccu_clk *clk = (struct sunxi_ccu_clk *)clkp;
+	struct sunxi_ccu_clk *clk_parent;
+	const char *parent;
+
+	if (clk->get_parent == NULL)
+		return NULL;
+
+	parent = clk->get_parent(sc, clk);
+	if (parent == NULL)
+		return NULL;
+
+	clk_parent = sunxi_ccu_clock_find(sc, parent);
+	if (clk_parent != NULL)
+		return &clk_parent->base;
+
+	/* No parent in this domain, try FDT */
+	return fdtbus_clock_get(sc->sc_phandle, parent);
+}
+
+static const struct clk_funcs sunxi_ccu_clock_funcs = {
+	.get = sunxi_ccu_clock_get,
+	.put = sunxi_ccu_clock_put,
+	.get_rate = sunxi_ccu_clock_get_rate,
+	.set_rate = sunxi_ccu_clock_set_rate,
+	.enable = sunxi_ccu_clock_enable,
+	.disable = sunxi_ccu_clock_disable,
+	.set_parent = sunxi_ccu_clock_set_parent,
+	.get_parent = sunxi_ccu_clock_get_parent,
+};
+
+struct sunxi_ccu_clk *
+sunxi_ccu_clock_find(struct sunxi_ccu_softc *sc, const char *name)
+{
+	for (int i = 0; i < sc->sc_nclks; i++) {
+		if (sc->sc_clks[i].base.name == NULL)
+			continue;
+		if (strcmp(sc->sc_clks[i].base.name, name) == 0)
+			return &sc->sc_clks[i];
+	}
+
+	return NULL;
+}
+
+int
+sunxi_ccu_attach(struct sunxi_ccu_softc *sc)
+{
+	bus_addr_t addr;
+	bus_size_t size;
+	int i;
+
+	if (fdtbus_get_reg(sc->sc_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return ENXIO;
+	}
+	if (bus_space_map(sc->sc_bst, addr, size, 0, &sc->sc_bsh) != 0) {
+		aprint_error(": couldn't map registers\n");
+		return ENXIO;
+	}
+
+	sc->sc_clkdom.funcs = &sunxi_ccu_clock_funcs;
+	sc->sc_clkdom.priv = sc;
+	for (i = 0; i < sc->sc_nclks; i++)
+		sc->sc_clks[i].base.domain = &sc->sc_clkdom;
+
+	fdtbus_register_clock_controller(sc->sc_dev, sc->sc_phandle,
+	    &sunxi_ccu_fdtclock_funcs);
+
+	fdtbus_register_reset_controller(sc->sc_dev, sc->sc_phandle,
+	    &sunxi_ccu_fdtreset_funcs);
+
+	return 0;
+}
+
+void
+sunxi_ccu_print(struct sunxi_ccu_softc *sc)
+{
+	struct sunxi_ccu_clk *clk;
+	struct clk *clkp_parent;
+	const char *type;
+	int i;
+
+	for (i = 0; i < sc->sc_nclks; i++) {
+		clk = &sc->sc_clks[i];
+		if (clk->type == SUNXI_CCU_UNKNOWN)
+			continue;
+
+		clkp_parent = clk_get_parent(&clk->base);
+
+		switch (clk->type) {
+		case SUNXI_CCU_GATE:	type = "gate"; break;
+		case SUNXI_CCU_NM:	type = "nm"; break;
+		default:		type = "???"; break;
+		}
+
+        	printf("  %-10s %2s %-10s %-5s %10d Hz\n",
+        	    clk->base.name,
+        	    clkp_parent ? "<-" : "",
+        	    clkp_parent ? clkp_parent->name : "",
+        	    type, clk_get_rate(&clk->base));
+	}
+}
Index: src/sys/arch/arm/sunxi/sunxi_ccu.h
diff -u /dev/null src/sys/arch/arm/sunxi/sunxi_ccu.h:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/arm/sunxi/sunxi_ccu.h	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,168 @@
+/* $NetBSD: sunxi_ccu.h,v 1.1 2017/06/28 23:51:29 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 _ARM_SUNXI_CCU_H
+#define _ARM_SUNXI_CCU_H
+
+#include <dev/clk/clk_backend.h>
+
+struct sunxi_ccu_softc;
+struct sunxi_ccu_clk;
+struct sunxi_ccu_reset;
+
+/*
+ * Resets
+ */
+
+struct sunxi_ccu_reset {
+	bus_size_t	reg;
+	uint32_t	mask;
+};
+
+#define	SUNXI_CCU_RESET(_id, _reg, _bit)	\
+	[_id] = {				\
+		.reg = (_reg),			\
+		.mask = __BIT(_bit),		\
+	}
+
+/*
+ * Clocks
+ */
+
+enum sunxi_ccu_clktype {
+	SUNXI_CCU_UNKNOWN,
+	SUNXI_CCU_GATE,
+	SUNXI_CCU_NM,
+};
+
+struct sunxi_ccu_gate {
+	bus_size_t	reg;
+	uint32_t	mask;
+	const char	*parent;
+};
+
+int	sunxi_ccu_gate_enable(struct sunxi_ccu_softc *,
+			      struct sunxi_ccu_clk *, int);
+const char *sunxi_ccu_gate_get_parent(struct sunxi_ccu_softc *,
+				      struct sunxi_ccu_clk *);
+
+#define	SUNXI_CCU_GATE(_id, _name, _pname, _reg, _bit)		\
+	[_id] = {						\
+		.type = SUNXI_CCU_GATE,				\
+		.base.name = (_name),				\
+		.u.gate.parent = (_pname),			\
+		.u.gate.reg = (_reg),				\
+		.u.gate.mask = __BIT(_bit),			\
+		.enable = sunxi_ccu_gate_enable,		\
+		.get_parent = sunxi_ccu_gate_get_parent,	\
+	}
+
+struct sunxi_ccu_nm {
+	bus_size_t	reg;
+	const char	**parents;
+	u_int		nparents;
+	uint32_t	n;
+	uint32_t	m;
+	uint32_t	sel;
+	uint32_t	flags;
+#define	SUNXI_CCU_NM_POWER_OF_TWO	__BIT(0)
+};
+
+u_int	sunxi_ccu_nm_get_rate(struct sunxi_ccu_softc *,
+			      struct sunxi_ccu_clk *);
+int	sunxi_ccu_nm_set_rate(struct sunxi_ccu_softc *,
+			      struct sunxi_ccu_clk *, u_int);
+int	sunxi_ccu_nm_set_parent(struct sunxi_ccu_softc *,
+				struct sunxi_ccu_clk *,
+				const char *);
+const char *sunxi_ccu_nm_get_parent(struct sunxi_ccu_softc *,
+				    struct sunxi_ccu_clk *);
+
+#define	SUNXI_CCU_NM(_id, _name, _parents, _reg, _n, _m, _sel,	\
+		     _flags)					\
+	[_id] = {						\
+		.type = SUNXI_CCU_NM,				\
+		.base.name = (_name),				\
+		.u.nm.reg = (_reg),				\
+		.u.nm.parents = (_parents),			\
+		.u.nm.nparents = __arraycount(_parents),	\
+		.u.nm.n = (_n),					\
+		.u.nm.m = (_m),					\
+		.u.nm.sel = (_sel),				\
+		.u.nm.flags = (_flags),				\
+		.set_parent = sunxi_ccu_nm_set_parent,		\
+		.get_parent = sunxi_ccu_nm_get_parent,		\
+	}
+
+struct sunxi_ccu_clk {
+	struct clk	base;
+	enum sunxi_ccu_clktype type;
+	union {
+		struct sunxi_ccu_gate gate;
+		struct sunxi_ccu_nm nm;
+	} u;
+
+	int		(*enable)(struct sunxi_ccu_softc *,
+				  struct sunxi_ccu_clk *, int);
+	u_int		(*get_rate)(struct sunxi_ccu_softc *,
+				    struct sunxi_ccu_clk *);
+	int		(*set_rate)(struct sunxi_ccu_softc *,
+				    struct sunxi_ccu_clk *, u_int);
+	const char *	(*get_parent)(struct sunxi_ccu_softc *,
+				      struct sunxi_ccu_clk *);
+	int		(*set_parent)(struct sunxi_ccu_softc *,
+				      struct sunxi_ccu_clk *,
+				      const char *);
+};
+
+struct sunxi_ccu_softc {
+	device_t		sc_dev;
+	int			sc_phandle;
+	bus_space_tag_t		sc_bst;
+	bus_space_handle_t	sc_bsh;
+
+	struct clk_domain	sc_clkdom;
+
+	struct sunxi_ccu_reset *sc_resets;
+	u_int			sc_nresets;
+
+	struct sunxi_ccu_clk	*sc_clks;
+	u_int			sc_nclks;
+};
+
+int	sunxi_ccu_attach(struct sunxi_ccu_softc *);
+struct sunxi_ccu_clk *sunxi_ccu_clock_find(struct sunxi_ccu_softc *,
+					   const char *);
+void	sunxi_ccu_print(struct sunxi_ccu_softc *);
+
+#define CCU_READ(sc, reg)	\
+	bus_space_read_4((sc)->sc_bst, (sc)->sc_bsh, (reg))
+#define CCU_WRITE(sc, reg, val)	\
+	bus_space_write_4((sc)->sc_bst, (sc)->sc_bsh, (reg), (val))
+
+#endif /* _ARM_SUNXI_CCU_H */
Index: src/sys/arch/arm/sunxi/sunxi_ccu_gate.c
diff -u /dev/null src/sys/arch/arm/sunxi/sunxi_ccu_gate.c:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/arm/sunxi/sunxi_ccu_gate.c	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,71 @@
+/* $NetBSD: sunxi_ccu_gate.c,v 1.1 2017/06/28 23:51:29 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_ccu_gate.c,v 1.1 2017/06/28 23:51:29 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+
+#include <dev/clk/clk_backend.h>
+
+#include <arm/sunxi/sunxi_ccu.h>
+
+int
+sunxi_ccu_gate_enable(struct sunxi_ccu_softc *sc, struct sunxi_ccu_clk *clk,
+    int enable)
+{
+	struct sunxi_ccu_gate *gate = &clk->u.gate;
+	uint32_t val;
+
+	KASSERT(clk->type == SUNXI_CCU_GATE);
+
+	val = CCU_READ(sc, gate->reg);
+	if (enable)
+		val |= gate->mask;
+	else
+		val &= ~gate->mask;
+	CCU_WRITE(sc, gate->reg, val);
+
+	return 0;
+}
+
+const char *
+sunxi_ccu_gate_get_parent(struct sunxi_ccu_softc *sc, struct sunxi_ccu_clk *clk)
+{
+	struct sunxi_ccu_gate *gate = &clk->u.gate;
+	struct sunxi_ccu_clk *clk_parent;
+
+	KASSERT(clk->type == SUNXI_CCU_GATE);
+
+	clk_parent = sunxi_ccu_clock_find(sc, gate->parent);
+	if (clk_parent == NULL)
+		return NULL;
+
+	return clk_parent->base.name;
+}
Index: src/sys/arch/arm/sunxi/sunxi_ccu_nm.c
diff -u /dev/null src/sys/arch/arm/sunxi/sunxi_ccu_nm.c:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/arm/sunxi/sunxi_ccu_nm.c	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,123 @@
+/* $NetBSD: sunxi_ccu_nm.c,v 1.1 2017/06/28 23:51:29 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_ccu_nm.c,v 1.1 2017/06/28 23:51:29 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+
+#include <dev/clk/clk_backend.h>
+
+#include <arm/sunxi/sunxi_ccu.h>
+
+u_int
+sunxi_ccu_nm_get_rate(struct sunxi_ccu_softc *sc,
+    struct sunxi_ccu_clk *clk)
+{
+	struct sunxi_ccu_nm *nm = &clk->u.nm;
+	struct clk *clkp, *clkp_parent;
+	u_int rate, n, m;
+	uint32_t val;
+
+	KASSERT(clk->type == SUNXI_CCU_NM);
+
+	clkp = &clk->base;
+	clkp_parent = clk_get_parent(clkp);
+	if (clkp_parent == NULL)
+		return 0;
+
+	rate = clk_get_rate(clkp_parent);
+	if (rate == 0)
+		return 0;
+
+	val = CCU_READ(sc, nm->reg);
+	n = __SHIFTOUT(val, nm->n);
+	m = __SHIFTOUT(val, nm->m);
+
+	if (nm->flags & SUNXI_CCU_NM_POWER_OF_TWO)
+		n <<= 1;
+	else
+		n++;
+
+	m++;
+
+	return rate / n / m;
+}
+
+int
+sunxi_ccu_nm_set_rate(struct sunxi_ccu_softc *sc,
+    struct sunxi_ccu_clk *clk, u_int rate)
+{
+	return EIO;
+}
+
+int
+sunxi_ccu_nm_set_parent(struct sunxi_ccu_softc *sc,
+    struct sunxi_ccu_clk *clk, const char *name)
+{
+	struct sunxi_ccu_nm *nm = &clk->u.nm;
+	uint32_t val;
+	u_int index;
+
+	KASSERT(clk->type == SUNXI_CCU_NM);
+
+	if (nm->sel == 0)
+		return ENODEV;
+
+	for (index = 0; index < nm->nparents; index++) {
+		if (nm->parents[index] != NULL &&
+		    strcmp(nm->parents[index], name) == 0)
+			break;
+	}
+	if (index == nm->nparents)
+		return EINVAL;
+
+	val = CCU_READ(sc, nm->reg);
+	val &= ~nm->sel;
+	val |= __SHIFTIN(index, nm->sel);
+	CCU_WRITE(sc, nm->reg, val);
+
+	return 0;
+}
+
+const char *
+sunxi_ccu_nm_get_parent(struct sunxi_ccu_softc *sc,
+    struct sunxi_ccu_clk *clk)
+{
+	struct sunxi_ccu_nm *nm = &clk->u.nm;
+	u_int index;
+	uint32_t val;
+
+	KASSERT(clk->type == SUNXI_CCU_NM);
+
+	val = CCU_READ(sc, nm->reg);
+	index = __SHIFTOUT(val, nm->sel);
+
+	return nm->parents[index];
+}
Index: src/sys/arch/arm/sunxi/sunxi_com.c
diff -u /dev/null src/sys/arch/arm/sunxi/sunxi_com.c:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/arm/sunxi/sunxi_com.c	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,178 @@
+/* $NetBSD: sunxi_com.c,v 1.1 2017/06/28 23:51:29 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+
+__KERNEL_RCSID(1, "$NetBSD: sunxi_com.c,v 1.1 2017/06/28 23:51:29 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/device.h>
+#include <sys/intr.h>
+#include <sys/systm.h>
+#include <sys/time.h>
+#include <sys/termios.h>
+
+#include <dev/ic/comvar.h>
+
+#include <dev/fdt/fdtvar.h>
+
+static int sunxi_com_match(device_t, cfdata_t, void *);
+static void sunxi_com_attach(device_t, device_t, void *);
+
+static const char * const compatible[] = {
+	"snps,dw-apb-uart",
+	NULL
+};
+
+struct sunxi_com_softc {
+	struct com_softc ssc_sc;
+	void *ssc_ih;
+
+	struct clk *ssc_clk;
+	struct fdtbus_reset *ssc_rst;
+};
+
+CFATTACH_DECL_NEW(sunxi_com, sizeof(struct sunxi_com_softc),
+	sunxi_com_match, sunxi_com_attach, NULL, NULL);
+
+static int
+sunxi_com_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_com_attach(device_t parent, device_t self, void *aux)
+{
+	struct sunxi_com_softc * const tsc = device_private(self);
+	struct com_softc * const sc = &tsc->ssc_sc;
+	struct fdt_attach_args * const faa = aux;
+	bus_space_handle_t bsh;
+	bus_space_tag_t bst;
+	char intrstr[128];
+	bus_addr_t addr;
+	bus_size_t size;
+	u_int reg_shift;
+	int error;
+
+	if (fdtbus_get_reg(faa->faa_phandle, 0, &addr, &size) != 0) {
+		aprint_error(": couldn't get registers\n");
+		return;
+	}
+
+	if (of_getprop_uint32(faa->faa_phandle, "reg-shift", &reg_shift)) {
+		/* missing or bad reg-shift property, assume 2 */
+		bst = faa->faa_a4x_bst;
+	} else {
+		if (reg_shift == 2) {
+			bst = faa->faa_a4x_bst;
+		} else if (reg_shift == 0) {
+			bst = faa->faa_bst;
+		} else {
+			aprint_error(": unsupported reg-shift value %d\n",
+			    reg_shift);
+			return;
+		}
+	}
+
+	sc->sc_dev = self;
+
+	tsc->ssc_clk = fdtbus_clock_get_index(faa->faa_phandle, 0);
+	tsc->ssc_rst = fdtbus_reset_get_index(faa->faa_phandle, 0);
+
+	if (tsc->ssc_clk == NULL) {
+		aprint_error(": couldn't get frequency\n");
+		return;
+	}
+
+	sc->sc_frequency = clk_get_rate(tsc->ssc_clk);
+	sc->sc_type = COM_TYPE_NORMAL;
+
+	error = bus_space_map(bst, addr, size, 0, &bsh);
+	if (error) {
+		aprint_error(": couldn't map %#llx: %d", (uint64_t)addr, error);
+		return;
+	}
+
+	COM_INIT_REGS(sc->sc_regs, bst, bsh, addr);
+
+	com_attach_subr(sc);
+	aprint_naive("\n");
+
+	if (!fdtbus_intr_str(faa->faa_phandle, 0, intrstr, sizeof(intrstr))) {
+		aprint_error_dev(self, "failed to decode interrupt\n");
+		return;
+	}
+
+	tsc->ssc_ih = fdtbus_intr_establish(faa->faa_phandle, 0, IPL_SERIAL,
+	    FDT_INTR_MPSAFE, comintr, sc);
+	if (tsc->ssc_ih == NULL) {
+		aprint_error_dev(self, "failed to establish interrupt on %s\n",
+		    intrstr);
+	}
+	aprint_normal_dev(self, "interrupting on %s\n", intrstr);
+}
+
+/*
+ * Console support
+ */
+
+static int
+sunxi_com_console_match(int phandle)
+{
+	return of_match_compatible(phandle, compatible);
+}
+
+static void
+sunxi_com_console_consinit(struct fdt_attach_args *faa, u_int uart_freq)
+{
+	const int phandle = faa->faa_phandle;
+	bus_space_tag_t bst = faa->faa_a4x_bst;
+	bus_addr_t addr;
+	tcflag_t flags;
+	int speed;
+
+	fdtbus_get_reg(phandle, 0, &addr, NULL);
+	speed = fdtbus_get_stdout_speed();
+	if (speed < 0)
+		speed = 115200;	/* default */
+	flags = fdtbus_get_stdout_flags();
+
+	if (comcnattach(bst, addr, speed, uart_freq, COM_TYPE_NORMAL, flags))
+		panic("Cannot initialize sunxi com console");
+}
+
+static const struct fdt_console sunxi_com_console = {
+	.match = sunxi_com_console_match,
+	.consinit = sunxi_com_console_consinit,
+};
+
+FDT_CONSOLE(sunxi_com, &sunxi_com_console);
Index: src/sys/arch/arm/sunxi/sunxi_platform.c
diff -u /dev/null src/sys/arch/arm/sunxi/sunxi_platform.c:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/arm/sunxi/sunxi_platform.c	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,160 @@
+/* $NetBSD: sunxi_platform.c,v 1.1 2017/06/28 23:51:29 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 "opt_soc.h"
+#include "opt_multiprocessor.h"
+#include "opt_fdt_arm.h"
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.1 2017/06/28 23:51:29 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/cpu.h>
+#include <sys/device.h>
+#include <sys/termios.h>
+
+#include <dev/fdt/fdtvar.h>
+#include <arm/fdt/arm_fdtvar.h>
+
+#include <uvm/uvm_extern.h>
+
+#include <machine/bootconfig.h>
+#include <arm/cpufunc.h>
+
+#include <arm/cortex/gtmr_var.h>
+#include <arm/cortex/gic_reg.h>
+
+#include <dev/ic/ns16550reg.h>
+#include <dev/ic/comreg.h>
+
+#include <arm/arm/psci.h>
+#include <arm/fdt/psci_fdt.h>
+
+#include <arm/sunxi/sunxi_platform.h>
+
+#define	SUNXI_REF_FREQ	24000000
+
+#define	SUN8I_WDT_BASE		0x01c20ca0
+#define	SUN8I_WDT_SIZE		0x20
+#define	SUN8I_WDT_CFG		0x14
+#define	 SUN8I_WDT_CFG_SYS	1
+#define	SUN8I_WDT_MODE		0x18
+#define	 SUN8I_WDT_MODE_EN	1
+
+#define	SUN8I_CPUCFG_BASE	0x01f01c00
+#define	SUN8I_CPUCFG_SIZE	0x400
+#define	SUN8I_PRCM_BASE		0x01f01400
+#define	SUN8I_PRCM_SIZE		0x800
+
+#define	DEVMAP_ALIGN(a)	((a) & ~L1_S_OFFSET)
+#define	DEVMAP_SIZE(s)	roundup2((s), L1_S_SIZE)
+#define	DEVMAP_ENTRY(va, pa, sz)			\
+	{						\
+		.pd_va = DEVMAP_ALIGN(va),		\
+		.pd_pa = DEVMAP_ALIGN(pa),		\
+		.pd_size = DEVMAP_SIZE(sz),		\
+		.pd_prot = VM_PROT_READ|VM_PROT_WRITE,	\
+		.pd_cache = PTE_NOCACHE			\
+	}
+#define	DEVMAP_ENTRY_END	{ 0 }
+
+extern struct bus_space armv7_generic_bs_tag;
+extern struct bus_space armv7_generic_a4x_bs_tag;
+extern struct arm32_bus_dma_tag armv7_generic_dma_tag;
+
+static const struct pmap_devmap *
+sunxi_platform_devmap(void)
+{
+	static const struct pmap_devmap devmap[] = {
+		DEVMAP_ENTRY(SUNXI_CORE_VBASE,
+			     SUNXI_CORE_PBASE,
+			     SUNXI_CORE_SIZE),
+		DEVMAP_ENTRY_END
+	};	
+
+	return devmap;
+}
+
+static void
+sunxi_platform_init_attach_args(struct fdt_attach_args *faa)
+{
+	faa->faa_bst = &armv7_generic_bs_tag;
+	faa->faa_a4x_bst = &armv7_generic_a4x_bs_tag;
+	faa->faa_dmat = &armv7_generic_dma_tag;
+}
+
+static void
+sunxi_platform_early_putchar(char c)
+{
+#ifdef CONSADDR
+#define CONSADDR_VA     ((CONSADDR - SUNXI_CORE_PBASE) + SUNXI_CORE_VBASE)
+	volatile uint32_t *uartaddr = (volatile uint32_t *)CONSADDR_VA;
+
+	while ((uartaddr[com_lsr] & LSR_TXRDY) == 0)
+		;
+
+	uartaddr[com_data] = c;
+#endif
+}
+
+static void
+sunxi_platform_device_register(device_t self, void *aux)
+{
+}
+
+static void
+sun8i_platform_reset(void)
+{
+	bus_space_tag_t bst = &armv7_generic_bs_tag;
+	bus_space_handle_t bsh;
+
+	bus_space_map(bst, SUN8I_WDT_BASE, SUN8I_WDT_SIZE, 0, &bsh);
+
+	bus_space_write_4(bst, bsh, SUN8I_WDT_CFG, SUN8I_WDT_CFG_SYS);
+	bus_space_write_4(bst, bsh, SUN8I_WDT_MODE, SUN8I_WDT_MODE_EN);
+}
+
+static u_int
+sunxi_platform_uart_freq(void)
+{
+	return SUNXI_REF_FREQ;
+}
+
+static const struct arm_platform sun8i_h3_platform = {
+	.devmap = sunxi_platform_devmap,
+	.bootstrap = psci_fdt_bootstrap,
+	.init_attach_args = sunxi_platform_init_attach_args,
+	.early_putchar = sunxi_platform_early_putchar,
+	.device_register = sunxi_platform_device_register,
+	.reset = sun8i_platform_reset,
+	.delay = gtmr_delay,
+	.uart_freq = sunxi_platform_uart_freq,
+};
+
+ARM_PLATFORM(sun8i_h3, "allwinner,sun8i-h3", &sun8i_h3_platform);
Index: src/sys/arch/arm/sunxi/sunxi_platform.h
diff -u /dev/null src/sys/arch/arm/sunxi/sunxi_platform.h:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/arm/sunxi/sunxi_platform.h	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,38 @@
+/* $NetBSD: sunxi_platform.h,v 1.1 2017/06/28 23:51:29 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 _ARM_SUNXI_PLATFORM_H
+#define _ARM_SUNXI_PLATFORM_H
+
+#include <arch/evbarm/fdt/platform.h>
+
+#define	SUNXI_CORE_VBASE	(KERNEL_VM_BASE + KERNEL_VM_SIZE)
+#define	SUNXI_CORE_PBASE	0x01c00000
+#define	SUNXI_CORE_SIZE		0x00400000
+
+#endif /* _ARM_SUNXI_PLATFORM_H */

Index: src/sys/arch/evbarm/conf/SUNXI
diff -u /dev/null src/sys/arch/evbarm/conf/SUNXI:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/evbarm/conf/SUNXI	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,109 @@
+#
+#	$NetBSD: SUNXI,v 1.1 2017/06/28 23:51:29 jmcneill Exp $
+#
+#	Allwinner sunxi family
+#
+
+include	"arch/evbarm/conf/std.sunxi"
+include	"arch/evbarm/conf/GENERIC.common"
+
+makeoptions	DTS="
+	sun8i-h3-bananapi-m2-plus.dts
+	sun8i-h3-beelink-x2.dts
+	sun8i-h3-nanopi-m1.dts
+	sun8i-h3-nanopi-neo.dts
+	sun8i-h3-orangepi-2.dts
+	sun8i-h3-orangepi-lite.dts
+	sun8i-h3-orangepi-pc-plus.dts
+	sun8i-h3-orangepi-pc.dts
+	sun8i-h3-orangepi-plus.dts
+	sun8i-h3-orangepi-plus2e.dts
+"
+
+options 	CPU_CORTEXA7
+options 	SOC_SUN8I_H3
+options 	MULTIPROCESSOR
+
+pseudo-device 	openfirm	# /dev/openfirm
+
+#options 	DIAGNOSTIC	# internal consistency checks
+#options 	DEBUG
+#options 	LOCKDEBUG
+#options 	PMAP_DEBUG	# Enable pmap_debug_level code
+#options 	IPKDB		# remote kernel debugging
+#options 	VERBOSE_INIT_ARM # verbose bootstrapping messages
+# CONSADDR is required for early init messages from VERBOSE_INIT_ARM.
+#options 	CONSADDR=0x01c28000
+
+makeoptions	DEBUG="-g"	# compile full symbol table
+makeoptions	COPY_SYMTAB=1
+
+config		netbsd		root on ? type ?
+
+# Device tree support
+armfdt0		at root
+fdt*		at fdtbus?
+
+# CPUs
+cpus*		at fdt? pass 0
+cpu*		at cpus?
+
+# Power state coordination interface
+psci*		at fdt?
+
+# Clock and reset controllers
+sun8ih3ccu*	at fdt? pass 4		# H3 CCU
+
+fclock*		at fdt? pass 4
+fregulator*	at fdt? pass 4
+gpiokeys*	at fdt?
+
+# Timer
+gtmr*		at fdt? pass 1		# ARM Generic Timer
+armgtmr0	at gtmr?
+
+# Interrupt controller
+gic*		at fdt? pass 1		# GIC
+armgic0		at gic?
+
+# Memory controller
+
+# DMA controller
+
+# Clock and Reset controller
+
+# GPIO controller
+#sunxigpio*	at fdt? pass 2		# GPIO
+#gpio*		at gpiobus?
+
+# Ethernet
+#awg*		at pci? dev ? function ?	# Allwinner Gigabit Ethernet
+#ukphy*		at mii? phy ?
+
+# UART
+com*		at fdt?			# UART
+
+# I2C
+#sunxiiic*	at fdt?			# I2C
+#iic*		at sunxiiic?
+
+# RTC
+
+# SDMMC
+#sunximmc*	at fdt?			# SDMMC
+#sdmmc*		at sdhc?
+#ld0		at sdmmc0
+#ld1		at sdmmc1
+#ld2		at sdmmc2
+#ld3		at sdmmc3
+#ld*		at sdmmc?
+
+# USB 2.0
+#sunxiusbphy*	at fdt?			# USB PHY
+#ehci*		at fdt?			# USB
+#usb*		at ehci?
+
+#include "dev/usb/usbdevices.config"
+#midi*		at midibus?
+
+cinclude "arch/evbarm/conf/SUNXI.local"
Index: src/sys/arch/evbarm/conf/files.sunxi
diff -u /dev/null src/sys/arch/evbarm/conf/files.sunxi:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/evbarm/conf/files.sunxi	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,8 @@
+#	$NetBSD: files.sunxi,v 1.1 2017/06/28 23:51:29 jmcneill Exp $
+#
+# Allwinner sunxi configuration info
+#
+
+include "arch/evbarm/conf/files.fdt"
+
+include "arch/arm/sunxi/files.sunxi"
Index: src/sys/arch/evbarm/conf/mk.sunxi
diff -u /dev/null src/sys/arch/evbarm/conf/mk.sunxi:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/evbarm/conf/mk.sunxi	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,32 @@
+#	$NetBSD: mk.sunxi,v 1.1 2017/06/28 23:51:29 jmcneill Exp $
+
+SYSTEM_FIRST_OBJ=	sunxi_start.o
+SYSTEM_FIRST_SFILE=	${THISARM}/sunxi/sunxi_start.S
+
+AFLAGS.sunxi_start.S+=	-Wa,-march=armv7-a+virt
+AFLAGS.psci_arm.S+=	-Wa,-march=armv7-a+sec+virt
+
+GENASSYM_EXTRAS+=	${THISARM}/sunxi/genassym.cf
+
+_OSRELEASE!=		${HOST_SH} $S/conf/osrelease.sh
+
+MKUBOOTIMAGEARGS=	-A arm -T kernel -O linux
+MKUBOOTIMAGEARGS+=	-a $(KERNEL_BASE_PHYS) -e $(KERNEL_BASE_PHYS)
+MKUBOOTIMAGEARGS+=	-n "NetBSD/$(BOARDTYPE) ${_OSRELEASE}"
+MKUBOOTIMAGEARGS_NONE=	${MKUBOOTIMAGEARGS} -C none
+MKUBOOTIMAGEARGS_GZ=	${MKUBOOTIMAGEARGS} -C gz
+
+SYSTEM_LD_TAIL_EXTRA+=; \
+	echo ${OBJCOPY} -S -O binary $@ $@.bin; \
+	${OBJCOPY} -S -O binary $@ $@.bin; \
+	echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_NONE} $@.bin $@.ub; \
+	${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_NONE} $@.bin $@.ub; \
+	echo ${TOOL_GZIP} -c $@.bin > $@.bin.gz; \
+	${TOOL_GZIP} -c $@.bin > $@.bin.gz; \
+	echo ${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_GZ} $@.bin.gz $@.gz.ub; \
+	${TOOL_MKUBOOTIMAGE} ${MKUBOOTIMAGEARGS_GZ} $@.bin.gz $@.gz.ub
+
+EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin@}
+EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.ub@}
+EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.bin.gz@}
+EXTRA_KERNELS+= ${KERNELS:@.KERNEL.@${.KERNEL.}.gz.ub@}
Index: src/sys/arch/evbarm/conf/std.sunxi
diff -u /dev/null src/sys/arch/evbarm/conf/std.sunxi:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/evbarm/conf/std.sunxi	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,29 @@
+#	$NetBSD: std.sunxi,v 1.1 2017/06/28 23:51:29 jmcneill Exp $
+#
+
+machine	evbarm arm
+include 	"arch/evbarm/conf/std.evbarm"
+
+include		"arch/evbarm/conf/files.sunxi"
+
+options 	FDT				# Flattened Device Tree support
+options 	MODULAR
+options 	MODULAR_DEFAULT_AUTOLOAD
+options 	__HAVE_CPU_COUNTER
+options 	__HAVE_FAST_SOFTINTS		# should be in types.h
+options 	ARM_HAS_VBAR
+#options 	__HAVE_MM_MD_DIRECT_MAPPED_PHYS
+#options 	PMAP_NEED_ALLOC_POOLPAGE
+options 	TPIDRPRW_IS_CURCPU
+options 	KERNEL_BASE_EXT=0x80000000
+options 	FPU_VFP
+options 	__BUS_SPACE_HAS_STREAM_METHODS
+
+makeoptions	KERNEL_BASE_PHYS="0x40008000"
+makeoptions	KERNEL_BASE_VIRT="0x80008000"
+makeoptions	BOARDTYPE="sunxi"
+makeoptions	BOARDMKFRAG="${THISARM}/conf/mk.sunxi"
+makeoptions	CPUFLAGS="-march=armv7-a -mfpu=neon"
+
+options 	ARM_INTR_IMPL="<arch/arm/fdt/fdt_intr.h>"
+options		ARM_GENERIC_TODR

Index: src/sys/arch/evbarm/sunxi/genassym.cf
diff -u /dev/null src/sys/arch/evbarm/sunxi/genassym.cf:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/evbarm/sunxi/genassym.cf	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,38 @@
+# $NetBSD: genassym.cf,v 1.1 2017/06/28 23:51:29 jmcneill Exp $
+
+#-
+# Copyright (c) 2013 The NetBSD Foundation, Inc.
+# All rights reserved.
+#
+# This code is derived from software contributed to The NetBSD Foundation
+# by Matt Thomas of 3am Software Foundry.
+#
+# 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+include <dev/ic/ns16550reg.h>
+include <dev/ic/comreg.h>
+
+define	LSR_TXRDY		LSR_TXRDY
+define	LSR_TSRE		LSR_TSRE
+define	COM_DATA		com_data
+define	COM_LSR			com_lsr
Index: src/sys/arch/evbarm/sunxi/sunxi_start.S
diff -u /dev/null src/sys/arch/evbarm/sunxi/sunxi_start.S:1.1
--- /dev/null	Wed Jun 28 23:51:29 2017
+++ src/sys/arch/evbarm/sunxi/sunxi_start.S	Wed Jun 28 23:51:29 2017
@@ -0,0 +1,192 @@
+/* $NetBSD: sunxi_start.S,v 1.1 2017/06/28 23:51:29 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2014, 2015 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Matt Thomas of 3am Software Foundry.
+ *
+ * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "opt_soc.h"
+#include "opt_cpuoptions.h"
+#include "opt_cputypes.h"
+#include "opt_multiprocessor.h"
+#include "opt_arm_debug.h"
+#include "opt_fdt_arm.h"
+
+#include <arm/asm.h>
+#include <arm/armreg.h>
+#include "assym.h"
+
+#include <arch/arm/sunxi/sunxi_platform.h>
+
+RCSID("$NetBSD: sunxi_start.S,v 1.1 2017/06/28 23:51:29 jmcneill Exp $")
+
+#if defined(VERBOSE_INIT_ARM) && defined(CONSADDR)
+#define	XPUTC(n)	mov r0, n; bl xputc
+#if KERNEL_BASE_VOFFSET == 0
+#define	XPUTC2(n)	mov r0, n; bl xputc
+#else
+#define XPUTC2(n)	mov r0, n; blx r11
+#endif
+#ifdef __ARMEB__
+#define COM_BSWAP
+#endif
+#define COM_MULT	4
+#define XPUTC_COM	1
+#else
+#define	XPUTC(n)
+#define	XPUTC2(n)
+#endif
+
+#define INIT_MEMSIZE	64
+#define	TEMP_L1_TABLE	(KERNEL_BASE - KERNEL_BASE_VOFFSET + INIT_MEMSIZE * L1_S_SIZE - L1_TABLE_SIZE)
+
+#define	MD_CPU_HATCH	_C_LABEL(arm_fdt_cpu_hatch)
+
+/*
+ * Kernel start routine for Allwinner sunxi SoCs
+ * At this point, this code has been loaded into SDRAM
+ * and the MMU maybe on or maybe off.
+ */
+#ifdef KERNEL_BASES_EQUAL
+	.text
+#else
+	.section .start,"ax",%progbits
+#endif
+
+	.global	_C_LABEL(sunxi_start)
+_C_LABEL(sunxi_start):
+#ifdef __ARMEB__
+	setend	be			/* force big endian */
+#endif
+	mov	r9, #0
+
+	/* Move into supervisor mode and disable IRQs/FIQs. */
+	cpsid	if, #PSR_SVC32_MODE
+
+	/*
+	 * Save any arguments passed to us.
+	 */
+	movw	r4, #:lower16:uboot_args
+	movt	r4, #:upper16:uboot_args
+	sub	r4, r4, #KERNEL_BASE_VOFFSET
+
+	stmia	r4, {r0-r3}		// Save the arguments
+
+	/* Add DTB PA (1MB) from r2 to MMU init table */
+	movw    r3, #:lower16:(L1_S_SIZE - 1)           /* align DTB PA to 1M */
+	movt    r3, #:upper16:(L1_S_SIZE - 1)
+	bic     r0, r2, r3
+	orr     r0, r0, #1                              /* 1MB mapping */
+	bic     r1, r2, r3
+	movw    r3, #:lower16:(L1_S_PROTO_armv7|L1_S_APv7_KRW|L1_S_CACHEABLE)
+	movt    r3, #:upper16:(L1_S_PROTO_armv7|L1_S_APv7_KRW|L1_S_CACHEABLE)
+	orr     r1, r1, r3
+	adr     r3, .Lmmu_init_table_dtb                /* table entry addr */
+	stmia   r3, {r0-r1}                             /* patch table entry */
+
+	/*
+	 * Turn on the SMP bit
+	 */
+	bl	cortex_init
+
+	/*
+	 * Set up a preliminary mapping in the MMU to allow us to run
+	 * at KERNEL_BASE with caches on.
+	 */
+	movw	r0, #:lower16:TEMP_L1_TABLE
+	movt	r0, #:upper16:TEMP_L1_TABLE
+	movw	r1, #:lower16:.Lmmu_init_table
+	movt	r1, #:upper16:.Lmmu_init_table
+	bl	arm_boot_l1pt_init
+	XPUTC(#'D')
+
+	/*
+	 * Turn on the MMU, Caches, etc.  Return to new enabled address space.
+	 */
+	movw	r0, #:lower16:TEMP_L1_TABLE
+	movt	r0, #:upper16:TEMP_L1_TABLE
+#if KERNEL_BASE_VOFFSET == 0
+	bl	arm_cpuinit
+#else
+	/*
+	 * After the MMU is on, we can execute in the normal .text segment
+	 * so setup the lr to be in .text.  Cache the address for xputc
+	 * before we go.
+	 */
+#if defined(VERBOSE_INIT_ARM)
+	adr	r11, xputc		@ for XPUTC2
+#endif
+	movw	lr, #:lower16:1f
+	movt	lr, #:upper16:1f
+	b	arm_cpuinit
+	.pushsection .text,"ax",%progbits
+1:
+#endif
+	XPUTC2(#'Z')
+
+	/*
+	 * Jump to start in locore.S, which in turn will call initarm and main.
+	 */
+	b	start
+
+	/* NOTREACHED */
+
+#ifndef KERNEL_BASES_EQUAL
+	.popsection
+#endif
+
+#include <arm/cortex/a9_mpsubr.S>
+
+.Lmmu_init_table:
+	MMU_INIT(KERNEL_BASE, KERNEL_BASE - KERNEL_BASE_VOFFSET, INIT_MEMSIZE,
+		L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE)
+
+#if KERNEL_BASE_VOFFSET != 0
+	/* Map KERNEL_BASE VA to SDRAM PA, write-back cacheable, shareable */
+	MMU_INIT(KERNEL_BASE - KERNEL_BASE_VOFFSET,
+		KERNEL_BASE - KERNEL_BASE_VOFFSET, INIT_MEMSIZE,
+		L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_CACHEABLE)
+#endif
+
+	/* Map CORE */
+	MMU_INIT(SUNXI_CORE_VBASE, SUNXI_CORE_PBASE,
+		(SUNXI_CORE_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
+		L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
+
+	/* Map CORE */
+	MMU_INIT(SUNXI_CORE_PBASE, SUNXI_CORE_PBASE,
+		(SUNXI_CORE_SIZE + L1_S_SIZE - 1) / L1_S_SIZE,
+		L1_S_PROTO_armv7 | L1_S_APv7_KRW | L1_S_V6_XN)
+
+.Lmmu_init_table_dtb:
+	/* Map DTB from bootloader (patched in later) */
+	MMU_INIT(0, 0, 0, 0)
+
+	/* end of table */
+	MMU_INIT(0, 0, 0, 0)
+
+END(_C_LABEL(sunxi_start))

Reply via email to