summaryrefslogtreecommitdiffstats
path: root/sys/arm
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arm')
-rw-r--r--sys/arm/allwinner/a10/a10_intc.c10
-rw-r--r--sys/arm/allwinner/a10_ehci.c1
-rw-r--r--sys/arm/allwinner/a10_gpio.c10
-rw-r--r--sys/arm/allwinner/a83t/a83t_padconf.c162
-rw-r--r--sys/arm/allwinner/a83t/a83t_r_padconf.c62
-rw-r--r--sys/arm/allwinner/a83t/files.a83t4
-rw-r--r--sys/arm/allwinner/a83t/std.a83t15
-rw-r--r--sys/arm/allwinner/allwinner_machdep.c24
-rw-r--r--sys/arm/allwinner/allwinner_machdep.h2
-rw-r--r--sys/arm/allwinner/aw_ccu.c133
-rw-r--r--sys/arm/allwinner/aw_mp.c97
-rw-r--r--sys/arm/allwinner/aw_mp.h1
-rw-r--r--sys/arm/allwinner/aw_nmi.c20
-rw-r--r--sys/arm/allwinner/aw_usbphy.c1
-rw-r--r--sys/arm/allwinner/clk/aw_ahbclk.c78
-rw-r--r--sys/arm/allwinner/clk/aw_apbclk.c56
-rw-r--r--sys/arm/allwinner/clk/aw_cpusclk.c320
-rw-r--r--sys/arm/allwinner/clk/aw_gate.c8
-rw-r--r--sys/arm/allwinner/clk/aw_gmacclk.c49
-rw-r--r--sys/arm/allwinner/clk/aw_pll.c27
-rw-r--r--sys/arm/allwinner/clk/aw_usbclk.c21
-rw-r--r--sys/arm/allwinner/files.allwinner2
-rw-r--r--sys/arm/allwinner/if_awg.c1418
-rw-r--r--sys/arm/allwinner/if_awgreg.h181
-rw-r--r--sys/arm/allwinner/std.allwinner1
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_mmc.c2
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_mmc.h2
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c2
-rw-r--r--sys/arm/amlogic/aml8726/aml8726_sdxc-m8.h2
-rw-r--r--sys/arm/arm/cpufunc_asm_arm11.S2
-rw-r--r--sys/arm/arm/exception.S2
-rw-r--r--sys/arm/arm/genassym.c1
-rw-r--r--sys/arm/arm/generic_timer.c10
-rw-r--r--sys/arm/arm/gic.c12
-rw-r--r--sys/arm/arm/machdep.c2
-rw-r--r--sys/arm/arm/mpcore_timer.c4
-rw-r--r--sys/arm/arm/pmap-v4.c6
-rw-r--r--sys/arm/arm/pmap-v6.c4
-rw-r--r--sys/arm/arm/swtch-v4.S2
-rw-r--r--sys/arm/at91/at91_cfata.c2
-rw-r--r--sys/arm/at91/at91_machdep.c2
-rw-r--r--sys/arm/at91/at91_mci.c4
-rw-r--r--sys/arm/at91/at91_reset.S2
-rw-r--r--sys/arm/at91/at91reg.h4
-rw-r--r--sys/arm/at91/at91sam9260.c2
-rw-r--r--sys/arm/at91/if_ate.c12
-rw-r--r--sys/arm/at91/if_atereg.h4
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_audio.c2
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_dma.c4
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_gpio.c208
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2835_intr.c11
-rw-r--r--sys/arm/broadcom/bcm2835/bcm2836.c7
-rw-r--r--sys/arm/cavium/cns11xx/if_ece.c2
-rw-r--r--sys/arm/conf/ALLWINNER2
-rw-r--r--sys/arm/freescale/imx/imx6_ipu.c2
-rw-r--r--sys/arm/freescale/imx/imx6_ssi.c4
-rw-r--r--sys/arm/freescale/imx/imx_gpio.c12
-rw-r--r--sys/arm/freescale/vybrid/vf_uart.c2
-rw-r--r--sys/arm/mv/mpic.c12
-rw-r--r--sys/arm/mv/mv_common.c2
-rw-r--r--sys/arm/nvidia/tegra_gpio.c42
-rw-r--r--sys/arm/qemu/virt_machdep.c17
-rw-r--r--sys/arm/samsung/exynos/exynos5_usb_phy.c2
-rw-r--r--sys/arm/ti/aintc.c10
-rw-r--r--sys/arm/ti/omap4/omap4_prcm_clks.c2
-rw-r--r--sys/arm/ti/ti_gpio.c164
-rw-r--r--sys/arm/ti/ti_gpio.h2
-rw-r--r--sys/arm/ti/ti_i2c.c4
-rw-r--r--sys/arm/ti/ti_pinmux.c2
-rw-r--r--sys/arm/ti/ti_prcm.c2
-rw-r--r--sys/arm/ti/ti_scm.c2
-rw-r--r--sys/arm/ti/ti_sdma.c24
-rw-r--r--sys/arm/xilinx/zy7_slcr.c2
-rw-r--r--sys/arm/xscale/i8134x/crb_machdep.c2
-rw-r--r--sys/arm/xscale/i8134x/i81342reg.h2
-rw-r--r--sys/arm/xscale/ixp425/avila_machdep.c2
-rw-r--r--sys/arm/xscale/ixp425/cambria_gpio.c2
-rw-r--r--sys/arm/xscale/ixp425/ixp425_npe.c6
-rw-r--r--sys/arm/xscale/ixp425/ixp425_npereg.h2
-rw-r--r--sys/arm/xscale/ixp425/ixp425_qmgr.c2
-rw-r--r--sys/arm/xscale/pxa/pxa_machdep.c2
81 files changed, 3059 insertions, 294 deletions
diff --git a/sys/arm/allwinner/a10/a10_intc.c b/sys/arm/allwinner/a10/a10_intc.c
index 7bd8e80..31e6ef4 100644
--- a/sys/arm/allwinner/a10/a10_intc.c
+++ b/sys/arm/allwinner/a10/a10_intc.c
@@ -298,14 +298,18 @@ static int
a10_intr_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
+ struct intr_map_data_fdt *daf;
struct a10_aintc_softc *sc;
- if (data->type != INTR_MAP_DATA_FDT || data->fdt.ncells != 1 ||
- data->fdt.cells[0] >= A10_INTR_MAX_NIRQS)
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
+ daf = (struct intr_map_data_fdt *)data;
+ if (daf->ncells != 1 || daf->cells[0] >= A10_INTR_MAX_NIRQS)
return (EINVAL);
sc = device_get_softc(dev);
- *isrcp = &sc->isrcs[data->fdt.cells[0]].isrc;
+ *isrcp = &sc->isrcs[daf->cells[0]].isrc;
return (0);
}
diff --git a/sys/arm/allwinner/a10_ehci.c b/sys/arm/allwinner/a10_ehci.c
index c325d60..4a9ee80 100644
--- a/sys/arm/allwinner/a10_ehci.c
+++ b/sys/arm/allwinner/a10_ehci.c
@@ -112,6 +112,7 @@ static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-ehci", (uintptr_t)&a10_ehci_conf },
{ "allwinner,sun6i-a31-ehci", (uintptr_t)&a31_ehci_conf },
{ "allwinner,sun7i-a20-ehci", (uintptr_t)&a10_ehci_conf },
+ { "allwinner,sun8i-a83t-ehci", (uintptr_t)&a31_ehci_conf },
{ NULL, (uintptr_t)NULL }
};
diff --git a/sys/arm/allwinner/a10_gpio.c b/sys/arm/allwinner/a10_gpio.c
index 4e6e612..079e715 100644
--- a/sys/arm/allwinner/a10_gpio.c
+++ b/sys/arm/allwinner/a10_gpio.c
@@ -99,6 +99,12 @@ extern const struct allwinner_padconf a31s_padconf;
extern const struct allwinner_padconf a31_r_padconf;
#endif
+/* Defined in a83t_padconf.c */
+#ifdef SOC_ALLWINNER_A83T
+extern const struct allwinner_padconf a83t_padconf;
+extern const struct allwinner_padconf a83t_r_padconf;
+#endif
+
static struct ofw_compat_data compat_data[] = {
#ifdef SOC_ALLWINNER_A10
{"allwinner,sun4i-a10-pinctrl", (uintptr_t)&a10_padconf},
@@ -115,6 +121,10 @@ static struct ofw_compat_data compat_data[] = {
#if defined(SOC_ALLWINNER_A31) || defined(SOC_ALLWINNER_A31S)
{"allwinner,sun6i-a31-r-pinctrl", (uintptr_t)&a31_r_padconf},
#endif
+#ifdef SOC_ALLWINNER_A83T
+ {"allwinner,sun8i-a83t-pinctrl", (uintptr_t)&a83t_padconf},
+ {"allwinner,sun8i-a83t-r-pinctrl", (uintptr_t)&a83t_r_padconf},
+#endif
{NULL, 0}
};
diff --git a/sys/arm/allwinner/a83t/a83t_padconf.c b/sys/arm/allwinner/a83t/a83t_padconf.c
new file mode 100644
index 0000000..bbf638e
--- /dev/null
+++ b/sys/arm/allwinner/a83t/a83t_padconf.c
@@ -0,0 +1,162 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/types.h>
+
+#include <arm/allwinner/allwinner_pinctrl.h>
+
+#ifdef SOC_ALLWINNER_A83T
+
+static const struct allwinner_pins a83t_pins[] = {
+ { "PB0", 1, 0, { "gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "eint" } },
+ { "PB1", 1, 1, { "gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "eint" } },
+ { "PB2", 1, 2, { "gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "eint" } },
+ { "PB3", 1, 3, { "gpio_in", "gpio_out", "uart2", "jtag", NULL, NULL, "eint" } },
+ { "PB4", 1, 4, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
+ { "PB5", 1, 5, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
+ { "PB6", 1, 6, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
+ { "PB7", 1, 7, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
+ { "PB8", 1, 8, { "gpio_in", "gpio_out", "i2s0", "tdm", NULL, NULL, "eint" } },
+ { "PB9", 1, 9, { "gpio_in", "gpio_out", "uart0", NULL, NULL, NULL, "eint" } },
+ { "PB10", 1, 10, { "gpio_in", "gpio_out", "uart0", NULL, NULL, NULL, "eint" } },
+
+ { "PC0", 2, 0, { "gpio_in", "gpio_out", "nand", "spi0" } },
+ { "PC1", 2, 1, { "gpio_in", "gpio_out", "nand", "spi0" } },
+ { "PC2", 2, 2, { "gpio_in", "gpio_out", "nand", "spi0" } },
+ { "PC3", 2, 3, { "gpio_in", "gpio_out", "nand", "spi0" } },
+ { "PC4", 2, 4, { "gpio_in", "gpio_out", "nand" } },
+ { "PC5", 2, 5, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC6", 2, 6, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC7", 2, 7, { "gpio_in", "gpio_out", "nand" } },
+ { "PC8", 2, 8, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC9", 2, 9, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC10", 2, 10, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC11", 2, 11, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC12", 2, 12, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC13", 2, 13, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC14", 2, 14, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC15", 2, 15, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC16", 2, 16, { "gpio_in", "gpio_out", "nand", "mmc2" } },
+ { "PC17", 2, 17, { "gpio_in", "gpio_out", "nand" } },
+ { "PC18", 2, 18, { "gpio_in", "gpio_out", "nand" } },
+
+ { "PD2", 3, 2, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD3", 3, 3, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD4", 3, 4, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD5", 3, 5, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD6", 3, 6, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD7", 3, 7, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD10", 3, 10, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD11", 3, 11, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD12", 3, 12, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD13", 3, 13, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD14", 3, 14, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD15", 3, 15, { "gpio_in", "gpio_out", "lcd", NULL, "emac" } },
+ { "PD18", 3, 18, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
+ { "PD19", 3, 19, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
+ { "PD20", 3, 20, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
+ { "PD21", 3, 21, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
+ { "PD22", 3, 22, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
+ { "PD23", 3, 23, { "gpio_in", "gpio_out", "lcd", "lvds", "emac" } },
+ { "PD24", 3, 24, { "gpio_in", "gpio_out", "lcd", "lvds" } },
+ { "PD25", 3, 25, { "gpio_in", "gpio_out", "lcd", "lvds" } },
+ { "PD26", 3, 26, { "gpio_in", "gpio_out", "lcd", "lvds" } },
+ { "PD27", 3, 27, { "gpio_in", "gpio_out", "lcd", "lvds" } },
+ { "PD28", 3, 28, { "gpio_in", "gpio_out", "pwm" } },
+ { "PD29", 3, 29, { "gpio_in", "gpio_out" } },
+
+ { "PE0", 4, 0, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE1", 4, 1, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE2", 4, 2, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE3", 4, 3, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE4", 4, 4, { "gpio_in", "gpio_out", "csi" } },
+ { "PE5", 4, 5, { "gpio_in", "gpio_out", "csi" } },
+ { "PE6", 4, 6, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE7", 4, 7, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE8", 4, 8, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE9", 4, 9, { "gpio_in", "gpio_out", "csi", NULL, "ccir" } },
+ { "PE10", 4, 10, { "gpio_in", "gpio_out", "csi", "uart4", "ccir" } },
+ { "PE11", 4, 11, { "gpio_in", "gpio_out", "csi", "uart4", "ccir" } },
+ { "PE12", 4, 12, { "gpio_in", "gpio_out", "csi", "uart4", "ccir" } },
+ { "PE13", 4, 13, { "gpio_in", "gpio_out", "csi", "uart4", "ccir" } },
+ { "PE14", 4, 14, { "gpio_in", "gpio_out", "csi", "twi2" } },
+ { "PE15", 4, 15, { "gpio_in", "gpio_out", "csi", "twi2" } },
+ { "PE16", 4, 16, { "gpio_in", "gpio_out" } },
+ { "PE17", 4, 17, { "gpio_in", "gpio_out" } },
+ { "PE18", 4, 18, { "gpio_in", "gpio_out", NULL, "owa" } },
+ { "PE19", 4, 19, { "gpio_in", "gpio_out" } },
+
+ { "PF0", 5, 0, { "gpio_in", "gpio_out", "mmc0", "jtag" } },
+ { "PF1", 5, 1, { "gpio_in", "gpio_out", "mmc0", "jtag" } },
+ { "PF2", 5, 2, { "gpio_in", "gpio_out", "mmc0", "uart0" } },
+ { "PF3", 5, 3, { "gpio_in", "gpio_out", "mmc0", "jtag" } },
+ { "PF4", 5, 4, { "gpio_in", "gpio_out", "mmc0", "uart0" } },
+ { "PF5", 5, 5, { "gpio_in", "gpio_out", "mmc0", "jtag" } },
+ { "PF6", 5, 6, { "gpio_in", "gpio_out" } },
+
+ { "PG0", 6, 0, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
+ { "PG1", 6, 1, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
+ { "PG2", 6, 2, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
+ { "PG3", 6, 3, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
+ { "PG4", 6, 4, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
+ { "PG5", 6, 5, { "gpio_in", "gpio_out", "mmc1", NULL, NULL, NULL, "eint" } },
+ { "PG6", 6, 6, { "gpio_in", "gpio_out", "uart1", "spi1", NULL, NULL, "eint" } },
+ { "PG7", 6, 7, { "gpio_in", "gpio_out", "uart1", "spi1", NULL, NULL, "eint" } },
+ { "PG8", 6, 8, { "gpio_in", "gpio_out", "uart1", "spi1", NULL, NULL, "eint" } },
+ { "PG9", 6, 9, { "gpio_in", "gpio_out", "uart1", "spi1", NULL, NULL, "eint" } },
+ { "PG10", 6, 10, { "gpio_in", "gpio_out", "i2s1", "uart3", NULL, NULL, "eint" } },
+ { "PG11", 6, 11, { "gpio_in", "gpio_out", "i2s1", "uart3", NULL, NULL, "eint" } },
+ { "PG12", 6, 12, { "gpio_in", "gpio_out", "i2s1", "uart3", NULL, NULL, "eint" } },
+ { "PG13", 6, 13, { "gpio_in", "gpio_out", "i2s1", "uart3", NULL, NULL, "eint" } },
+
+ { "PH0", 7, 0, { "gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, "eint" } },
+ { "PH1", 7, 1, { "gpio_in", "gpio_out", "i2c0", NULL, NULL, NULL, "eint" } },
+ { "PH2", 7, 2, { "gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, "eint" } },
+ { "PH3", 7, 3, { "gpio_in", "gpio_out", "i2c1", NULL, NULL, NULL, "eint" } },
+ { "PH4", 7, 4, { "gpio_in", "gpio_out", "i2c2", NULL, NULL, NULL, "eint" } },
+ { "PH5", 7, 5, { "gpio_in", "gpio_out", "i2c2", NULL, NULL, NULL, "eint" } },
+ { "PH6", 7, 6, { "gpio_in", "gpio_out", "hdmiddc", NULL, NULL, NULL, "eint" } },
+ { "PH7", 7, 7, { "gpio_in", "gpio_out", "hdmiddc", NULL, NULL, NULL, "eint" } },
+ { "PH8", 7, 8, { "gpio_in", "gpio_out", "hdmiddc", NULL, NULL, NULL, "eint" } },
+ { "PH9", 7, 9, { "gpio_in", "gpio_out", NULL, NULL, NULL, NULL, "eint" } },
+ { "PH10", 7, 10, { "gpio_in", "gpio_out", NULL, NULL, NULL, NULL, "eint" } },
+ { "PH11", 7, 11, { "gpio_in", "gpio_out", NULL, NULL, NULL, NULL, "eint" } },
+};
+
+const struct allwinner_padconf a83t_padconf = {
+ .npins = nitems(a83t_pins),
+ .pins = a83t_pins,
+};
+
+#endif /* !SOC_ALLWINNER_A83T */
diff --git a/sys/arm/allwinner/a83t/a83t_r_padconf.c b/sys/arm/allwinner/a83t/a83t_r_padconf.c
new file mode 100644
index 0000000..e463745
--- /dev/null
+++ b/sys/arm/allwinner/a83t/a83t_r_padconf.c
@@ -0,0 +1,62 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/types.h>
+
+#include <arm/allwinner/allwinner_pinctrl.h>
+
+#ifdef SOC_ALLWINNER_A83T
+
+static const struct allwinner_pins a83t_r_pins[] = {
+ { "PL0", 0, 0, { "gpio_in", "gpio_out", "s_rsb", "s_i2c", NULL, NULL, "eint" } },
+ { "PL1", 0, 1, { "gpio_in", "gpio_out", "s_rsb", "s_i2c", NULL, NULL, "eint" } },
+ { "PL2", 0, 2, { "gpio_in", "gpio_out", "s_uart", NULL, NULL, NULL, "eint" } },
+ { "PL3", 0, 3, { "gpio_in", "gpio_out", "s_uart", NULL, NULL, NULL, "eint" } },
+ { "PL4", 0, 4, { "gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "eint" } },
+ { "PL5", 0, 5, { "gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "eint" } },
+ { "PL6", 0, 6, { "gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "eint" } },
+ { "PL7", 0, 7, { "gpio_in", "gpio_out", "s_jtag", NULL, NULL, NULL, "eint" } },
+ { "PL8", 0, 8, { "gpio_in", "gpio_out", "s_i2c", NULL, NULL, NULL, "eint" } },
+ { "PL9", 0, 9, { "gpio_in", "gpio_out", "s_i2c", NULL, NULL, NULL, "eint" } },
+ { "PL10", 0, 10, { "gpio_in", "gpio_out", "s_pwm", NULL, NULL, NULL, "eint" } },
+ { "PL11", 0, 11, { "gpio_in", "gpio_out", NULL, NULL, NULL, "eint" } },
+ { "PL12", 0, 12, { "gpio_in", "gpio_out", "s_cir", NULL, NULL, NULL, "eint" } },
+};
+
+const struct allwinner_padconf a83t_r_padconf = {
+ .npins = nitems(a83t_r_pins),
+ .pins = a83t_r_pins,
+};
+
+#endif /* !SOC_ALLWINNER_A83T */
diff --git a/sys/arm/allwinner/a83t/files.a83t b/sys/arm/allwinner/a83t/files.a83t
new file mode 100644
index 0000000..45334a0
--- /dev/null
+++ b/sys/arm/allwinner/a83t/files.a83t
@@ -0,0 +1,4 @@
+# $FreeBSD$
+
+arm/allwinner/a83t/a83t_padconf.c standard
+arm/allwinner/a83t/a83t_r_padconf.c standard
diff --git a/sys/arm/allwinner/a83t/std.a83t b/sys/arm/allwinner/a83t/std.a83t
new file mode 100644
index 0000000..06b1ed4
--- /dev/null
+++ b/sys/arm/allwinner/a83t/std.a83t
@@ -0,0 +1,15 @@
+# Allwinner A83T common options
+#$FreeBSD$
+
+cpu CPU_CORTEXA
+machine arm armv6
+makeoptions CONF_CFLAGS="-march=armv7a"
+
+makeoptions KERNVIRTADDR=0xc0200000
+options KERNVIRTADDR=0xc0200000
+
+options IPI_IRQ_START=0
+options IPI_IRQ_END=15
+
+files "../allwinner/files.allwinner"
+files "../allwinner/a83t/files.a83t"
diff --git a/sys/arm/allwinner/allwinner_machdep.c b/sys/arm/allwinner/allwinner_machdep.c
index e5c8eb8..7916441 100644
--- a/sys/arm/allwinner/allwinner_machdep.c
+++ b/sys/arm/allwinner/allwinner_machdep.c
@@ -94,6 +94,15 @@ a31s_attach(platform_t plat)
return (0);
}
+static int
+a83t_attach(platform_t plat)
+{
+ soc_type = ALLWINNERSOC_A83T;
+ soc_family = ALLWINNERSOC_SUN8I;
+
+ return (0);
+}
+
static vm_offset_t
allwinner_lastaddr(platform_t plat)
{
@@ -196,6 +205,21 @@ static platform_method_t a31s_methods[] = {
FDT_PLATFORM_DEF(a31s, "a31s", 0, "allwinner,sun6i-a31s", 200);
#endif
+#if defined(SOC_ALLWINNER_A83T)
+static platform_method_t a83t_methods[] = {
+ PLATFORMMETHOD(platform_attach, a83t_attach),
+ PLATFORMMETHOD(platform_lastaddr, allwinner_lastaddr),
+ PLATFORMMETHOD(platform_devmap_init, allwinner_devmap_init),
+
+#ifdef SMP
+ PLATFORMMETHOD(platform_mp_start_ap, a83t_mp_start_ap),
+ PLATFORMMETHOD(platform_mp_setmaxid, aw_mp_setmaxid),
+#endif
+ PLATFORMMETHOD_END,
+};
+FDT_PLATFORM_DEF(a83t, "a83t", 0, "allwinner,sun8i-a83t", 200);
+#endif
+
u_int
allwinner_soc_type(void)
{
diff --git a/sys/arm/allwinner/allwinner_machdep.h b/sys/arm/allwinner/allwinner_machdep.h
index c640494..91c97ac 100644
--- a/sys/arm/allwinner/allwinner_machdep.h
+++ b/sys/arm/allwinner/allwinner_machdep.h
@@ -36,11 +36,13 @@
#define ALLWINNERSOC_A20 0x20000000
#define ALLWINNERSOC_A31 0x31000000
#define ALLWINNERSOC_A31S 0x31000001
+#define ALLWINNERSOC_A83T 0x83000000
#define ALLWINNERSOC_SUN4I 0x40000000
#define ALLWINNERSOC_SUN5I 0x50000000
#define ALLWINNERSOC_SUN6I 0x60000000
#define ALLWINNERSOC_SUN7I 0x70000000
+#define ALLWINNERSOC_SUN8I 0x80000000
u_int allwinner_soc_type(void);
u_int allwinner_soc_family(void);
diff --git a/sys/arm/allwinner/aw_ccu.c b/sys/arm/allwinner/aw_ccu.c
index d2ce774..a8342ca 100644
--- a/sys/arm/allwinner/aw_ccu.c
+++ b/sys/arm/allwinner/aw_ccu.c
@@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$");
#include <machine/bus.h>
#include <dev/fdt/simplebus.h>
+#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_bus.h>
#include <dev/ofw/ofw_bus_subr.h>
@@ -53,40 +54,74 @@ __FBSDID("$FreeBSD$");
#define CCU_BASE 0x01c20000
#define CCU_SIZE 0x400
+#define PRCM_BASE 0x01f01400
+#define PRCM_SIZE 0x200
+
+#define SYSCTRL_BASE 0x01c00000
+#define SYSCTRL_SIZE 0x34
+
struct aw_ccu_softc {
struct simplebus_softc sc;
bus_space_tag_t bst;
- bus_space_handle_t bsh;
+ bus_space_handle_t ccu_bsh;
+ bus_space_handle_t prcm_bsh;
+ bus_space_handle_t sysctrl_bsh;
struct mtx mtx;
+ int flags;
};
+#define CLOCK_CCU (1 << 0)
+#define CLOCK_PRCM (1 << 1)
+#define CLOCK_SYSCTRL (1 << 2)
+
static struct ofw_compat_data compat_data[] = {
- { "allwinner,sun4i-a10", 1 },
- { "allwinner,sun7i-a20", 1 },
- { "allwinner,sun6i-a31", 1 },
- { "allwinner,sun6i-a31s", 1 },
+ { "allwinner,sun4i-a10", CLOCK_CCU },
+ { "allwinner,sun7i-a20", CLOCK_CCU },
+ { "allwinner,sun6i-a31", CLOCK_CCU },
+ { "allwinner,sun6i-a31s", CLOCK_CCU },
+ { "allwinner,sun8i-a83t", CLOCK_CCU|CLOCK_PRCM|CLOCK_SYSCTRL },
{ NULL, 0 }
};
static int
-aw_ccu_check_addr(bus_addr_t addr)
+aw_ccu_check_addr(struct aw_ccu_softc *sc, bus_addr_t addr,
+ bus_space_handle_t *pbsh, bus_size_t *poff)
{
- if (addr < CCU_BASE || addr >= (CCU_BASE + CCU_SIZE))
- return (EINVAL);
- return (0);
+ if (addr >= CCU_BASE && addr < (CCU_BASE + CCU_SIZE) &&
+ (sc->flags & CLOCK_CCU) != 0) {
+ *poff = addr - CCU_BASE;
+ *pbsh = sc->ccu_bsh;
+ return (0);
+ }
+ if (addr >= PRCM_BASE && addr < (PRCM_BASE + PRCM_SIZE) &&
+ (sc->flags & CLOCK_PRCM) != 0) {
+ *poff = addr - PRCM_BASE;
+ *pbsh = sc->prcm_bsh;
+ return (0);
+ }
+ if (addr >= SYSCTRL_BASE && addr < (SYSCTRL_BASE + SYSCTRL_SIZE) &&
+ (sc->flags & CLOCK_SYSCTRL) != 0) {
+ *poff = addr - SYSCTRL_BASE;
+ *pbsh = sc->sysctrl_bsh;
+ return (0);
+ }
+ return (EINVAL);
}
static int
aw_ccu_write_4(device_t dev, bus_addr_t addr, uint32_t val)
{
struct aw_ccu_softc *sc;
+ bus_space_handle_t bsh;
+ bus_size_t reg;
- if (aw_ccu_check_addr(addr) != 0)
+ sc = device_get_softc(dev);
+
+ if (aw_ccu_check_addr(sc, addr, &bsh, &reg) != 0)
return (EINVAL);
- sc = device_get_softc(dev);
mtx_assert(&sc->mtx, MA_OWNED);
- bus_space_write_4(sc->bst, sc->bsh, addr - CCU_BASE, val);
+ bus_space_write_4(sc->bst, bsh, reg, val);
return (0);
}
@@ -95,13 +130,16 @@ static int
aw_ccu_read_4(device_t dev, bus_addr_t addr, uint32_t *val)
{
struct aw_ccu_softc *sc;
+ bus_space_handle_t bsh;
+ bus_size_t reg;
+
+ sc = device_get_softc(dev);
- if (aw_ccu_check_addr(addr) != 0)
+ if (aw_ccu_check_addr(sc, addr, &bsh, &reg) != 0)
return (EINVAL);
- sc = device_get_softc(dev);
mtx_assert(&sc->mtx, MA_OWNED);
- *val = bus_space_read_4(sc->bst, sc->bsh, addr - CCU_BASE);
+ *val = bus_space_read_4(sc->bst, bsh, reg);
return (0);
}
@@ -110,17 +148,20 @@ static int
aw_ccu_modify_4(device_t dev, bus_addr_t addr, uint32_t clr, uint32_t set)
{
struct aw_ccu_softc *sc;
+ bus_space_handle_t bsh;
+ bus_size_t reg;
uint32_t val;
- if (aw_ccu_check_addr(addr) != 0)
+ sc = device_get_softc(dev);
+
+ if (aw_ccu_check_addr(sc, addr, &bsh, &reg) != 0)
return (EINVAL);
- sc = device_get_softc(dev);
mtx_assert(&sc->mtx, MA_OWNED);
- val = bus_space_read_4(sc->bst, sc->bsh, addr - CCU_BASE);
+ val = bus_space_read_4(sc->bst, bsh, reg);
val &= ~clr;
val |= set;
- bus_space_write_4(sc->bst, sc->bsh, addr - CCU_BASE, val);
+ bus_space_write_4(sc->bst, bsh, reg, val);
return (0);
}
@@ -143,20 +184,32 @@ aw_ccu_device_unlock(device_t dev)
mtx_unlock(&sc->mtx);
}
+static const struct ofw_compat_data *
+aw_ccu_search_compatible(void)
+{
+ const struct ofw_compat_data *compat;
+ phandle_t root;
+
+ root = OF_finddevice("/");
+ for (compat = compat_data; compat_data->ocd_str != NULL; compat++)
+ if (fdt_is_compatible(root, compat->ocd_str))
+ break;
+
+ return (compat);
+}
+
static int
aw_ccu_probe(device_t dev)
{
const char *name;
- device_t pdev;
name = ofw_bus_get_name(dev);
if (name == NULL || strcmp(name, "clocks") != 0)
return (ENXIO);
- pdev = device_get_parent(dev);
- if (ofw_bus_search_compatible(pdev, compat_data)->ocd_data == 0)
- return (0);
+ if (aw_ccu_search_compatible()->ocd_data == 0)
+ return (ENXIO);
device_set_desc(dev, "Allwinner Clock Control Unit");
return (BUS_PROBE_SPECIFIC);
@@ -175,15 +228,37 @@ aw_ccu_attach(device_t dev)
simplebus_init(dev, node);
+ sc->flags = aw_ccu_search_compatible()->ocd_data;
+
/*
- * Map CCU registers. The DT doesn't have a "reg" property for the
- * /clocks node and child nodes have conflicting "reg" properties.
+ * Map registers. The DT doesn't have a "reg" property
+ * for the /clocks node and child nodes have conflicting "reg"
+ * properties.
*/
sc->bst = bus_get_bus_tag(dev);
- error = bus_space_map(sc->bst, CCU_BASE, CCU_SIZE, 0, &sc->bsh);
- if (error != 0) {
- device_printf(dev, "couldn't map CCU: %d\n", error);
- return (error);
+ if (sc->flags & CLOCK_CCU) {
+ error = bus_space_map(sc->bst, CCU_BASE, CCU_SIZE, 0,
+ &sc->ccu_bsh);
+ if (error != 0) {
+ device_printf(dev, "couldn't map CCU: %d\n", error);
+ return (error);
+ }
+ }
+ if (sc->flags & CLOCK_PRCM) {
+ error = bus_space_map(sc->bst, PRCM_BASE, PRCM_SIZE, 0,
+ &sc->prcm_bsh);
+ if (error != 0) {
+ device_printf(dev, "couldn't map PRCM: %d\n", error);
+ return (error);
+ }
+ }
+ if (sc->flags & CLOCK_SYSCTRL) {
+ error = bus_space_map(sc->bst, SYSCTRL_BASE, SYSCTRL_SIZE, 0,
+ &sc->sysctrl_bsh);
+ if (error != 0) {
+ device_printf(dev, "couldn't map SYSCTRL: %d\n", error);
+ return (error);
+ }
}
mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
diff --git a/sys/arm/allwinner/aw_mp.c b/sys/arm/allwinner/aw_mp.c
index 9e46f2d..ce0dddd 100644
--- a/sys/arm/allwinner/aw_mp.c
+++ b/sys/arm/allwinner/aw_mp.c
@@ -55,6 +55,9 @@ __FBSDID("$FreeBSD$");
#define CPUCFG_SIZE 0x400
#define PRCM_BASE 0x01f01400
#define PRCM_SIZE 0x800
+/* Register for multi-cluster SoC */
+#define CPUXCFG_BASE 0x01700000
+#define CPUXCFG_SIZE 0x400
#define CPU_OFFSET 0x40
#define CPU_OFFSET_CTL 0x04
@@ -80,6 +83,14 @@ __FBSDID("$FreeBSD$");
#define CPUCFG_DBGCTL0 0x1e0
#define CPUCFG_DBGCTL1 0x1e4
+#define CPUS_CL_RST(cl) (0x30 + (cluster) * 0x4)
+#define CPUX_CL_CTRL0(cl) (0x0 + (cluster) * 0x10)
+#define CPUX_CL_CTRL1(cl) (0x4 + (cluster) * 0x10)
+#define CPUX_CL_CPU_STATUS(cl) (0x30 + (cluster) * 0x4)
+#define CPUX_CL_RST(cl) (0x80 + (cluster) * 0x4)
+#define PRCM_CL_PWROFF(cl) (0x100 + (cluster) * 0x4)
+#define PRCM_CL_PWR_CLAMP(cl, cpu) (0x140 + (cluster) * 0x4 + (cpu) * 0x4)
+
void
aw_mp_setmaxid(platform_t plat)
{
@@ -202,3 +213,89 @@ a31_mp_start_ap(platform_t plat)
bus_space_unmap(fdtbus_bs_tag, cpucfg, CPUCFG_SIZE);
bus_space_unmap(fdtbus_bs_tag, prcm, PRCM_SIZE);
}
+
+static void
+aw_mc_mp_start_cpu(bus_space_handle_t cpuscfg, bus_space_handle_t cpuxcfg,
+ bus_space_handle_t prcm, int cluster, int cpu)
+{
+ uint32_t val;
+ int i;
+
+ /* Assert core reset */
+ val = bus_space_read_4(fdtbus_bs_tag, cpuxcfg, CPUX_CL_RST(cluster));
+ val &= ~(1 << cpu);
+ bus_space_write_4(fdtbus_bs_tag, cpuxcfg, CPUX_CL_RST(cluster), val);
+
+ /* Assert power-on reset */
+ val = bus_space_read_4(fdtbus_bs_tag, cpuscfg, CPUS_CL_RST(cluster));
+ val &= ~(1 << cpu);
+ bus_space_write_4(fdtbus_bs_tag, cpuscfg, CPUS_CL_RST(cluster), val);
+
+ /* Disable automatic L1 cache invalidate at reset */
+ val = bus_space_read_4(fdtbus_bs_tag, cpuxcfg, CPUX_CL_CTRL0(cluster));
+ val &= ~(1 << cpu);
+ bus_space_write_4(fdtbus_bs_tag, cpuxcfg, CPUX_CL_CTRL0(cluster), val);
+
+ /* Release power clamp */
+ for (i = 0; i <= CPU_PWR_CLAMP_STEPS; i++)
+ bus_space_write_4(fdtbus_bs_tag, prcm,
+ PRCM_CL_PWR_CLAMP(cluster, cpu), 0xff >> i);
+ while (bus_space_read_4(fdtbus_bs_tag, prcm,
+ PRCM_CL_PWR_CLAMP(cluster, cpu)) != 0)
+ ;
+
+ /* Clear power-off gating */
+ val = bus_space_read_4(fdtbus_bs_tag, prcm, PRCM_CL_PWROFF(cluster));
+ val &= ~(1 << cpu);
+ bus_space_write_4(fdtbus_bs_tag, prcm, PRCM_CL_PWROFF(cluster), val);
+
+ /* De-assert power-on reset */
+ val = bus_space_read_4(fdtbus_bs_tag, cpuscfg, CPUS_CL_RST(cluster));
+ val |= (1 << cpu);
+ bus_space_write_4(fdtbus_bs_tag, cpuscfg, CPUS_CL_RST(cluster), val);
+
+ /* De-assert core reset */
+ val = bus_space_read_4(fdtbus_bs_tag, cpuxcfg, CPUX_CL_RST(cluster));
+ val |= (1 << cpu);
+ bus_space_write_4(fdtbus_bs_tag, cpuxcfg, CPUX_CL_RST(cluster), val);
+}
+
+static void
+aw_mc_mp_start_ap(bus_space_handle_t cpuscfg, bus_space_handle_t cpuxcfg,
+ bus_space_handle_t prcm)
+{
+ int cluster, cpu;
+
+ KASSERT(mp_ncpus <= 4, ("multiple clusters not yet supported"));
+
+ dcache_wbinv_poc_all();
+
+ bus_space_write_4(fdtbus_bs_tag, cpuscfg, CPUCFG_P_REG0,
+ pmap_kextract((vm_offset_t)mpentry));
+
+ cluster = 0;
+ for (cpu = 1; cpu < mp_ncpus; cpu++)
+ aw_mc_mp_start_cpu(cpuscfg, cpuxcfg, prcm, cluster, cpu);
+}
+
+void
+a83t_mp_start_ap(platform_t plat)
+{
+ bus_space_handle_t cpuscfg, cpuxcfg, prcm;
+
+ if (bus_space_map(fdtbus_bs_tag, CPUCFG_BASE, CPUCFG_SIZE,
+ 0, &cpuscfg) != 0)
+ panic("Couldn't map the CPUCFG\n");
+ if (bus_space_map(fdtbus_bs_tag, CPUXCFG_BASE, CPUXCFG_SIZE,
+ 0, &cpuxcfg) != 0)
+ panic("Couldn't map the CPUXCFG\n");
+ if (bus_space_map(fdtbus_bs_tag, PRCM_BASE, PRCM_SIZE, 0,
+ &prcm) != 0)
+ panic("Couldn't map the PRCM\n");
+
+ aw_mc_mp_start_ap(cpuscfg, cpuxcfg, prcm);
+ armv7_sev();
+ bus_space_unmap(fdtbus_bs_tag, cpuxcfg, CPUXCFG_SIZE);
+ bus_space_unmap(fdtbus_bs_tag, cpuscfg, CPUCFG_SIZE);
+ bus_space_unmap(fdtbus_bs_tag, prcm, PRCM_SIZE);
+}
diff --git a/sys/arm/allwinner/aw_mp.h b/sys/arm/allwinner/aw_mp.h
index 402147a..591ecea 100644
--- a/sys/arm/allwinner/aw_mp.h
+++ b/sys/arm/allwinner/aw_mp.h
@@ -31,5 +31,6 @@
void aw_mp_setmaxid(platform_t plat);
void a20_mp_start_ap(platform_t plat);
void a31_mp_start_ap(platform_t plat);
+void a83t_mp_start_ap(platform_t plat);
#endif /* _AW_MP_H_ */
diff --git a/sys/arm/allwinner/aw_nmi.c b/sys/arm/allwinner/aw_nmi.c
index 1cdd50e..2b23a4b 100644
--- a/sys/arm/allwinner/aw_nmi.c
+++ b/sys/arm/allwinner/aw_nmi.c
@@ -188,16 +188,18 @@ static int
aw_nmi_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
+ struct intr_map_data_fdt *daf;
struct aw_nmi_softc *sc;
int error;
u_int irq;
- sc = device_get_softc(dev);
if (data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
- error = aw_nmi_map_fdt(dev, data->fdt.ncells, data->fdt.cells, &irq,
- NULL, NULL);
+ sc = device_get_softc(dev);
+ daf = (struct intr_map_data_fdt *)data;
+
+ error = aw_nmi_map_fdt(dev, daf->ncells, daf->cells, &irq, NULL, NULL);
if (error == 0)
*isrcp = &sc->intr.isrc;
@@ -208,6 +210,7 @@ static int
aw_nmi_setup_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
+ struct intr_map_data_fdt *daf;
struct aw_nmi_softc *sc;
struct aw_nmi_intr *nmi_intr;
int error, icfg;
@@ -215,14 +218,15 @@ aw_nmi_setup_intr(device_t dev, struct intr_irqsrc *isrc,
enum intr_trigger trig;
enum intr_polarity pol;
- sc = device_get_softc(dev);
- nmi_intr = (struct aw_nmi_intr *)isrc;
-
/* Get config for interrupt. */
if (data == NULL || data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
- error = aw_nmi_map_fdt(dev, data->fdt.ncells, data->fdt.cells, &irq,
- &pol, &trig);
+
+ sc = device_get_softc(dev);
+ nmi_intr = (struct aw_nmi_intr *)isrc;
+ daf = (struct intr_map_data_fdt *)data;
+
+ error = aw_nmi_map_fdt(dev, daf->ncells, daf->cells, &irq, &pol, &trig);
if (error != 0)
return (error);
if (nmi_intr->irq != irq)
diff --git a/sys/arm/allwinner/aw_usbphy.c b/sys/arm/allwinner/aw_usbphy.c
index 25e8da0..31d2313 100644
--- a/sys/arm/allwinner/aw_usbphy.c
+++ b/sys/arm/allwinner/aw_usbphy.c
@@ -55,6 +55,7 @@ static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun5i-a13-usb-phy", 1 },
{ "allwinner,sun6i-a31-usb-phy", 1 },
{ "allwinner,sun7i-a20-usb-phy", 1 },
+ { "allwinner,sun8i-a83t-usb-phy", 1 },
{ NULL, 0 }
};
diff --git a/sys/arm/allwinner/clk/aw_ahbclk.c b/sys/arm/allwinner/clk/aw_ahbclk.c
index 1d3b1a4..00a0afe 100644
--- a/sys/arm/allwinner/clk/aw_ahbclk.c
+++ b/sys/arm/allwinner/clk/aw_ahbclk.c
@@ -63,16 +63,35 @@ __FBSDID("$FreeBSD$");
#define A31_AHB1_CLK_SRC_SEL_MAX 3
#define A31_AHB1_CLK_SRC_SEL_SHIFT 12
+#define A83T_AHB1_CLK_SRC_SEL (0x3 << 12)
+#define A83T_AHB1_CLK_SRC_SEL_ISPLL(x) ((x) & 0x2)
+#define A83T_AHB1_CLK_SRC_SEL_MAX 3
+#define A83T_AHB1_CLK_SRC_SEL_SHIFT 12
+#define A83T_AHB1_PRE_DIV (0x3 << 6)
+#define A83T_AHB1_PRE_DIV_SHIFT 6
+#define A83T_AHB1_CLK_DIV_RATIO (0x3 << 4)
+#define A83T_AHB1_CLK_DIV_RATIO_SHIFT 4
+
+#define H3_AHB2_CLK_CFG (0x3 << 0)
+#define H3_AHB2_CLK_CFG_SHIFT 0
+#define H3_AHB2_CLK_CFG_AHB1 0
+#define H3_AHB2_CLK_CFG_PLL_PERIPH_DIV2 1
+#define H3_AHB2_CLK_CFG_MAX 1
+
enum aw_ahbclk_type {
AW_A10_AHB = 1,
AW_A13_AHB,
AW_A31_AHB1,
+ AW_A83T_AHB1,
+ AW_H3_AHB2,
};
static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-ahb-clk", AW_A10_AHB },
{ "allwinner,sun5i-a13-ahb-clk", AW_A13_AHB },
{ "allwinner,sun6i-a31-ahb1-clk", AW_A31_AHB1 },
+ { "allwinner,sun8i-a83t-ahb1-clk", AW_A83T_AHB1 },
+ { "allwinner,sun8i-h3-ahb2-clk", AW_H3_AHB2 },
{ NULL, 0 }
};
@@ -113,6 +132,19 @@ aw_ahbclk_init(struct clknode *clk, device_t dev)
index = (val & A31_AHB1_CLK_SRC_SEL) >>
A31_AHB1_CLK_SRC_SEL_SHIFT;
break;
+ case AW_A83T_AHB1:
+ DEVICE_LOCK(sc);
+ AHBCLK_READ(sc, &val);
+ DEVICE_UNLOCK(sc);
+ index = (val & A83T_AHB1_CLK_SRC_SEL) >>
+ A83T_AHB1_CLK_SRC_SEL_SHIFT;
+ break;
+ case AW_H3_AHB2:
+ DEVICE_LOCK(sc);
+ AHBCLK_READ(sc, &val);
+ DEVICE_UNLOCK(sc);
+ index = (val & H3_AHB2_CLK_CFG) >> H3_AHB2_CLK_CFG_SHIFT;
+ break;
default:
return (ENXIO);
}
@@ -133,11 +165,10 @@ aw_ahbclk_recalc_freq(struct clknode *clk, uint64_t *freq)
AHBCLK_READ(sc, &val);
DEVICE_UNLOCK(sc);
- div = 1 << ((val & A10_AHB_CLK_DIV_RATIO) >>
- A10_AHB_CLK_DIV_RATIO_SHIFT);
-
switch (sc->type) {
case AW_A31_AHB1:
+ div = 1 << ((val & A10_AHB_CLK_DIV_RATIO) >>
+ A10_AHB_CLK_DIV_RATIO_SHIFT);
src_sel = (val & A31_AHB1_CLK_SRC_SEL) >>
A31_AHB1_CLK_SRC_SEL_SHIFT;
if (src_sel == A31_AHB1_CLK_SRC_SEL_PLL6)
@@ -146,7 +177,28 @@ aw_ahbclk_recalc_freq(struct clknode *clk, uint64_t *freq)
else
pre_div = 1;
break;
+ case AW_A83T_AHB1:
+ div = 1 << ((val & A83T_AHB1_CLK_DIV_RATIO) >>
+ A83T_AHB1_CLK_DIV_RATIO_SHIFT);
+ src_sel = (val & A83T_AHB1_CLK_SRC_SEL) >>
+ A83T_AHB1_CLK_SRC_SEL_SHIFT;
+ if (A83T_AHB1_CLK_SRC_SEL_ISPLL(src_sel))
+ pre_div = ((val & A83T_AHB1_PRE_DIV) >>
+ A83T_AHB1_PRE_DIV_SHIFT) + 1;
+ else
+ pre_div = 1;
+ break;
+ case AW_H3_AHB2:
+ src_sel = (val & H3_AHB2_CLK_CFG) >> H3_AHB2_CLK_CFG_SHIFT;
+ if (src_sel == H3_AHB2_CLK_CFG_PLL_PERIPH_DIV2)
+ div = 2;
+ else
+ div = 1;
+ pre_div = 1;
+ break;
default:
+ div = 1 << ((val & A10_AHB_CLK_DIV_RATIO) >>
+ A10_AHB_CLK_DIV_RATIO_SHIFT);
pre_div = 1;
break;
}
@@ -179,6 +231,26 @@ aw_ahbclk_set_mux(struct clknode *clk, int index)
AHBCLK_WRITE(sc, val);
DEVICE_UNLOCK(sc);
break;
+ case AW_A83T_AHB1:
+ if (index < 0 || index > A83T_AHB1_CLK_SRC_SEL_MAX)
+ return (ERANGE);
+ DEVICE_LOCK(sc);
+ AHBCLK_READ(sc, &val);
+ val &= ~A83T_AHB1_CLK_SRC_SEL;
+ val |= (index << A83T_AHB1_CLK_SRC_SEL_SHIFT);
+ AHBCLK_WRITE(sc, val);
+ DEVICE_UNLOCK(sc);
+ break;
+ case AW_H3_AHB2:
+ if (index < 0 || index > H3_AHB2_CLK_CFG)
+ return (ERANGE);
+ DEVICE_LOCK(sc);
+ AHBCLK_READ(sc, &val);
+ val &= ~H3_AHB2_CLK_CFG;
+ val |= (index << H3_AHB2_CLK_CFG_SHIFT);
+ AHBCLK_WRITE(sc, val);
+ DEVICE_UNLOCK(sc);
+ break;
default:
return (ENXIO);
}
diff --git a/sys/arm/allwinner/clk/aw_apbclk.c b/sys/arm/allwinner/clk/aw_apbclk.c
index a56387b..7620c45 100644
--- a/sys/arm/allwinner/clk/aw_apbclk.c
+++ b/sys/arm/allwinner/clk/aw_apbclk.c
@@ -49,24 +49,32 @@ __FBSDID("$FreeBSD$");
#include "clkdev_if.h"
-#define APB0_CLK_RATIO (0x3 << 8)
-#define APB0_CLK_RATIO_SHIFT 8
-#define APB1_CLK_SRC_SEL (0x3 << 24)
-#define APB1_CLK_SRC_SEL_SHIFT 24
-#define APB1_CLK_SRC_SEL_MAX 0x3
-#define APB1_CLK_RAT_N (0x3 << 16)
-#define APB1_CLK_RAT_N_SHIFT 16
-#define APB1_CLK_RAT_M (0x1f << 0)
-#define APB1_CLK_RAT_M_SHIFT 0
+#define A10_APB0_CLK_RATIO (0x3 << 8)
+#define A10_APB0_CLK_RATIO_SHIFT 8
+#define A10_APB1_CLK_SRC_SEL (0x3 << 24)
+#define A10_APB1_CLK_SRC_SEL_SHIFT 24
+#define A10_APB1_CLK_SRC_SEL_MAX 0x3
+#define A10_APB1_CLK_RAT_N (0x3 << 16)
+#define A10_APB1_CLK_RAT_N_SHIFT 16
+#define A10_APB1_CLK_RAT_M (0x1f << 0)
+#define A10_APB1_CLK_RAT_M_SHIFT 0
+#define A23_APB0_CLK_RATIO (0x3 << 0)
+#define A23_APB0_CLK_RATIO_SHIFT 0
+#define A83T_APB1_CLK_RATIO (0x3 << 8)
+#define A83T_APB1_CLK_RATIO_SHIFT 8
enum aw_apbclk_type {
AW_A10_APB0 = 1,
AW_A10_APB1,
+ AW_A23_APB0,
+ AW_A83T_APB1,
};
static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-apb0-clk", AW_A10_APB0 },
{ "allwinner,sun4i-a10-apb1-clk", AW_A10_APB1 },
+ { "allwinner,sun8i-a23-apb0-clk", AW_A23_APB0 },
+ { "allwinner,sun8i-a83t-apb1-clk", AW_A83T_APB1 },
{ NULL, 0 }
};
@@ -91,13 +99,16 @@ aw_apbclk_init(struct clknode *clk, device_t dev)
switch (sc->type) {
case AW_A10_APB0:
+ case AW_A23_APB0:
+ case AW_A83T_APB1:
index = 0;
break;
case AW_A10_APB1:
DEVICE_LOCK(sc);
APBCLK_READ(sc, &val);
DEVICE_UNLOCK(sc);
- index = (val & APB1_CLK_SRC_SEL) >> APB1_CLK_SRC_SEL_SHIFT;
+ index = (val & A10_APB1_CLK_SRC_SEL) >>
+ A10_APB1_CLK_SRC_SEL_SHIFT;
break;
default:
return (ENXIO);
@@ -121,16 +132,29 @@ aw_apbclk_recalc_freq(struct clknode *clk, uint64_t *freq)
switch (sc->type) {
case AW_A10_APB0:
- div = 1 << ((val & APB0_CLK_RATIO) >> APB0_CLK_RATIO_SHIFT);
+ div = 1 << ((val & A10_APB0_CLK_RATIO) >>
+ A10_APB0_CLK_RATIO_SHIFT);
if (div == 1)
div = 2;
*freq = *freq / div;
break;
case AW_A10_APB1:
- n = 1 << ((val & APB1_CLK_RAT_N) >> APB1_CLK_RAT_N_SHIFT);
- m = ((val & APB1_CLK_RAT_N) >> APB1_CLK_RAT_M_SHIFT) + 1;
+ n = 1 << ((val & A10_APB1_CLK_RAT_N) >>
+ A10_APB1_CLK_RAT_N_SHIFT);
+ m = ((val & A10_APB1_CLK_RAT_N) >>
+ A10_APB1_CLK_RAT_M_SHIFT) + 1;
*freq = *freq / n / m;
break;
+ case AW_A23_APB0:
+ div = 1 << ((val & A23_APB0_CLK_RATIO) >>
+ A23_APB0_CLK_RATIO_SHIFT);
+ *freq = *freq / div;
+ break;
+ case AW_A83T_APB1:
+ div = ((val & A83T_APB1_CLK_RATIO) >>
+ A83T_APB1_CLK_RATIO_SHIFT) + 1;
+ *freq = *freq / div;
+ break;
default:
return (ENXIO);
}
@@ -149,13 +173,13 @@ aw_apbclk_set_mux(struct clknode *clk, int index)
if (sc->type != AW_A10_APB1)
return (ENXIO);
- if (index < 0 || index > APB1_CLK_SRC_SEL_MAX)
+ if (index < 0 || index > A10_APB1_CLK_SRC_SEL_MAX)
return (ERANGE);
DEVICE_LOCK(sc);
APBCLK_READ(sc, &val);
- val &= ~APB1_CLK_SRC_SEL;
- val |= (index << APB1_CLK_SRC_SEL_SHIFT);
+ val &= ~A10_APB1_CLK_SRC_SEL;
+ val |= (index << A10_APB1_CLK_SRC_SEL_SHIFT);
APBCLK_WRITE(sc, val);
DEVICE_UNLOCK(sc);
diff --git a/sys/arm/allwinner/clk/aw_cpusclk.c b/sys/arm/allwinner/clk/aw_cpusclk.c
new file mode 100644
index 0000000..6d18284
--- /dev/null
+++ b/sys/arm/allwinner/clk/aw_cpusclk.c
@@ -0,0 +1,320 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Allwinner CPUS clock
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/ofw_subr.h>
+
+#include <dev/extres/clk/clk.h>
+
+#include "clkdev_if.h"
+
+#define A80_CPUS_CLK_SRC_SEL (0x3 << 16)
+#define A80_CPUS_CLK_SRC_SEL_SHIFT 16
+#define A80_CPUS_CLK_SRC_SEL_X32KI 0
+#define A80_CPUS_CLK_SRC_SEL_OSC24M 1
+#define A80_CPUS_CLK_SRC_SEL_PLL_PERIPH 2
+#define A80_CPUS_CLK_SRC_SEL_PLL_AUDIO 3
+#define A80_CPUS_POST_DIV (0x1f << 8)
+#define A80_CPUS_POST_DIV_SHIFT 8
+#define A80_CPUS_CLK_RATIO (0x3 << 4)
+#define A80_CPUS_CLK_RATIO_SHIFT 4
+
+#define A83T_CPUS_CLK_SRC_SEL (0x3 << 16)
+#define A83T_CPUS_CLK_SRC_SEL_SHIFT 16
+#define A83T_CPUS_CLK_SRC_SEL_X32KI 0
+#define A83T_CPUS_CLK_SRC_SEL_OSC24M 1
+#define A83T_CPUS_CLK_SRC_SEL_PLL_PERIPH 2
+#define A83T_CPUS_CLK_SRC_SEL_INTERNAL_OSC 3
+#define A83T_CPUS_POST_DIV (0x1f << 8)
+#define A83T_CPUS_POST_DIV_SHIFT 8
+#define A83T_CPUS_CLK_RATIO (0x3 << 4)
+#define A83T_CPUS_CLK_RATIO_SHIFT 4
+
+enum aw_cpusclk_type {
+ AW_A80_CPUS = 1,
+ AW_A83T_CPUS,
+};
+
+static struct ofw_compat_data compat_data[] = {
+ { "allwinner,sun9i-a80-cpus-clk", AW_A80_CPUS },
+ { "allwinner,sun8i-a83t-cpus-clk", AW_A83T_CPUS },
+ { NULL, 0 }
+};
+
+struct aw_cpusclk_sc {
+ device_t clkdev;
+ bus_addr_t reg;
+ enum aw_cpusclk_type type;
+};
+
+#define CPUSCLK_READ(sc, val) CLKDEV_READ_4((sc)->clkdev, (sc)->reg, (val))
+#define CPUSCLK_WRITE(sc, val) CLKDEV_WRITE_4((sc)->clkdev, (sc)->reg, (val))
+#define DEVICE_LOCK(sc) CLKDEV_DEVICE_LOCK((sc)->clkdev)
+#define DEVICE_UNLOCK(sc) CLKDEV_DEVICE_UNLOCK((sc)->clkdev)
+
+static int
+aw_cpusclk_init(struct clknode *clk, device_t dev)
+{
+ struct aw_cpusclk_sc *sc;
+ uint32_t val, mask, shift, index;
+
+ sc = clknode_get_softc(clk);
+
+ switch (sc->type) {
+ case AW_A80_CPUS:
+ mask = A80_CPUS_CLK_SRC_SEL;
+ shift = A80_CPUS_CLK_SRC_SEL_SHIFT;
+ break;
+ case AW_A83T_CPUS:
+ mask = A83T_CPUS_CLK_SRC_SEL;
+ shift = A83T_CPUS_CLK_SRC_SEL_SHIFT;
+ break;
+ default:
+ return (ENXIO);
+ }
+
+ DEVICE_LOCK(sc);
+ CPUSCLK_READ(sc, &val);
+ DEVICE_UNLOCK(sc);
+ index = (val & mask) >> shift;
+
+ clknode_init_parent_idx(clk, index);
+ return (0);
+}
+
+static int
+aw_cpusclk_recalc_freq(struct clknode *clk, uint64_t *freq)
+{
+ struct aw_cpusclk_sc *sc;
+ uint32_t val, src_sel, post_div, clk_ratio;
+
+ sc = clknode_get_softc(clk);
+
+ DEVICE_LOCK(sc);
+ CPUSCLK_READ(sc, &val);
+ DEVICE_UNLOCK(sc);
+
+ switch (sc->type) {
+ case AW_A80_CPUS:
+ src_sel = (val & A80_CPUS_CLK_SRC_SEL) >>
+ A80_CPUS_CLK_SRC_SEL_SHIFT;
+ post_div = ((val & A80_CPUS_POST_DIV) >>
+ A80_CPUS_POST_DIV_SHIFT) + 1;
+ clk_ratio = ((val & A80_CPUS_CLK_RATIO) >>
+ A80_CPUS_CLK_RATIO_SHIFT) + 1;
+ if (src_sel == A80_CPUS_CLK_SRC_SEL_PLL_PERIPH)
+ *freq = *freq / post_div / clk_ratio;
+ else
+ *freq = *freq / clk_ratio;
+ break;
+ case AW_A83T_CPUS:
+ src_sel = (val & A83T_CPUS_CLK_SRC_SEL) >>
+ A83T_CPUS_CLK_SRC_SEL_SHIFT;
+ post_div = ((val & A83T_CPUS_POST_DIV) >>
+ A83T_CPUS_POST_DIV_SHIFT) + 1;
+ clk_ratio = 1 << ((val & A83T_CPUS_CLK_RATIO) >>
+ A83T_CPUS_CLK_RATIO_SHIFT);
+ if (src_sel == A83T_CPUS_CLK_SRC_SEL_PLL_PERIPH)
+ *freq = *freq / post_div / clk_ratio;
+ else
+ *freq = *freq / clk_ratio;
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ return (0);
+}
+
+static int
+aw_cpusclk_set_mux(struct clknode *clk, int index)
+{
+ struct aw_cpusclk_sc *sc;
+ uint32_t mask, shift, val;
+
+ sc = clknode_get_softc(clk);
+
+ switch (sc->type) {
+ case AW_A80_CPUS:
+ mask = A80_CPUS_CLK_SRC_SEL;
+ shift = A80_CPUS_CLK_SRC_SEL_SHIFT;
+ break;
+ case AW_A83T_CPUS:
+ mask = A83T_CPUS_CLK_SRC_SEL;
+ shift = A83T_CPUS_CLK_SRC_SEL_SHIFT;
+ break;
+ default:
+ return (ENXIO);
+ }
+
+ DEVICE_LOCK(sc);
+ CPUSCLK_READ(sc, &val);
+ val &= ~mask;
+ val |= (index << shift);
+ CPUSCLK_WRITE(sc, val);
+ DEVICE_UNLOCK(sc);
+
+ return (0);
+}
+
+static clknode_method_t aw_cpusclk_clknode_methods[] = {
+ /* Device interface */
+ CLKNODEMETHOD(clknode_init, aw_cpusclk_init),
+ CLKNODEMETHOD(clknode_recalc_freq, aw_cpusclk_recalc_freq),
+ CLKNODEMETHOD(clknode_set_mux, aw_cpusclk_set_mux),
+ CLKNODEMETHOD_END
+};
+DEFINE_CLASS_1(aw_cpusclk_clknode, aw_cpusclk_clknode_class,
+ aw_cpusclk_clknode_methods, sizeof(struct aw_cpusclk_sc), clknode_class);
+
+static int
+aw_cpusclk_probe(device_t dev)
+{
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "Allwinner CPUS Clock");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+aw_cpusclk_attach(device_t dev)
+{
+ struct clknode_init_def def;
+ struct aw_cpusclk_sc *sc;
+ struct clkdom *clkdom;
+ struct clknode *clk;
+ clk_t clk_parent;
+ bus_addr_t paddr;
+ bus_size_t psize;
+ phandle_t node;
+ int error, ncells, i;
+
+ node = ofw_bus_get_node(dev);
+
+ if (ofw_reg_to_paddr(node, 0, &paddr, &psize, NULL) != 0) {
+ device_printf(dev, "cannot parse 'reg' property\n");
+ return (ENXIO);
+ }
+
+ error = ofw_bus_parse_xref_list_get_length(node, "clocks",
+ "#clock-cells", &ncells);
+ if (error != 0) {
+ device_printf(dev, "cannot get clock count\n");
+ return (error);
+ }
+
+ clkdom = clkdom_create(dev);
+
+ memset(&def, 0, sizeof(def));
+ def.id = 1;
+ def.parent_names = malloc(sizeof(char *) * ncells, M_OFWPROP,
+ M_WAITOK);
+ for (i = 0; i < ncells; i++) {
+ error = clk_get_by_ofw_index(dev, i, &clk_parent);
+ if (error != 0) {
+ device_printf(dev, "cannot get clock %d\n", i);
+ goto fail;
+ }
+ def.parent_names[i] = clk_get_name(clk_parent);
+ clk_release(clk_parent);
+ }
+ def.parent_cnt = ncells;
+
+ error = clk_parse_ofw_clk_name(dev, node, &def.name);
+ if (error != 0) {
+ device_printf(dev, "cannot parse clock name\n");
+ error = ENXIO;
+ goto fail;
+ }
+
+ clk = clknode_create(clkdom, &aw_cpusclk_clknode_class, &def);
+ if (clk == NULL) {
+ device_printf(dev, "cannot create clknode\n");
+ error = ENXIO;
+ goto fail;
+ }
+ sc = clknode_get_softc(clk);
+ sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+ sc->reg = paddr;
+ sc->clkdev = device_get_parent(dev);
+
+ clknode_register(clkdom, clk);
+
+ if (clkdom_finit(clkdom) != 0) {
+ device_printf(dev, "cannot finalize clkdom initialization\n");
+ error = ENXIO;
+ goto fail;
+ }
+
+ if (bootverbose)
+ clkdom_dump(clkdom);
+
+ return (0);
+
+fail:
+ return (error);
+}
+
+static device_method_t aw_cpusclk_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, aw_cpusclk_probe),
+ DEVMETHOD(device_attach, aw_cpusclk_attach),
+
+ DEVMETHOD_END
+};
+
+static driver_t aw_cpusclk_driver = {
+ "aw_cpusclk",
+ aw_cpusclk_methods,
+ 0
+};
+
+static devclass_t aw_cpusclk_devclass;
+
+EARLY_DRIVER_MODULE(aw_cpusclk, simplebus, aw_cpusclk_driver,
+ aw_cpusclk_devclass, 0, 0, BUS_PASS_BUS + BUS_PASS_ORDER_MIDDLE);
diff --git a/sys/arm/allwinner/clk/aw_gate.c b/sys/arm/allwinner/clk/aw_gate.c
index d43d021..6634c57 100644
--- a/sys/arm/allwinner/clk/aw_gate.c
+++ b/sys/arm/allwinner/clk/aw_gate.c
@@ -76,6 +76,14 @@ static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun6i-a31-apb2-gates-clk",
(uintptr_t)"Allwinner APB2 Clock Gates" },
+ { "allwinner,sun8i-a83t-bus-gates-clk",
+ (uintptr_t)"Allwinner Bus Clock Gates" },
+ { "allwinner,sun8i-a83t-apb0-gates-clk",
+ (uintptr_t)"Allwinner APB0 Clock Gates" },
+
+ { "allwinner,sun9i-a80-apbs-gates-clk",
+ (uintptr_t)"Allwinner APBS Clock Gates" },
+
{ NULL, 0 }
};
diff --git a/sys/arm/allwinner/clk/aw_gmacclk.c b/sys/arm/allwinner/clk/aw_gmacclk.c
index 5e2f618..72495fd 100644
--- a/sys/arm/allwinner/clk/aw_gmacclk.c
+++ b/sys/arm/allwinner/clk/aw_gmacclk.c
@@ -60,18 +60,41 @@ __FBSDID("$FreeBSD$");
#define GMAC_CLK_SRC_EXT_RGMII 1
#define GMAC_CLK_SRC_RGMII 2
+#define EMAC_TXC_DIV_CFG (1 << 15)
+#define EMAC_TXC_DIV_CFG_SHIFT 15
+#define EMAC_TXC_DIV_CFG_125MHZ 0
+#define EMAC_TXC_DIV_CFG_25MHZ 1
+#define EMAC_PHY_SELECT (1 << 16)
+#define EMAC_PHY_SELECT_SHIFT 16
+#define EMAC_PHY_SELECT_INT 0
+#define EMAC_PHY_SELECT_EXT 1
+#define EMAC_ETXDC (0x7 << 10)
+#define EMAC_ETXDC_SHIFT 10
+#define EMAC_ERXDC (0x1f << 5)
+#define EMAC_ERXDC_SHIFT 5
+
#define CLK_IDX_MII 0
#define CLK_IDX_RGMII 1
#define CLK_IDX_COUNT 2
+enum aw_gmacclk_type {
+ GMACCLK_A20 = 1,
+ GMACCLK_A83T,
+};
+
static struct ofw_compat_data compat_data[] = {
- { "allwinner,sun7i-a20-gmac-clk", 1 },
+ { "allwinner,sun7i-a20-gmac-clk", GMACCLK_A20 },
+ { "allwinner,sun8i-a83t-emac-clk", GMACCLK_A83T },
{ NULL, 0 }
};
struct aw_gmacclk_sc {
device_t clkdev;
bus_addr_t reg;
+ enum aw_gmacclk_type type;
+
+ int rx_delay;
+ int tx_delay;
};
#define GMACCLK_READ(sc, val) CLKDEV_READ_4((sc)->clkdev, (sc)->reg, (val))
@@ -110,7 +133,7 @@ static int
aw_gmacclk_set_mux(struct clknode *clk, int index)
{
struct aw_gmacclk_sc *sc;
- uint32_t val, clk_src, pit;
+ uint32_t val, clk_src, pit, txc_div;
int error;
sc = clknode_get_softc(clk);
@@ -120,10 +143,12 @@ aw_gmacclk_set_mux(struct clknode *clk, int index)
case CLK_IDX_MII:
clk_src = GMAC_CLK_SRC_MII;
pit = GMAC_CLK_PIT_MII;
+ txc_div = EMAC_TXC_DIV_CFG_25MHZ;
break;
case CLK_IDX_RGMII:
clk_src = GMAC_CLK_SRC_RGMII;
pit = GMAC_CLK_PIT_RGMII;
+ txc_div = EMAC_TXC_DIV_CFG_125MHZ;
break;
default:
return (ENXIO);
@@ -134,6 +159,20 @@ aw_gmacclk_set_mux(struct clknode *clk, int index)
val &= ~(GMAC_CLK_SRC | GMAC_CLK_PIT);
val |= (clk_src << GMAC_CLK_SRC_SHIFT);
val |= (pit << GMAC_CLK_PIT_SHIFT);
+ if (sc->type == GMACCLK_A83T) {
+ val &= ~EMAC_TXC_DIV_CFG;
+ val |= (txc_div << EMAC_TXC_DIV_CFG_SHIFT);
+ val &= ~EMAC_PHY_SELECT;
+ val |= (EMAC_PHY_SELECT_EXT << EMAC_PHY_SELECT_SHIFT);
+ if (sc->tx_delay >= 0) {
+ val &= ~EMAC_ETXDC;
+ val |= (sc->tx_delay << EMAC_ETXDC_SHIFT);
+ }
+ if (sc->rx_delay >= 0) {
+ val &= ~EMAC_ERXDC;
+ val |= (sc->rx_delay << EMAC_ERXDC_SHIFT);
+ }
+ }
GMACCLK_WRITE(sc, val);
DEVICE_UNLOCK(sc);
@@ -158,7 +197,7 @@ aw_gmacclk_probe(device_t dev)
if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
return (ENXIO);
- device_set_desc(dev, "Allwinner Module Clock");
+ device_set_desc(dev, "Allwinner GMAC Clock");
return (BUS_PROBE_DEFAULT);
}
@@ -221,6 +260,10 @@ aw_gmacclk_attach(device_t dev)
sc = clknode_get_softc(clk);
sc->reg = paddr;
sc->clkdev = device_get_parent(dev);
+ sc->type = ofw_bus_search_compatible(dev, compat_data)->ocd_data;
+ sc->tx_delay = sc->rx_delay = -1;
+ OF_getencprop(node, "tx-delay", &sc->tx_delay, sizeof(sc->tx_delay));
+ OF_getencprop(node, "rx-delay", &sc->rx_delay, sizeof(sc->rx_delay));
clknode_register(clkdom, clk);
diff --git a/sys/arm/allwinner/clk/aw_pll.c b/sys/arm/allwinner/clk/aw_pll.c
index 2e67646..b7c2a7e 100644
--- a/sys/arm/allwinner/clk/aw_pll.c
+++ b/sys/arm/allwinner/clk/aw_pll.c
@@ -124,6 +124,12 @@ __FBSDID("$FreeBSD$");
#define A31_PLL6_DEFAULT_K 0x1
#define A31_PLL6_TIMEOUT 10
+#define A80_PLL4_CLK_OUT_EN (1 << 20)
+#define A80_PLL4_PLL_DIV2 (1 << 18)
+#define A80_PLL4_PLL_DIV1 (1 << 16)
+#define A80_PLL4_FACTOR_N (0xff << 8)
+#define A80_PLL4_FACTOR_N_SHIFT 8
+
#define CLKID_A10_PLL3_1X 0
#define CLKID_A10_PLL3_2X 1
@@ -146,6 +152,7 @@ enum aw_pll_type {
AWPLL_A10_PLL6,
AWPLL_A31_PLL1,
AWPLL_A31_PLL6,
+ AWPLL_A80_PLL4,
};
struct aw_pll_sc {
@@ -524,6 +531,24 @@ a31_pll6_recalc(struct aw_pll_sc *sc, uint64_t *freq)
return (0);
}
+static int
+a80_pll4_recalc(struct aw_pll_sc *sc, uint64_t *freq)
+{
+ uint32_t val, n, div1, div2;
+
+ DEVICE_LOCK(sc);
+ PLL_READ(sc, &val);
+ DEVICE_UNLOCK(sc);
+
+ n = (val & A80_PLL4_FACTOR_N) >> A80_PLL4_FACTOR_N_SHIFT;
+ div1 = (val & A80_PLL4_PLL_DIV1) == 0 ? 1 : 2;
+ div2 = (val & A80_PLL4_PLL_DIV2) == 0 ? 1 : 2;
+
+ *freq = (*freq * n) / div1 / div2;
+
+ return (0);
+}
+
#define PLL(_type, _recalc, _set_freq, _init) \
[(_type)] = { \
.recalc = (_recalc), \
@@ -539,6 +564,7 @@ static struct aw_pll_funcs aw_pll_func[] = {
PLL(AWPLL_A10_PLL6, a10_pll6_recalc, a10_pll6_set_freq, a10_pll6_init),
PLL(AWPLL_A31_PLL1, a31_pll1_recalc, NULL, NULL),
PLL(AWPLL_A31_PLL6, a31_pll6_recalc, NULL, a31_pll6_init),
+ PLL(AWPLL_A80_PLL4, a80_pll4_recalc, NULL, NULL),
};
static struct ofw_compat_data compat_data[] = {
@@ -549,6 +575,7 @@ static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-pll6-clk", AWPLL_A10_PLL6 },
{ "allwinner,sun6i-a31-pll1-clk", AWPLL_A31_PLL1 },
{ "allwinner,sun6i-a31-pll6-clk", AWPLL_A31_PLL6 },
+ { "allwinner,sun9i-a80-pll4-clk", AWPLL_A80_PLL4 },
{ NULL, 0 }
};
diff --git a/sys/arm/allwinner/clk/aw_usbclk.c b/sys/arm/allwinner/clk/aw_usbclk.c
index bac9991..cd935c4 100644
--- a/sys/arm/allwinner/clk/aw_usbclk.c
+++ b/sys/arm/allwinner/clk/aw_usbclk.c
@@ -62,11 +62,13 @@ __FBSDID("$FreeBSD$");
enum aw_usbclk_type {
AW_A10_USBCLK = 1,
AW_A31_USBCLK,
+ AW_A83T_USBCLK,
};
static struct ofw_compat_data compat_data[] = {
{ "allwinner,sun4i-a10-usb-clk", AW_A10_USBCLK },
{ "allwinner,sun6i-a31-usb-clk", AW_A31_USBCLK },
+ { "allwinner,sun8i-a83t-usb-clk", AW_A83T_USBCLK },
{ NULL, 0 }
};
@@ -162,10 +164,11 @@ aw_usbclk_attach(device_t dev)
struct aw_usbclk_softc *sc;
struct clkdom *clkdom;
const char **names;
+ const char *pname;
int index, nout, error;
enum aw_usbclk_type type;
uint32_t *indices;
- clk_t clk_parent;
+ clk_t clk_parent, clk_parent_pll;
bus_size_t psize;
phandle_t node;
@@ -196,11 +199,21 @@ aw_usbclk_attach(device_t dev)
device_printf(dev, "cannot parse clock parent\n");
return (ENXIO);
}
+ if (type == AW_A83T_USBCLK) {
+ error = clk_get_by_ofw_index(dev, 1, &clk_parent_pll);
+ if (error != 0) {
+ device_printf(dev, "cannot parse pll clock parent\n");
+ return (ENXIO);
+ }
+ }
for (index = 0; index < nout; index++) {
- error = aw_usbclk_create(dev, sc->reg, clkdom,
- clk_get_name(clk_parent), names[index],
- indices != NULL ? indices[index] : index);
+ if (strcmp(names[index], "usb_hsic_pll") == 0)
+ pname = clk_get_name(clk_parent_pll);
+ else
+ pname = clk_get_name(clk_parent);
+ error = aw_usbclk_create(dev, sc->reg, clkdom, pname,
+ names[index], indices != NULL ? indices[index] : index);
if (error)
goto fail;
}
diff --git a/sys/arm/allwinner/files.allwinner b/sys/arm/allwinner/files.allwinner
index d02a868..a138989 100644
--- a/sys/arm/allwinner/files.allwinner
+++ b/sys/arm/allwinner/files.allwinner
@@ -18,6 +18,7 @@ arm/allwinner/a20/a20_cpu_cfg.c standard
arm/allwinner/allwinner_machdep.c standard
arm/allwinner/aw_mp.c optional smp
arm/allwinner/axp209.c optional axp209
+arm/allwinner/if_awg.c optional awg
arm/allwinner/if_emac.c optional emac
arm/allwinner/sunxi_dma_if.m standard
dev/iicbus/twsi/a10_twsi.c optional twsi
@@ -35,6 +36,7 @@ arm/allwinner/clk/aw_apbclk.c standard
arm/allwinner/clk/aw_axiclk.c standard
arm/allwinner/clk/aw_codecclk.c standard
arm/allwinner/clk/aw_cpuclk.c standard
+arm/allwinner/clk/aw_cpusclk.c standard
arm/allwinner/clk/aw_debeclk.c standard
arm/allwinner/clk/aw_gate.c standard
arm/allwinner/clk/aw_gmacclk.c standard
diff --git a/sys/arm/allwinner/if_awg.c b/sys/arm/allwinner/if_awg.c
new file mode 100644
index 0000000..87606c3
--- /dev/null
+++ b/sys/arm/allwinner/if_awg.c
@@ -0,0 +1,1418 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Allwinner Gigabit Ethernet MAC (EMAC) controller
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/rman.h>
+#include <sys/kernel.h>
+#include <sys/endian.h>
+#include <sys/mbuf.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <sys/module.h>
+#include <sys/taskqueue.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+#include <net/if_var.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <arm/allwinner/if_awgreg.h>
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
+#include <dev/extres/regulator/regulator.h>
+
+#include "miibus_if.h"
+
+#define RD4(sc, reg) bus_read_4((sc)->res[0], (reg))
+#define WR4(sc, reg, val) bus_write_4((sc)->res[0], (reg), (val))
+
+#define AWG_LOCK(sc) mtx_lock(&(sc)->mtx)
+#define AWG_UNLOCK(sc) mtx_unlock(&(sc)->mtx);
+#define AWG_ASSERT_LOCKED(sc) mtx_assert(&(sc)->mtx, MA_OWNED)
+#define AWG_ASSERT_UNLOCKED(sc) mtx_assert(&(sc)->mtx, MA_NOTOWNED)
+
+#define DESC_ALIGN 4
+#define TX_DESC_COUNT 256
+#define TX_DESC_SIZE (sizeof(struct emac_desc) * TX_DESC_COUNT)
+#define RX_DESC_COUNT 256
+#define RX_DESC_SIZE (sizeof(struct emac_desc) * RX_DESC_COUNT)
+
+#define DESC_OFF(n) ((n) * sizeof(struct emac_desc))
+#define TX_NEXT(n) (((n) + 1) & (TX_DESC_COUNT - 1))
+#define TX_SKIP(n, o) (((n) + (o)) & (TX_DESC_COUNT - 1))
+#define RX_NEXT(n) (((n) + 1) & (RX_DESC_COUNT - 1))
+
+#define TX_MAX_SEGS 10
+
+#define SOFT_RST_RETRY 1000
+#define MII_BUSY_RETRY 1000
+#define MDIO_FREQ 2500000
+
+#define BURST_LEN_DEFAULT 8
+#define RX_TX_PRI_DEFAULT 0
+#define PAUSE_TIME_DEFAULT 0x400
+#define TX_INTERVAL_DEFAULT 64
+
+/* Burst length of RX and TX DMA transfers */
+static int awg_burst_len = BURST_LEN_DEFAULT;
+TUNABLE_INT("hw.awg.burst_len", &awg_burst_len);
+
+/* RX / TX DMA priority. If 1, RX DMA has priority over TX DMA. */
+static int awg_rx_tx_pri = RX_TX_PRI_DEFAULT;
+TUNABLE_INT("hw.awg.rx_tx_pri", &awg_rx_tx_pri);
+
+/* Pause time field in the transmitted control frame */
+static int awg_pause_time = PAUSE_TIME_DEFAULT;
+TUNABLE_INT("hw.awg.pause_time", &awg_pause_time);
+
+/* Request a TX interrupt every <n> descriptors */
+static int awg_tx_interval = TX_INTERVAL_DEFAULT;
+TUNABLE_INT("hw.awg.tx_interval", &awg_tx_interval);
+
+static struct ofw_compat_data compat_data[] = {
+ { "allwinner,sun8i-a83t-emac", 1 },
+ { NULL, 0 }
+};
+
+struct awg_bufmap {
+ bus_dmamap_t map;
+ struct mbuf *mbuf;
+};
+
+struct awg_txring {
+ bus_dma_tag_t desc_tag;
+ bus_dmamap_t desc_map;
+ struct emac_desc *desc_ring;
+ bus_addr_t desc_ring_paddr;
+ bus_dma_tag_t buf_tag;
+ struct awg_bufmap buf_map[TX_DESC_COUNT];
+ u_int cur, next, queued;
+};
+
+struct awg_rxring {
+ bus_dma_tag_t desc_tag;
+ bus_dmamap_t desc_map;
+ struct emac_desc *desc_ring;
+ bus_addr_t desc_ring_paddr;
+ bus_dma_tag_t buf_tag;
+ struct awg_bufmap buf_map[RX_DESC_COUNT];
+ u_int cur;
+};
+
+struct awg_softc {
+ struct resource *res[2];
+ struct mtx mtx;
+ if_t ifp;
+ device_t miibus;
+ struct callout stat_ch;
+ struct task link_task;
+ void *ih;
+ u_int mdc_div_ratio_m;
+ int link;
+ int if_flags;
+
+ struct awg_txring tx;
+ struct awg_rxring rx;
+};
+
+static struct resource_spec awg_spec[] = {
+ { SYS_RES_MEMORY, 0, RF_ACTIVE },
+ { SYS_RES_IRQ, 0, RF_ACTIVE },
+ { -1, 0 }
+};
+
+static int
+awg_miibus_readreg(device_t dev, int phy, int reg)
+{
+ struct awg_softc *sc;
+ int retry, val;
+
+ sc = device_get_softc(dev);
+ val = 0;
+
+ WR4(sc, EMAC_MII_CMD,
+ (sc->mdc_div_ratio_m << MDC_DIV_RATIO_M_SHIFT) |
+ (phy << PHY_ADDR_SHIFT) |
+ (reg << PHY_REG_ADDR_SHIFT) |
+ MII_BUSY);
+ for (retry = MII_BUSY_RETRY; retry > 0; retry--) {
+ if ((RD4(sc, EMAC_MII_CMD) & MII_BUSY) == 0) {
+ val = RD4(sc, EMAC_MII_DATA);
+ break;
+ }
+ DELAY(10);
+ }
+
+ if (retry == 0)
+ device_printf(dev, "phy read timeout, phy=%d reg=%d\n",
+ phy, reg);
+
+ return (val);
+}
+
+static int
+awg_miibus_writereg(device_t dev, int phy, int reg, int val)
+{
+ struct awg_softc *sc;
+ int retry;
+
+ sc = device_get_softc(dev);
+
+ WR4(sc, EMAC_MII_DATA, val);
+ WR4(sc, EMAC_MII_CMD,
+ (sc->mdc_div_ratio_m << MDC_DIV_RATIO_M_SHIFT) |
+ (phy << PHY_ADDR_SHIFT) |
+ (reg << PHY_REG_ADDR_SHIFT) |
+ MII_WR | MII_BUSY);
+ for (retry = MII_BUSY_RETRY; retry > 0; retry--) {
+ if ((RD4(sc, EMAC_MII_CMD) & MII_BUSY) == 0)
+ break;
+ DELAY(10);
+ }
+
+ if (retry == 0)
+ device_printf(dev, "phy write timeout, phy=%d reg=%d\n",
+ phy, reg);
+
+ return (0);
+}
+
+static void
+awg_update_link_locked(struct awg_softc *sc)
+{
+ struct mii_data *mii;
+ uint32_t val;
+
+ AWG_ASSERT_LOCKED(sc);
+
+ if ((if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) == 0)
+ return;
+ mii = device_get_softc(sc->miibus);
+
+ if ((mii->mii_media_status & (IFM_ACTIVE | IFM_AVALID)) ==
+ (IFM_ACTIVE | IFM_AVALID)) {
+ switch (IFM_SUBTYPE(mii->mii_media_active)) {
+ case IFM_1000_T:
+ case IFM_1000_SX:
+ case IFM_100_TX:
+ case IFM_10_T:
+ sc->link = 1;
+ break;
+ default:
+ sc->link = 0;
+ break;
+ }
+ } else
+ sc->link = 0;
+
+ if (sc->link == 0)
+ return;
+
+ val = RD4(sc, EMAC_BASIC_CTL_0);
+ val &= ~(BASIC_CTL_SPEED | BASIC_CTL_DUPLEX);
+
+ if (IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_T ||
+ IFM_SUBTYPE(mii->mii_media_active) == IFM_1000_SX)
+ val |= BASIC_CTL_SPEED_1000 << BASIC_CTL_SPEED_SHIFT;
+ else if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX)
+ val |= BASIC_CTL_SPEED_100 << BASIC_CTL_SPEED_SHIFT;
+ else
+ val |= BASIC_CTL_SPEED_10 << BASIC_CTL_SPEED_SHIFT;
+
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
+ val |= BASIC_CTL_DUPLEX;
+
+ WR4(sc, EMAC_BASIC_CTL_0, val);
+
+ val = RD4(sc, EMAC_RX_CTL_0);
+ val &= ~RX_FLOW_CTL_EN;
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_RXPAUSE) != 0)
+ val |= RX_FLOW_CTL_EN;
+ WR4(sc, EMAC_RX_CTL_0, val);
+
+ val = RD4(sc, EMAC_TX_FLOW_CTL);
+ val &= ~(PAUSE_TIME|TX_FLOW_CTL_EN);
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_ETH_TXPAUSE) != 0)
+ val |= TX_FLOW_CTL_EN;
+ if ((IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) != 0)
+ val |= awg_pause_time << PAUSE_TIME_SHIFT;
+ WR4(sc, EMAC_TX_FLOW_CTL, val);
+}
+
+static void
+awg_link_task(void *arg, int pending)
+{
+ struct awg_softc *sc;
+
+ sc = arg;
+
+ AWG_LOCK(sc);
+ awg_update_link_locked(sc);
+ AWG_UNLOCK(sc);
+}
+
+static void
+awg_miibus_statchg(device_t dev)
+{
+ struct awg_softc *sc;
+
+ sc = device_get_softc(dev);
+
+ taskqueue_enqueue(taskqueue_swi, &sc->link_task);
+}
+
+static void
+awg_media_status(if_t ifp, struct ifmediareq *ifmr)
+{
+ struct awg_softc *sc;
+ struct mii_data *mii;
+
+ sc = if_getsoftc(ifp);
+ mii = device_get_softc(sc->miibus);
+
+ AWG_LOCK(sc);
+ mii_pollstat(mii);
+ ifmr->ifm_active = mii->mii_media_active;
+ ifmr->ifm_status = mii->mii_media_status;
+ AWG_UNLOCK(sc);
+}
+
+static int
+awg_media_change(if_t ifp)
+{
+ struct awg_softc *sc;
+ struct mii_data *mii;
+ int error;
+
+ sc = if_getsoftc(ifp);
+ mii = device_get_softc(sc->miibus);
+
+ AWG_LOCK(sc);
+ error = mii_mediachg(mii);
+ AWG_UNLOCK(sc);
+
+ return (error);
+}
+
+static void
+awg_setup_txdesc(struct awg_softc *sc, int index, int flags, bus_addr_t paddr,
+ u_int len)
+{
+ uint32_t status, size;
+
+ if (paddr == 0 || len == 0) {
+ status = 0;
+ size = 0;
+ --sc->tx.queued;
+ } else {
+ status = TX_DESC_CTL;
+ size = flags | len;
+ if ((index & (awg_tx_interval - 1)) == 0)
+ size |= htole32(TX_INT_CTL);
+ ++sc->tx.queued;
+ }
+
+ sc->tx.desc_ring[index].addr = htole32((uint32_t)paddr);
+ sc->tx.desc_ring[index].size = htole32(size);
+ sc->tx.desc_ring[index].status = htole32(status);
+}
+
+static int
+awg_setup_txbuf(struct awg_softc *sc, int index, struct mbuf **mp)
+{
+ bus_dma_segment_t segs[TX_MAX_SEGS];
+ int error, nsegs, cur, i, flags;
+ u_int csum_flags;
+ struct mbuf *m;
+
+ m = *mp;
+ error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag,
+ sc->tx.buf_map[index].map, m, segs, &nsegs, BUS_DMA_NOWAIT);
+ if (error == EFBIG) {
+ m = m_collapse(m, M_NOWAIT, TX_MAX_SEGS);
+ if (m == NULL)
+ return (0);
+ *mp = m;
+ error = bus_dmamap_load_mbuf_sg(sc->tx.buf_tag,
+ sc->tx.buf_map[index].map, m, segs, &nsegs, BUS_DMA_NOWAIT);
+ }
+ if (error != 0)
+ return (0);
+
+ bus_dmamap_sync(sc->tx.buf_tag, sc->tx.buf_map[index].map,
+ BUS_DMASYNC_PREWRITE);
+
+ flags = TX_FIR_DESC;
+ if ((m->m_pkthdr.csum_flags & CSUM_IP) != 0) {
+ if ((m->m_pkthdr.csum_flags & (CSUM_TCP|CSUM_UDP)) != 0)
+ csum_flags = TX_CHECKSUM_CTL_FULL;
+ else
+ csum_flags = TX_CHECKSUM_CTL_IP;
+ flags |= (csum_flags << TX_CHECKSUM_CTL_SHIFT);
+ }
+
+ for (cur = index, i = 0; i < nsegs; i++) {
+ sc->tx.buf_map[cur].mbuf = (i == 0 ? m : NULL);
+ if (i == nsegs - 1)
+ flags |= TX_LAST_DESC;
+ awg_setup_txdesc(sc, cur, flags, segs[i].ds_addr,
+ segs[i].ds_len);
+ flags &= ~TX_FIR_DESC;
+ cur = TX_NEXT(cur);
+ }
+
+ return (nsegs);
+}
+
+static void
+awg_setup_rxdesc(struct awg_softc *sc, int index, bus_addr_t paddr)
+{
+ uint32_t status, size;
+
+ status = RX_DESC_CTL;
+ size = MCLBYTES - 1;
+
+ sc->rx.desc_ring[index].addr = htole32((uint32_t)paddr);
+ sc->rx.desc_ring[index].size = htole32(size);
+ sc->rx.desc_ring[index].next =
+ htole32(sc->rx.desc_ring_paddr + DESC_OFF(RX_NEXT(index)));
+ sc->rx.desc_ring[index].status = htole32(status);
+}
+
+static int
+awg_setup_rxbuf(struct awg_softc *sc, int index, struct mbuf *m)
+{
+ bus_dma_segment_t seg;
+ int error, nsegs;
+
+ m_adj(m, ETHER_ALIGN);
+
+ error = bus_dmamap_load_mbuf_sg(sc->rx.buf_tag,
+ sc->rx.buf_map[index].map, m, &seg, &nsegs, 0);
+ if (error != 0)
+ return (error);
+
+ bus_dmamap_sync(sc->rx.buf_tag, sc->rx.buf_map[index].map,
+ BUS_DMASYNC_PREREAD);
+
+ sc->rx.buf_map[index].mbuf = m;
+ awg_setup_rxdesc(sc, index, seg.ds_addr);
+
+ return (0);
+}
+
+static struct mbuf *
+awg_alloc_mbufcl(struct awg_softc *sc)
+{
+ struct mbuf *m;
+
+ m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
+ if (m != NULL)
+ m->m_pkthdr.len = m->m_len = m->m_ext.ext_size;
+
+ return (m);
+}
+
+static void
+awg_start_locked(struct awg_softc *sc)
+{
+ struct mbuf *m;
+ uint32_t val;
+ if_t ifp;
+ int cnt, nsegs;
+
+ AWG_ASSERT_LOCKED(sc);
+
+ if (!sc->link)
+ return;
+
+ ifp = sc->ifp;
+
+ if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING|IFF_DRV_OACTIVE)) !=
+ IFF_DRV_RUNNING)
+ return;
+
+ for (cnt = 0; ; cnt++) {
+ if (sc->tx.queued >= TX_DESC_COUNT - TX_MAX_SEGS) {
+ if_setdrvflagbits(ifp, IFF_DRV_OACTIVE, 0);
+ break;
+ }
+
+ m = if_dequeue(ifp);
+ if (m == NULL)
+ break;
+
+ nsegs = awg_setup_txbuf(sc, sc->tx.cur, &m);
+ if (nsegs == 0) {
+ if_sendq_prepend(ifp, m);
+ break;
+ }
+ if_bpfmtap(ifp, m);
+ sc->tx.cur = TX_SKIP(sc->tx.cur, nsegs);
+ }
+
+ if (cnt != 0) {
+ bus_dmamap_sync(sc->tx.desc_tag, sc->tx.desc_map,
+ BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
+
+ /* Start and run TX DMA */
+ val = RD4(sc, EMAC_TX_CTL_1);
+ WR4(sc, EMAC_TX_CTL_1, val | TX_DMA_START);
+ }
+}
+
+static void
+awg_start(if_t ifp)
+{
+ struct awg_softc *sc;
+
+ sc = if_getsoftc(ifp);
+
+ AWG_LOCK(sc);
+ awg_start_locked(sc);
+ AWG_UNLOCK(sc);
+}
+
+static void
+awg_tick(void *softc)
+{
+ struct awg_softc *sc;
+ struct mii_data *mii;
+ if_t ifp;
+ int link;
+
+ sc = softc;
+ ifp = sc->ifp;
+ mii = device_get_softc(sc->miibus);
+
+ AWG_ASSERT_LOCKED(sc);
+
+ if ((if_getdrvflags(ifp) & IFF_DRV_RUNNING) == 0)
+ return;
+
+ link = sc->link;
+ mii_tick(mii);
+ if (sc->link && !link)
+ awg_start_locked(sc);
+
+ callout_reset(&sc->stat_ch, hz, awg_tick, sc);
+}
+
+/* Bit Reversal - http://aggregate.org/MAGIC/#Bit%20Reversal */
+static uint32_t
+bitrev32(uint32_t x)
+{
+ x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1));
+ x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2));
+ x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4));
+ x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8));
+
+ return (x >> 16) | (x << 16);
+}
+
+static void
+awg_setup_rxfilter(struct awg_softc *sc)
+{
+ uint32_t val, crc, hashreg, hashbit, hash[2], machi, maclo;
+ int mc_count, mcnt, i;
+ uint8_t *eaddr, *mta;
+ if_t ifp;
+
+ AWG_ASSERT_LOCKED(sc);
+
+ ifp = sc->ifp;
+ val = 0;
+ hash[0] = hash[1] = 0;
+
+ mc_count = if_multiaddr_count(ifp, -1);
+
+ if (if_getflags(ifp) & IFF_PROMISC)
+ val |= DIS_ADDR_FILTER;
+ else if (if_getflags(ifp) & IFF_ALLMULTI) {
+ val |= RX_ALL_MULTICAST;
+ hash[0] = hash[1] = ~0;
+ } else if (mc_count > 0) {
+ val |= HASH_MULTICAST;
+
+ mta = malloc(sizeof(unsigned char) * ETHER_ADDR_LEN * mc_count,
+ M_DEVBUF, M_NOWAIT);
+ if (mta == NULL) {
+ if_printf(ifp,
+ "failed to allocate temporary multicast list\n");
+ return;
+ }
+
+ if_multiaddr_array(ifp, mta, &mcnt, mc_count);
+ for (i = 0; i < mcnt; i++) {
+ crc = ether_crc32_le(mta + (i * ETHER_ADDR_LEN),
+ ETHER_ADDR_LEN) & 0x7f;
+ crc = bitrev32(~crc) >> 26;
+ hashreg = (crc >> 5);
+ hashbit = (crc & 0x1f);
+ hash[hashreg] |= (1 << hashbit);
+ }
+
+ free(mta, M_DEVBUF);
+ }
+
+ /* Write our unicast address */
+ eaddr = IF_LLADDR(ifp);
+ machi = (eaddr[5] << 8) | eaddr[4];
+ maclo = (eaddr[3] << 24) | (eaddr[2] << 16) | (eaddr[1] << 8) |
+ (eaddr[0] << 0);
+ WR4(sc, EMAC_ADDR_HIGH(0), machi);
+ WR4(sc, EMAC_ADDR_LOW(0), maclo);
+
+ /* Multicast hash filters */
+ WR4(sc, EMAC_RX_HASH_0, hash[1]);
+ WR4(sc, EMAC_RX_HASH_1, hash[0]);
+
+ /* RX frame filter config */
+ WR4(sc, EMAC_RX_FRM_FLT, val);
+}
+
+static void
+awg_init_locked(struct awg_softc *sc)
+{
+ struct mii_data *mii;
+ uint32_t val;
+ if_t ifp;
+
+ mii = device_get_softc(sc->miibus);
+ ifp = sc->ifp;
+
+ AWG_ASSERT_LOCKED(sc);
+
+ if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
+ return;
+
+ awg_setup_rxfilter(sc);
+
+ /* Configure DMA burst length and priorities */
+ val = awg_burst_len << BASIC_CTL_BURST_LEN_SHIFT;
+ if (awg_rx_tx_pri)
+ val |= BASIC_CTL_RX_TX_PRI;
+ WR4(sc, EMAC_BASIC_CTL_1, val);
+
+ /* Enable interrupts */
+ WR4(sc, EMAC_INT_EN, RX_INT_EN | TX_INT_EN | TX_BUF_UA_INT_EN);
+
+ /* Enable transmit DMA */
+ val = RD4(sc, EMAC_TX_CTL_1);
+ WR4(sc, EMAC_TX_CTL_1, val | TX_DMA_EN | TX_MD);
+
+ /* Enable receive DMA */
+ val = RD4(sc, EMAC_RX_CTL_1);
+ WR4(sc, EMAC_RX_CTL_1, val | RX_DMA_EN | RX_MD);
+
+ /* Enable transmitter */
+ val = RD4(sc, EMAC_TX_CTL_0);
+ WR4(sc, EMAC_TX_CTL_0, val | TX_EN);
+
+ /* Enable receiver */
+ val = RD4(sc, EMAC_RX_CTL_0);
+ WR4(sc, EMAC_RX_CTL_0, val | RX_EN | CHECK_CRC);
+
+ if_setdrvflagbits(ifp, IFF_DRV_RUNNING, IFF_DRV_OACTIVE);
+
+ mii_mediachg(mii);
+ callout_reset(&sc->stat_ch, hz, awg_tick, sc);
+}
+
+static void
+awg_init(void *softc)
+{
+ struct awg_softc *sc;
+
+ sc = softc;
+
+ AWG_LOCK(sc);
+ awg_init_locked(sc);
+ AWG_UNLOCK(sc);
+}
+
+static void
+awg_stop(struct awg_softc *sc)
+{
+ if_t ifp;
+ uint32_t val;
+
+ AWG_ASSERT_LOCKED(sc);
+
+ ifp = sc->ifp;
+
+ callout_stop(&sc->stat_ch);
+
+ /* Stop transmit DMA and flush data in the TX FIFO */
+ val = RD4(sc, EMAC_TX_CTL_1);
+ val &= ~TX_DMA_EN;
+ val |= FLUSH_TX_FIFO;
+ WR4(sc, EMAC_TX_CTL_1, val);
+
+ /* Disable transmitter */
+ val = RD4(sc, EMAC_TX_CTL_0);
+ WR4(sc, EMAC_TX_CTL_0, val & ~TX_EN);
+
+ /* Disable receiver */
+ val = RD4(sc, EMAC_RX_CTL_0);
+ WR4(sc, EMAC_RX_CTL_0, val & ~RX_EN);
+
+ /* Disable interrupts */
+ WR4(sc, EMAC_INT_EN, 0);
+
+ /* Disable transmit DMA */
+ val = RD4(sc, EMAC_TX_CTL_1);
+ WR4(sc, EMAC_TX_CTL_1, val & ~TX_DMA_EN);
+
+ /* Disable receive DMA */
+ val = RD4(sc, EMAC_RX_CTL_1);
+ WR4(sc, EMAC_RX_CTL_1, val & ~RX_DMA_EN);
+
+ sc->link = 0;
+
+ if_setdrvflagbits(ifp, 0, IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+}
+
+static void
+awg_rxintr(struct awg_softc *sc)
+{
+ if_t ifp;
+ struct mbuf *m, *m0;
+ int error, index, len;
+ uint32_t status;
+
+ ifp = sc->ifp;
+
+ bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+ for (index = sc->rx.cur; ; index = RX_NEXT(index)) {
+ status = le32toh(sc->rx.desc_ring[index].status);
+ if ((status & RX_DESC_CTL) != 0)
+ break;
+
+ bus_dmamap_sync(sc->rx.buf_tag, sc->rx.buf_map[index].map,
+ BUS_DMASYNC_POSTREAD);
+ bus_dmamap_unload(sc->rx.buf_tag, sc->rx.buf_map[index].map);
+
+ len = (status & RX_FRM_LEN) >> RX_FRM_LEN_SHIFT;
+ if (len != 0) {
+ m = sc->rx.buf_map[index].mbuf;
+ m->m_pkthdr.rcvif = ifp;
+ m->m_pkthdr.len = len;
+ m->m_len = len;
+ if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
+
+ if ((if_getcapenable(ifp) & IFCAP_RXCSUM) != 0 &&
+ (status & RX_FRM_TYPE) != 0) {
+ m->m_pkthdr.csum_flags = CSUM_IP_CHECKED;
+ if ((status & RX_HEADER_ERR) == 0)
+ m->m_pkthdr.csum_flags |= CSUM_IP_VALID;
+ if ((status & RX_PAYLOAD_ERR) == 0) {
+ m->m_pkthdr.csum_flags |=
+ CSUM_DATA_VALID | CSUM_PSEUDO_HDR;
+ m->m_pkthdr.csum_data = 0xffff;
+ }
+ }
+
+ AWG_UNLOCK(sc);
+ if_input(ifp, m);
+ AWG_LOCK(sc);
+ }
+
+ if ((m0 = awg_alloc_mbufcl(sc)) != NULL) {
+ error = awg_setup_rxbuf(sc, index, m0);
+ if (error != 0) {
+ /* XXX hole in RX ring */
+ }
+ } else
+ if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
+ }
+
+ if (index != sc->rx.cur) {
+ bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map,
+ BUS_DMASYNC_PREWRITE);
+ }
+
+ sc->rx.cur = index;
+}
+
+static void
+awg_txintr(struct awg_softc *sc)
+{
+ struct awg_bufmap *bmap;
+ struct emac_desc *desc;
+ uint32_t status;
+ if_t ifp;
+ int i;
+
+ AWG_ASSERT_LOCKED(sc);
+
+ bus_dmamap_sync(sc->tx.desc_tag, sc->tx.desc_map,
+ BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
+
+ ifp = sc->ifp;
+ for (i = sc->tx.next; sc->tx.queued > 0; i = TX_NEXT(i)) {
+ desc = &sc->tx.desc_ring[i];
+ status = le32toh(desc->status);
+ if ((status & TX_DESC_CTL) != 0)
+ break;
+ bmap = &sc->tx.buf_map[i];
+ if (bmap->mbuf != NULL) {
+ bus_dmamap_sync(sc->tx.buf_tag, bmap->map,
+ BUS_DMASYNC_POSTWRITE);
+ bus_dmamap_unload(sc->tx.buf_tag, bmap->map);
+ m_freem(bmap->mbuf);
+ bmap->mbuf = NULL;
+ }
+ awg_setup_txdesc(sc, i, 0, 0, 0);
+ if_setdrvflagbits(ifp, 0, IFF_DRV_OACTIVE);
+ if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
+ }
+
+ sc->tx.next = i;
+
+ bus_dmamap_sync(sc->tx.desc_tag, sc->tx.desc_map,
+ BUS_DMASYNC_PREWRITE);
+}
+
+static void
+awg_intr(void *arg)
+{
+ struct awg_softc *sc;
+ uint32_t val;
+
+ sc = arg;
+
+ AWG_LOCK(sc);
+ val = RD4(sc, EMAC_INT_STA);
+ WR4(sc, EMAC_INT_STA, val);
+
+ if (val & RX_INT)
+ awg_rxintr(sc);
+
+ if (val & (TX_INT|TX_BUF_UA_INT)) {
+ awg_txintr(sc);
+ if (!if_sendq_empty(sc->ifp))
+ awg_start_locked(sc);
+ }
+
+ AWG_UNLOCK(sc);
+}
+
+static int
+awg_ioctl(if_t ifp, u_long cmd, caddr_t data)
+{
+ struct awg_softc *sc;
+ struct mii_data *mii;
+ struct ifreq *ifr;
+ int flags, mask, error;
+
+ sc = if_getsoftc(ifp);
+ mii = device_get_softc(sc->miibus);
+ ifr = (struct ifreq *)data;
+ error = 0;
+
+ switch (cmd) {
+ case SIOCSIFFLAGS:
+ AWG_LOCK(sc);
+ if (if_getflags(ifp) & IFF_UP) {
+ if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
+ flags = if_getflags(ifp) ^ sc->if_flags;
+ if ((flags & (IFF_PROMISC|IFF_ALLMULTI)) != 0)
+ awg_setup_rxfilter(sc);
+ } else
+ awg_init_locked(sc);
+ } else {
+ if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
+ awg_stop(sc);
+ }
+ sc->if_flags = if_getflags(ifp);
+ AWG_UNLOCK(sc);
+ break;
+ case SIOCADDMULTI:
+ case SIOCDELMULTI:
+ if (if_getdrvflags(ifp) & IFF_DRV_RUNNING) {
+ AWG_LOCK(sc);
+ awg_setup_rxfilter(sc);
+ AWG_UNLOCK(sc);
+ }
+ break;
+ case SIOCSIFMEDIA:
+ case SIOCGIFMEDIA:
+ error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, cmd);
+ break;
+ case SIOCSIFCAP:
+ mask = ifr->ifr_reqcap ^ if_getcapenable(ifp);
+ if (mask & IFCAP_VLAN_MTU)
+ if_togglecapenable(ifp, IFCAP_VLAN_MTU);
+ if (mask & IFCAP_RXCSUM)
+ if_togglecapenable(ifp, IFCAP_RXCSUM);
+ if (mask & IFCAP_TXCSUM)
+ if_togglecapenable(ifp, IFCAP_TXCSUM);
+ if ((if_getcapenable(ifp) & (IFCAP_RXCSUM|IFCAP_TXCSUM)) != 0)
+ if_sethwassistbits(ifp, CSUM_IP, 0);
+ else
+ if_sethwassistbits(ifp, 0, CSUM_IP);
+ break;
+ default:
+ error = ether_ioctl(ifp, cmd, data);
+ break;
+ }
+
+ return (error);
+}
+
+static int
+awg_setup_extres(device_t dev)
+{
+ struct awg_softc *sc;
+ hwreset_t rst_ahb;
+ clk_t clk_ahb, clk_tx, clk_tx_parent;
+ regulator_t reg;
+ const char *tx_parent_name;
+ char *phy_type;
+ phandle_t node;
+ uint64_t freq;
+ int error, div;
+
+ sc = device_get_softc(dev);
+ node = ofw_bus_get_node(dev);
+ rst_ahb = NULL;
+ clk_ahb = NULL;
+ clk_tx = NULL;
+ clk_tx_parent = NULL;
+ reg = NULL;
+ phy_type = NULL;
+
+ /* Get AHB clock and reset resources */
+ error = hwreset_get_by_ofw_name(dev, "ahb", &rst_ahb);
+ if (error != 0) {
+ device_printf(dev, "cannot get ahb reset\n");
+ goto fail;
+ }
+ error = clk_get_by_ofw_name(dev, "ahb", &clk_ahb);
+ if (error != 0) {
+ device_printf(dev, "cannot get ahb clock\n");
+ goto fail;
+ }
+
+ /* Configure PHY for MII or RGMII mode */
+ if (OF_getprop_alloc(node, "phy-mode", 1, (void **)&phy_type)) {
+ if (bootverbose)
+ device_printf(dev, "PHY type: %s\n", phy_type);
+
+ if (strcmp(phy_type, "rgmii") == 0)
+ tx_parent_name = "emac_int_tx";
+ else
+ tx_parent_name = "mii_phy_tx";
+ free(phy_type, M_OFWPROP);
+
+ /* Get the TX clock */
+ error = clk_get_by_ofw_name(dev, "tx", &clk_tx);
+ if (error != 0) {
+ device_printf(dev, "cannot get tx clock\n");
+ goto fail;
+ }
+
+ /* Find the desired parent clock based on phy-mode property */
+ error = clk_get_by_name(dev, tx_parent_name, &clk_tx_parent);
+ if (error != 0) {
+ device_printf(dev, "cannot get clock '%s'\n",
+ tx_parent_name);
+ goto fail;
+ }
+
+ /* Set TX clock parent */
+ error = clk_set_parent_by_clk(clk_tx, clk_tx_parent);
+ if (error != 0) {
+ device_printf(dev, "cannot set tx clock parent\n");
+ goto fail;
+ }
+
+ /* Enable TX clock */
+ error = clk_enable(clk_tx);
+ if (error != 0) {
+ device_printf(dev, "cannot enable tx clock\n");
+ goto fail;
+ }
+ }
+
+ /* Enable AHB clock */
+ error = clk_enable(clk_ahb);
+ if (error != 0) {
+ device_printf(dev, "cannot enable ahb clock\n");
+ goto fail;
+ }
+
+ /* De-assert reset */
+ error = hwreset_deassert(rst_ahb);
+ if (error != 0) {
+ device_printf(dev, "cannot de-assert ahb reset\n");
+ goto fail;
+ }
+
+ /* Enable PHY regulator if applicable */
+ if (regulator_get_by_ofw_property(dev, "phy-supply", &reg) == 0) {
+ error = regulator_enable(reg);
+ if (error != 0) {
+ device_printf(dev, "cannot enable PHY regulator\n");
+ goto fail;
+ }
+ }
+
+ /* Determine MDC clock divide ratio based on AHB clock */
+ error = clk_get_freq(clk_ahb, &freq);
+ if (error != 0) {
+ device_printf(dev, "cannot get AHB clock frequency\n");
+ goto fail;
+ }
+ div = freq / MDIO_FREQ;
+ if (div <= 16)
+ sc->mdc_div_ratio_m = MDC_DIV_RATIO_M_16;
+ else if (div <= 32)
+ sc->mdc_div_ratio_m = MDC_DIV_RATIO_M_32;
+ else if (div <= 64)
+ sc->mdc_div_ratio_m = MDC_DIV_RATIO_M_64;
+ else if (div <= 128)
+ sc->mdc_div_ratio_m = MDC_DIV_RATIO_M_128;
+ else {
+ device_printf(dev, "cannot determine MDC clock divide ratio\n");
+ error = ENXIO;
+ goto fail;
+ }
+
+ if (bootverbose)
+ device_printf(dev, "AHB frequency %llu Hz, MDC div: 0x%x\n",
+ freq, sc->mdc_div_ratio_m);
+
+ return (0);
+
+fail:
+ free(phy_type, M_OFWPROP);
+
+ if (reg != NULL)
+ regulator_release(reg);
+ if (clk_tx_parent != NULL)
+ clk_release(clk_tx_parent);
+ if (clk_tx != NULL)
+ clk_release(clk_tx);
+ if (clk_ahb != NULL)
+ clk_release(clk_ahb);
+ if (rst_ahb != NULL)
+ hwreset_release(rst_ahb);
+ return (error);
+}
+
+static void
+awg_get_eaddr(device_t dev, uint8_t *eaddr)
+{
+ struct awg_softc *sc;
+ uint32_t maclo, machi, rnd;
+
+ sc = device_get_softc(dev);
+
+ machi = RD4(sc, EMAC_ADDR_HIGH(0)) & 0xffff;
+ maclo = RD4(sc, EMAC_ADDR_LOW(0));
+
+ if (maclo == 0xffffffff && machi == 0xffff) {
+ /* MAC address in hardware is invalid, create one */
+ rnd = arc4random();
+ maclo = 0x00f2 | (rnd & 0xffff0000);
+ machi = rnd & 0xffff;
+ }
+
+ eaddr[0] = maclo & 0xff;
+ eaddr[1] = (maclo >> 8) & 0xff;
+ eaddr[2] = (maclo >> 16) & 0xff;
+ eaddr[3] = (maclo >> 24) & 0xff;
+ eaddr[4] = machi & 0xff;
+ eaddr[5] = (machi >> 8) & 0xff;
+}
+
+#ifdef AWG_DEBUG
+static void
+awg_dump_regs(device_t dev)
+{
+ static const struct {
+ const char *name;
+ u_int reg;
+ } regs[] = {
+ { "BASIC_CTL_0", EMAC_BASIC_CTL_0 },
+ { "BASIC_CTL_1", EMAC_BASIC_CTL_1 },
+ { "INT_STA", EMAC_INT_STA },
+ { "INT_EN", EMAC_INT_EN },
+ { "TX_CTL_0", EMAC_TX_CTL_0 },
+ { "TX_CTL_1", EMAC_TX_CTL_1 },
+ { "TX_FLOW_CTL", EMAC_TX_FLOW_CTL },
+ { "TX_DMA_LIST", EMAC_TX_DMA_LIST },
+ { "RX_CTL_0", EMAC_RX_CTL_0 },
+ { "RX_CTL_1", EMAC_RX_CTL_1 },
+ { "RX_DMA_LIST", EMAC_RX_DMA_LIST },
+ { "RX_FRM_FLT", EMAC_RX_FRM_FLT },
+ { "RX_HASH_0", EMAC_RX_HASH_0 },
+ { "RX_HASH_1", EMAC_RX_HASH_1 },
+ { "MII_CMD", EMAC_MII_CMD },
+ { "ADDR_HIGH0", EMAC_ADDR_HIGH(0) },
+ { "ADDR_LOW0", EMAC_ADDR_LOW(0) },
+ { "TX_DMA_STA", EMAC_TX_DMA_STA },
+ { "TX_DMA_CUR_DESC", EMAC_TX_DMA_CUR_DESC },
+ { "TX_DMA_CUR_BUF", EMAC_TX_DMA_CUR_BUF },
+ { "RX_DMA_STA", EMAC_RX_DMA_STA },
+ { "RX_DMA_CUR_DESC", EMAC_RX_DMA_CUR_DESC },
+ { "RX_DMA_CUR_BUF", EMAC_RX_DMA_CUR_BUF },
+ { "RGMII_STA", EMAC_RGMII_STA },
+ };
+ struct awg_softc *sc;
+ unsigned int n;
+
+ sc = device_get_softc(dev);
+
+ for (n = 0; n < nitems(regs); n++)
+ device_printf(dev, " %-20s %08x\n", regs[n].name,
+ RD4(sc, regs[n].reg));
+}
+#endif
+
+static int
+awg_reset(device_t dev)
+{
+ struct awg_softc *sc;
+ int retry;
+
+ sc = device_get_softc(dev);
+
+ /* Soft reset all registers and logic */
+ WR4(sc, EMAC_BASIC_CTL_1, BASIC_CTL_SOFT_RST);
+
+ /* Wait for soft reset bit to self-clear */
+ for (retry = SOFT_RST_RETRY; retry > 0; retry--) {
+ if ((RD4(sc, EMAC_BASIC_CTL_1) & BASIC_CTL_SOFT_RST) == 0)
+ break;
+ DELAY(10);
+ }
+ if (retry == 0) {
+ device_printf(dev, "soft reset timed out\n");
+#ifdef AWG_DEBUG
+ awg_dump_regs(dev);
+#endif
+ return (ETIMEDOUT);
+ }
+
+ return (0);
+}
+
+static void
+awg_dmamap_cb(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+ if (error != 0)
+ return;
+ *(bus_addr_t *)arg = segs[0].ds_addr;
+}
+
+static int
+awg_setup_dma(device_t dev)
+{
+ struct awg_softc *sc;
+ struct mbuf *m;
+ int error, i;
+
+ sc = device_get_softc(dev);
+
+ /* Setup TX ring */
+ error = bus_dma_tag_create(
+ bus_get_dma_tag(dev), /* Parent tag */
+ DESC_ALIGN, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ TX_DESC_SIZE, 1, /* maxsize, nsegs */
+ TX_DESC_SIZE, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->tx.desc_tag);
+ if (error != 0) {
+ device_printf(dev, "cannot create TX descriptor ring tag\n");
+ return (error);
+ }
+
+ error = bus_dmamem_alloc(sc->tx.desc_tag, (void **)&sc->tx.desc_ring,
+ BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->tx.desc_map);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate TX descriptor ring\n");
+ return (error);
+ }
+
+ error = bus_dmamap_load(sc->tx.desc_tag, sc->tx.desc_map,
+ sc->tx.desc_ring, TX_DESC_SIZE, awg_dmamap_cb,
+ &sc->tx.desc_ring_paddr, 0);
+ if (error != 0) {
+ device_printf(dev, "cannot load TX descriptor ring\n");
+ return (error);
+ }
+
+ for (i = 0; i < TX_DESC_COUNT; i++)
+ sc->tx.desc_ring[i].next =
+ htole32(sc->tx.desc_ring_paddr + DESC_OFF(TX_NEXT(i)));
+
+ error = bus_dma_tag_create(
+ bus_get_dma_tag(dev), /* Parent tag */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MCLBYTES, TX_MAX_SEGS, /* maxsize, nsegs */
+ MCLBYTES, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->tx.buf_tag);
+ if (error != 0) {
+ device_printf(dev, "cannot create TX buffer tag\n");
+ return (error);
+ }
+
+ sc->tx.queued = TX_DESC_COUNT;
+ for (i = 0; i < TX_DESC_COUNT; i++) {
+ error = bus_dmamap_create(sc->tx.buf_tag, 0,
+ &sc->tx.buf_map[i].map);
+ if (error != 0) {
+ device_printf(dev, "cannot create TX buffer map\n");
+ return (error);
+ }
+ awg_setup_txdesc(sc, i, 0, 0, 0);
+ }
+
+ /* Setup RX ring */
+ error = bus_dma_tag_create(
+ bus_get_dma_tag(dev), /* Parent tag */
+ DESC_ALIGN, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ RX_DESC_SIZE, 1, /* maxsize, nsegs */
+ RX_DESC_SIZE, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->rx.desc_tag);
+ if (error != 0) {
+ device_printf(dev, "cannot create RX descriptor ring tag\n");
+ return (error);
+ }
+
+ error = bus_dmamem_alloc(sc->rx.desc_tag, (void **)&sc->rx.desc_ring,
+ BUS_DMA_COHERENT | BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->rx.desc_map);
+ if (error != 0) {
+ device_printf(dev, "cannot allocate RX descriptor ring\n");
+ return (error);
+ }
+
+ error = bus_dmamap_load(sc->rx.desc_tag, sc->rx.desc_map,
+ sc->rx.desc_ring, RX_DESC_SIZE, awg_dmamap_cb,
+ &sc->rx.desc_ring_paddr, 0);
+ if (error != 0) {
+ device_printf(dev, "cannot load RX descriptor ring\n");
+ return (error);
+ }
+
+ error = bus_dma_tag_create(
+ bus_get_dma_tag(dev), /* Parent tag */
+ 1, 0, /* alignment, boundary */
+ BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+ BUS_SPACE_MAXADDR, /* highaddr */
+ NULL, NULL, /* filter, filterarg */
+ MCLBYTES, 1, /* maxsize, nsegs */
+ MCLBYTES, /* maxsegsize */
+ 0, /* flags */
+ NULL, NULL, /* lockfunc, lockarg */
+ &sc->rx.buf_tag);
+ if (error != 0) {
+ device_printf(dev, "cannot create RX buffer tag\n");
+ return (error);
+ }
+
+ for (i = 0; i < RX_DESC_COUNT; i++) {
+ error = bus_dmamap_create(sc->rx.buf_tag, 0,
+ &sc->rx.buf_map[i].map);
+ if (error != 0) {
+ device_printf(dev, "cannot create RX buffer map\n");
+ return (error);
+ }
+ if ((m = awg_alloc_mbufcl(sc)) == NULL) {
+ device_printf(dev, "cannot allocate RX mbuf\n");
+ return (ENOMEM);
+ }
+ error = awg_setup_rxbuf(sc, i, m);
+ if (error != 0) {
+ device_printf(dev, "cannot create RX buffer\n");
+ return (error);
+ }
+ }
+ bus_dmamap_sync(sc->rx.desc_tag, sc->rx.desc_map,
+ BUS_DMASYNC_PREWRITE);
+
+ /* Write transmit and receive descriptor base address registers */
+ WR4(sc, EMAC_TX_DMA_LIST, sc->tx.desc_ring_paddr);
+ WR4(sc, EMAC_RX_DMA_LIST, sc->rx.desc_ring_paddr);
+
+ return (0);
+}
+
+static int
+awg_probe(device_t dev)
+{
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "Allwinner Gigabit Ethernet");
+ return (BUS_PROBE_DEFAULT);
+}
+
+static int
+awg_attach(device_t dev)
+{
+ uint8_t eaddr[ETHER_ADDR_LEN];
+ struct awg_softc *sc;
+ phandle_t node;
+ int error;
+
+ sc = device_get_softc(dev);
+ node = ofw_bus_get_node(dev);
+
+ if (bus_alloc_resources(dev, awg_spec, sc->res) != 0) {
+ device_printf(dev, "cannot allocate resources for device\n");
+ return (ENXIO);
+ }
+
+ mtx_init(&sc->mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF);
+ callout_init_mtx(&sc->stat_ch, &sc->mtx, 0);
+ TASK_INIT(&sc->link_task, 0, awg_link_task, sc);
+
+ /* Setup clocks and regulators */
+ error = awg_setup_extres(dev);
+ if (error != 0)
+ return (error);
+
+ /* Read MAC address before resetting the chip */
+ awg_get_eaddr(dev, eaddr);
+
+ /* Soft reset EMAC core */
+ error = awg_reset(dev);
+ if (error != 0)
+ return (error);
+
+ /* Setup DMA descriptors */
+ error = awg_setup_dma(dev);
+ if (error != 0)
+ return (error);
+
+ /* Install interrupt handler */
+ error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_NET | INTR_MPSAFE,
+ NULL, awg_intr, sc, &sc->ih);
+ if (error != 0) {
+ device_printf(dev, "cannot setup interrupt handler\n");
+ return (error);
+ }
+
+ /* Setup ethernet interface */
+ sc->ifp = if_alloc(IFT_ETHER);
+ if_setsoftc(sc->ifp, sc);
+ if_initname(sc->ifp, device_get_name(dev), device_get_unit(dev));
+ if_setflags(sc->ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
+ if_setstartfn(sc->ifp, awg_start);
+ if_setioctlfn(sc->ifp, awg_ioctl);
+ if_setinitfn(sc->ifp, awg_init);
+ if_setsendqlen(sc->ifp, TX_DESC_COUNT - 1);
+ if_setsendqready(sc->ifp);
+ if_sethwassist(sc->ifp, CSUM_IP | CSUM_UDP | CSUM_TCP);
+ if_setcapabilities(sc->ifp, IFCAP_VLAN_MTU | IFCAP_HWCSUM);
+ if_setcapenable(sc->ifp, if_getcapabilities(sc->ifp));
+
+ /* Attach MII driver */
+ error = mii_attach(dev, &sc->miibus, sc->ifp, awg_media_change,
+ awg_media_status, BMSR_DEFCAPMASK, MII_PHY_ANY, MII_OFFSET_ANY,
+ MIIF_DOPAUSE);
+ if (error != 0) {
+ device_printf(dev, "cannot attach PHY\n");
+ return (error);
+ }
+
+ /* Attach ethernet interface */
+ ether_ifattach(sc->ifp, eaddr);
+
+ return (0);
+}
+
+static device_method_t awg_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, awg_probe),
+ DEVMETHOD(device_attach, awg_attach),
+
+ /* MII interface */
+ DEVMETHOD(miibus_readreg, awg_miibus_readreg),
+ DEVMETHOD(miibus_writereg, awg_miibus_writereg),
+ DEVMETHOD(miibus_statchg, awg_miibus_statchg),
+
+ DEVMETHOD_END
+};
+
+static driver_t awg_driver = {
+ "awg",
+ awg_methods,
+ sizeof(struct awg_softc),
+};
+
+static devclass_t awg_devclass;
+
+DRIVER_MODULE(awg, simplebus, awg_driver, awg_devclass, 0, 0);
+DRIVER_MODULE(miibus, awg, miibus_driver, miibus_devclass, 0, 0);
+
+MODULE_DEPEND(awg, ether, 1, 1, 1);
+MODULE_DEPEND(awg, miibus, 1, 1, 1);
diff --git a/sys/arm/allwinner/if_awgreg.h b/sys/arm/allwinner/if_awgreg.h
new file mode 100644
index 0000000..53a15c1
--- /dev/null
+++ b/sys/arm/allwinner/if_awgreg.h
@@ -0,0 +1,181 @@
+/*-
+ * Copyright (c) 2016 Jared McNeill <jmcneill@invisible.ca>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+/*
+ * Allwinner Gigabit Ethernet
+ */
+
+#ifndef __IF_AWGREG_H__
+#define __IF_AWGREG_H__
+
+#define EMAC_BASIC_CTL_0 0x00
+#define BASIC_CTL_SPEED (0x3 << 2)
+#define BASIC_CTL_SPEED_SHIFT 2
+#define BASIC_CTL_SPEED_1000 0
+#define BASIC_CTL_SPEED_10 2
+#define BASIC_CTL_SPEED_100 3
+#define BASIC_CTL_LOOPBACK (1 << 1)
+#define BASIC_CTL_DUPLEX (1 << 0)
+#define EMAC_BASIC_CTL_1 0x04
+#define BASIC_CTL_BURST_LEN (0x3f << 24)
+#define BASIC_CTL_BURST_LEN_SHIFT 24
+#define BASIC_CTL_RX_TX_PRI (1 << 1)
+#define BASIC_CTL_SOFT_RST (1 << 0)
+#define EMAC_INT_STA 0x08
+#define RX_BUF_UA_INT (1 << 10)
+#define RX_INT (1 << 8)
+#define TX_UNDERFLOW_INT (1 << 4)
+#define TX_BUF_UA_INT (1 << 2)
+#define TX_DMA_STOPPED_INT (1 << 1)
+#define TX_INT (1 << 0)
+#define EMAC_INT_EN 0x0c
+#define RX_BUF_UA_INT_EN (1 << 10)
+#define RX_INT_EN (1 << 8)
+#define TX_UNDERFLOW_INT_EN (1 << 4)
+#define TX_BUF_UA_INT_EN (1 << 2)
+#define TX_DMA_STOPPED_INT_EN (1 << 1)
+#define TX_INT_EN (1 << 0)
+#define EMAC_TX_CTL_0 0x10
+#define TX_EN (1 << 31)
+#define EMAC_TX_CTL_1 0x14
+#define TX_DMA_START (1 << 31)
+#define TX_DMA_EN (1 << 30)
+#define TX_MD (1 << 1)
+#define FLUSH_TX_FIFO (1 << 0)
+#define EMAC_TX_FLOW_CTL 0x1c
+#define PAUSE_TIME (0xffff << 4)
+#define PAUSE_TIME_SHIFT 4
+#define TX_FLOW_CTL_EN (1 << 0)
+#define EMAC_TX_DMA_LIST 0x20
+#define EMAC_RX_CTL_0 0x24
+#define RX_EN (1 << 31)
+#define JUMBO_FRM_EN (1 << 29)
+#define STRIP_FCS (1 << 28)
+#define CHECK_CRC (1 << 27)
+#define RX_FLOW_CTL_EN (1 << 16)
+#define EMAC_RX_CTL_1 0x28
+#define RX_DMA_START (1 << 31)
+#define RX_DMA_EN (1 << 30)
+#define RX_MD (1 << 1)
+#define EMAC_RX_DMA_LIST 0x34
+#define EMAC_RX_FRM_FLT 0x38
+#define DIS_ADDR_FILTER (1 << 31)
+#define DIS_BROADCAST (1 << 17)
+#define RX_ALL_MULTICAST (1 << 16)
+#define CTL_FRM_FILTER (0x3 << 12)
+#define CTL_FRM_FILTER_SHIFT 12
+#define HASH_MULTICAST (1 << 9)
+#define HASH_UNICAST (1 << 8)
+#define SA_FILTER_EN (1 << 6)
+#define SA_INV_FILTER (1 << 5)
+#define DA_INV_FILTER (1 << 4)
+#define FLT_MD (1 << 1)
+#define RX_ALL (1 << 0)
+#define EMAC_RX_HASH_0 0x40
+#define EMAC_RX_HASH_1 0x44
+#define EMAC_MII_CMD 0x48
+#define MDC_DIV_RATIO_M (0x7 << 20)
+#define MDC_DIV_RATIO_M_16 0
+#define MDC_DIV_RATIO_M_32 1
+#define MDC_DIV_RATIO_M_64 2
+#define MDC_DIV_RATIO_M_128 3
+#define MDC_DIV_RATIO_M_SHIFT 20
+#define PHY_ADDR (0x1f << 12)
+#define PHY_ADDR_SHIFT 12
+#define PHY_REG_ADDR (0x1f << 4)
+#define PHY_REG_ADDR_SHIFT 4
+#define MII_WR (1 << 1)
+#define MII_BUSY (1 << 0)
+#define EMAC_MII_DATA 0x4c
+#define EMAC_ADDR_HIGH(n) (0x50 + (n) * 8)
+#define EMAC_ADDR_LOW(n) (0x54 + (n) * 8)
+#define EMAC_TX_DMA_STA 0x80
+#define EMAC_TX_DMA_CUR_DESC 0x84
+#define EMAC_TX_DMA_CUR_BUF 0x88
+#define EMAC_RX_DMA_STA 0xc0
+#define EMAC_RX_DMA_CUR_DESC 0xc4
+#define EMAC_RX_DMA_CUR_BUF 0xc8
+#define EMAC_RGMII_STA 0xd0
+
+struct emac_desc {
+ uint32_t status;
+/* Transmit */
+#define TX_DESC_CTL (1 << 31)
+#define TX_HEADER_ERR (1 << 16)
+#define TX_LENGTH_ERR (1 << 14)
+#define TX_PAYLOAD_ERR (1 << 12)
+#define TX_CRS_ERR (1 << 10)
+#define TX_COL_ERR_0 (1 << 9)
+#define TX_COL_ERR_1 (1 << 8)
+#define TX_COL_CNT (0xf << 3)
+#define TX_COL_CNT_SHIFT 3
+#define TX_DEFER_ERR (1 << 2)
+#define TX_UNDERFLOW_ERR (1 << 1)
+#define TX_DEFER (1 << 0)
+/* Receive */
+#define RX_DESC_CTL (1 << 31)
+#define RX_DAF_FAIL (1 << 30)
+#define RX_FRM_LEN (0x3fff << 16)
+#define RX_FRM_LEN_SHIFT 16
+#define RX_NO_ENOUGH_BUF_ERR (1 << 14)
+#define RX_SAF_FAIL (1 << 13)
+#define RX_OVERFLOW_ERR (1 << 11)
+#define RX_FIR_DESC (1 << 9)
+#define RX_LAST_DESC (1 << 8)
+#define RX_HEADER_ERR (1 << 7)
+#define RX_COL_ERR (1 << 6)
+#define RX_FRM_TYPE (1 << 5)
+#define RX_LENGTH_ERR (1 << 4)
+#define RX_PHY_ERR (1 << 3)
+#define RX_CRC_ERR (1 << 1)
+#define RX_PAYLOAD_ERR (1 << 0)
+
+ uint32_t size;
+/* Transmit */
+#define TX_INT_CTL (1 << 31)
+#define TX_LAST_DESC (1 << 30)
+#define TX_FIR_DESC (1 << 29)
+#define TX_CHECKSUM_CTL (0x3 << 27)
+#define TX_CHECKSUM_CTL_IP 1
+#define TX_CHECKSUM_CTL_NO_PSE 2
+#define TX_CHECKSUM_CTL_FULL 3
+#define TX_CHECKSUM_CTL_SHIFT 27
+#define TX_CRC_CTL (1 << 26)
+#define TX_BUF_SIZE (0xfff << 0)
+#define TX_BUF_SIZE_SHIFT 0
+/* Receive */
+#define RX_INT_CTL (1 << 31)
+#define RX_BUF_SIZE (0xfff << 0)
+#define RX_BUF_SIZE_SHIFT 0
+
+ uint32_t addr;
+
+ uint32_t next;
+} __packed;
+
+#endif /* !__IF_AWGREG_H__ */
diff --git a/sys/arm/allwinner/std.allwinner b/sys/arm/allwinner/std.allwinner
index 885d41d..5ac9dd6 100644
--- a/sys/arm/allwinner/std.allwinner
+++ b/sys/arm/allwinner/std.allwinner
@@ -14,3 +14,4 @@ options IPI_IRQ_END=15
files "../allwinner/files.allwinner"
files "../allwinner/a20/files.a20"
files "../allwinner/a31/files.a31"
+files "../allwinner/a83t/files.a83t"
diff --git a/sys/arm/amlogic/aml8726/aml8726_mmc.c b/sys/arm/amlogic/aml8726/aml8726_mmc.c
index 0e24975..5205507 100644
--- a/sys/arm/amlogic/aml8726/aml8726_mmc.c
+++ b/sys/arm/amlogic/aml8726/aml8726_mmc.c
@@ -240,7 +240,7 @@ aml8726_mmc_start_command(struct aml8726_mmc_softc *sc, struct mmc_command *cmd)
* Start and transmission bits are per section 4.7.2 of the:
*
* SD Specifications Part 1
- * Physicaly Layer Simplified Specification
+ * Physical Layer Simplified Specification
* Version 4.10
*/
cmdr = AML_MMC_CMD_START_BIT | AML_MMC_CMD_TRANS_BIT_HOST | cmd->opcode;
diff --git a/sys/arm/amlogic/aml8726/aml8726_mmc.h b/sys/arm/amlogic/aml8726/aml8726_mmc.h
index 64e3bae..a2dde21 100644
--- a/sys/arm/amlogic/aml8726/aml8726_mmc.h
+++ b/sys/arm/amlogic/aml8726/aml8726_mmc.h
@@ -39,7 +39,7 @@
* Read and write are per section 4.6.2 of the:
*
* SD Specifications Part 1
- * Physicaly Layer Simplified Specification
+ * Physical Layer Simplified Specification
* Version 4.10
*/
#define AML_MMC_CMD_TIMEOUT 50
diff --git a/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c b/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c
index 75825fb..a5be5e4 100644
--- a/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c
+++ b/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.c
@@ -484,7 +484,7 @@ aml8726_sdxc_finish_command(struct aml8726_sdxc_softc *sc, int mmc_error)
if (stop_cmd != NULL) {
/*
- * If the original command executed successfuly, then
+ * If the original command executed successfully, then
* the hardware will also have automatically executed
* a stop command so don't bother with the one supplied
* with the original request.
diff --git a/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.h b/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.h
index 013a86e..1d0dc14 100644
--- a/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.h
+++ b/sys/arm/amlogic/aml8726/aml8726_sdxc-m8.h
@@ -38,7 +38,7 @@
* Read and write are per section 4.6.2 of the:
*
* SD Specifications Part 1
- * Physicaly Layer Simplified Specification
+ * Physical Layer Simplified Specification
* Version 4.10
*/
#define AML_SDXC_CMD_TIMEOUT 50
diff --git a/sys/arm/arm/cpufunc_asm_arm11.S b/sys/arm/arm/cpufunc_asm_arm11.S
index f83f819..d6538c6 100644
--- a/sys/arm/arm/cpufunc_asm_arm11.S
+++ b/sys/arm/arm/cpufunc_asm_arm11.S
@@ -30,7 +30,7 @@
*
* ARM11 assembly functions for CPU / MMU / TLB specific operations
*
- * XXX We make no attempt at present to take advantage of the v6 memroy
+ * XXX We make no attempt at present to take advantage of the v6 memory
* architecture or physically tagged cache.
*/
diff --git a/sys/arm/arm/exception.S b/sys/arm/arm/exception.S
index 9f186a5..9466cf6 100644
--- a/sys/arm/arm/exception.S
+++ b/sys/arm/arm/exception.S
@@ -175,7 +175,7 @@ _C_LABEL(dtrace_invop_jump_addr):
ldr r4, [r5, #4]; /* reset it to point at the */ \
cmp r4, #0xffffffff; /* end of memory if necessary; */ \
movne r1, #0xffffffff; /* leave value in r4 for later */ \
- strne r1, [r5, #4]; /* comparision against PC. */ \
+ strne r1, [r5, #4]; /* comparison against PC. */ \
ldr r3, [r5]; /* Retrieve global RAS_START */ \
cmp r3, #0; /* and reset it if non-zero. */ \
movne r1, #0; /* If non-zero RAS_START and */ \
diff --git a/sys/arm/arm/genassym.c b/sys/arm/arm/genassym.c
index f9cb23e..9c67018 100644
--- a/sys/arm/arm/genassym.c
+++ b/sys/arm/arm/genassym.c
@@ -28,6 +28,7 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
+#include <sys/cpuset.h>
#include <sys/systm.h>
#include <sys/assym.h>
#include <sys/proc.h>
diff --git a/sys/arm/arm/generic_timer.c b/sys/arm/arm/generic_timer.c
index 6e6fcea..dcf48bc 100644
--- a/sys/arm/arm/generic_timer.c
+++ b/sys/arm/arm/generic_timer.c
@@ -100,7 +100,7 @@ static struct arm_tmr_softc *arm_tmr_sc = NULL;
static struct resource_spec timer_spec[] = {
{ SYS_RES_IRQ, 0, RF_ACTIVE }, /* Secure */
{ SYS_RES_IRQ, 1, RF_ACTIVE }, /* Non-secure */
- { SYS_RES_IRQ, 2, RF_ACTIVE }, /* Virt */
+ { SYS_RES_IRQ, 2, RF_ACTIVE | RF_OPTIONAL }, /* Virt */
{ SYS_RES_IRQ, 3, RF_ACTIVE | RF_OPTIONAL }, /* Hyp */
{ -1, 0 }
};
@@ -392,13 +392,17 @@ arm_tmr_attach(device_t dev)
#ifdef __arm__
sc->physical = true;
#else /* __aarch64__ */
- sc->physical = false;
+ /* If we do not have a virtual timer use the physical. */
+ sc->physical = (sc->res[2] == NULL) ? true : false;
#endif
arm_tmr_sc = sc;
/* Setup secure, non-secure and virtual IRQs handler */
for (i = 0; i < 3; i++) {
+ /* If we do not have the interrupt, skip it. */
+ if (sc->res[i] == NULL)
+ continue;
error = bus_setup_intr(dev, sc->res[i], INTR_TYPE_CLK,
arm_tmr_intr, NULL, sc, &sc->ihl[i]);
if (error) {
@@ -417,7 +421,7 @@ arm_tmr_attach(device_t dev)
sc->et.et_quality = 1000;
sc->et.et_frequency = sc->clkfreq;
- sc->et.et_min_period = (0x00000002LLU << 32) / sc->et.et_frequency;
+ sc->et.et_min_period = (0x00000010LLU << 32) / sc->et.et_frequency;
sc->et.et_max_period = (0xfffffffeLLU << 32) / sc->et.et_frequency;
sc->et.et_start = arm_tmr_start;
sc->et.et_stop = arm_tmr_stop;
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
index 08693d9..17e1525 100644
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -1006,18 +1006,22 @@ gic_map_intr(device_t dev, struct intr_map_data *data, u_int *irqp,
enum intr_polarity pol;
enum intr_trigger trig;
struct arm_gic_softc *sc;
+#ifdef FDT
+ struct intr_map_data_fdt *daf;
+#endif
sc = device_get_softc(dev);
switch (data->type) {
#ifdef FDT
case INTR_MAP_DATA_FDT:
- if (gic_map_fdt(dev, data->fdt.ncells, data->fdt.cells, &irq,
- &pol, &trig) != 0)
+ daf = (struct intr_map_data_fdt *)data;
+ if (gic_map_fdt(dev, daf->ncells, daf->cells, &irq, &pol,
+ &trig) != 0)
return (EINVAL);
break;
#endif
default:
- return (EINVAL);
+ return (ENOTSUP);
}
if (irq >= sc->nirqs)
@@ -1231,7 +1235,7 @@ arm_gic_next_irq(struct arm_gic_softc *sc, int last_irq)
active_irq = gic_c_read_4(sc, GICC_IAR);
/*
- * Immediatly EOIR the SGIs, because doing so requires the other
+ * Immediately EOIR the SGIs, because doing so requires the other
* bits (ie CPU number), not just the IRQ number, and we do not
* have this information later.
*/
diff --git a/sys/arm/arm/machdep.c b/sys/arm/arm/machdep.c
index 453c197..49d5986 100644
--- a/sys/arm/arm/machdep.c
+++ b/sys/arm/arm/machdep.c
@@ -36,7 +36,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * Machine dependant functions for kernel setup
+ * Machine dependent functions for kernel setup
*
* Created : 17/09/94
* Updated : 18/04/01 updated for new wscons
diff --git a/sys/arm/arm/mpcore_timer.c b/sys/arm/arm/mpcore_timer.c
index fb30d38..03f8e4b 100644
--- a/sys/arm/arm/mpcore_timer.c
+++ b/sys/arm/arm/mpcore_timer.c
@@ -367,7 +367,7 @@ attach_et(struct arm_tmr_softc *sc)
* globally and registers both the timecount and eventtimer objects.
*
* RETURNS
- * Zero on sucess or ENXIO if an error occuried.
+ * Zero on success or ENXIO if an error occuried.
*/
static int
arm_tmr_attach(device_t dev)
@@ -457,7 +457,7 @@ EARLY_DRIVER_MODULE(mp_tmr, ofwbus, arm_tmr_driver, arm_tmr_devclass, 0, 0,
/*
* Handle a change in clock frequency. The mpcore timer runs at half the CPU
* frequency. When the CPU frequency changes due to power-saving or thermal
- * managment, the platform-specific code that causes the frequency change calls
+ * management, the platform-specific code that causes the frequency change calls
* this routine to inform the clock driver, and we in turn inform the event
* timer system, which actually updates the value in et->frequency for us and
* reschedules the current event(s) in a way that's atomic with respect to
diff --git a/sys/arm/arm/pmap-v4.c b/sys/arm/arm/pmap-v4.c
index 733ccf2..3bdc9e4 100644
--- a/sys/arm/arm/pmap-v4.c
+++ b/sys/arm/arm/pmap-v4.c
@@ -126,7 +126,7 @@
*
* pmap.c
*
- * Machine dependant vm stuff
+ * Machine dependent vm stuff
*
* Created : 20/09/94
*/
@@ -1386,9 +1386,9 @@ pmap_clearbit(struct vm_page *pg, u_int maskbits)
*
* Don't turn caching on again if this is a
* modified emulation. This would be
- * inconsitent with the settings created by
+ * inconsistent with the settings created by
* pmap_fix_cache(). Otherwise, it's safe
- * to re-enable cacheing.
+ * to re-enable caching.
*
* There's no need to call pmap_fix_cache()
* here: all pages are losing their write
diff --git a/sys/arm/arm/pmap-v6.c b/sys/arm/arm/pmap-v6.c
index f5a6fa8..703f39d 100644
--- a/sys/arm/arm/pmap-v6.c
+++ b/sys/arm/arm/pmap-v6.c
@@ -705,7 +705,7 @@ pmap_preboot_get_pages(u_int num)
}
/*
- * The fundamental initalization of PMAP stuff.
+ * The fundamental initialization of PMAP stuff.
*
* Some things already happened in locore.S and some things could happen
* before pmap_bootstrap_prepare() is called, so let's recall what is done:
@@ -1210,7 +1210,7 @@ pmap_bootstrap(vm_offset_t firstaddr)
/*
* Note that in very short time in initarm(), we are going to
- * initialize phys_avail[] array and no futher page allocation
+ * initialize phys_avail[] array and no further page allocation
* can happen after that until vm subsystem will be initialized.
*/
kernel_vm_end_new = kernel_vm_end;
diff --git a/sys/arm/arm/swtch-v4.S b/sys/arm/arm/swtch-v4.S
index 6fdbeed..21924dc 100644
--- a/sys/arm/arm/swtch-v4.S
+++ b/sys/arm/arm/swtch-v4.S
@@ -296,7 +296,7 @@ ENTRY(cpu_switch)
beq .Lcs_context_switched /* yes! */
/*
- * Definately need to flush the cache.
+ * Definitely need to flush the cache.
*/
ldr r1, .Lcpufuncs
diff --git a/sys/arm/at91/at91_cfata.c b/sys/arm/at91/at91_cfata.c
index 37ce434..d4848ff 100644
--- a/sys/arm/at91/at91_cfata.c
+++ b/sys/arm/at91/at91_cfata.c
@@ -26,7 +26,7 @@
* common memory mode. Interrupts are driven by polling. The driver
* implements an ATA bridge and attached ATA channel driver on top
* of it.
- * NOTE WELL: this driver uses polling mode. To achive an acceptable
+ * NOTE WELL: this driver uses polling mode. To achieve an acceptable
* operating speed you will probably want to use HZ=2000 in kernel
* config.
*/
diff --git a/sys/arm/at91/at91_machdep.c b/sys/arm/at91/at91_machdep.c
index b6ff9ca..6be7f72 100644
--- a/sys/arm/at91/at91_machdep.c
+++ b/sys/arm/at91/at91_machdep.c
@@ -36,7 +36,7 @@
*
* machdep.c
*
- * Machine dependant functions for kernel setup
+ * Machine dependent functions for kernel setup
*
* This file needs a lot of work.
*
diff --git a/sys/arm/at91/at91_mci.c b/sys/arm/at91/at91_mci.c
index cf884b9..bb5b7d5 100644
--- a/sys/arm/at91/at91_mci.c
+++ b/sys/arm/at91/at91_mci.c
@@ -92,7 +92,7 @@ __FBSDID("$FreeBSD$");
* speed is 25MHz and the next highest speed is 15MHz or less. This appears
* to work on virtually all SD cards, since it is what this driver has been
* doing prior to the introduction of this option, where the overclocking vs
- * underclocking decision was automaticly "overclock". Modern SD cards can
+ * underclocking decision was automatically "overclock". Modern SD cards can
* run at 45mhz/1-bit in standard mode (high speed mode enable commands not
* sent) without problems.
*
@@ -212,7 +212,7 @@ at91_bswap_buf(struct at91_mci_softc *sc, void * dptr, void * sptr, uint32_t mem
/*
* If the hardware doesn't need byte-swapping, let bcopy() do the
* work. Use bounce buffer even if we don't need byteswap, since
- * buffer may straddle a page boundry, and we don't handle
+ * buffer may straddle a page boundary, and we don't handle
* multi-segment transfers in hardware. Seen from 'bsdlabel -w' which
* uses raw geom access to the volume. Greg Ansley (gja (at)
* ansley.com)
diff --git a/sys/arm/at91/at91_reset.S b/sys/arm/at91/at91_reset.S
index 28703cc..36d72e4 100644
--- a/sys/arm/at91/at91_reset.S
+++ b/sys/arm/at91/at91_reset.S
@@ -14,7 +14,7 @@ __FBSDID("$FreeBSD$");
/*
* From AT91SAM9G20 Datasheet errata 44:3.5:
*
- * When User Reset occurs durring SDRAM read acces, eh SDRAM clock is turned
+ * When User Reset occurs during SDRAM read access, the SDRAM clock is turned
* off while data are ready to be read on the data bus. The SDRAM maintains
* the data until the clock restarts.
*
diff --git a/sys/arm/at91/at91reg.h b/sys/arm/at91/at91reg.h
index e0aaa81..35e14f5 100644
--- a/sys/arm/at91/at91reg.h
+++ b/sys/arm/at91/at91reg.h
@@ -39,9 +39,9 @@
#define AT91_PA_BASE 0xf0000000
/* A few things that we count on being the same
- * throught the whole family of SOCs */
+ * throughout the whole family of SOCs */
-/* SYSC System Controler */
+/* SYSC System Controller */
/* System Registers */
#define AT91_SYS_BASE 0xffff000
#define AT91_SYS_SIZE 0x1000
diff --git a/sys/arm/at91/at91sam9260.c b/sys/arm/at91/at91sam9260.c
index 5b0f537..4514d87 100644
--- a/sys/arm/at91/at91sam9260.c
+++ b/sys/arm/at91/at91sam9260.c
@@ -188,7 +188,7 @@ at91_clock_init(void)
* PMC alogrithm choose the divisor that causes the input clock
* to be near the optimal 2 MHz per datasheet. We know
* we are going to be using this for the USB clock at 96 MHz.
- * Causes no extra frequency deviation for all recomended crystal
+ * Causes no extra frequency deviation for all recommended crystal
* values. See Note 1, table 40-16 SAM9260 doc.
*/
clk = at91_pmc_clock_ref("pllb");
diff --git a/sys/arm/at91/if_ate.c b/sys/arm/at91/if_ate.c
index 082b24f..fdca46b 100644
--- a/sys/arm/at91/if_ate.c
+++ b/sys/arm/at91/if_ate.c
@@ -651,7 +651,7 @@ ate_activate(device_t dev)
ate_getaddr, &sc->tx_desc_phys, 0) != 0)
goto errout;
- /* Initilize descriptors; mark all empty */
+ /* Initialize descriptors; mark all empty */
for (i = 0; i < ATE_MAX_TX_BUFFERS; i++) {
sc->tx_descs[i].addr =0;
sc->tx_descs[i].status = ETHB_TX_USED;
@@ -919,7 +919,7 @@ ate_intr(void *xsc)
/*
* Simulate SAM9 FIRST/LAST bits for RM9200.
* RM9200 EMAC has only on Rx buffer per packet.
- * But sometime we are handed a zero lenght packet.
+ * But sometime we are handed a zero length packet.
*/
if ((rxdhead->status & ETH_LEN_MASK) == 0)
rxdhead->status = 0; /* Mark error */
@@ -980,7 +980,7 @@ ate_intr(void *xsc)
do {
/* Last buffer may just be 1-4 bytes of FCS so remain
- * may be zero for last decriptor. */
+ * may be zero for last descriptor. */
if (remain > 0) {
/* Make sure we get the current bytes */
bus_dmamap_sync(sc->rx_tag, sc->rx_map[sc->rxhead],
@@ -989,7 +989,7 @@ ate_intr(void *xsc)
count = MIN(remain, sc->rx_buf_size);
/* XXX Performance robbing copy. Could
- * recieve directly to mbufs if not an
+ * receive directly to mbufs if not an
* RM9200. And even then we could likely
* copy just the protocol headers. XXX */
m_append(mb, count, sc->rx_buf[sc->rxhead]);
@@ -1468,7 +1468,7 @@ ate_miibus_readreg(device_t dev, int phy, int reg)
int val;
/*
- * XXX if we implement agressive power savings, then we need
+ * XXX if we implement aggressive power savings, then we need
* XXX to make sure that the clock to the emac is on here
*/
@@ -1488,7 +1488,7 @@ ate_miibus_writereg(device_t dev, int phy, int reg, int data)
struct ate_softc *sc;
/*
- * XXX if we implement agressive power savings, then we need
+ * XXX if we implement aggressive power savings, then we need
* XXX to make sure that the clock to the emac is on here
*/
diff --git a/sys/arm/at91/if_atereg.h b/sys/arm/at91/if_atereg.h
index fc7e4de..c6cbbcf 100644
--- a/sys/arm/at91/if_atereg.h
+++ b/sys/arm/at91/if_atereg.h
@@ -28,7 +28,7 @@
#ifndef ARM_AT91_IF_ATEREG_H
#define ARM_AT91_IF_ATEREG_H
-/* deines begining ETHB_ are EMACB (newer SAM9 hardware) versions only */
+/* Defines beginning ETHB_ are EMACB (newer SAM9 hardware) versions only. */
#define ETH_CTL 0x00 /* EMAC Control Register */
#define ETH_CFG 0x04 /* EMAC Configuration Register */
@@ -191,7 +191,7 @@ typedef struct {
#define ETH_MAC_LOCAL_3 (1U << 24) /* Packet matched addr 3 */
#define ETH_MAC_LOCAL_2 (1U << 25) /* Packet matched addr 2 */
#define ETH_MAC_LOCAL_1 (1U << 26) /* Packet matched addr 1 */
-#define ETH_MAC_UNK (1U << 27) /* Unkown source address RFU */
+#define ETH_MAC_UNK (1U << 27) /* Unknown source address RFU */
#define ETH_MAC_EXT (1U << 28) /* External Address */
#define ETH_MAC_UCAST (1U << 29) /* Unicast hash match */
#define ETH_MAC_MCAST (1U << 30) /* Multicast hash match */
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_audio.c b/sys/arm/broadcom/bcm2835/bcm2835_audio.c
index bfed287..8658c26 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_audio.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_audio.c
@@ -828,7 +828,7 @@ bcm2835_audio_attach(device_t dev)
/*
* We need interrupts enabled for VCHI to work properly,
- * so delay intialization until it happens
+ * so delay initialization until it happens.
*/
sc->intr_hook.ich_func = bcm2835_audio_delayed_init;
sc->intr_hook.ich_arg = sc;
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_dma.c b/sys/arm/broadcom/bcm2835/bcm2835_dma.c
index 347be2b..f174701 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_dma.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_dma.c
@@ -278,7 +278,7 @@ bcm_dma_init(device_t dev)
/*
* Least alignment for busdma-allocated stuff is cache
- * line size, so just make sure nothing stupid happend
+ * line size, so just make sure nothing stupid happened
* and we got properly aligned address
*/
if ((uintptr_t)cb_virt & 0x1f) {
@@ -539,7 +539,7 @@ bcm_dma_reg_dump(int ch)
* ch - channel number
* src, dst - source and destination address in
* ARM physical memory address space.
- * len - amount of bytes to be transfered
+ * len - amount of bytes to be transferred
*
* Returns 0 on success, -1 otherwise
*/
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
index 7c67a38..9619503 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_gpio.c
@@ -67,8 +67,16 @@ __FBSDID("$FreeBSD$");
#define BCM_GPIO_IRQS 4
#define BCM_GPIO_PINS 54
#define BCM_GPIO_PINS_PER_BANK 32
+
+#ifdef INTRNG
+#define BCM_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
+ GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN | GPIO_INTR_LEVEL_LOW | \
+ GPIO_INTR_LEVEL_HIGH | GPIO_INTR_EDGE_RISING | \
+ GPIO_INTR_EDGE_FALLING | GPIO_INTR_EDGE_BOTH)
+#else
#define BCM_GPIO_DEFAULT_CAPS (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | \
GPIO_PIN_PULLUP | GPIO_PIN_PULLDOWN)
+#endif
static struct resource_spec bcm_gpio_res_spec[] = {
{ SYS_RES_MEMORY, 0, RF_ACTIVE },
@@ -88,7 +96,7 @@ struct bcm_gpio_sysctl {
struct bcm_gpio_irqsrc {
struct intr_irqsrc bgi_isrc;
uint32_t bgi_irq;
- uint32_t bgi_reg;
+ uint32_t bgi_mode;
uint32_t bgi_mask;
};
#endif
@@ -894,6 +902,17 @@ bcm_gpio_detach(device_t dev)
#ifdef INTRNG
static inline void
+bcm_gpio_modify(struct bcm_gpio_softc *sc, uint32_t reg, uint32_t mask,
+ bool set_bits)
+{
+
+ if (set_bits)
+ BCM_GPIO_SET_BITS(sc, reg, mask);
+ else
+ BCM_GPIO_CLEAR_BITS(sc, reg, mask);
+}
+
+static inline void
bcm_gpio_isrc_eoi(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
{
uint32_t bank;
@@ -906,28 +925,64 @@ bcm_gpio_isrc_eoi(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
static inline bool
bcm_gpio_isrc_is_level(struct bcm_gpio_irqsrc *bgi)
{
- uint32_t bank;
- bank = BCM_GPIO_BANK(bgi->bgi_irq);
- return (bgi->bgi_reg == BCM_GPIO_GPHEN(bank) ||
- bgi->bgi_reg == BCM_GPIO_GPLEN(bank));
+ return (bgi->bgi_mode == GPIO_INTR_LEVEL_LOW ||
+ bgi->bgi_mode == GPIO_INTR_LEVEL_HIGH);
}
static inline void
bcm_gpio_isrc_mask(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
{
+ uint32_t bank;
+ bank = BCM_GPIO_BANK(bgi->bgi_irq);
BCM_GPIO_LOCK(sc);
- BCM_GPIO_CLEAR_BITS(sc, bgi->bgi_reg, bgi->bgi_mask);
- BCM_GPIO_UNLOCK(bcm_gpio_sc);
+ switch (bgi->bgi_mode) {
+ case GPIO_INTR_LEVEL_LOW:
+ BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPLEN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_LEVEL_HIGH:
+ BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPHEN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_EDGE_RISING:
+ BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_EDGE_FALLING:
+ BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_EDGE_BOTH:
+ BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
+ BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
+ break;
+ }
+ BCM_GPIO_UNLOCK(sc);
}
static inline void
bcm_gpio_isrc_unmask(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi)
{
+ uint32_t bank;
+ bank = BCM_GPIO_BANK(bgi->bgi_irq);
BCM_GPIO_LOCK(sc);
- BCM_GPIO_SET_BITS(sc, bgi->bgi_reg, bgi->bgi_mask);
+ switch (bgi->bgi_mode) {
+ case GPIO_INTR_LEVEL_LOW:
+ BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPLEN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_LEVEL_HIGH:
+ BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPHEN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_EDGE_RISING:
+ BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_EDGE_FALLING:
+ BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
+ break;
+ case GPIO_INTR_EDGE_BOTH:
+ BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
+ BCM_GPIO_SET_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
+ break;
+ }
BCM_GPIO_UNLOCK(sc);
}
@@ -983,7 +1038,7 @@ bcm_gpio_pic_attach(struct bcm_gpio_softc *sc)
for (irq = 0; irq < BCM_GPIO_PINS; irq++) {
sc->sc_isrcs[irq].bgi_irq = irq;
sc->sc_isrcs[irq].bgi_mask = BCM_GPIO_MASK(irq);
- sc->sc_isrcs[irq].bgi_reg = 0;
+ sc->sc_isrcs[irq].bgi_mode = GPIO_INTR_CONFORM;
error = intr_isrc_register(&sc->sc_isrcs[irq].bgi_isrc,
sc->sc_dev, 0, "%s,%u", name, irq);
@@ -1007,6 +1062,26 @@ bcm_gpio_pic_detach(struct bcm_gpio_softc *sc)
}
static void
+bcm_gpio_pic_config_intr(struct bcm_gpio_softc *sc, struct bcm_gpio_irqsrc *bgi,
+ uint32_t mode)
+{
+ uint32_t bank;
+
+ bank = BCM_GPIO_BANK(bgi->bgi_irq);
+ BCM_GPIO_LOCK(sc);
+ bcm_gpio_modify(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask,
+ mode == GPIO_INTR_EDGE_RISING || mode == GPIO_INTR_EDGE_BOTH);
+ bcm_gpio_modify(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask,
+ mode == GPIO_INTR_EDGE_FALLING || mode == GPIO_INTR_EDGE_BOTH);
+ bcm_gpio_modify(sc, BCM_GPIO_GPHEN(bank), bgi->bgi_mask,
+ mode == GPIO_INTR_LEVEL_HIGH);
+ bcm_gpio_modify(sc, BCM_GPIO_GPLEN(bank), bgi->bgi_mask,
+ mode == GPIO_INTR_LEVEL_LOW);
+ bgi->bgi_mode = mode;
+ BCM_GPIO_UNLOCK(sc);
+}
+
+static void
bcm_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
{
struct bcm_gpio_softc *sc = device_get_softc(dev);
@@ -1026,11 +1101,11 @@ bcm_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
}
static int
-bcm_gpio_pic_map_fdt(struct bcm_gpio_softc *sc, u_int ncells, pcell_t *cells,
- u_int *irqp, uint32_t *regp)
+bcm_gpio_pic_map_fdt(struct bcm_gpio_softc *sc, struct intr_map_data_fdt *daf,
+ u_int *irqp, uint32_t *modep)
{
u_int irq;
- uint32_t reg, bank;
+ uint32_t mode, bank;
/*
* The first cell is the interrupt number.
@@ -1041,51 +1116,83 @@ bcm_gpio_pic_map_fdt(struct bcm_gpio_softc *sc, u_int ncells, pcell_t *cells,
* 4 = active high level-sensitive.
* 8 = active low level-sensitive.
*/
- if (ncells != 2)
+ if (daf->ncells != 2)
return (EINVAL);
- irq = cells[0];
+ irq = daf->cells[0];
if (irq >= BCM_GPIO_PINS || bcm_gpio_pin_is_ro(sc, irq))
return (EINVAL);
- /*
- * All interrupt types could be set for an interrupt at one moment.
- * At least, the combination of 'low-to-high' and 'high-to-low' edge
- * triggered interrupt types can make a sense. However, no combo is
- * supported now.
- */
+ /* Only reasonable modes are supported. */
bank = BCM_GPIO_BANK(irq);
- if (cells[1] == 1)
- reg = BCM_GPIO_GPREN(bank);
- else if (cells[1] == 2)
- reg = BCM_GPIO_GPFEN(bank);
- else if (cells[1] == 4)
- reg = BCM_GPIO_GPHEN(bank);
- else if (cells[1] == 8)
- reg = BCM_GPIO_GPLEN(bank);
+ if (daf->cells[1] == 1)
+ mode = GPIO_INTR_EDGE_RISING;
+ else if (daf->cells[1] == 2)
+ mode = GPIO_INTR_EDGE_FALLING;
+ else if (daf->cells[1] == 3)
+ mode = GPIO_INTR_EDGE_BOTH;
+ else if (daf->cells[1] == 4)
+ mode = GPIO_INTR_LEVEL_HIGH;
+ else if (daf->cells[1] == 8)
+ mode = GPIO_INTR_LEVEL_LOW;
else
return (EINVAL);
*irqp = irq;
- if (regp != NULL)
- *regp = reg;
+ if (modep != NULL)
+ *modep = mode;
+ return (0);
+}
+
+static int
+bcm_gpio_pic_map_gpio(struct bcm_gpio_softc *sc, struct intr_map_data_gpio *dag,
+ u_int *irqp, uint32_t *modep)
+{
+ u_int irq;
+ uint32_t mode;
+
+ irq = dag->gpio_pin_num;
+ if (irq >= BCM_GPIO_PINS || bcm_gpio_pin_is_ro(sc, irq))
+ return (EINVAL);
+
+ mode = dag->gpio_intr_mode;
+ if (mode != GPIO_INTR_LEVEL_LOW && mode != GPIO_INTR_LEVEL_HIGH &&
+ mode != GPIO_INTR_EDGE_RISING && mode != GPIO_INTR_EDGE_FALLING &&
+ mode != GPIO_INTR_EDGE_BOTH)
+ return (EINVAL);
+
+ *irqp = irq;
+ if (modep != NULL)
+ *modep = mode;
return (0);
}
static int
+bcm_gpio_pic_map(struct bcm_gpio_softc *sc, struct intr_map_data *data,
+ u_int *irqp, uint32_t *modep)
+{
+
+ switch (data->type) {
+ case INTR_MAP_DATA_FDT:
+ return (bcm_gpio_pic_map_fdt(sc,
+ (struct intr_map_data_fdt *)data, irqp, modep));
+ case INTR_MAP_DATA_GPIO:
+ return (bcm_gpio_pic_map_gpio(sc,
+ (struct intr_map_data_gpio *)data, irqp, modep));
+ default:
+ return (ENOTSUP);
+ }
+}
+
+static int
bcm_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
int error;
u_int irq;
- struct bcm_gpio_softc *sc;
-
- if (data->type != INTR_MAP_DATA_FDT)
- return (ENOTSUP);
+ struct bcm_gpio_softc *sc = device_get_softc(dev);
- sc = device_get_softc(dev);
- error = bcm_gpio_pic_map_fdt(sc, data->fdt.ncells, data->fdt.cells,
- &irq, NULL);
+ error = bcm_gpio_pic_map(sc, data, &irq, NULL);
if (error == 0)
*isrcp = &sc->sc_isrcs[irq].bgi_isrc;
return (error);
@@ -1124,19 +1231,18 @@ bcm_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
u_int irq;
- uint32_t bank, reg;
+ uint32_t mode;
struct bcm_gpio_softc *sc;
struct bcm_gpio_irqsrc *bgi;
- if (data == NULL || data->type != INTR_MAP_DATA_FDT)
+ if (data == NULL)
return (ENOTSUP);
sc = device_get_softc(dev);
bgi = (struct bcm_gpio_irqsrc *)isrc;
/* Get and check config for an interrupt. */
- if (bcm_gpio_pic_map_fdt(sc, data->fdt.ncells, data->fdt.cells, &irq,
- &reg) != 0 || bgi->bgi_irq != irq)
+ if (bcm_gpio_pic_map(sc, data, &irq, &mode) != 0 || bgi->bgi_irq != irq)
return (EINVAL);
/*
@@ -1144,17 +1250,9 @@ bcm_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
* only check that its configuration match.
*/
if (isrc->isrc_handlers != 0)
- return (bgi->bgi_reg == reg ? 0 : EINVAL);
+ return (bgi->bgi_mode == mode ? 0 : EINVAL);
- bank = BCM_GPIO_BANK(irq);
- BCM_GPIO_LOCK(sc);
- BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPREN(bank), bgi->bgi_mask);
- BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPFEN(bank), bgi->bgi_mask);
- BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPHEN(bank), bgi->bgi_mask);
- BCM_GPIO_CLEAR_BITS(sc, BCM_GPIO_GPLEN(bank), bgi->bgi_mask);
- bgi->bgi_reg = reg;
- BCM_GPIO_SET_BITS(sc, reg, bgi->bgi_mask);
- BCM_GPIO_UNLOCK(sc);
+ bcm_gpio_pic_config_intr(sc, bgi, mode);
return (0);
}
@@ -1165,12 +1263,8 @@ bcm_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
struct bcm_gpio_softc *sc = device_get_softc(dev);
struct bcm_gpio_irqsrc *bgi = (struct bcm_gpio_irqsrc *)isrc;
- if (isrc->isrc_handlers == 0) {
- BCM_GPIO_LOCK(sc);
- BCM_GPIO_CLEAR_BITS(sc, bgi->bgi_reg, bgi->bgi_mask);
- bgi->bgi_reg = 0;
- BCM_GPIO_UNLOCK(sc);
- }
+ if (isrc->isrc_handlers == 0)
+ bcm_gpio_pic_config_intr(sc, bgi, GPIO_INTR_CONFORM);
return (0);
}
diff --git a/sys/arm/broadcom/bcm2835/bcm2835_intr.c b/sys/arm/broadcom/bcm2835/bcm2835_intr.c
index 8124c96..39ad5f7 100644
--- a/sys/arm/broadcom/bcm2835/bcm2835_intr.c
+++ b/sys/arm/broadcom/bcm2835/bcm2835_intr.c
@@ -268,14 +268,17 @@ bcm_intc_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
u_int irq;
+ struct intr_map_data_fdt *daf;
struct bcm_intc_softc *sc;
if (data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
- if (data->fdt.ncells == 1)
- irq = data->fdt.cells[0];
- else if (data->fdt.ncells == 2)
- irq = data->fdt.cells[0] * 32 + data->fdt.cells[1];
+
+ daf = (struct intr_map_data_fdt *)data;
+ if (daf->ncells == 1)
+ irq = daf->cells[0];
+ else if (daf->ncells == 2)
+ irq = daf->cells[0] * 32 + daf->cells[1];
else
return (EINVAL);
diff --git a/sys/arm/broadcom/bcm2835/bcm2836.c b/sys/arm/broadcom/bcm2835/bcm2836.c
index 16c1e4b..3991609 100644
--- a/sys/arm/broadcom/bcm2835/bcm2836.c
+++ b/sys/arm/broadcom/bcm2835/bcm2836.c
@@ -461,15 +461,18 @@ static int
bcm_lintc_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
+ struct intr_map_data_fdt *daf;
struct bcm_lintc_softc *sc;
if (data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
- if (data->fdt.ncells != 1 || data->fdt.cells[0] >= BCM_LINTC_NIRQS)
+
+ daf = (struct intr_map_data_fdt *)data;
+ if (daf->ncells != 1 || daf->cells[0] >= BCM_LINTC_NIRQS)
return (EINVAL);
sc = device_get_softc(dev);
- *isrcp = &sc->bls_isrcs[data->fdt.cells[0]].bli_isrc;
+ *isrcp = &sc->bls_isrcs[daf->cells[0]].bli_isrc;
return (0);
}
diff --git a/sys/arm/cavium/cns11xx/if_ece.c b/sys/arm/cavium/cns11xx/if_ece.c
index 2ae3d22..9ed5cbd 100644
--- a/sys/arm/cavium/cns11xx/if_ece.c
+++ b/sys/arm/cavium/cns11xx/if_ece.c
@@ -1685,7 +1685,7 @@ ece_encap(struct ece_softc *sc, struct mbuf *m0)
/*
* After all descriptors are set, we set the flags to start the
- * sending proces.
+ * sending process.
*/
for (seg = 0; seg < nsegs; seg++) {
desc->cown = 0;
diff --git a/sys/arm/conf/ALLWINNER b/sys/arm/conf/ALLWINNER
index 9bb0e0a..3d0acb5 100644
--- a/sys/arm/conf/ALLWINNER
+++ b/sys/arm/conf/ALLWINNER
@@ -28,6 +28,7 @@ options INTRNG
options SOC_ALLWINNER_A20
options SOC_ALLWINNER_A31
options SOC_ALLWINNER_A31S
+options SOC_ALLWINNER_A83T
options HZ=100
options SCHED_ULE # ULE scheduler
@@ -121,6 +122,7 @@ device bpf
#device emac # 10/100 integrated EMAC controller
device dwc # 10/100/1000 integrated GMAC controller
+device awg # 10/100/1000 integrated EMAC controller
# USB ethernet support, requires miibus
device miibus
diff --git a/sys/arm/freescale/imx/imx6_ipu.c b/sys/arm/freescale/imx/imx6_ipu.c
index d1efbff..f561fa7 100644
--- a/sys/arm/freescale/imx/imx6_ipu.c
+++ b/sys/arm/freescale/imx/imx6_ipu.c
@@ -872,7 +872,7 @@ ipu_init_buffer(struct ipu_softc *sc)
stride = sc->sc_mode->hdisplay * MODE_BPP / 8;
- /* init channel paramters */
+ /* init channel parameters */
CH_PARAM_RESET(&param);
/* XXX: interlaced modes are not supported yet */
CH_PARAM_SET_FW(&param, sc->sc_mode->hdisplay - 1);
diff --git a/sys/arm/freescale/imx/imx6_ssi.c b/sys/arm/freescale/imx/imx6_ssi.c
index 9387aa3..9000ae3 100644
--- a/sys/arm/freescale/imx/imx6_ssi.c
+++ b/sys/arm/freescale/imx/imx6_ssi.c
@@ -738,7 +738,7 @@ ssi_attach(device_t dev)
sc->lock = snd_mtxcreate(device_get_nameunit(dev), "ssi softc");
if (sc->lock == NULL) {
- device_printf(dev, "Cant create mtx\n");
+ device_printf(dev, "Can't create mtx\n");
return (ENXIO);
}
@@ -764,7 +764,7 @@ ssi_attach(device_t dev)
/*
* Maximum possible DMA buffer.
- * Will be used partialy to match 24 bit word.
+ * Will be used partially to match 24 bit word.
*/
sc->dma_size = 131072;
diff --git a/sys/arm/freescale/imx/imx_gpio.c b/sys/arm/freescale/imx/imx_gpio.c
index ba82f5c..c5f7b8c 100644
--- a/sys/arm/freescale/imx/imx_gpio.c
+++ b/sys/arm/freescale/imx/imx_gpio.c
@@ -225,13 +225,15 @@ gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
{
int error;
u_int irq;
+ struct intr_map_data_fdt *daf;
struct imx51_gpio_softc *sc;
if (data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
- error = gpio_pic_map_fdt(dev, data->fdt.ncells, data->fdt.cells, &irq,
- NULL, NULL);
+ daf = (struct intr_map_data_fdt *)data;
+ error = gpio_pic_map_fdt(dev, daf->ncells, daf->cells, &irq, NULL,
+ NULL);
if (error == 0) {
sc = device_get_softc(dev);
*isrcp = &sc->gpio_pic_irqsrc[irq].gi_isrc;
@@ -265,6 +267,7 @@ static int
gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
+ struct intr_map_data_fdt *daf;
struct imx51_gpio_softc *sc;
struct gpio_irqsrc *gi;
int error, icfg;
@@ -278,8 +281,9 @@ gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
/* Get config for interrupt. */
if (data == NULL || data->type != INTR_MAP_DATA_FDT)
return (ENOTSUP);
- error = gpio_pic_map_fdt(dev, data->fdt.ncells, data->fdt.cells, &irq,
- &pol, &trig);
+ daf = (struct intr_map_data_fdt *)data;
+ error = gpio_pic_map_fdt(dev, daf->ncells, daf->cells, &irq, &pol,
+ &trig);
if (error != 0)
return (error);
if (gi->gi_irq != irq)
diff --git a/sys/arm/freescale/vybrid/vf_uart.c b/sys/arm/freescale/vybrid/vf_uart.c
index 312f18c..61a08fb 100644
--- a/sys/arm/freescale/vybrid/vf_uart.c
+++ b/sys/arm/freescale/vybrid/vf_uart.c
@@ -205,7 +205,7 @@ uart_reinit(struct uart_softc *sc, int clkspeed, int baud)
bas = &sc->sc_bas;
if (!bas) {
- printf("Error: cant reconfigure bas\n");
+ printf("Error: can't reconfigure bas\n");
return;
}
diff --git a/sys/arm/mv/mpic.c b/sys/arm/mv/mpic.c
index 4c5856a..7e07d66 100644
--- a/sys/arm/mv/mpic.c
+++ b/sys/arm/mv/mpic.c
@@ -339,15 +339,19 @@ static int
mpic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
+ struct intr_map_data_fdt *daf;
struct mv_mpic_softc *sc;
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
sc = device_get_softc(dev);
+ daf = (struct intr_map_data_fdt *)data;
- if (data->type != INTR_MAP_DATA_FDT || data->fdt.ncells !=1 ||
- data->fdt.cells[0] >= sc->nirqs)
+ if (daf->ncells !=1 || daf->cells[0] >= sc->nirqs)
return (EINVAL);
- *isrcp = &sc->mpic_isrcs[data->fdt.cells[0]].mmi_isrc;
+ *isrcp = &sc->mpic_isrcs[daf->cells[0]].mmi_isrc;
return (0);
}
@@ -564,7 +568,7 @@ mv_msi_data(int irq, uint64_t *addr, uint32_t *data)
node = ofw_bus_get_node(mv_mpic_sc->sc_dev);
- /* Get physical addres of register space */
+ /* Get physical address of register space */
error = fdt_get_range(OF_parent(node), 0, &phys, &size);
if (error) {
printf("%s: Cannot get register physical address, err:%d",
diff --git a/sys/arm/mv/mv_common.c b/sys/arm/mv/mv_common.c
index 2bd13f6..55e3cd1 100644
--- a/sys/arm/mv/mv_common.c
+++ b/sys/arm/mv/mv_common.c
@@ -1398,7 +1398,7 @@ decode_win_pcie_setup(u_long base)
/*
* Upper 16 bits in BAR register is interpreted as BAR size
- * (in 64 kB units) plus 64kB, so substract 0x10000
+ * (in 64 kB units) plus 64kB, so subtract 0x10000
* form value passed to register to get correct value.
*/
size -= 0x10000;
diff --git a/sys/arm/nvidia/tegra_gpio.c b/sys/arm/nvidia/tegra_gpio.c
index 0b2b081..7329ce0 100644
--- a/sys/arm/nvidia/tegra_gpio.c
+++ b/sys/arm/nvidia/tegra_gpio.c
@@ -579,14 +579,19 @@ tegra_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
sc = device_get_softc(dev);
- if (data->type == INTR_MAP_DATA_FDT)
- rv = tegra_gpio_pic_map_fdt(sc, data->fdt.ncells,
- data->fdt.cells, &irq, NULL);
- else if (data->type == INTR_MAP_DATA_GPIO)
- rv = tegra_gpio_pic_map_gpio(sc, data->gpio.gpio_pin_num,
- data->gpio.gpio_pin_flags, data->gpio.gpio_intr_mode,
- &irq, NULL);
- else
+ if (data->type == INTR_MAP_DATA_FDT) {
+ struct intr_map_data_fdt *daf;
+
+ daf = (struct intr_map_data_fdt *)data;
+ rv = tegra_gpio_pic_map_fdt(sc, daf->ncells, daf->cells, &irq,
+ NULL);
+ } else if (data->type == INTR_MAP_DATA_GPIO) {
+ struct intr_map_data_gpio *dag;
+
+ dag = (struct intr_map_data_gpio *)data;
+ rv = tegra_gpio_pic_map_gpio(sc, dag->gpio_pin_num,
+ dag->gpio_pin_flags, dag->gpio_intr_mode, &irq, NULL);
+ } else
return (ENOTSUP);
if (rv == 0)
@@ -648,14 +653,19 @@ tegra_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
return (ENOTSUP);
/* Get and check config for an interrupt. */
- if (data->type == INTR_MAP_DATA_FDT)
- rv = tegra_gpio_pic_map_fdt(sc, data->fdt.ncells,
- data->fdt.cells, &irq, &cfgreg);
- else if (data->type == INTR_MAP_DATA_GPIO)
- rv = tegra_gpio_pic_map_gpio(sc, data->gpio.gpio_pin_num,
- data->gpio.gpio_pin_flags, data->gpio.gpio_intr_mode,
- &irq, &cfgreg);
- else
+ if (data->type == INTR_MAP_DATA_FDT) {
+ struct intr_map_data_fdt *daf;
+
+ daf = (struct intr_map_data_fdt *)data;
+ rv = tegra_gpio_pic_map_fdt(sc, daf->ncells, daf->cells, &irq,
+ &cfgreg);
+ } else if (data->type == INTR_MAP_DATA_GPIO) {
+ struct intr_map_data_gpio *dag;
+
+ dag = (struct intr_map_data_gpio *)data;
+ rv = tegra_gpio_pic_map_gpio(sc, dag->gpio_pin_num,
+ dag->gpio_pin_flags, dag->gpio_intr_mode, &irq, &cfgreg);
+ } else
return (ENOTSUP);
if (rv != 0)
return (EINVAL);
diff --git a/sys/arm/qemu/virt_machdep.c b/sys/arm/qemu/virt_machdep.c
index 95cc225..d15b97c 100644
--- a/sys/arm/qemu/virt_machdep.c
+++ b/sys/arm/qemu/virt_machdep.c
@@ -97,3 +97,20 @@ static platform_method_t virt_methods[] = {
};
FDT_PLATFORM_DEF(virt, "virt", 0, "linux,dummy-virt", 1);
+
+static int
+gem5_devmap_init(platform_t plat)
+{
+
+ devmap_add_entry(0x1c090000, 0x100000); /* Uart */
+ return (0);
+}
+
+static platform_method_t gem5_methods[] = {
+ PLATFORMMETHOD(platform_devmap_init, gem5_devmap_init),
+ PLATFORMMETHOD(platform_lastaddr, virt_lastaddr),
+
+ PLATFORMMETHOD_END,
+};
+
+FDT_PLATFORM_DEF(gem5, "gem5", 0, "arm,vexpress", 1);
diff --git a/sys/arm/samsung/exynos/exynos5_usb_phy.c b/sys/arm/samsung/exynos/exynos5_usb_phy.c
index 2756efb..430c8f8 100644
--- a/sys/arm/samsung/exynos/exynos5_usb_phy.c
+++ b/sys/arm/samsung/exynos/exynos5_usb_phy.c
@@ -161,7 +161,7 @@ vbus_on(struct usb_phy_softc *sc)
gpio_dev = devclass_get_device(devclass_find("gpio"), 0);
if (gpio_dev == NULL) {
- device_printf(sc->dev, "cant find gpio_dev\n");
+ device_printf(sc->dev, "can't find gpio_dev\n");
return (1);
}
diff --git a/sys/arm/ti/aintc.c b/sys/arm/ti/aintc.c
index ebe4864..5fb4695 100644
--- a/sys/arm/ti/aintc.c
+++ b/sys/arm/ti/aintc.c
@@ -178,14 +178,18 @@ static int
ti_aintc_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
+ struct intr_map_data_fdt *daf;
struct ti_aintc_softc *sc;
- if (data->type != INTR_MAP_DATA_FDT || data->fdt.ncells != 1 ||
- data->fdt.cells[0] >= INTC_NIRQS)
+ if (data->type != INTR_MAP_DATA_FDT)
+ return (ENOTSUP);
+
+ daf = (struct intr_map_data_fdt *)data;
+ if (daf->ncells != 1 || daf->cells[0] >= INTC_NIRQS)
return (EINVAL);
sc = device_get_softc(dev);
- *isrcp = &sc->aintc_isrcs[data->fdt.cells[0]].tai_isrc;
+ *isrcp = &sc->aintc_isrcs[daf->cells[0]].tai_isrc;
return (0);
}
diff --git a/sys/arm/ti/omap4/omap4_prcm_clks.c b/sys/arm/ti/omap4/omap4_prcm_clks.c
index e83e6ee..e17fe3d 100644
--- a/sys/arm/ti/omap4/omap4_prcm_clks.c
+++ b/sys/arm/ti/omap4/omap4_prcm_clks.c
@@ -1329,7 +1329,7 @@ omap4_clk_hsusbhost_accessible(struct ti_clock_dev *clkdev)
* Inherits the locks from the omap_prcm driver, no internal locking.
*
* RETURNS:
- * Returns 0 if sucessful otherwise a negative error code on failure.
+ * Returns 0 if successful otherwise a negative error code on failure.
*/
static int
omap4_clk_hsusbhost_set_source(struct ti_clock_dev *clkdev,
diff --git a/sys/arm/ti/ti_gpio.c b/sys/arm/ti/ti_gpio.c
index 54e5042..a67884e 100644
--- a/sys/arm/ti/ti_gpio.c
+++ b/sys/arm/ti/ti_gpio.c
@@ -290,7 +290,7 @@ ti_gpio_valid_pin(struct ti_gpio_softc *sc, int pin)
}
/**
- * ti_gpio_pin_getcaps - Gets the capabilties of a given pin
+ * ti_gpio_pin_getcaps - Gets the capabilities of a given pin
* @dev: gpio device handle
* @pin: the number of the pin
* @caps: pointer to a value that upon return will contain the capabilities
@@ -300,6 +300,11 @@ ti_gpio_valid_pin(struct ti_gpio_softc *sc, int pin)
* - GPIO_PIN_OUTPUT
* - GPIO_PIN_PULLUP
* - GPIO_PIN_PULLDOWN
+ * - GPIO_INTR_LEVEL_LOW
+ * - GPIO_INTR_LEVEL_HIGH
+ * - GPIO_INTR_EDGE_RISING
+ * - GPIO_INTR_EDGE_FALLING
+ * - GPIO_INTR_EDGE_BOTH
*
* LOCKING:
* No locking required, returns static data.
@@ -316,8 +321,15 @@ ti_gpio_pin_getcaps(device_t dev, uint32_t pin, uint32_t *caps)
if (ti_gpio_valid_pin(sc, pin) != 0)
return (EINVAL);
+#ifdef INTRNG
+ *caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP |
+ GPIO_PIN_PULLDOWN | GPIO_INTR_LEVEL_LOW | GPIO_INTR_LEVEL_HIGH |
+ GPIO_INTR_EDGE_RISING | GPIO_INTR_EDGE_FALLING |
+ GPIO_INTR_EDGE_BOTH);
+#else
*caps = (GPIO_PIN_INPUT | GPIO_PIN_OUTPUT | GPIO_PIN_PULLUP |
GPIO_PIN_PULLDOWN);
+#endif
return (0);
}
@@ -800,17 +812,13 @@ ti_gpio_detach(device_t dev)
#ifdef INTRNG
static inline void
-ti_gpio_rwreg_set(struct ti_gpio_softc *sc, uint32_t reg, uint32_t mask)
-{
-
- ti_gpio_write_4(sc, reg, ti_gpio_read_4(sc, reg) | mask);
-}
-
-static inline void
-ti_gpio_rwreg_clr(struct ti_gpio_softc *sc, uint32_t reg, uint32_t mask)
+ti_gpio_rwreg_modify(struct ti_gpio_softc *sc, uint32_t reg, uint32_t mask,
+ bool set_bits)
{
+ uint32_t value;
- ti_gpio_write_4(sc, reg, ti_gpio_read_4(sc, reg) & ~mask);
+ value = ti_gpio_read_4(sc, reg);
+ ti_gpio_write_4(sc, reg, set_bits ? value | mask : value & ~mask);
}
static inline void
@@ -841,8 +849,8 @@ static inline bool
ti_gpio_isrc_is_level(struct ti_gpio_irqsrc *tgi)
{
- return (tgi->tgi_cfgreg == TI_GPIO_LEVELDETECT0 ||
- tgi->tgi_cfgreg == TI_GPIO_LEVELDETECT1);
+ return (tgi->tgi_mode == GPIO_INTR_LEVEL_LOW ||
+ tgi->tgi_mode == GPIO_INTR_LEVEL_HIGH);
}
static int
@@ -889,7 +897,7 @@ ti_gpio_pic_attach(struct ti_gpio_softc *sc)
for (irq = 0; irq < sc->sc_maxpin; irq++) {
sc->sc_isrcs[irq].tgi_irq = irq;
sc->sc_isrcs[irq].tgi_mask = TI_GPIO_MASK(irq);
- sc->sc_isrcs[irq].tgi_cfgreg = 0;
+ sc->sc_isrcs[irq].tgi_mode = GPIO_INTR_CONFORM;
error = intr_isrc_register(&sc->sc_isrcs[irq].tgi_isrc,
sc->sc_dev, 0, "%s,%u", name, irq);
@@ -913,6 +921,24 @@ ti_gpio_pic_detach(struct ti_gpio_softc *sc)
}
static void
+ti_gpio_pic_config_intr(struct ti_gpio_softc *sc, struct ti_gpio_irqsrc *tgi,
+ uint32_t mode)
+{
+
+ TI_GPIO_LOCK(sc);
+ ti_gpio_rwreg_modify(sc, TI_GPIO_RISINGDETECT, tgi->tgi_mask,
+ mode == GPIO_INTR_EDGE_RISING || mode == GPIO_INTR_EDGE_BOTH);
+ ti_gpio_rwreg_modify(sc, TI_GPIO_FALLINGDETECT, tgi->tgi_mask,
+ mode == GPIO_INTR_EDGE_FALLING || mode == GPIO_INTR_EDGE_BOTH);
+ ti_gpio_rwreg_modify(sc, TI_GPIO_LEVELDETECT1, tgi->tgi_mask,
+ mode == GPIO_INTR_LEVEL_HIGH);
+ ti_gpio_rwreg_modify(sc, TI_GPIO_LEVELDETECT0, tgi->tgi_mask,
+ mode == GPIO_INTR_LEVEL_LOW);
+ tgi->tgi_mode = mode;
+ TI_GPIO_UNLOCK(sc);
+}
+
+static void
ti_gpio_pic_disable_intr(device_t dev, struct intr_irqsrc *isrc)
{
struct ti_gpio_softc *sc = device_get_softc(dev);
@@ -932,10 +958,10 @@ ti_gpio_pic_enable_intr(device_t dev, struct intr_irqsrc *isrc)
}
static int
-ti_gpio_pic_map_fdt(struct ti_gpio_softc *sc, u_int ncells, pcell_t *cells,
- u_int *irqp, uint32_t *regp)
+ti_gpio_pic_map_fdt(struct ti_gpio_softc *sc, struct intr_map_data_fdt *daf,
+ u_int *irqp, uint32_t *modep)
{
- uint32_t reg;
+ uint32_t mode;
/*
* The first cell is the interrupt number.
@@ -946,46 +972,76 @@ ti_gpio_pic_map_fdt(struct ti_gpio_softc *sc, u_int ncells, pcell_t *cells,
* 4 = active high level-sensitive.
* 8 = active low level-sensitive.
*/
- if (ncells != 2 || cells[0] >= sc->sc_maxpin)
+ if (daf->ncells != 2 || daf->cells[0] >= sc->sc_maxpin)
return (EINVAL);
- /*
- * All interrupt types could be set for an interrupt at one moment.
- * At least, the combination of 'low-to-high' and 'high-to-low' edge
- * triggered interrupt types can make a sense. However, no combo is
- * supported now.
- */
- if (cells[1] == 1)
- reg = TI_GPIO_RISINGDETECT;
- else if (cells[1] == 2)
- reg = TI_GPIO_FALLINGDETECT;
- else if (cells[1] == 4)
- reg = TI_GPIO_LEVELDETECT1;
- else if (cells[1] == 8)
- reg = TI_GPIO_LEVELDETECT0;
+ /* Only reasonable modes are supported. */
+ if (daf->cells[1] == 1)
+ mode = GPIO_INTR_EDGE_RISING;
+ else if (daf->cells[1] == 2)
+ mode = GPIO_INTR_EDGE_FALLING;
+ else if (daf->cells[1] == 3)
+ mode = GPIO_INTR_EDGE_BOTH;
+ else if (daf->cells[1] == 4)
+ mode = GPIO_INTR_LEVEL_HIGH;
+ else if (daf->cells[1] == 8)
+ mode = GPIO_INTR_LEVEL_LOW;
else
return (EINVAL);
- *irqp = cells[0];
- if (regp != NULL)
- *regp = reg;
+ *irqp = daf->cells[0];
+ if (modep != NULL)
+ *modep = mode;
return (0);
}
static int
+ti_gpio_pic_map_gpio(struct ti_gpio_softc *sc, struct intr_map_data_gpio *dag,
+ u_int *irqp, uint32_t *modep)
+{
+ uint32_t mode;
+
+ if (dag->gpio_pin_num >= sc->sc_maxpin)
+ return (EINVAL);
+
+ mode = dag->gpio_intr_mode;
+ if (mode != GPIO_INTR_LEVEL_LOW && mode != GPIO_INTR_LEVEL_HIGH &&
+ mode != GPIO_INTR_EDGE_RISING && mode != GPIO_INTR_EDGE_FALLING &&
+ mode != GPIO_INTR_EDGE_BOTH)
+ return (EINVAL);
+
+ *irqp = dag->gpio_pin_num;
+ if (modep != NULL)
+ *modep = mode;
+ return (0);
+}
+
+static int
+ti_gpio_pic_map(struct ti_gpio_softc *sc, struct intr_map_data *data,
+ u_int *irqp, uint32_t *modep)
+{
+
+ switch (data->type) {
+ case INTR_MAP_DATA_FDT:
+ return (ti_gpio_pic_map_fdt(sc,
+ (struct intr_map_data_fdt *)data, irqp, modep));
+ case INTR_MAP_DATA_GPIO:
+ return (ti_gpio_pic_map_gpio(sc,
+ (struct intr_map_data_gpio *)data, irqp, modep));
+ default:
+ return (ENOTSUP);
+ }
+}
+
+static int
ti_gpio_pic_map_intr(device_t dev, struct intr_map_data *data,
struct intr_irqsrc **isrcp)
{
int error;
u_int irq;
- struct ti_gpio_softc *sc;
-
- if (data->type != INTR_MAP_DATA_FDT)
- return (ENOTSUP);
+ struct ti_gpio_softc *sc = device_get_softc(dev);
- sc = device_get_softc(dev);
- error = ti_gpio_pic_map_fdt(sc, data->fdt.ncells, data->fdt.cells, &irq,
- NULL);
+ error = ti_gpio_pic_map(sc, data, &irq, NULL);
if (error == 0)
*isrcp = &sc->sc_isrcs[irq].tgi_isrc;
return (error);
@@ -1024,19 +1080,18 @@ ti_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
struct resource *res, struct intr_map_data *data)
{
u_int irq;
- uint32_t cfgreg;
+ uint32_t mode;
struct ti_gpio_softc *sc;
struct ti_gpio_irqsrc *tgi;
- if (data == NULL || data->type != INTR_MAP_DATA_FDT)
+ if (data == NULL)
return (ENOTSUP);
sc = device_get_softc(dev);
tgi = (struct ti_gpio_irqsrc *)isrc;
/* Get and check config for an interrupt. */
- if (ti_gpio_pic_map_fdt(sc, data->fdt.ncells, data->fdt.cells, &irq,
- &cfgreg) != 0 || tgi->tgi_irq != irq)
+ if (ti_gpio_pic_map(sc, data, &irq, &mode) != 0 || tgi->tgi_irq != irq)
return (EINVAL);
/*
@@ -1044,16 +1099,9 @@ ti_gpio_pic_setup_intr(device_t dev, struct intr_irqsrc *isrc,
* only check that its configuration match.
*/
if (isrc->isrc_handlers != 0)
- return (tgi->tgi_cfgreg == cfgreg ? 0 : EINVAL);
+ return (tgi->tgi_mode == mode ? 0 : EINVAL);
- TI_GPIO_LOCK(sc);
- ti_gpio_rwreg_clr(sc, TI_GPIO_RISINGDETECT, tgi->tgi_mask);
- ti_gpio_rwreg_clr(sc, TI_GPIO_FALLINGDETECT, tgi->tgi_mask);
- ti_gpio_rwreg_clr(sc, TI_GPIO_LEVELDETECT1, tgi->tgi_mask);
- ti_gpio_rwreg_clr(sc, TI_GPIO_LEVELDETECT0, tgi->tgi_mask);
- tgi->tgi_cfgreg = cfgreg;
- ti_gpio_rwreg_set(sc, cfgreg, tgi->tgi_mask);
- TI_GPIO_UNLOCK(sc);
+ ti_gpio_pic_config_intr(sc, tgi, mode);
return (0);
}
@@ -1064,12 +1112,8 @@ ti_gpio_pic_teardown_intr(device_t dev, struct intr_irqsrc *isrc,
struct ti_gpio_softc *sc = device_get_softc(dev);
struct ti_gpio_irqsrc *tgi = (struct ti_gpio_irqsrc *)isrc;
- if (isrc->isrc_handlers == 0) {
- TI_GPIO_LOCK(sc);
- ti_gpio_rwreg_clr(sc, tgi->tgi_cfgreg, tgi->tgi_mask);
- tgi->tgi_cfgreg = 0;
- TI_GPIO_UNLOCK(sc);
- }
+ if (isrc->isrc_handlers == 0)
+ ti_gpio_pic_config_intr(sc, tgi, GPIO_INTR_CONFORM);
return (0);
}
diff --git a/sys/arm/ti/ti_gpio.h b/sys/arm/ti/ti_gpio.h
index 174dd62..c9785dd 100644
--- a/sys/arm/ti/ti_gpio.h
+++ b/sys/arm/ti/ti_gpio.h
@@ -49,7 +49,7 @@ struct ti_gpio_irqsrc {
struct intr_irqsrc tgi_isrc;
u_int tgi_irq;
uint32_t tgi_mask;
- uint32_t tgi_cfgreg;
+ uint32_t tgi_mode;
};
#endif
diff --git a/sys/arm/ti/ti_i2c.c b/sys/arm/ti/ti_i2c.c
index 92a44a7..55336ff 100644
--- a/sys/arm/ti/ti_i2c.c
+++ b/sys/arm/ti/ti_i2c.c
@@ -236,7 +236,7 @@ ti_i2c_transfer_intr(struct ti_i2c_softc* sc, uint16_t status)
if (status & I2C_STAT_RDR) {
/*
* Receive draining interrupt - last data received.
- * The set FIFO threshold wont be reached to trigger
+ * The set FIFO threshold won't be reached to trigger
* RRDY.
*/
ti_i2c_dbg(sc, "Receive draining interrupt\n");
@@ -272,7 +272,7 @@ ti_i2c_transfer_intr(struct ti_i2c_softc* sc, uint16_t status)
/*
* Transmit draining interrupt - FIFO level is below
* the set threshold and the amount of data still to
- * be transferred wont reach the set FIFO threshold.
+ * be transferred won't reach the set FIFO threshold.
*/
ti_i2c_dbg(sc, "Transmit draining interrupt\n");
diff --git a/sys/arm/ti/ti_pinmux.c b/sys/arm/ti/ti_pinmux.c
index ff4743d..ffeaf75 100644
--- a/sys/arm/ti/ti_pinmux.c
+++ b/sys/arm/ti/ti_pinmux.c
@@ -394,7 +394,7 @@ ti_pinmux_probe(device_t dev)
* @dev: new device
*
* RETURNS
- * Zero on sucess or ENXIO if an error occuried.
+ * Zero on success or ENXIO if an error occuried.
*/
static int
ti_pinmux_attach(device_t dev)
diff --git a/sys/arm/ti/ti_prcm.c b/sys/arm/ti/ti_prcm.c
index c5ab9c7..d742d07 100644
--- a/sys/arm/ti/ti_prcm.c
+++ b/sys/arm/ti/ti_prcm.c
@@ -31,7 +31,7 @@
*/
/**
- * Power, Reset and Clock Managment Module
+ * Power, Reset and Clock Management Module
*
* This is a very simple driver wrapper around the PRCM set of registers in
* the OMAP3 chip. It allows you to turn on and off things like the functional
diff --git a/sys/arm/ti/ti_scm.c b/sys/arm/ti/ti_scm.c
index 14e9200..5608265 100644
--- a/sys/arm/ti/ti_scm.c
+++ b/sys/arm/ti/ti_scm.c
@@ -111,7 +111,7 @@ ti_scm_probe(device_t dev)
* globally and registers both the timecount and eventtimer objects.
*
* RETURNS
- * Zero on sucess or ENXIO if an error occuried.
+ * Zero on success or ENXIO if an error occuried.
*/
static int
ti_scm_attach(device_t dev)
diff --git a/sys/arm/ti/ti_sdma.c b/sys/arm/ti/ti_sdma.c
index a8faba8..7e5e957 100644
--- a/sys/arm/ti/ti_sdma.c
+++ b/sys/arm/ti/ti_sdma.c
@@ -446,7 +446,7 @@ ti_sdma_deactivate_channel(unsigned int ch)
* ti_sdma_disable_channel_irq - disables IRQ's on the given channel
* @ch: the channel to disable IRQ's on
*
- * Disable interupt generation for the given channel.
+ * Disable interrupt generation for the given channel.
*
* LOCKING:
* DMA registers protected by internal mutex
@@ -608,7 +608,7 @@ ti_sdma_get_channel_status(unsigned int ch, uint32_t *status)
/**
* ti_sdma_start_xfer - starts a DMA transfer
- * @ch: the channel number to set the endianess of
+ * @ch: the channel number to set the endianness of
* @src_paddr: the source phsyical address
* @dst_paddr: the destination phsyical address
* @frmcnt: the number of frames per block
@@ -707,7 +707,7 @@ ti_sdma_start_xfer(unsigned int ch, unsigned int src_paddr,
* frmcnt = 1, elmcnt = 512, pktsize = 128
*
* Total transfer bytes = 1 * 512 = 512 elements or 2048 bytes
- * Packets transfered = 128 / 512 = 4
+ * Packets transferred = 128 / 512 = 4
*
*
* LOCKING:
@@ -787,7 +787,7 @@ ti_sdma_start_xfer_packet(unsigned int ch, unsigned int src_paddr,
/**
* ti_sdma_stop_xfer - stops any currently active transfers
- * @ch: the channel number to set the endianess of
+ * @ch: the channel number to set the endianness of
*
* This function call is effectively a NOP if no transaction is in progress.
*
@@ -835,10 +835,10 @@ ti_sdma_stop_xfer(unsigned int ch)
}
/**
- * ti_sdma_set_xfer_endianess - sets the endianess of subsequent transfers
- * @ch: the channel number to set the endianess of
- * @src: the source endianess (either DMA_ENDIAN_LITTLE or DMA_ENDIAN_BIG)
- * @dst: the destination endianess (either DMA_ENDIAN_LITTLE or DMA_ENDIAN_BIG)
+ * ti_sdma_set_xfer_endianess - sets the endianness of subsequent transfers
+ * @ch: the channel number to set the endianness of
+ * @src: the source endianness (either DMA_ENDIAN_LITTLE or DMA_ENDIAN_BIG)
+ * @dst: the destination endianness (either DMA_ENDIAN_LITTLE or DMA_ENDIAN_BIG)
*
*
* LOCKING:
@@ -879,9 +879,9 @@ ti_sdma_set_xfer_endianess(unsigned int ch, unsigned int src, unsigned int dst)
/**
* ti_sdma_set_xfer_burst - sets the source and destination element size
* @ch: the channel number to set the burst settings of
- * @src: the source endianess (either DMA_BURST_NONE, DMA_BURST_16, DMA_BURST_32
+ * @src: the source endianness (either DMA_BURST_NONE, DMA_BURST_16, DMA_BURST_32
* or DMA_BURST_64)
- * @dst: the destination endianess (either DMA_BURST_NONE, DMA_BURST_16,
+ * @dst: the destination endianness (either DMA_BURST_NONE, DMA_BURST_16,
* DMA_BURST_32 or DMA_BURST_64)
*
* This function sets the size of the elements for all subsequent transfers.
@@ -923,7 +923,7 @@ ti_sdma_set_xfer_burst(unsigned int ch, unsigned int src, unsigned int dst)
/**
* ti_sdma_set_xfer_data_type - driver attach function
- * @ch: the channel number to set the endianess of
+ * @ch: the channel number to set the endianness of
* @type: the xfer data type (either DMA_DATA_8BITS_SCALAR, DMA_DATA_16BITS_SCALAR
* or DMA_DATA_32BITS_SCALAR)
*
@@ -1065,7 +1065,7 @@ ti_sdma_sync_params(unsigned int ch, unsigned int trigger, unsigned int mode)
/**
* ti_sdma_set_addr_mode - driver attach function
- * @ch: the channel number to set the endianess of
+ * @ch: the channel number to set the endianness of
* @rd_mode: the xfer source addressing mode (either DMA_ADDR_CONSTANT,
* DMA_ADDR_POST_INCREMENT, DMA_ADDR_SINGLE_INDEX or
* DMA_ADDR_DOUBLE_INDEX)
diff --git a/sys/arm/xilinx/zy7_slcr.c b/sys/arm/xilinx/zy7_slcr.c
index e243ff6..c99d5b0 100644
--- a/sys/arm/xilinx/zy7_slcr.c
+++ b/sys/arm/xilinx/zy7_slcr.c
@@ -177,7 +177,7 @@ zy7_slcr_preload_pl(void)
/* After PL configuration, enable level shifters and deassert top-level
* PL resets. Called from zy7_devcfg.c. Optionally, the level shifters
* can be left disabled but that's rare of an FPGA application. That option
- * is controled by a sysctl in the devcfg driver.
+ * is controlled by a sysctl in the devcfg driver.
*/
void
zy7_slcr_postload_pl(int en_level_shifters)
diff --git a/sys/arm/xscale/i8134x/crb_machdep.c b/sys/arm/xscale/i8134x/crb_machdep.c
index 5268ca9..898bbaa 100644
--- a/sys/arm/xscale/i8134x/crb_machdep.c
+++ b/sys/arm/xscale/i8134x/crb_machdep.c
@@ -38,7 +38,7 @@
*
* machdep.c
*
- * Machine dependant functions for kernel setup
+ * Machine dependent functions for kernel setup
*
* This file needs a lot of work.
*
diff --git a/sys/arm/xscale/i8134x/i81342reg.h b/sys/arm/xscale/i8134x/i81342reg.h
index fd087ce..2402194 100644
--- a/sys/arm/xscale/i8134x/i81342reg.h
+++ b/sys/arm/xscale/i8134x/i81342reg.h
@@ -184,7 +184,7 @@
#define ATU_IATVR2 0x005c /* Inbound ATU Translate Value Register 2 */
#define ATU_IAUTVR2 0x0060 /* Inbound ATU Upper Translate Value Register 2*/
#define ATU_ERLR 0x0064 /* Expansion ROM Limit Register */
-#define ATU_ERTVR 0x0068 /* Expansion ROM Translater Value Register */
+#define ATU_ERTVR 0x0068 /* Expansion ROM Translator Value Register */
#define ATU_ERUTVR 0x006c /* Expansion ROM Upper Translate Value Register*/
#define ATU_CR 0x0070 /* ATU Configuration Register */
#define ATU_CR_OUT_EN (1 << 1)
diff --git a/sys/arm/xscale/ixp425/avila_machdep.c b/sys/arm/xscale/ixp425/avila_machdep.c
index 46e4b10..f26d3ca 100644
--- a/sys/arm/xscale/ixp425/avila_machdep.c
+++ b/sys/arm/xscale/ixp425/avila_machdep.c
@@ -38,7 +38,7 @@
*
* machdep.c
*
- * Machine dependant functions for kernel setup
+ * Machine dependent functions for kernel setup
*
* This file needs a lot of work.
*
diff --git a/sys/arm/xscale/ixp425/cambria_gpio.c b/sys/arm/xscale/ixp425/cambria_gpio.c
index aa3947b..c871418 100644
--- a/sys/arm/xscale/ixp425/cambria_gpio.c
+++ b/sys/arm/xscale/ixp425/cambria_gpio.c
@@ -32,7 +32,7 @@
* The Cambria PLD does not set the i2c ack bit after each write, if we used the
* regular iicbus interface it would abort the xfer after the address byte
* times out and not write our latch. To get around this we grab the iicbus and
- * then do our own bit banging. This is a comprimise to changing all the iicbb
+ * then do our own bit banging. This is a compromise to changing all the iicbb
* device methods to allow a flag to be passed down and is similir to how Linux
* does it.
*
diff --git a/sys/arm/xscale/ixp425/ixp425_npe.c b/sys/arm/xscale/ixp425/ixp425_npe.c
index 6dbce4c..95facb4 100644
--- a/sys/arm/xscale/ixp425/ixp425_npe.c
+++ b/sys/arm/xscale/ixp425/ixp425_npe.c
@@ -507,7 +507,7 @@ ixpnpe_load_firmware(struct ixpnpe_softc *sc, const char *imageName,
/*
* If download was successful, store image Id in list of
- * currently loaded images. If a critical error occured
+ * currently loaded images. If a critical error occurred
* during download, record that the NPE has an invalid image
*/
mtx_lock(&sc->sc_mtx);
@@ -864,7 +864,7 @@ npe_cpu_reset(struct ixpnpe_softc *sc)
while (npe_checkbits(sc,
IX_NPEDL_REG_OFFSET_STAT, IX_NPEDL_MASK_STAT_IFNE)) {
/*
- * Step execution of the NPE intruction to read inFIFO using
+ * Step execution of the NPE instruction to read inFIFO using
* the Debug Executing Context stack.
*/
error = npe_cpu_step(sc, IX_NPEDL_INSTR_RD_FIFO, 0, 0);
@@ -1307,7 +1307,7 @@ npe_logical_reg_write(struct ixpnpe_softc *sc, uint32_t regAddr, uint32_t regVal
((regVal & IX_NPEDL_MASK_IMMED_INSTR_COPROC_DATA) <<
IX_NPEDL_DISPLACE_IMMED_INSTR_COPROC_DATA);
- /* step execution of NPE intruction using Debug ECS */
+ /* step execution of NPE instruction using Debug ECS */
error = npe_cpu_step(sc, npeInstruction,
ctxtNum, IX_NPEDL_WR_INSTR_LDUR);
}
diff --git a/sys/arm/xscale/ixp425/ixp425_npereg.h b/sys/arm/xscale/ixp425/ixp425_npereg.h
index 069e9d7..94aff85 100644
--- a/sys/arm/xscale/ixp425/ixp425_npereg.h
+++ b/sys/arm/xscale/ixp425/ixp425_npereg.h
@@ -125,7 +125,7 @@
/*
* Reset value for Mailbox (MBST) register
- * NOTE that if used, it should be complemented with an NPE intruction
+ * NOTE that if used, it should be complemented with an NPE instruction
* to clear the Mailbox at the NPE side as well
*/
#define IX_NPEDL_REG_RESET_MBST 0x0000F0F0
diff --git a/sys/arm/xscale/ixp425/ixp425_qmgr.c b/sys/arm/xscale/ixp425/ixp425_qmgr.c
index 822623c..d6db260 100644
--- a/sys/arm/xscale/ixp425/ixp425_qmgr.c
+++ b/sys/arm/xscale/ixp425/ixp425_qmgr.c
@@ -421,7 +421,7 @@ ixpqmgr_qwrite(int qId, uint32_t entry)
return ENOSPC;
}
/*
- * No overflow occured : someone is draining the queue
+ * No overflow occurred : someone is draining the queue
* and the current counter needs to be
* updated from the current number of entries in the queue
*/
diff --git a/sys/arm/xscale/pxa/pxa_machdep.c b/sys/arm/xscale/pxa/pxa_machdep.c
index 32cbcd8..bc3ab6f 100644
--- a/sys/arm/xscale/pxa/pxa_machdep.c
+++ b/sys/arm/xscale/pxa/pxa_machdep.c
@@ -38,7 +38,7 @@
*
* machdep.c
*
- * Machine dependant functions for kernel setup
+ * Machine dependent functions for kernel setup
*
* This file needs a lot of work.
*
OpenPOWER on IntegriCloud