Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/arch/arm/allwinner Flesh out allwinner support.



details:   https://anonhg.NetBSD.org/src/rev/b915601790fe
branches:  trunk
changeset: 789755:b915601790fe
user:      matt <matt%NetBSD.org@localhost>
date:      Sat Sep 07 00:35:52 2013 +0000

description:
Flesh out allwinner support.

diffstat:

 sys/arch/arm/allwinner/awin_ahcisata.c |   37 ++-
 sys/arch/arm/allwinner/awin_board.c    |   47 ++-
 sys/arch/arm/allwinner/awin_com.c      |   67 ++-
 sys/arch/arm/allwinner/awin_gpio.c     |  254 +++++++++++++-
 sys/arch/arm/allwinner/awin_intr.h     |   14 +-
 sys/arch/arm/allwinner/awin_io.c       |   12 +-
 sys/arch/arm/allwinner/awin_reg.h      |  594 +++++++++++++++++++++++++++-----
 sys/arch/arm/allwinner/awin_sdhc.c     |   41 +-
 sys/arch/arm/allwinner/awin_twi.c      |   77 +++-
 sys/arch/arm/allwinner/awin_usb.c      |   80 ++--
 sys/arch/arm/allwinner/awin_var.h      |   15 +-
 sys/arch/arm/allwinner/files.awin      |    6 +-
 12 files changed, 1032 insertions(+), 212 deletions(-)

diffs (truncated from 1897 to 300 lines):

diff -r e82e626ef120 -r b915601790fe sys/arch/arm/allwinner/awin_ahcisata.c
--- a/sys/arch/arm/allwinner/awin_ahcisata.c    Sat Sep 07 00:33:32 2013 +0000
+++ b/sys/arch/arm/allwinner/awin_ahcisata.c    Sat Sep 07 00:35:52 2013 +0000
@@ -31,8 +31,9 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: awin_ahcisata.c,v 1.2 2013/09/04 09:09:25 jmcneill Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_ahcisata.c,v 1.3 2013/09/07 00:35:52 matt Exp $");
 
+#include <sys/param.h>
 #include <sys/bus.h>
 #include <sys/device.h>
 #include <sys/intr.h>
@@ -71,6 +72,38 @@
        return 1;
 }
 
+static void inline
+awin_ahci_set_clear(bus_space_tag_t bst, bus_space_handle_t bsh,
+    bus_size_t o, uint32_t set_mask, uint32_t clr_mask)
+{
+       const uint32_t old = bus_space_read_4(bst, bsh, o);
+       const uint32_t new = set_mask | (old & ~clr_mask);
+       if (old != new) {
+               bus_space_write_4(bst, bsh, o, new);
+       }
+}
+
+static void
+awin_ahci_enable(bus_space_tag_t bst, bus_space_handle_t bsh)
+{
+       /*
+        * SATA needs PLL6 to be a 100MHz clock.
+        */
+       awin_pll6_enable();
+
+       /*
+        * Make sure it's enabled for the AHB.
+        */
+       awin_ahci_set_clear(bst, bsh, AWIN_AHB_GATING0_REG,
+           AWIN_AHB_GATING0_SATA, 0);
+       delay(10000);
+
+       /*
+        * Now turn it on.
+        */
+       bus_space_write_4(bst, bsh, AWIN_SATA_CLK_REG, AWIN_CLK_ENABLE);
+}
+
 static void
 awin_ahci_attach(device_t parent, device_t self, void *aux)
 {
@@ -79,6 +112,8 @@
        struct awinio_attach_args * const aio = aux;
        const struct awin_locators * const loc = &aio->aio_loc;
 
+       awin_ahci_enable(aio->aio_core_bst, aio->aio_ccm_bsh);
+
         sc->sc_atac.atac_dev = self;
        sc->sc_dmat = aio->aio_dmat;
        sc->sc_ahcit = aio->aio_core_bst;
diff -r e82e626ef120 -r b915601790fe sys/arch/arm/allwinner/awin_board.c
--- a/sys/arch/arm/allwinner/awin_board.c       Sat Sep 07 00:33:32 2013 +0000
+++ b/sys/arch/arm/allwinner/awin_board.c       Sat Sep 07 00:35:52 2013 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: awin_board.c,v 1.2 2013/09/04 17:45:40 matt Exp $      */
+/*     $NetBSD: awin_board.c,v 1.3 2013/09/07 00:35:52 matt Exp $      */
 /*-
  * Copyright (c) 2012 The NetBSD Foundation, Inc.
  * All rights reserved.
@@ -34,7 +34,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: awin_board.c,v 1.2 2013/09/04 17:45:40 matt Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_board.c,v 1.3 2013/09/07 00:35:52 matt Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -64,7 +64,7 @@
 #include <dev/ic/comreg.h>
 #include <dev/cons.h>
 
-static volatile uin32t_t *uart_base;
+static volatile uint32_t *uart_base;
 
 static int
 awin_cngetc(dev_t dv)
@@ -95,7 +95,7 @@
        .cn_getc = awin_cngetc,
        .cn_pollc = nullcnpollc,
 };
-#endif /* BCM53XX_CONSOLE_EARLY */
+#endif /* AWIN_CONSOLE_EARLY */
 
 static void
 awin_cpu_clk(void)
@@ -104,7 +104,7 @@
        const uint32_t cpu0_cfg = bus_space_read_4(&awin_bs_tag, awin_core_bsh,
            AWIN_CCM_OFFSET + AWIN_CPU_AHB_APB0_CFG_REG);
        const u_int cpu_clk_sel = __SHIFTIN(cpu0_cfg, AWIN_CPU_CLK_SRC_SEL);
-       switch (cpu_clk_sel) {
+       switch (__SHIFTOUT(cpu_clk_sel, AWIN_CPU_CLK_SRC_SEL)) {
        case AWIN_CPU_CLK_SRC_SEL_LOSC:
                ci->ci_data.cpu_cc_freq = 32768;
                break;
@@ -119,7 +119,7 @@
                u_int k = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_K) + 1;
                u_int m = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_M) + 1;
                ci->ci_data.cpu_cc_freq =
-                   (AWIN_REF_FREQ * (n ? n : 1) * k / m) >> p;
+                   ((uint64_t)AWIN_REF_FREQ * (n ? n : 1) * k / m) >> p;
                break;
        }
        case AWIN_CPU_CLK_SRC_SEL_200MHZ:
@@ -136,16 +136,23 @@
 #ifdef AWIN_CONSOLE_EARLY
        uart_base = (volatile uint32_t *)uartbase;
        cn_tab = &awin_earlycons;
+       printf("Early console started\n");
 #endif
 
        error = bus_space_map(&awin_bs_tag, AWIN_CORE_PBASE,
            AWIN_CORE_SIZE, 0, &awin_core_bsh);
        if (error)
-               panic("%s: failed to map BCM53xx %s registers: %d",
+               panic("%s: failed to map a[12]0 %s registers: %d",
                    __func__, "io", error);
        KASSERT(awin_core_bsh == iobase);
 
+       printf("CPU Speed is");
        awin_cpu_clk();
+       printf(" %"PRIu64"\n", curcpu()->ci_data.cpu_cc_freq);
+
+       printf("Determining GPIO configuration");
+       awin_gpio_init();
+       printf("\n");
 }
 
 #ifdef MULTIPROCESSOR
@@ -170,3 +177,29 @@
 #endif
        return memsize;
 }
+
+void
+awin_pll6_enable(void)
+{
+       bus_space_tag_t bst = &awin_bs_tag;
+       bus_space_handle_t bsh = awin_core_bsh;
+
+       /*
+        * SATA needs PLL6 to be a 100MHz clock.
+        */
+       const uint32_t ocfg = bus_space_read_4(bst, bsh, AWIN_PLL6_CFG_REG);
+       const u_int k = __SHIFTOUT(ocfg, AWIN_PLL_CFG_FACTOR_K);
+
+       /*
+        * Output freq is 24MHz * n * k / m / 6.
+        * To get to 100MHz, k & m must be equal and n must be 25.
+        */
+       uint32_t ncfg = ocfg;
+       ncfg &= ~(AWIN_PLL_CFG_FACTOR_M|AWIN_PLL_CFG_FACTOR_N);
+       ncfg |= __SHIFTIN(k, AWIN_PLL_CFG_FACTOR_M);
+       ncfg |= __SHIFTIN(25, AWIN_PLL_CFG_FACTOR_N);
+       ncfg |= AWIN_PLL_CFG_ENABLE | AWIN_PLL6_CFG_SATA_CLK_EN;
+       if (ncfg != ocfg) {
+               bus_space_write_4(bst, bsh, AWIN_PLL6_CFG_REG, ncfg);
+       }
+}
diff -r e82e626ef120 -r b915601790fe sys/arch/arm/allwinner/awin_com.c
--- a/sys/arch/arm/allwinner/awin_com.c Sat Sep 07 00:33:32 2013 +0000
+++ b/sys/arch/arm/allwinner/awin_com.c Sat Sep 07 00:35:52 2013 +0000
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: awin_com.c,v 1.1 2013/09/04 02:39:01 matt Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_com.c,v 1.2 2013/09/07 00:35:52 matt Exp $");
 
 #include <sys/bus.h>
 #include <sys/device.h>
@@ -53,6 +53,29 @@
        void *asc_ih;
 };
 
+static const struct awin_gpio_pinset awin_com_pinsets[] = {
+       { 'B', AWIN_PIO_PB_UART0_FUNC, AWIN_PIO_PB_UART0_PINS },
+       { 'A', AWIN_PIO_PA_UART1_FUNC, AWIN_PIO_PA_UART1_PINS },
+       { 'I', AWIN_PIO_PI_UART2_FUNC, AWIN_PIO_PI_UART2_PINS },
+       { 'H', AWIN_PIO_PH_UART3_FUNC, AWIN_PIO_PH_UART3_PINS },
+       { 'H', AWIN_PIO_PH_UART4_FUNC, AWIN_PIO_PH_UART4_PINS },
+       { 'H', AWIN_PIO_PH_UART5_FUNC, AWIN_PIO_PH_UART5_PINS },
+       { 'I', AWIN_PIO_PI_UART6_FUNC, AWIN_PIO_PI_UART6_PINS },
+       { 'I', AWIN_PIO_PI_UART7_FUNC, AWIN_PIO_PI_UART7_PINS },
+};
+
+/* alternative pinnings */
+static const struct awin_gpio_pinset awin_com_alt_pinsets[] = {
+       { 'F', AWIN_PIO_PF_UART0_FUNC, AWIN_PIO_PF_UART0_PINS },
+       { 0, 0, 0},
+       { 'A', AWIN_PIO_PA_UART2_FUNC, AWIN_PIO_PA_UART2_PINS },
+       { 'G', AWIN_PIO_PG_UART3_FUNC, AWIN_PIO_PG_UART3_PINS },
+       { 'G', AWIN_PIO_PG_UART4_FUNC, AWIN_PIO_PG_UART4_PINS },
+       { 'I', AWIN_PIO_PI_UART5_FUNC, AWIN_PIO_PI_UART5_PINS },
+       { 'A', AWIN_PIO_PA_UART6_FUNC, AWIN_PIO_PA_UART6_PINS },
+       { 'A', AWIN_PIO_PA_UART7_FUNC, AWIN_PIO_PA_UART7_PINS },
+};
+
 CFATTACH_DECL_NEW(awin_com, sizeof(struct awin_com_softc),
        awin_com_match, awin_com_attach, NULL, NULL);
 
@@ -63,42 +86,54 @@
 {
        struct awinio_attach_args * const aio = aux;
        const struct awin_locators * const loc = &aio->aio_loc;
-       const int port = cf->cf_loc[AWINIOCF_PORT];
        bus_space_tag_t iot = aio->aio_core_a4x_bst;
-        bus_space_handle_t bsh;
+       bus_space_handle_t bsh;
+       const struct awin_gpio_pinset * const pinset = loc->loc_port +
+           ((cf->cf_flags & 1) ? awin_com_alt_pinsets : awin_com_pinsets);
 
-       if (strcmp(cf->cf_name, loc->loc_name))
-               return 0;
-
-        KASSERT(loc->loc_offset >= AWIN_UART0_OFFSET);
+       KASSERT(!strcmp(cf->cf_name, loc->loc_name));
+       KASSERT(loc->loc_offset >= AWIN_UART0_OFFSET);
        KASSERT(loc->loc_offset <= AWIN_UART7_OFFSET);
        KASSERT((loc->loc_offset & 0x3ff) == 0);
-        KASSERT((awin_com_ports & __BIT(loc->loc_port)) == 0);
+       KASSERT((awin_com_ports & __BIT(loc->loc_port)) == 0);
+       KASSERT(cf->cf_loc[AWINIOCF_PORT] == AWINIOCF_PORT_DEFAULT
+           || cf->cf_loc[AWINIOCF_PORT] == loc->loc_port);
 
-        if (port != AWINIOCF_PORT_DEFAULT && port != loc->loc_port)
-                return 0;
+       if (!awin_gpio_pinset_available(pinset))
+               return 0;
+
+       if (com_is_console(iot, AWIN_CORE_PBASE + loc->loc_offset, NULL))
+               return 1;
 
-        if (com_is_console(iot, AWIN_CORE_PBASE + loc->loc_offset, NULL))
-                return 1;
+       awin_gpio_pinset_acquire(pinset);
+
+       bus_space_subregion(iot, aio->aio_core_bsh,
+           loc->loc_offset, loc->loc_size, &bsh);
 
-        bus_space_subregion(iot, aio->aio_core_bsh,
-            loc->loc_offset, loc->loc_size, &bsh);
+       const int rv = comprobe1(iot, bsh);
 
-        return comprobe1(iot, bsh);
+       awin_gpio_pinset_release(pinset);
+
+       return rv;
 }
 
 static void
 awin_com_attach(device_t parent, device_t self, void *aux)
 {
+       cfdata_t cf = device_cfdata(self);
        struct awin_com_softc * const asc = device_private(self);
        struct com_softc * const sc = &asc->asc_sc;
        struct awinio_attach_args * const aio = aux;
        const struct awin_locators * const loc = &aio->aio_loc;
        bus_space_tag_t iot = aio->aio_core_a4x_bst;
        const bus_addr_t iobase = AWIN_CORE_PBASE + loc->loc_offset;
+       const struct awin_gpio_pinset * const pinset = loc->loc_port +
+           ((cf->cf_flags & 1) ? awin_com_alt_pinsets : awin_com_pinsets);
        bus_space_handle_t ioh;
 
-        awin_com_ports |= __BIT(loc->loc_port);
+       awin_com_ports |= __BIT(loc->loc_port);
+
+       awin_gpio_pinset_acquire(pinset);
 
        sc->sc_dev = self;
        sc->sc_frequency = AWIN_UART_FREQ;
diff -r e82e626ef120 -r b915601790fe sys/arch/arm/allwinner/awin_gpio.c
--- a/sys/arch/arm/allwinner/awin_gpio.c        Sat Sep 07 00:33:32 2013 +0000
+++ b/sys/arch/arm/allwinner/awin_gpio.c        Sat Sep 07 00:35:52 2013 +0000
@@ -31,23 +31,62 @@
 
 #include <sys/cdefs.h>
 
-__KERNEL_RCSID(1, "$NetBSD: awin_gpio.c,v 1.1 2013/09/04 02:39:01 matt Exp $");
+__KERNEL_RCSID(1, "$NetBSD: awin_gpio.c,v 1.2 2013/09/07 00:35:52 matt Exp $");
 
 #include <sys/bus.h>
 #include <sys/device.h>
 #include <sys/intr.h>
 #include <sys/systm.h>
 
+#include <sys/gpio.h>
+



Home | Main Index | Thread Index | Old Index