Module Name: src
Committed By: jmcneill
Date: Sun Jul 2 00:14:09 UTC 2017
Modified Files:
src/sys/arch/arm/sunxi: files.sunxi sunxi_ccu.c sunxi_ccu.h
sunxi_ccu_nkmp.c sunxi_platform.c sunxi_usbphy.c
src/sys/arch/evbarm/conf: SUNXI
Added Files:
src/sys/arch/arm/sunxi: sun6i_a31_ccu.c sun6i_a31_ccu.h sunxi_ccu_div.c
Log Message:
Add basic support for Allwinner A31.
To generate a diff of this commit:
cvs rdiff -u -r1.6 -r1.7 src/sys/arch/arm/sunxi/files.sunxi
cvs rdiff -u -r0 -r1.1 src/sys/arch/arm/sunxi/sun6i_a31_ccu.c \
src/sys/arch/arm/sunxi/sun6i_a31_ccu.h \
src/sys/arch/arm/sunxi/sunxi_ccu_div.c
cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/sunxi/sunxi_ccu.c \
src/sys/arch/arm/sunxi/sunxi_ccu.h
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c \
src/sys/arch/arm/sunxi/sunxi_platform.c \
src/sys/arch/arm/sunxi/sunxi_usbphy.c
cvs rdiff -u -r1.7 -r1.8 src/sys/arch/evbarm/conf/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/sunxi/files.sunxi
diff -u src/sys/arch/arm/sunxi/files.sunxi:1.6 src/sys/arch/arm/sunxi/files.sunxi:1.7
--- src/sys/arch/arm/sunxi/files.sunxi:1.6 Sat Jul 1 16:25:16 2017
+++ src/sys/arch/arm/sunxi/files.sunxi Sun Jul 2 00:14:09 2017
@@ -1,4 +1,4 @@
-# $NetBSD: files.sunxi,v 1.6 2017/07/01 16:25:16 jmcneill Exp $
+# $NetBSD: files.sunxi,v 1.7 2017/07/02 00:14:09 jmcneill Exp $
#
# Configuration info for Allwinner sunxi family SoCs
#
@@ -20,11 +20,17 @@ file arch/arm/sunxi/sunxi_platform.c so
# CCU
define sunxi_ccu
file arch/arm/sunxi/sunxi_ccu.c sunxi_ccu
+file arch/arm/sunxi/sunxi_ccu_div.c sunxi_ccu
file arch/arm/sunxi/sunxi_ccu_gate.c sunxi_ccu
file arch/arm/sunxi/sunxi_ccu_nm.c sunxi_ccu
file arch/arm/sunxi/sunxi_ccu_nkmp.c sunxi_ccu
file arch/arm/sunxi/sunxi_ccu_prediv.c sunxi_ccu
+# CCU (A31)
+device sun6ia31ccu: sunxi_ccu
+attach sun6ia31ccu at fdt with sunxi_a31_ccu
+file arch/arm/sunxi/sun6i_a31_ccu.c sunxi_a31_ccu
+
# CCU (H3)
device sun8ih3ccu: sunxi_ccu
attach sun8ih3ccu at fdt with sunxi_h3_ccu
@@ -71,3 +77,5 @@ file arch/arm/sunxi/sunxi_emac.c sunxi_
defflag opt_soc.h SOC_SUNXI
defflag opt_soc.h SOC_SUN8I: SOC_SUNXI
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
Index: src/sys/arch/arm/sunxi/sunxi_ccu.c
diff -u src/sys/arch/arm/sunxi/sunxi_ccu.c:1.4 src/sys/arch/arm/sunxi/sunxi_ccu.c:1.5
--- src/sys/arch/arm/sunxi/sunxi_ccu.c:1.4 Thu Jun 29 21:34:50 2017
+++ src/sys/arch/arm/sunxi/sunxi_ccu.c Sun Jul 2 00:14:09 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_ccu.c,v 1.4 2017/06/29 21:34:50 jmcneill Exp $ */
+/* $NetBSD: sunxi_ccu.c,v 1.5 2017/07/02 00:14:09 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_ccu.c,v 1.4 2017/06/29 21:34:50 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu.c,v 1.5 2017/07/02 00:14:09 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -328,16 +328,17 @@ sunxi_ccu_print(struct sunxi_ccu_softc *
case SUNXI_CCU_NM: type = "nm"; break;
case SUNXI_CCU_NKMP: type = "nkmp"; break;
case SUNXI_CCU_PREDIV: type = "prediv"; break;
+ case SUNXI_CCU_DIV: type = "div"; break;
default: type = "???"; break;
}
aprint_debug_dev(sc->sc_dev,
- "%3d %-12s %2s %-12s %-7s %10d Hz\n",
+ "%3d %-12s %2s %-12s %-7s ",
i,
clk->base.name,
clkp_parent ? "<-" : "",
clkp_parent ? clkp_parent->name : "",
- type,
- clk_get_rate(&clk->base));
+ type);
+ aprint_debug("%10d Hz\n", clk_get_rate(&clk->base));
}
}
Index: src/sys/arch/arm/sunxi/sunxi_ccu.h
diff -u src/sys/arch/arm/sunxi/sunxi_ccu.h:1.4 src/sys/arch/arm/sunxi/sunxi_ccu.h:1.5
--- src/sys/arch/arm/sunxi/sunxi_ccu.h:1.4 Thu Jun 29 17:08:52 2017
+++ src/sys/arch/arm/sunxi/sunxi_ccu.h Sun Jul 2 00:14:09 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_ccu.h,v 1.4 2017/06/29 17:08:52 jmcneill Exp $ */
+/* $NetBSD: sunxi_ccu.h,v 1.5 2017/07/02 00:14:09 jmcneill Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <[email protected]>
@@ -60,6 +60,7 @@ enum sunxi_ccu_clktype {
SUNXI_CCU_NM,
SUNXI_CCU_NKMP,
SUNXI_CCU_PREDIV,
+ SUNXI_CCU_DIV,
};
struct sunxi_ccu_gate {
@@ -170,6 +171,44 @@ const char *sunxi_ccu_nm_get_parent(stru
.get_parent = sunxi_ccu_nm_get_parent, \
}
+struct sunxi_ccu_div {
+ bus_size_t reg;
+ const char **parents;
+ u_int nparents;
+ uint32_t div;
+ uint32_t sel;
+ uint32_t flags;
+#define SUNXI_CCU_DIV_POWER_OF_TWO __BIT(0)
+#define SUNXI_CCU_DIV_ZERO_IS_ONE __BIT(1)
+};
+
+u_int sunxi_ccu_div_get_rate(struct sunxi_ccu_softc *,
+ struct sunxi_ccu_clk *);
+int sunxi_ccu_div_set_rate(struct sunxi_ccu_softc *,
+ struct sunxi_ccu_clk *, u_int);
+int sunxi_ccu_div_set_parent(struct sunxi_ccu_softc *,
+ struct sunxi_ccu_clk *,
+ const char *);
+const char *sunxi_ccu_div_get_parent(struct sunxi_ccu_softc *,
+ struct sunxi_ccu_clk *);
+
+#define SUNXI_CCU_DIV(_id, _name, _parents, _reg, _div, \
+ _sel, _flags) \
+ [_id] = { \
+ .type = SUNXI_CCU_DIV, \
+ .base.name = (_name), \
+ .u.div.reg = (_reg), \
+ .u.div.parents = (_parents), \
+ .u.div.nparents = __arraycount(_parents), \
+ .u.div.div = (_div), \
+ .u.div.sel = (_sel), \
+ .u.div.flags = (_flags), \
+ .get_rate = sunxi_ccu_div_get_rate, \
+ .set_rate = sunxi_ccu_div_set_rate, \
+ .set_parent = sunxi_ccu_div_set_parent, \
+ .get_parent = sunxi_ccu_div_get_parent, \
+ }
+
struct sunxi_ccu_prediv {
bus_size_t reg;
const char **parents;
@@ -220,6 +259,7 @@ struct sunxi_ccu_clk {
struct sunxi_ccu_nm nm;
struct sunxi_ccu_nkmp nkmp;
struct sunxi_ccu_prediv prediv;
+ struct sunxi_ccu_div div;
} u;
int (*enable)(struct sunxi_ccu_softc *,
Index: src/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c
diff -u src/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c:1.2 src/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c:1.3
--- src/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c:1.2 Thu Jun 29 10:53:59 2017
+++ src/sys/arch/arm/sunxi/sunxi_ccu_nkmp.c Sun Jul 2 00:14:09 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_ccu_nkmp.c,v 1.2 2017/06/29 10:53:59 jmcneill Exp $ */
+/* $NetBSD: sunxi_ccu_nkmp.c,v 1.3 2017/07/02 00:14:09 jmcneill Exp $ */
/*-
* Copyright (c) 2017 Jared McNeill <[email protected]>
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_nkmp.c,v 1.2 2017/06/29 10:53:59 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_ccu_nkmp.c,v 1.3 2017/07/02 00:14:09 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -85,7 +85,10 @@ sunxi_ccu_nkmp_get_rate(struct sunxi_ccu
m = __SHIFTOUT(val, nkmp->m);
else
m = 0;
- p = __SHIFTOUT(val, nkmp->p);
+ if (nkmp->p)
+ p = __SHIFTOUT(val, nkmp->p);
+ else
+ p = 0;
if (nkmp->enable && !(val & nkmp->enable))
return 0;
Index: src/sys/arch/arm/sunxi/sunxi_platform.c
diff -u src/sys/arch/arm/sunxi/sunxi_platform.c:1.2 src/sys/arch/arm/sunxi/sunxi_platform.c:1.3
--- src/sys/arch/arm/sunxi/sunxi_platform.c:1.2 Fri Jun 30 09:05:52 2017
+++ src/sys/arch/arm/sunxi/sunxi_platform.c Sun Jul 2 00:14:09 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_platform.c,v 1.2 2017/06/30 09:05:52 jmcneill Exp $ */
+/* $NetBSD: sunxi_platform.c,v 1.3 2017/07/02 00:14:09 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.2 2017/06/30 09:05:52 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.3 2017/07/02 00:14:09 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -60,12 +60,12 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_platfo
#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 SUN6I_WDT_BASE 0x01c20ca0
+#define SUN6I_WDT_SIZE 0x20
+#define SUN6I_WDT_CFG 0x14
+#define SUN6I_WDT_CFG_SYS 1
+#define SUN6I_WDT_MODE 0x18
+#define SUN6I_WDT_MODE_EN 1
#define DEVMAP_ALIGN(a) ((a) & ~L1_S_OFFSET)
@@ -124,33 +124,46 @@ sunxi_platform_device_register(device_t
{
}
+static u_int
+sunxi_platform_uart_freq(void)
+{
+ return SUNXI_REF_FREQ;
+}
+
static void
-sun8i_platform_reset(void)
+sun6i_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_map(bst, SUN6I_WDT_BASE, SUN6I_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);
+ bus_space_write_4(bst, bsh, SUN6I_WDT_CFG, SUN6I_WDT_CFG_SYS);
+ bus_space_write_4(bst, bsh, SUN6I_WDT_MODE, SUN6I_WDT_MODE_EN);
}
-static u_int
-sunxi_platform_uart_freq(void)
-{
- return SUNXI_REF_FREQ;
-}
+static const struct arm_platform sun8i_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 = sun6i_platform_reset,
+ .delay = gtmr_delay,
+ .uart_freq = sunxi_platform_uart_freq,
+};
+
+ARM_PLATFORM(sun8i_h3, "allwinner,sun8i-h3", &sun8i_platform);
-static const struct arm_platform sun8i_h3_platform = {
+static const struct arm_platform sun6i_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,
+ .reset = sun6i_platform_reset,
.delay = gtmr_delay,
.uart_freq = sunxi_platform_uart_freq,
};
-ARM_PLATFORM(sun8i_h3, "allwinner,sun8i-h3", &sun8i_h3_platform);
+ARM_PLATFORM(sun6i_a31, "allwinner,sun6i-a31", &sun6i_platform);
Index: src/sys/arch/arm/sunxi/sunxi_usbphy.c
diff -u src/sys/arch/arm/sunxi/sunxi_usbphy.c:1.2 src/sys/arch/arm/sunxi/sunxi_usbphy.c:1.3
--- src/sys/arch/arm/sunxi/sunxi_usbphy.c:1.2 Thu Jun 29 20:54:03 2017
+++ src/sys/arch/arm/sunxi/sunxi_usbphy.c Sun Jul 2 00:14:09 2017
@@ -1,4 +1,4 @@
-/* $NetBSD: sunxi_usbphy.c,v 1.2 2017/06/29 20:54:03 jmcneill Exp $ */
+/* $NetBSD: sunxi_usbphy.c,v 1.3 2017/07/02 00:14:09 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.2 2017/06/29 20:54:03 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sunxi_usbphy.c,v 1.3 2017/07/02 00:14:09 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -53,9 +53,15 @@ __KERNEL_RCSID(0, "$NetBSD: sunxi_usbphy
static int sunxi_usbphy_match(device_t, cfdata_t, void *);
static void sunxi_usbphy_attach(device_t, device_t, void *);
-static const char * const compatible[] = {
- "allwinner,sun8i-h3-usb-phy",
- NULL
+enum sunxi_usbphy_type {
+ USBPHY_A31,
+ USBPHY_H3,
+};
+
+static const struct of_compat_data compat_data[] = {
+ { "allwinner,sun6i-a31-usb-phy", USBPHY_A31 },
+ { "allwinner,sun8i-h3-usb-phy", USBPHY_H3 },
+ { NULL }
};
#define SUNXI_MAXUSBPHY 4
@@ -70,6 +76,7 @@ struct sunxi_usbphy_softc {
device_t sc_dev;
bus_space_tag_t sc_bst;
bus_space_handle_t sc_bsh_phy_ctrl;
+ enum sunxi_usbphy_type sc_type;
struct sunxi_usbphy sc_phys[SUNXI_MAXUSBPHY];
u_int sc_nphys;
@@ -133,10 +140,12 @@ sunxi_usbphy_enable(device_t dev, void *
USBPHY_WRITE(sc, phy->phy_index, HCI_ICR, val);
}
- /* H3-specific */
- val = USBPHY_READ(sc, phy->phy_index, PMU_UNK_H3);
- val &= ~PMU_UNK_H3_CLR;
- USBPHY_WRITE(sc, phy->phy_index, PMU_UNK_H3, val);
+ if (sc->sc_type == USBPHY_H3) {
+ /* H3-specific */
+ val = USBPHY_READ(sc, phy->phy_index, PMU_UNK_H3);
+ val &= ~PMU_UNK_H3_CLR;
+ USBPHY_WRITE(sc, phy->phy_index, PMU_UNK_H3, val);
+ }
if (phy->phy_reg == NULL)
return 0;
@@ -162,7 +171,7 @@ sunxi_usbphy_match(device_t parent, cfda
{
struct fdt_attach_args * const faa = aux;
- return of_match_compatible(faa->faa_phandle, compatible);
+ return of_match_compat_data(faa->faa_phandle, compat_data);
}
static void
@@ -181,6 +190,7 @@ sunxi_usbphy_attach(device_t parent, dev
sc->sc_dev = self;
sc->sc_bst = faa->faa_bst;
+ sc->sc_type = of_search_compatible(phandle, compat_data)->data;
if (fdtbus_get_reg(phandle, 0, &addr, &size) != 0) {
aprint_error(": couldn't get phy ctrl registers\n");
Index: src/sys/arch/evbarm/conf/SUNXI
diff -u src/sys/arch/evbarm/conf/SUNXI:1.7 src/sys/arch/evbarm/conf/SUNXI:1.8
--- src/sys/arch/evbarm/conf/SUNXI:1.7 Sat Jul 1 16:25:15 2017
+++ src/sys/arch/evbarm/conf/SUNXI Sun Jul 2 00:14:09 2017
@@ -1,5 +1,5 @@
#
-# $NetBSD: SUNXI,v 1.7 2017/07/01 16:25:15 jmcneill Exp $
+# $NetBSD: SUNXI,v 1.8 2017/07/02 00:14:09 jmcneill Exp $
#
# Allwinner sunxi family
#
@@ -8,6 +8,13 @@ include "arch/evbarm/conf/std.sunxi"
include "arch/evbarm/conf/GENERIC.common"
makeoptions DTS="
+ sun6i-a31-app4-evb1.dts
+ sun6i-a31-colombus.dts
+ sun6i-a31-hummingbird.dts
+ sun6i-a31-i7.dts
+ sun6i-a31-m9.dts
+ sun6i-a31-mele-a1000g-quad.dts
+
sun8i-h3-bananapi-m2-plus.dts
sun8i-h3-beelink-x2.dts
sun8i-h3-nanopi-m1.dts
@@ -21,6 +28,7 @@ makeoptions DTS="
"
options CPU_CORTEXA7
+options SOC_SUN6I_A31
options SOC_SUN8I_H3
options MULTIPROCESSOR
@@ -52,9 +60,10 @@ cpu* at cpus?
psci* at fdt?
# Clock and reset controllers
+sun6ia31ccu* at fdt? pass 4 # A31 CCU
sun8ih3ccu* at fdt? pass 4 # H3 CCU
-fclock* at fdt? pass 4
+fclock* at fdt? pass 3
fregulator* at fdt? pass 4
gpiokeys* at fdt?
Added files:
Index: src/sys/arch/arm/sunxi/sun6i_a31_ccu.c
diff -u /dev/null src/sys/arch/arm/sunxi/sun6i_a31_ccu.c:1.1
--- /dev/null Sun Jul 2 00:14:09 2017
+++ src/sys/arch/arm/sunxi/sun6i_a31_ccu.c Sun Jul 2 00:14:09 2017
@@ -0,0 +1,277 @@
+/* $NetBSD: sun6i_a31_ccu.c,v 1.1 2017/07/02 00:14:09 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2017 Jared McNeill <[email protected]>
+ * Copyright (c) 2017 Emmanuel Vadot <[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: sun6i_a31_ccu.c,v 1.1 2017/07/02 00:14:09 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/sun6i_a31_ccu.h>
+
+#define PLL_PERIPH_CTRL_REG 0x028
+#define AHB1_APB1_CFG_REG 0x054
+#define APB2_CLK_DIV_REG 0x058
+#define AHB1_GATING_REG0 0x060
+#define AHB1_GATING_REG1 0x064
+#define APB1_GATING_REG 0x068
+#define APB2_GATING_REG 0x06c
+#define SD0_CLK_REG 0x088
+#define SD1_CLK_REG 0x08c
+#define SD2_CLK_REG 0x090
+#define SD3_CLK_REG 0x094
+#define USBPHY_CFG_REG 0x0cc
+#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
+
+static int sun6i_a31_ccu_match(device_t, cfdata_t, void *);
+static void sun6i_a31_ccu_attach(device_t, device_t, void *);
+
+static const char * const compatible[] = {
+ "allwinner,sun6i-a31-ccu",
+ NULL
+};
+
+CFATTACH_DECL_NEW(sunxi_a31_ccu, sizeof(struct sunxi_ccu_softc),
+ sun6i_a31_ccu_match, sun6i_a31_ccu_attach, NULL, NULL);
+
+static struct sunxi_ccu_reset sun6i_a31_ccu_resets[] = {
+ SUNXI_CCU_RESET(A31_RST_USB_PHY0, USBPHY_CFG_REG, 0),
+ SUNXI_CCU_RESET(A31_RST_USB_PHY1, USBPHY_CFG_REG, 1),
+ SUNXI_CCU_RESET(A31_RST_USB_PHY2, USBPHY_CFG_REG, 2),
+
+ SUNXI_CCU_RESET(A31_RST_AHB1_MIPI_DSI, BUS_SOFT_RST_REG0, 1),
+ SUNXI_CCU_RESET(A31_RST_AHB1_SS, BUS_SOFT_RST_REG0, 5),
+ SUNXI_CCU_RESET(A31_RST_AHB1_DMA, BUS_SOFT_RST_REG0, 6),
+ SUNXI_CCU_RESET(A31_RST_AHB1_MMC0, BUS_SOFT_RST_REG0, 8),
+ SUNXI_CCU_RESET(A31_RST_AHB1_MMC1, BUS_SOFT_RST_REG0, 9),
+ SUNXI_CCU_RESET(A31_RST_AHB1_MMC2, BUS_SOFT_RST_REG0, 10),
+ SUNXI_CCU_RESET(A31_RST_AHB1_MMC3, BUS_SOFT_RST_REG0, 11),
+ SUNXI_CCU_RESET(A31_RST_AHB1_NAND1, BUS_SOFT_RST_REG0, 12),
+ SUNXI_CCU_RESET(A31_RST_AHB1_NAND0, BUS_SOFT_RST_REG0, 13),
+ SUNXI_CCU_RESET(A31_RST_AHB1_SDRAM, BUS_SOFT_RST_REG0, 14),
+ SUNXI_CCU_RESET(A31_RST_AHB1_EMAC, BUS_SOFT_RST_REG0, 17),
+ SUNXI_CCU_RESET(A31_RST_AHB1_TS, BUS_SOFT_RST_REG0, 18),
+ SUNXI_CCU_RESET(A31_RST_AHB1_HSTIMER, BUS_SOFT_RST_REG0, 19),
+ SUNXI_CCU_RESET(A31_RST_AHB1_SPI0, BUS_SOFT_RST_REG0, 20),
+ SUNXI_CCU_RESET(A31_RST_AHB1_SPI1, BUS_SOFT_RST_REG0, 21),
+ SUNXI_CCU_RESET(A31_RST_AHB1_SPI2, BUS_SOFT_RST_REG0, 22),
+ SUNXI_CCU_RESET(A31_RST_AHB1_SPI3, BUS_SOFT_RST_REG0, 23),
+ SUNXI_CCU_RESET(A31_RST_AHB1_OTG, BUS_SOFT_RST_REG0, 24),
+ SUNXI_CCU_RESET(A31_RST_AHB1_EHCI0, BUS_SOFT_RST_REG0, 26),
+ SUNXI_CCU_RESET(A31_RST_AHB1_EHCI1, BUS_SOFT_RST_REG0, 27),
+ SUNXI_CCU_RESET(A31_RST_AHB1_OHCI0, BUS_SOFT_RST_REG0, 29),
+ SUNXI_CCU_RESET(A31_RST_AHB1_OHCI1, BUS_SOFT_RST_REG0, 30),
+ SUNXI_CCU_RESET(A31_RST_AHB1_OHCI2, BUS_SOFT_RST_REG0, 31),
+
+ SUNXI_CCU_RESET(A31_RST_AHB1_VE, BUS_SOFT_RST_REG1, 0),
+ SUNXI_CCU_RESET(A31_RST_AHB1_LCD0, BUS_SOFT_RST_REG1, 4),
+ SUNXI_CCU_RESET(A31_RST_AHB1_LCD1, BUS_SOFT_RST_REG1, 5),
+ SUNXI_CCU_RESET(A31_RST_AHB1_CSI, BUS_SOFT_RST_REG1, 8),
+ SUNXI_CCU_RESET(A31_RST_AHB1_HDMI, BUS_SOFT_RST_REG1, 11),
+ SUNXI_CCU_RESET(A31_RST_AHB1_BE0, BUS_SOFT_RST_REG1, 12),
+ SUNXI_CCU_RESET(A31_RST_AHB1_BE1, BUS_SOFT_RST_REG1, 13),
+ SUNXI_CCU_RESET(A31_RST_AHB1_FE0, BUS_SOFT_RST_REG1, 14),
+ SUNXI_CCU_RESET(A31_RST_AHB1_FE1, BUS_SOFT_RST_REG1, 15),
+ SUNXI_CCU_RESET(A31_RST_AHB1_MP, BUS_SOFT_RST_REG1, 16),
+ SUNXI_CCU_RESET(A31_RST_AHB1_GPU, BUS_SOFT_RST_REG1, 20),
+ SUNXI_CCU_RESET(A31_RST_AHB1_DEU0, BUS_SOFT_RST_REG1, 23),
+ SUNXI_CCU_RESET(A31_RST_AHB1_DEU1, BUS_SOFT_RST_REG1, 24),
+ SUNXI_CCU_RESET(A31_RST_AHB1_DRC0, BUS_SOFT_RST_REG1, 25),
+ SUNXI_CCU_RESET(A31_RST_AHB1_DRC1, BUS_SOFT_RST_REG1, 26),
+
+ SUNXI_CCU_RESET(A31_RST_AHB1_LVDS, BUS_SOFT_RST_REG2, 0),
+
+ SUNXI_CCU_RESET(A31_RST_APB1_CODEC, BUS_SOFT_RST_REG3, 0),
+ SUNXI_CCU_RESET(A31_RST_APB1_SPDIF, BUS_SOFT_RST_REG3, 1),
+ SUNXI_CCU_RESET(A31_RST_APB1_DIGITAL_MIC, BUS_SOFT_RST_REG3, 4),
+ SUNXI_CCU_RESET(A31_RST_APB1_DAUDIO0, BUS_SOFT_RST_REG3, 12),
+ SUNXI_CCU_RESET(A31_RST_APB1_DAUDIO1, BUS_SOFT_RST_REG3, 13),
+
+ SUNXI_CCU_RESET(A31_RST_APB2_I2C0, BUS_SOFT_RST_REG4, 0),
+ SUNXI_CCU_RESET(A31_RST_APB2_I2C1, BUS_SOFT_RST_REG4, 1),
+ SUNXI_CCU_RESET(A31_RST_APB2_I2C2, BUS_SOFT_RST_REG4, 2),
+ SUNXI_CCU_RESET(A31_RST_APB2_I2C3, BUS_SOFT_RST_REG4, 3),
+ SUNXI_CCU_RESET(A31_RST_APB2_UART0, BUS_SOFT_RST_REG4, 16),
+ SUNXI_CCU_RESET(A31_RST_APB2_UART1, BUS_SOFT_RST_REG4, 17),
+ SUNXI_CCU_RESET(A31_RST_APB2_UART2, BUS_SOFT_RST_REG4, 18),
+ SUNXI_CCU_RESET(A31_RST_APB2_UART3, BUS_SOFT_RST_REG4, 19),
+ SUNXI_CCU_RESET(A31_RST_APB2_UART4, BUS_SOFT_RST_REG4, 20),
+ SUNXI_CCU_RESET(A31_RST_APB2_UART5, BUS_SOFT_RST_REG4, 21),
+};
+
+static const char *ahb1_parents[] = { "losc", "hosc", "axi", "pll_periph" };
+static const char *apb1_parents[] = { "ahb1" };
+static const char *apb2_parents[] = { "losc", "hosc", "pll_periph", "pll_periph" };
+static const char *mod_parents[] = { "hosc", "pll_periph" };
+
+static struct sunxi_ccu_clk sun6i_a31_ccu_clks[] = {
+ SUNXI_CCU_NKMP(A31_CLK_PLL_PERIPH, "pll_periph", "hosc",
+ PLL_PERIPH_CTRL_REG, /* reg */
+ __BITS(12,8), /* n */
+ __BITS(5,4), /* k */
+ 0, /* m */
+ 0, /* p */
+ __BIT(31), /* enable */
+ SUNXI_CCU_NKMP_DIVIDE_BY_TWO),
+
+ SUNXI_CCU_DIV(A31_CLK_APB1, "apb1", apb1_parents,
+ AHB1_APB1_CFG_REG, /* reg */
+ __BITS(9,8), /* div */
+ 0, /* sel */
+ SUNXI_CCU_DIV_POWER_OF_TWO|SUNXI_CCU_DIV_ZERO_IS_ONE),
+
+ SUNXI_CCU_PREDIV(A31_CLK_AHB1, "ahb1", ahb1_parents,
+ AHB1_APB1_CFG_REG, /* reg */
+ __BITS(7,6), /* prediv */
+ __BIT(3), /* prediv_sel */
+ __BITS(5,4), /* div */
+ __BITS(13,12), /* sel */
+ SUNXI_CCU_PREDIV_POWER_OF_TWO),
+
+ SUNXI_CCU_NM(A31_CLK_APB2, "apb2", apb2_parents,
+ APB2_CLK_DIV_REG, /* reg */
+ __BITS(17,16), /* n */
+ __BITS(4,0), /* m */
+ __BITS(25,24), /* sel */
+ 0, /* enable */
+ SUNXI_CCU_NM_POWER_OF_TWO),
+
+ SUNXI_CCU_NM(A31_CLK_MMC0, "mmc0", mod_parents,
+ SD0_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
+ SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
+ SUNXI_CCU_NM(A31_CLK_MMC1, "mmc1", mod_parents,
+ SD1_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
+ SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
+ SUNXI_CCU_NM(A31_CLK_MMC2, "mmc2", mod_parents,
+ SD2_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
+ SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
+ SUNXI_CCU_NM(A31_CLK_MMC3, "mmc3", mod_parents,
+ SD3_CLK_REG, __BITS(17, 16), __BITS(3,0), __BITS(25, 24), __BIT(31),
+ SUNXI_CCU_NM_POWER_OF_TWO|SUNXI_CCU_NM_ROUND_DOWN),
+
+ SUNXI_CCU_GATE(A31_CLK_AHB1_MMC0, "ahb1-mmc0", "ahb1",
+ AHB1_GATING_REG0, 8),
+ SUNXI_CCU_GATE(A31_CLK_AHB1_MMC1, "ahb1-mmc1", "ahb1",
+ AHB1_GATING_REG0, 9),
+ SUNXI_CCU_GATE(A31_CLK_AHB1_MMC2, "ahb1-mmc2", "ahb1",
+ AHB1_GATING_REG0, 10),
+ SUNXI_CCU_GATE(A31_CLK_AHB1_MMC3, "ahb1-mmc3", "ahb1",
+ AHB1_GATING_REG0, 11),
+ SUNXI_CCU_GATE(A31_CLK_AHB1_EMAC, "ahb1-emac", "ahb1",
+ AHB1_GATING_REG0, 17),
+ SUNXI_CCU_GATE(A31_CLK_AHB1_OTG, "ahb1-otg", "ahb1",
+ AHB1_GATING_REG0, 24),
+ SUNXI_CCU_GATE(A31_CLK_AHB1_EHCI0, "ahb1-ehci0", "ahb1",
+ AHB1_GATING_REG0, 26),
+ SUNXI_CCU_GATE(A31_CLK_AHB1_EHCI1, "ahb1-ehci1", "ahb1",
+ AHB1_GATING_REG0, 27),
+ SUNXI_CCU_GATE(A31_CLK_AHB1_OHCI0, "ahb1-ohci0", "ahb1",
+ AHB1_GATING_REG0, 29),
+ SUNXI_CCU_GATE(A31_CLK_AHB1_OHCI1, "ahb1-ohci1", "ahb1",
+ AHB1_GATING_REG0, 30),
+ SUNXI_CCU_GATE(A31_CLK_AHB1_OHCI2, "ahb1-ohci2", "ahb1",
+ AHB1_GATING_REG0, 31),
+
+ SUNXI_CCU_GATE(A31_CLK_APB2_I2C0, "apb2-i2c0", "apb2",
+ APB2_GATING_REG, 0),
+ SUNXI_CCU_GATE(A31_CLK_APB2_I2C1, "apb2-i2c1", "apb2",
+ APB2_GATING_REG, 1),
+ SUNXI_CCU_GATE(A31_CLK_APB2_I2C2, "apb2-i2c2", "apb2",
+ APB2_GATING_REG, 2),
+ SUNXI_CCU_GATE(A31_CLK_APB2_I2C3, "apb2-i2c3", "apb2",
+ APB2_GATING_REG, 3),
+ SUNXI_CCU_GATE(A31_CLK_APB2_UART0, "apb2-uart0", "apb2",
+ APB2_GATING_REG, 16),
+ SUNXI_CCU_GATE(A31_CLK_APB2_UART1, "apb2-uart1", "apb2",
+ APB2_GATING_REG, 17),
+ SUNXI_CCU_GATE(A31_CLK_APB2_UART2, "apb2-uart2", "apb2",
+ APB2_GATING_REG, 18),
+ SUNXI_CCU_GATE(A31_CLK_APB2_UART3, "apb2-uart3", "apb2",
+ APB2_GATING_REG, 19),
+ SUNXI_CCU_GATE(A31_CLK_APB2_UART4, "apb2-uart4", "apb2",
+ APB2_GATING_REG, 20),
+ SUNXI_CCU_GATE(A31_CLK_APB2_UART5, "apb2-uart5", "apb2",
+ APB2_GATING_REG, 21),
+
+ SUNXI_CCU_GATE(A31_CLK_USB_PHY0, "usb-phy0", "hosc",
+ USBPHY_CFG_REG, 8),
+ SUNXI_CCU_GATE(A31_CLK_USB_PHY1, "usb-phy1", "hosc",
+ USBPHY_CFG_REG, 9),
+ SUNXI_CCU_GATE(A31_CLK_USB_PHY2, "usb-phy2", "hosc",
+ USBPHY_CFG_REG, 10),
+ SUNXI_CCU_GATE(A31_CLK_USB_OHCI0, "usb-ohci0", "hosc",
+ USBPHY_CFG_REG, 16),
+ SUNXI_CCU_GATE(A31_CLK_USB_OHCI1, "usb-ohci1", "hosc",
+ USBPHY_CFG_REG, 17),
+ SUNXI_CCU_GATE(A31_CLK_USB_OHCI2, "usb-ohci2", "hosc",
+ USBPHY_CFG_REG, 18),
+};
+
+static int
+sun6i_a31_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
+sun6i_a31_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 = sun6i_a31_ccu_resets;
+ sc->sc_nresets = __arraycount(sun6i_a31_ccu_resets);
+
+ sc->sc_clks = sun6i_a31_ccu_clks;
+ sc->sc_nclks = __arraycount(sun6i_a31_ccu_clks);
+
+ if (sunxi_ccu_attach(sc) != 0)
+ return;
+
+ aprint_naive("\n");
+ aprint_normal(": A31 CCU\n");
+
+ sunxi_ccu_print(sc);
+}
Index: src/sys/arch/arm/sunxi/sun6i_a31_ccu.h
diff -u /dev/null src/sys/arch/arm/sunxi/sun6i_a31_ccu.h:1.1
--- /dev/null Sun Jul 2 00:14:09 2017
+++ src/sys/arch/arm/sunxi/sun6i_a31_ccu.h Sun Jul 2 00:14:09 2017
@@ -0,0 +1,250 @@
+/* $NetBSD: sun6i_a31_ccu.h,v 1.1 2017/07/02 00:14:09 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2017 Emmanuel Vadot <[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$
+ */
+
+#ifndef __CCU_A31_H__
+#define __CCU_A31_H__
+
+#define A31_RST_USB_PHY0 0
+#define A31_RST_USB_PHY1 1
+#define A31_RST_USB_PHY2 2
+#define A31_RST_AHB1_MIPI_DSI 3
+#define A31_RST_AHB1_SS 4
+#define A31_RST_AHB1_DMA 5
+#define A31_RST_AHB1_MMC0 6
+#define A31_RST_AHB1_MMC1 7
+#define A31_RST_AHB1_MMC2 8
+#define A31_RST_AHB1_MMC3 9
+#define A31_RST_AHB1_NAND1 10
+#define A31_RST_AHB1_NAND0 11
+#define A31_RST_AHB1_SDRAM 12
+#define A31_RST_AHB1_EMAC 13
+#define A31_RST_AHB1_TS 14
+#define A31_RST_AHB1_HSTIMER 15
+#define A31_RST_AHB1_SPI0 16
+#define A31_RST_AHB1_SPI1 17
+#define A31_RST_AHB1_SPI2 18
+#define A31_RST_AHB1_SPI3 19
+#define A31_RST_AHB1_OTG 20
+#define A31_RST_AHB1_EHCI0 21
+#define A31_RST_AHB1_EHCI1 22
+#define A31_RST_AHB1_OHCI0 23
+#define A31_RST_AHB1_OHCI1 24
+#define A31_RST_AHB1_OHCI2 25
+#define A31_RST_AHB1_VE 26
+#define A31_RST_AHB1_LCD0 27
+#define A31_RST_AHB1_LCD1 28
+#define A31_RST_AHB1_CSI 29
+#define A31_RST_AHB1_HDMI 30
+#define A31_RST_AHB1_BE0 31
+#define A31_RST_AHB1_BE1 32
+#define A31_RST_AHB1_FE0 33
+#define A31_RST_AHB1_FE1 34
+#define A31_RST_AHB1_MP 35
+#define A31_RST_AHB1_GPU 36
+#define A31_RST_AHB1_DEU0 37
+#define A31_RST_AHB1_DEU1 38
+#define A31_RST_AHB1_DRC0 39
+#define A31_RST_AHB1_DRC1 40
+#define A31_RST_AHB1_LVDS 41
+#define A31_RST_APB1_CODEC 42
+#define A31_RST_APB1_SPDIF 43
+#define A31_RST_APB1_DIGITAL_MIC 44
+#define A31_RST_APB1_DAUDIO0 45
+#define A31_RST_APB1_DAUDIO1 46
+#define A31_RST_APB2_I2C0 47
+#define A31_RST_APB2_I2C1 48
+#define A31_RST_APB2_I2C2 49
+#define A31_RST_APB2_I2C3 50
+#define A31_RST_APB2_UART0 51
+#define A31_RST_APB2_UART1 52
+#define A31_RST_APB2_UART2 53
+#define A31_RST_APB2_UART3 54
+#define A31_RST_APB2_UART4 55
+#define A31_RST_APB2_UART5 56
+
+#define A31_CLK_PLL_CPU 0
+#define A31_CLK_PLL_AUDIO_BASE 1
+#define A31_CLK_PLL_AUDIO 2
+#define A31_CLK_PLL_AUDIO_2X 3
+#define A31_CLK_PLL_AUDIO_4X 4
+#define A31_CLK_PLL_AUDIO_8X 5
+#define A31_CLK_PLL_VIDEO0 6
+#define A31_CLK_PLL_VIDEO0_2X 7
+#define A31_CLK_PLL_VE 8
+#define A31_CLK_PLL_DDR 9
+#define A31_CLK_PLL_PERIPH 10
+#define A31_CLK_PLL_PERIPH_2X 11
+#define A31_CLK_PLL_VIDEO1 12
+#define A31_CLK_PLL_VIDEO1_2X 13
+#define A31_CLK_PLL_GPU 14
+#define A31_CLK_PLL_MIPI 15
+#define A31_CLK_PLL9 16
+#define A31_CLK_PLL10 17
+#define A31_CLK_CPU 18
+#define A31_CLK_AXI 19
+#define A31_CLK_AHB1 20
+#define A31_CLK_APB1 21
+#define A31_CLK_APB2 22
+#define A31_CLK_AHB1_MIPIDSI 23
+#define A31_CLK_AHB1_SS 24
+#define A31_CLK_AHB1_DMA 25
+#define A31_CLK_AHB1_MMC0 26
+#define A31_CLK_AHB1_MMC1 27
+#define A31_CLK_AHB1_MMC2 28
+#define A31_CLK_AHB1_MMC3 29
+#define A31_CLK_AHB1_NAND1 30
+#define A31_CLK_AHB1_NAND0 31
+#define A31_CLK_AHB1_SDRAM 32
+#define A31_CLK_AHB1_EMAC 33
+#define A31_CLK_AHB1_TS 34
+#define A31_CLK_AHB1_HSTIMER 35
+#define A31_CLK_AHB1_SPI0 36
+#define A31_CLK_AHB1_SPI1 37
+#define A31_CLK_AHB1_SPI2 38
+#define A31_CLK_AHB1_SPI3 39
+#define A31_CLK_AHB1_OTG 40
+#define A31_CLK_AHB1_EHCI0 41
+#define A31_CLK_AHB1_EHCI1 42
+#define A31_CLK_AHB1_OHCI0 43
+#define A31_CLK_AHB1_OHCI1 44
+#define A31_CLK_AHB1_OHCI2 45
+#define A31_CLK_AHB1_VE 46
+#define A31_CLK_AHB1_LCD0 47
+#define A31_CLK_AHB1_LCD1 48
+#define A31_CLK_AHB1_CSI 49
+#define A31_CLK_AHB1_HDMI 50
+#define A31_CLK_AHB1_BE0 51
+#define A31_CLK_AHB1_BE1 52
+#define A31_CLK_AHB1_FE0 53
+#define A31_CLK_AHB1_FE1 54
+#define A31_CLK_AHB1_MP 55
+#define A31_CLK_AHB1_GPU 56
+#define A31_CLK_AHB1_DEU0 57
+#define A31_CLK_AHB1_DEU1 58
+#define A31_CLK_AHB1_DRC0 59
+#define A31_CLK_AHB1_DRC1 60
+#define A31_CLK_APB1_CODEC 61
+#define A31_CLK_APB1_SPDIF 62
+#define A31_CLK_APB1_DIGITAL_MIC 63
+#define A31_CLK_APB1_PIO 64
+#define A31_CLK_APB1_DAUDIO0 65
+#define A31_CLK_APB1_DAUDIO1 66
+#define A31_CLK_APB2_I2C0 67
+#define A31_CLK_APB2_I2C1 68
+#define A31_CLK_APB2_I2C2 69
+#define A31_CLK_APB2_I2C3 70
+#define A31_CLK_APB2_UART0 71
+#define A31_CLK_APB2_UART1 72
+#define A31_CLK_APB2_UART2 73
+#define A31_CLK_APB2_UART3 74
+#define A31_CLK_APB2_UART4 75
+#define A31_CLK_APB2_UART5 76
+#define A31_CLK_NAND0 77
+#define A31_CLK_NAND1 78
+#define A31_CLK_MMC0 79
+#define A31_CLK_MMC0_SAMPLE 80
+#define A31_CLK_MMC0_OUTPUT 81
+#define A31_CLK_MMC1 82
+#define A31_CLK_MMC1_SAMPLE 83
+#define A31_CLK_MMC1_OUTPUT 84
+#define A31_CLK_MMC2 85
+#define A31_CLK_MMC2_SAMPLE 86
+#define A31_CLK_MMC2_OUTPUT 87
+#define A31_CLK_MMC3 88
+#define A31_CLK_MMC3_SAMPLE 89
+#define A31_CLK_MMC3_OUTPUT 90
+#define A31_CLK_TS 91
+#define A31_CLK_SS 92
+#define A31_CLK_SPI0 93
+#define A31_CLK_SPI1 94
+#define A31_CLK_SPI2 95
+#define A31_CLK_SPI3 96
+#define A31_CLK_DAUDIO0 97
+#define A31_CLK_DAUDIO1 98
+#define A31_CLK_SPDIF 99
+#define A31_CLK_USB_PHY0 100
+#define A31_CLK_USB_PHY1 101
+#define A31_CLK_USB_PHY2 102
+#define A31_CLK_USB_OHCI0 103
+#define A31_CLK_USB_OHCI1 104
+#define A31_CLK_USB_OHCI2 105
+#define A31_CLK_MDFS 107
+#define A31_CLK_SDRAM0 108
+#define A31_CLK_SDRAM1 109
+#define A31_CLK_DRAM_VE 110
+#define A31_CLK_DRAM_CSI_ISP 111
+#define A31_CLK_DRAM_TS 112
+#define A31_CLK_DRAM_DRC0 113
+#define A31_CLK_DRAM_DRC1 114
+#define A31_CLK_DRAM_DEU0 115
+#define A31_CLK_DRAM_DEU1 116
+#define A31_CLK_DRAM_FE0 117
+#define A31_CLK_DRAM_FE1 118
+#define A31_CLK_DRAM_BE0 119
+#define A31_CLK_DRAM_BE1 120
+#define A31_CLK_DRAM_MP 121
+#define A31_CLK_BE0 122
+#define A31_CLK_BE1 123
+#define A31_CLK_FE0 124
+#define A31_CLK_FE1 125
+#define A31_CLK_MP 126
+#define A31_CLK_LCD0_CH0 127
+#define A31_CLK_LCD1_CH0 128
+#define A31_CLK_LCD0_CH1 129
+#define A31_CLK_LCD1_CH1 130
+#define A31_CLK_CSI0_SCLK 131
+#define A31_CLK_CSI0_MCLK 132
+#define A31_CLK_CSI1_MCLK 133
+#define A31_CLK_VE 134
+#define A31_CLK_CODEC 135
+#define A31_CLK_AVS 136
+#define A31_CLK_DIGITAL_MIC 137
+#define A31_CLK_HDMI 138
+#define A31_CLK_HDMI_DDC 139
+#define A31_CLK_PS 140
+#define A31_CLK_MBUS0 141
+#define A31_CLK_MBUS1 142
+#define A31_CLK_MIPI_DSI 143
+#define A31_CLK_MIPI_DSI_DPHY 144
+#define A31_CLK_MIPI_CSI_DPHY 145
+#define A31_CLK_IEP_DRC0 146
+#define A31_CLK_IEP_DRC1 147
+#define A31_CLK_IEP_DEU0 148
+#define A31_CLK_IEP_DEU1 149
+#define A31_CLK_GPU_CORE 150
+#define A31_CLK_GPU_MEMORY 151
+#define A31_CLK_GPU_HYD 152
+#define A31_CLK_ATS 153
+#define A31_CLK_TRACE 154
+#define A31_CLK_OUT_A 155
+#define A31_CLK_OUT_B 156
+#define A31_CLK_OUT_C 157
+
+#endif /* __CCU_A31 H__ */
Index: src/sys/arch/arm/sunxi/sunxi_ccu_div.c
diff -u /dev/null src/sys/arch/arm/sunxi/sunxi_ccu_div.c:1.1
--- /dev/null Sun Jul 2 00:14:09 2017
+++ src/sys/arch/arm/sunxi/sunxi_ccu_div.c Sun Jul 2 00:14:09 2017
@@ -0,0 +1,124 @@
+/* $NetBSD: sunxi_ccu_div.c,v 1.1 2017/07/02 00:14:09 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_ccu_div.c,v 1.1 2017/07/02 00:14:09 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_div_get_rate(struct sunxi_ccu_softc *sc,
+ struct sunxi_ccu_clk *clk)
+{
+ struct sunxi_ccu_div *div = &clk->u.div;
+ struct clk *clkp, *clkp_parent;
+ u_int rate, ratio;
+ uint32_t val;
+
+ KASSERT(clk->type == SUNXI_CCU_DIV);
+
+ 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, div->reg);
+ ratio = __SHIFTOUT(val, div->div);
+ if ((div->flags & SUNXI_CCU_DIV_ZERO_IS_ONE) != 0 && ratio == 0)
+ ratio = 1;
+ if (div->flags & SUNXI_CCU_DIV_POWER_OF_TWO)
+ ratio = 1 << ratio;
+ else
+ ratio++;
+
+ return rate / ratio;
+}
+
+int
+sunxi_ccu_div_set_rate(struct sunxi_ccu_softc *sc,
+ struct sunxi_ccu_clk *clk, u_int new_rate)
+{
+ return EINVAL;
+}
+
+int
+sunxi_ccu_div_set_parent(struct sunxi_ccu_softc *sc,
+ struct sunxi_ccu_clk *clk, const char *name)
+{
+ struct sunxi_ccu_div *div = &clk->u.div;
+ uint32_t val;
+ u_int index;
+
+ KASSERT(clk->type == SUNXI_CCU_DIV);
+
+ if (div->sel == 0)
+ return ENODEV;
+
+ for (index = 0; index < div->nparents; index++) {
+ if (div->parents[index] != NULL &&
+ strcmp(div->parents[index], name) == 0)
+ break;
+ }
+ if (index == div->nparents)
+ return EINVAL;
+
+ val = CCU_READ(sc, div->reg);
+ val &= ~div->sel;
+ val |= __SHIFTIN(index, div->sel);
+ CCU_WRITE(sc, div->reg, val);
+
+ return 0;
+}
+
+const char *
+sunxi_ccu_div_get_parent(struct sunxi_ccu_softc *sc,
+ struct sunxi_ccu_clk *clk)
+{
+ struct sunxi_ccu_div *div = &clk->u.div;
+ u_int index;
+ uint32_t val;
+
+ KASSERT(clk->type == SUNXI_CCU_DIV);
+
+ if (div->sel == 0)
+ return div->parents[0];
+
+ val = CCU_READ(sc, div->reg);
+ index = __SHIFTOUT(val, div->sel);
+
+ return div->parents[index];
+}