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 <jmcne...@invisible.ca> @@ -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 <jmcne...@invisible.ca> @@ -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 <jmcne...@invisible.ca> @@ -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 <jmcne...@invisible.ca> @@ -31,7 +31,7 @@ #include "opt_fdt_arm.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: sunxi_platform.c,v 1.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 <jmcne...@invisible.ca> @@ -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 <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: 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 <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_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 <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_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]; +}