Module Name: src Committed By: jmcneill Date: Fri Oct 10 07:36:11 UTC 2014
Modified Files: src/sys/arch/arm/allwinner: awin_board.c awin_intr.h awin_io.c awin_mmc.c awin_reg.h awin_usb.c awin_wdt.c Log Message: Work-in-progress support for the AllWinner A31 SoC. To generate a diff of this commit: cvs rdiff -u -r1.20 -r1.21 src/sys/arch/arm/allwinner/awin_board.c cvs rdiff -u -r1.4 -r1.5 src/sys/arch/arm/allwinner/awin_intr.h cvs rdiff -u -r1.15 -r1.16 src/sys/arch/arm/allwinner/awin_io.c cvs rdiff -u -r1.11 -r1.12 src/sys/arch/arm/allwinner/awin_mmc.c cvs rdiff -u -r1.26 -r1.27 src/sys/arch/arm/allwinner/awin_reg.h cvs rdiff -u -r1.13 -r1.14 src/sys/arch/arm/allwinner/awin_usb.c cvs rdiff -u -r1.3 -r1.4 src/sys/arch/arm/allwinner/awin_wdt.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/arch/arm/allwinner/awin_board.c diff -u src/sys/arch/arm/allwinner/awin_board.c:1.20 src/sys/arch/arm/allwinner/awin_board.c:1.21 --- src/sys/arch/arm/allwinner/awin_board.c:1.20 Sat Oct 4 19:38:17 2014 +++ src/sys/arch/arm/allwinner/awin_board.c Fri Oct 10 07:36:11 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_board.c,v 1.20 2014/10/04 19:38:17 martin Exp $ */ +/* $NetBSD: awin_board.c,v 1.21 2014/10/10 07:36:11 jmcneill Exp $ */ /*- * Copyright (c) 2012 The NetBSD Foundation, Inc. * All rights reserved. @@ -35,7 +35,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: awin_board.c,v 1.20 2014/10/04 19:38:17 martin Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_board.c,v 1.21 2014/10/10 07:36:11 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -123,8 +123,11 @@ static void awin_cpu_clk(void) { struct cpu_info * const ci = curcpu(); + u_int reg = awin_chip_id() == AWIN_CHIP_ID_A31 ? + AWIN_A31_CPU_AXI_CFG_REG : + AWIN_CPU_AHB_APB0_CFG_REG; const uint32_t cpu0_cfg = bus_space_read_4(&awin_bs_tag, awin_core_bsh, - AWIN_CCM_OFFSET + AWIN_CPU_AHB_APB0_CFG_REG); + AWIN_CCM_OFFSET + reg); const u_int cpu_clk_sel = __SHIFTIN(cpu0_cfg, AWIN_CPU_CLK_SRC_SEL); switch (__SHIFTOUT(cpu_clk_sel, AWIN_CPU_CLK_SRC_SEL)) { case AWIN_CPU_CLK_SRC_SEL_LOSC: @@ -136,10 +139,18 @@ awin_cpu_clk(void) case AWIN_CPU_CLK_SRC_SEL_PLL1: { const uint32_t pll1_cfg = bus_space_read_4(&awin_bs_tag, awin_core_bsh, AWIN_CCM_OFFSET + AWIN_PLL1_CFG_REG); - u_int p = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_OUT_EXP_DIVP); - u_int n = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_N); - u_int k = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_K) + 1; - u_int m = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_M) + 1; + u_int p, n, k, m; + if (awin_chip_id() == AWIN_CHIP_ID_A31) { + p = 0; + n = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_N) + 1; + k = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_K) + 1; + m = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_M) + 1; + } else { + p = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_OUT_EXP_DIVP); + n = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_N); + k = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_K) + 1; + m = __SHIFTOUT(pll1_cfg, AWIN_PLL_CFG_FACTOR_M) + 1; + } ci->ci_data.cpu_cc_freq = ((uint64_t)AWIN_REF_FREQ * (n ? n : 1) * k / m) >> p; break; @@ -185,11 +196,24 @@ awin_bootstrap(vaddr_t iobase, vaddr_t u #endif #ifdef VERBOSE_INIT_ARM - uint32_t s0 = bus_space_read_4(&awin_bs_tag, awin_core_bsh, - AWIN_CPUCFG_OFFSET + AWIN_CPUCFG_CPU0_STATUS_REG); - uint32_t s1 = bus_space_read_4(&awin_bs_tag, awin_core_bsh, - AWIN_CPUCFG_OFFSET + AWIN_CPUCFG_CPU1_STATUS_REG); - printf("%s: cpu status: 0=%#x 1=%#x\n", __func__, s0, s1); + if (awin_chip_id() == AWIN_CHIP_ID_A31) { + uint32_t s0 = bus_space_read_4(&awin_bs_tag, awin_core_bsh, + AWIN_A31_CPUCFG_OFFSET + AWIN_A31_CPUCFG_CPU0_STATUS_REG); + uint32_t s1 = bus_space_read_4(&awin_bs_tag, awin_core_bsh, + AWIN_A31_CPUCFG_OFFSET + AWIN_A31_CPUCFG_CPU1_STATUS_REG); + uint32_t s2 = bus_space_read_4(&awin_bs_tag, awin_core_bsh, + AWIN_A31_CPUCFG_OFFSET + AWIN_A31_CPUCFG_CPU2_STATUS_REG); + uint32_t s3 = bus_space_read_4(&awin_bs_tag, awin_core_bsh, + AWIN_A31_CPUCFG_OFFSET + AWIN_A31_CPUCFG_CPU3_STATUS_REG); + printf("%s: cpu status: 0=%#x 1=%#x 2=%#x 3=%#x\n", __func__, + s0, s1, s2, s3); + } else { + uint32_t s0 = bus_space_read_4(&awin_bs_tag, awin_core_bsh, + AWIN_CPUCFG_OFFSET + AWIN_CPUCFG_CPU0_STATUS_REG); + uint32_t s1 = bus_space_read_4(&awin_bs_tag, awin_core_bsh, + AWIN_CPUCFG_OFFSET + AWIN_CPUCFG_CPU1_STATUS_REG); + printf("%s: cpu status: 0=%#x 1=%#x\n", __func__, s0, s1); + } #endif #if !defined(MULTIPROCESSOR) && defined(VERBOSE_INIT_ARM) @@ -228,16 +252,27 @@ awin_cpu_hatch(struct cpu_info *ci) psize_t awin_memprobe(void) { - const uint32_t dcr = bus_space_read_4(&awin_bs_tag, awin_core_bsh, - AWIN_DRAM_OFFSET + AWIN_DRAM_DCR_REG); + psize_t memsize; - psize_t memsize = (__SHIFTOUT(dcr, AWIN_DRAM_DCR_BUS_WIDTH) + 1) - / __SHIFTOUT(dcr, AWIN_DRAM_DCR_IO_WIDTH); - memsize *= 1 << (__SHIFTOUT(dcr, AWIN_DRAM_DCR_CHIP_DENSITY) + 28 - 3); + if (awin_chip_id() == AWIN_CHIP_ID_A31) { #ifdef VERBOSE_INIT_ARM - printf("sdram_config = %#x, memsize = %uMB\n", dcr, - (u_int)(memsize >> 20)); + printf("memprobe not supported on A31\n"); #endif + memsize = 0; + } else { + const uint32_t dcr = bus_space_read_4(&awin_bs_tag, + awin_core_bsh, + AWIN_DRAM_OFFSET + AWIN_DRAM_DCR_REG); + + memsize = (__SHIFTOUT(dcr, AWIN_DRAM_DCR_BUS_WIDTH) + 1) + / __SHIFTOUT(dcr, AWIN_DRAM_DCR_IO_WIDTH); + memsize *= 1 << (__SHIFTOUT(dcr, AWIN_DRAM_DCR_CHIP_DENSITY) + + 28 - 3); +#ifdef VERBOSE_INIT_ARM + printf("sdram_config = %#x, memsize = %uMB\n", dcr, + (u_int)(memsize >> 20)); +#endif + } return memsize; } Index: src/sys/arch/arm/allwinner/awin_intr.h diff -u src/sys/arch/arm/allwinner/awin_intr.h:1.4 src/sys/arch/arm/allwinner/awin_intr.h:1.5 --- src/sys/arch/arm/allwinner/awin_intr.h:1.4 Wed Sep 3 21:42:46 2014 +++ src/sys/arch/arm/allwinner/awin_intr.h Fri Oct 10 07:36:11 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_intr.h,v 1.4 2014/09/03 21:42:46 jmcneill Exp $ */ +/* $NetBSD: awin_intr.h,v 1.5 2014/10/10 07:36:11 jmcneill Exp $ */ /*- * Copyright (c) 2013 The NetBSD Foundation, Inc. * All rights reserved. @@ -134,4 +134,21 @@ #define AWIN_IRQ_TWI4 121 #define AWIN_IRQ_IIS2 122 +/* + * A31 + */ +#define AWIN_A31_IRQ_UART0 32 +#define AWIN_A31_IRQ_AC 61 +#define AWIN_A31_IRQ_DMA 82 +#define AWIN_A31_IRQ_SDMMC0 92 +#define AWIN_A31_IRQ_SDMMC1 93 +#define AWIN_A31_IRQ_SDMMC2 94 +#define AWIN_A31_IRQ_SDMMC3 95 +#define AWIN_A31_IRQ_USB0 103 +#define AWIN_A31_IRQ_USB1 104 +#define AWIN_A31_IRQ_USB2 105 +#define AWIN_A31_IRQ_USB3 106 +#define AWIN_A31_IRQ_USB4 108 +#define AWIN_A31_IRQ_GMAC 114 + #endif /* _ARM_ALLWINNER_AWIN_INTR_H_ */ Index: src/sys/arch/arm/allwinner/awin_io.c diff -u src/sys/arch/arm/allwinner/awin_io.c:1.15 src/sys/arch/arm/allwinner/awin_io.c:1.16 --- src/sys/arch/arm/allwinner/awin_io.c:1.15 Thu Sep 11 02:21:19 2014 +++ src/sys/arch/arm/allwinner/awin_io.c Fri Oct 10 07:36:11 2014 @@ -31,7 +31,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.15 2014/09/11 02:21:19 jmcneill Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_io.c,v 1.16 2014/10/10 07:36:11 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -94,27 +94,33 @@ awinio_print(void *aux, const char *pnp) static const struct awin_locators awin_locators[] = { { "awinicu", OFFANDSIZE(INTC), NOPORT, NOINTR, A10|REQ }, { "awingpio", OFFANDSIZE(PIO), NOPORT, NOINTR, AANY|REQ }, - { "awindma", OFFANDSIZE(DMA), NOPORT, AWIN_IRQ_DMA, AANY|REQ }, + { "awindma", OFFANDSIZE(DMA), NOPORT, AWIN_IRQ_DMA, A10|A20|REQ }, + { "awindma", OFFANDSIZE(DMA), NOPORT, AWIN_A31_IRQ_DMA, A31|REQ }, { "awintmr", OFFANDSIZE(TMR), NOPORT, AWIN_IRQ_TMR0, A10 }, - { "com", OFFANDSIZE(UART0), 0, AWIN_IRQ_UART0, AANY }, - { "com", OFFANDSIZE(UART1), 1, AWIN_IRQ_UART1, AANY }, - { "com", OFFANDSIZE(UART2), 2, AWIN_IRQ_UART2, AANY }, - { "com", OFFANDSIZE(UART3), 3, AWIN_IRQ_UART3, AANY }, - { "com", OFFANDSIZE(UART4), 4, AWIN_IRQ_UART4, AANY }, - { "com", OFFANDSIZE(UART5), 5, AWIN_IRQ_UART5, AANY }, - { "com", OFFANDSIZE(UART6), 6, AWIN_IRQ_UART6, AANY }, - { "com", OFFANDSIZE(UART7), 7, AWIN_IRQ_UART7, AANY }, + { "com", OFFANDSIZE(UART0), 0, AWIN_IRQ_UART0, A10|A20 }, + { "com", OFFANDSIZE(UART1), 1, AWIN_IRQ_UART1, A10|A20 }, + { "com", OFFANDSIZE(UART2), 2, AWIN_IRQ_UART2, A10|A20 }, + { "com", OFFANDSIZE(UART3), 3, AWIN_IRQ_UART3, A10|A20 }, + { "com", OFFANDSIZE(UART4), 4, AWIN_IRQ_UART4, A10|A20 }, + { "com", OFFANDSIZE(UART5), 5, AWIN_IRQ_UART5, A10|A20 }, + { "com", OFFANDSIZE(UART6), 6, AWIN_IRQ_UART6, A10|A20 }, + { "com", OFFANDSIZE(UART7), 7, AWIN_IRQ_UART7, A10|A20 }, + { "com", OFFANDSIZE(UART0), 0, AWIN_A31_IRQ_UART0, A31 }, { "awinwdt", OFFANDSIZE(TMR), NOPORT, NOINTR, AANY }, { "awinrtc", OFFANDSIZE(TMR), NOPORT, NOINTR, AANY }, { "awinhdmi", OFFANDSIZE(HDMI), NOPORT, AWIN_IRQ_HDMI0, A20 }, - { "awinusb", OFFANDSIZE(USB1), 0, NOINTR, AANY }, - { "awinusb", OFFANDSIZE(USB2), 1, NOINTR, AANY }, - { "motg", OFFANDSIZE(USB0), NOPORT, AWIN_IRQ_USB0, AANY }, - { "awinmmc", OFFANDSIZE(SDMMC0), 0, AWIN_IRQ_SDMMC0, AANY }, - { "awinmmc", OFFANDSIZE(SDMMC1), 1, AWIN_IRQ_SDMMC1, AANY }, - { "awinmmc", OFFANDSIZE(SDMMC2), 2, AWIN_IRQ_SDMMC2, AANY }, - { "awinmmc", OFFANDSIZE(SDMMC3), 3, AWIN_IRQ_SDMMC3, AANY }, - { "awinmmc", OFFANDSIZE(SDMMC1), 4, AWIN_IRQ_SDMMC1, AANY }, + { "awinusb", OFFANDSIZE(USB1), 0, NOINTR, A10|A20 }, + { "awinusb", OFFANDSIZE(USB2), 1, NOINTR, A10|A20 }, + { "awinusb", OFFANDSIZE(A31_USB1), 0, NOINTR, A31 }, + { "awinusb", OFFANDSIZE(A31_USB2), 1, NOINTR, A31 }, + { "motg", OFFANDSIZE(USB0), NOPORT, AWIN_IRQ_USB0, A10|A20 }, + { "motg", OFFANDSIZE(A31_USB0), NOPORT, AWIN_A31_IRQ_USB0, A31 }, + { "awinmmc", OFFANDSIZE(SDMMC0), 0, AWIN_IRQ_SDMMC0, A10|A20 }, + { "awinmmc", OFFANDSIZE(SDMMC1), 1, AWIN_IRQ_SDMMC1, A10|A20 }, + { "awinmmc", OFFANDSIZE(SDMMC2), 2, AWIN_IRQ_SDMMC2, A10|A20 }, + { "awinmmc", OFFANDSIZE(SDMMC3), 3, AWIN_IRQ_SDMMC3, A10|A20 }, + { "awinmmc", OFFANDSIZE(SDMMC1), 4, AWIN_IRQ_SDMMC1, A10|A20 }, + { "awinmmc", OFFANDSIZE(SDMMC0), 0, AWIN_A31_IRQ_SDMMC0, A31 }, { "ahcisata", OFFANDSIZE(SATA), NOPORT, AWIN_IRQ_SATA, AANY }, { "awiniic", OFFANDSIZE(TWI0), 0, AWIN_IRQ_TWI0, AANY }, { "awiniic", OFFANDSIZE(TWI1), 1, AWIN_IRQ_TWI1, AANY }, @@ -126,9 +132,11 @@ static const struct awin_locators awin_l { "spi", OFFANDSIZE(SPI2), 1, AWIN_IRQ_SPI2, AANY }, { "spi", OFFANDSIZE(SPI3), 3, AWIN_IRQ_SPI3, AANY }, { "awe", OFFANDSIZE(EMAC), NOPORT, AWIN_IRQ_EMAC, AANY }, - { "awge", OFFANDSIZE(GMAC), NOPORT, AWIN_IRQ_GMAC, A20|A31 }, + { "awge", OFFANDSIZE(GMAC), NOPORT, AWIN_IRQ_GMAC, A20 }, + { "awge", OFFANDSIZE(GMAC), NOPORT, AWIN_A31_IRQ_GMAC, A31 }, { "awincrypto", OFFANDSIZE(SS), NOPORT, AWIN_IRQ_SS, AANY }, - { "awinac", OFFANDSIZE(AC), NOPORT, AWIN_IRQ_AC, AANY }, + { "awinac", OFFANDSIZE(AC), NOPORT, AWIN_IRQ_AC, A10|A20 }, + { "awinac", OFFANDSIZE(AC), NOPORT, AWIN_A31_IRQ_AC, A31 }, }; static int Index: src/sys/arch/arm/allwinner/awin_mmc.c diff -u src/sys/arch/arm/allwinner/awin_mmc.c:1.11 src/sys/arch/arm/allwinner/awin_mmc.c:1.12 --- src/sys/arch/arm/allwinner/awin_mmc.c:1.11 Fri Oct 3 11:23:29 2014 +++ src/sys/arch/arm/allwinner/awin_mmc.c Fri Oct 10 07:36:11 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: awin_mmc.c,v 1.11 2014/10/03 11:23:29 jmcneill Exp $ */ +/* $NetBSD: awin_mmc.c,v 1.12 2014/10/10 07:36:11 jmcneill Exp $ */ /*- * Copyright (c) 2014 Jared D. McNeill <jmcne...@invisible.ca> @@ -29,7 +29,7 @@ #include "locators.h" #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: awin_mmc.c,v 1.11 2014/10/03 11:23:29 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: awin_mmc.c,v 1.12 2014/10/10 07:36:11 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -46,7 +46,6 @@ __KERNEL_RCSID(0, "$NetBSD: awin_mmc.c,v #include <arm/allwinner/awin_var.h> #define AWIN_MMC_NDESC 16 -#define AWIN_MMC_WATERMARK 0x20070008 static int awin_mmc_match(device_t, cfdata_t, void *); static void awin_mmc_attach(device_t, device_t, void *); @@ -105,6 +104,9 @@ struct awin_mmc_softc { unsigned int sc_pll_freq; unsigned int sc_mod_clk; + uint32_t sc_dma_ftrgl; + uint32_t sc_fifo_reg; + uint32_t sc_idma_xferlen; bus_dma_segment_t sc_idma_segs[1]; int sc_idma_nsegs; @@ -158,11 +160,24 @@ awin_mmc_probe_clocks(struct awin_mmc_so val = bus_space_read_4(aio->aio_core_bst, aio->aio_ccm_bsh, AWIN_PLL6_CFG_REG); - n = (val >> 8) & 0x1f; - k = ((val >> 4) & 3) + 1; - p = 1 << ((val >> 16) & 3); - - freq = 24000000 * n * k / p; + if (awin_chip_id() == AWIN_CHIP_ID_A31) { + n = ((val >> 8) & 0x1f) + 1; + k = ((val >> 4) & 3) + 1; + freq = 24000000 * n * k / 2; +#ifdef AWIN_MMC_DEBUG + device_printf(sc->sc_dev, "n = %d k = %d freq = %u\n", + n, k, freq); +#endif + } else { + n = (val >> 8) & 0x1f; + k = ((val >> 4) & 3) + 1; + p = 1 << ((val >> 16) & 3); + freq = 24000000 * n * k / p; +#ifdef AWIN_MMC_DEBUG + device_printf(sc->sc_dev, "n = %d k = %d p = %d freq = %u\n", + n, k, p, freq); +#endif + } sc->sc_pll_freq = freq; div = ((sc->sc_pll_freq + 99999999) / 100000000) - 1; @@ -275,6 +290,14 @@ awin_mmc_attach(device_t parent, device_ } } + if (awin_chip_id() == AWIN_CHIP_ID_A31) { + sc->sc_dma_ftrgl = 0x2007000f; + sc->sc_fifo_reg = AWIN_A31_MMC_FIFO; + } else { + sc->sc_dma_ftrgl = 0x20070008; + sc->sc_fifo_reg = AWIN_MMC_FIFO; + } + if (sc->sc_use_dma) { if (awin_mmc_idma_setup(sc) != 0) { aprint_error_dev(self, "failed to setup DMA\n"); @@ -302,6 +325,7 @@ awin_mmc_attach_i(device_t self) awin_mmc_host_reset(sc); awin_mmc_bus_width(sc, 1); + awin_mmc_bus_clock(sc, 400); memset(&saa, 0, sizeof(saa)); saa.saa_busname = "sdmmc"; @@ -344,6 +368,11 @@ awin_mmc_intr(void *priv) MMC_WRITE(sc, AWIN_MMC_RINT, rint); MMC_WRITE(sc, AWIN_MMC_MINT, mint); +#ifdef AWIN_MMC_DEBUG + device_printf(sc->sc_dev, "mmc intr idst=%08X rint=%08X mint=%08X\n", + idst, rint, mint); +#endif + if (idst) { sc->sc_idma_idst |= idst; cv_broadcast(&sc->sc_idst_cv); @@ -362,7 +391,7 @@ awin_mmc_intr(void *priv) static int awin_mmc_wait_rint(struct awin_mmc_softc *sc, uint32_t mask, int timeout) { - int retry = timeout; + int retry; int error; KASSERT(mutex_owned(&sc->sc_intr_lock)); @@ -370,13 +399,22 @@ awin_mmc_wait_rint(struct awin_mmc_softc if (sc->sc_intr_rint & mask) return 0; + retry = sc->sc_use_dma ? (timeout / hz) : 10000; + while (retry > 0) { - error = cv_timedwait(&sc->sc_intr_cv, - &sc->sc_intr_lock, hz); - if (error && error != EWOULDBLOCK) - return error; - if (sc->sc_intr_rint & mask) - return 0; + if (sc->sc_use_dma) { + error = cv_timedwait(&sc->sc_intr_cv, + &sc->sc_intr_lock, hz); + if (error && error != EWOULDBLOCK) + return error; + if (sc->sc_intr_rint & mask) + return 0; + } else { + sc->sc_intr_rint |= MMC_READ(sc, AWIN_MMC_RINT); + if (sc->sc_intr_rint & mask) + return 0; + delay(1000); + } --retry; } @@ -609,9 +647,9 @@ awin_mmc_pio_transfer(struct awin_mmc_so if (awin_mmc_pio_wait(sc, cmd)) return ETIMEDOUT; if (cmd->c_flags & SCF_CMD_READ) { - datap[i] = MMC_READ(sc, AWIN_MMC_FIFO); + datap[i] = MMC_READ(sc, sc->sc_fifo_reg); } else { - MMC_WRITE(sc, AWIN_MMC_FIFO, datap[i]); + MMC_WRITE(sc, sc->sc_fifo_reg, datap[i]); } } @@ -690,7 +728,7 @@ awin_mmc_dma_prepare(struct awin_mmc_sof val |= AWIN_MMC_IDST_TRANSMIT_INT; MMC_WRITE(sc, AWIN_MMC_IDIE, val); MMC_WRITE(sc, AWIN_MMC_DLBA, desc_paddr); - MMC_WRITE(sc, AWIN_MMC_FTRGLEVEL, AWIN_MMC_WATERMARK); + MMC_WRITE(sc, AWIN_MMC_FTRGLEVEL, sc->sc_dma_ftrgl); return 0; } Index: src/sys/arch/arm/allwinner/awin_reg.h diff -u src/sys/arch/arm/allwinner/awin_reg.h:1.26 src/sys/arch/arm/allwinner/awin_reg.h:1.27 --- src/sys/arch/arm/allwinner/awin_reg.h:1.26 Fri Oct 3 11:21:56 2014 +++ src/sys/arch/arm/allwinner/awin_reg.h Fri Oct 10 07:36:11 2014 @@ -52,7 +52,7 @@ #define AWIN_SRAMB_SIZE 0x00010000 /* Secure */ #define AWIN_CORE_PBASE 0x01C00000 -#define AWIN_CORE_SIZE 0x00300000 +#define AWIN_CORE_SIZE 0x00400000 #define AWIN_SRAM_OFFSET 0x00000000 #define AWIN_DRAM_OFFSET 0x00001000 #define AWIN_DMA_OFFSET 0x00002000 @@ -1687,4 +1687,52 @@ struct awin_mmc_idma_descriptor { #define AWIN_HDMI_DDC_CLOCK_M __BITS(6,3) #define AWIN_HDMI_DDC_CLOCK_N __BITS(2,0) +/* + * A31 registers + */ +#define AWIN_A31_USB0_OFFSET 0x00019000 /* OTG */ +#define AWIN_A31_USB1_OFFSET 0x0001a000 /* EHCI0/OHCI0 */ +#define AWIN_A31_USB2_OFFSET 0x0001b000 /* EHCI1/OHCI1 */ +#define AWIN_A31_USB3_OFFSET 0x0001b000 /* OHCI2 */ + +#define AWIN_A31_CPUCFG_OFFSET 0x00031C00 + +#define AWIN_A31_CPU_AXI_CFG_REG 0x0050 + +#define AWIN_A31_AHB_GATING0_USB_OHCI2 __BIT(31) +#define AWIN_A31_AHB_GATING0_USB_OHCI1 __BIT(30) +#define AWIN_A31_AHB_GATING0_USB_OHCI0 __BIT(29) +#define AWIN_A31_AHB_GATING0_USB_EHCI1 __BIT(27) +#define AWIN_A31_AHB_GATING0_USB_EHCI0 __BIT(26) +#define AWIN_A31_AHB_GATING0_USB0 __BIT(24) + +#define AWIN_A31_USB_CLK_OHCI2_ENABLE __BIT(18) +#define AWIN_A31_USB_CLK_OHCI1_ENABLE __BIT(17) +#define AWIN_A31_USB_CLK_OHCI0_ENABLE __BIT(16) +#define AWIN_A31_USB_CLK_USBPHY2_ENABLE __BIT(10) +#define AWIN_A31_USB_CLK_USBPHY1_ENABLE __BIT(9) +#define AWIN_A31_USB_CLK_USBPHY0_ENABLE __BIT(8) +#define AWIN_A31_USB_CLK_PHY2_ENABLE __BIT(2) +#define AWIN_A31_USB_CLK_PHY1_ENABLE __BIT(1) +#define AWIN_A31_USB_CLK_PHY0_ENABLE __BIT(0) + +#define AWIN_A31_CPUCFG_CPU0_STATUS_REG 0x0048 +#define AWIN_A31_CPUCFG_CPU1_STATUS_REG 0x0088 +#define AWIN_A31_CPUCFG_CPU2_STATUS_REG 0x00C8 +#define AWIN_A31_CPUCFG_CPU3_STATUS_REG 0x00108 + +#define AWIN_A31_WDOG1_IRQ_EN_REG 0x00A0 +#define AWIN_A31_WDOG1_IRQ_STA_REG 0x00A4 +#define AWIN_A31_WDOG1_CTRL_REG 0x00B0 +#define AWIN_A31_WDOG1_CFG_REG 0x00B4 +#define AWIN_A31_WDOG1_MODE_REG 0x00B8 + +#define AWIN_A31_WDOG_CFG_CONFIG __BITS(1,0) +#define AWIN_A31_WDOG_CFG_CONFIG_SYS 1 +#define AWIN_A31_WDOG_CFG_CONFIG_INT 2 + +#define AWIN_A31_WDOG_MODE_EN __BIT(0) + +#define AWIN_A31_MMC_FIFO 0x0200 + #endif /* _ARM_ALLWINNER_AWIN_REG_H_ */ Index: src/sys/arch/arm/allwinner/awin_usb.c diff -u src/sys/arch/arm/allwinner/awin_usb.c:1.13 src/sys/arch/arm/allwinner/awin_usb.c:1.14 --- src/sys/arch/arm/allwinner/awin_usb.c:1.13 Sat Sep 13 17:48:00 2014 +++ src/sys/arch/arm/allwinner/awin_usb.c Fri Oct 10 07:36:11 2014 @@ -34,7 +34,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: awin_usb.c,v 1.13 2014/09/13 17:48:00 jmcneill Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_usb.c,v 1.14 2014/10/10 07:36:11 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -90,6 +90,8 @@ struct awinusb_attach_args { #if NOHCI > 0 static const int awinusb_ohci_irqs[2] = { AWIN_IRQ_USB3, AWIN_IRQ_USB4 }; +static const int awinusb_ohci_irqs_a31[2] = { AWIN_A31_IRQ_USB3, + AWIN_A31_IRQ_USB4 }; #ifdef OHCI_DEBUG #define OHCI_DPRINTF(x) if (ohcidebug) printf x @@ -145,7 +147,9 @@ ohci_awinusb_attach(device_t parent, dev /* Attach usb device. */ sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint); - const int irq = awinusb_ohci_irqs[usbaa->usbaa_port]; + const int irq = awin_chip_id() == AWIN_CHIP_ID_A31 ? + awinusb_ohci_irqs_a31[usbaa->usbaa_port] : + awinusb_ohci_irqs[usbaa->usbaa_port]; usbsc->usbsc_ohci_ih = intr_establish(irq, IPL_USB, IST_LEVEL, ohci_intr, sc); if (usbsc->usbsc_ohci_ih == NULL) { @@ -169,6 +173,8 @@ static int ehci_awinusb_match(device_t, static void ehci_awinusb_attach(device_t, device_t, void *); static const int awinusb_ehci_irqs[2] = { AWIN_IRQ_USB1, AWIN_IRQ_USB2 }; +static const int awinusb_ehci_irqs_a31[2] = { AWIN_A31_IRQ_USB1, + AWIN_A31_IRQ_USB2 }; CFATTACH_DECL_NEW(ehci_awinusb, sizeof(struct ehci_softc), ehci_awinusb_match, ehci_awinusb_attach, NULL, NULL); @@ -218,7 +224,9 @@ ehci_awinusb_attach(device_t parent, dev /* Attach usb device. */ sc->sc_child = config_found(self, &sc->sc_bus, usbctlprint); - const int irq = awinusb_ehci_irqs[usbaa->usbaa_port]; + const int irq = awin_chip_id() == AWIN_CHIP_ID_A31 ? + awinusb_ehci_irqs_a31[usbaa->usbaa_port] : + awinusb_ehci_irqs[usbaa->usbaa_port]; usbsc->usbsc_ehci_ih = intr_establish(irq, IPL_USB, IST_LEVEL, ehci_intr, sc); if (usbsc->usbsc_ehci_ih == NULL) { @@ -289,6 +297,16 @@ static const uint32_t awinusb_ahb_gating #endif AWIN_AHB_GATING0_USB_EHCI1, }; +static const uint32_t awinusb_ahb_gating_a31[2] = { +#if NOHCI > 0 + AWIN_A31_AHB_GATING0_USB_OHCI0 | +#endif + AWIN_A31_AHB_GATING0_USB_EHCI0, +#if NOHCI > 0 + AWIN_A31_AHB_GATING0_USB_OHCI1 | +#endif + AWIN_A31_AHB_GATING0_USB_EHCI1, +}; static const uint32_t awinusb_usb_clk_set[2] = { #if NOHCI > 0 AWIN_USB_CLK_OHCI0_ENABLE | @@ -299,6 +317,20 @@ static const uint32_t awinusb_usb_clk_se #endif AWIN_USB_CLK_USBPHY_ENABLE|AWIN_USB_CLK_PHY2_ENABLE, }; +static const uint32_t awinusb_usb_clk_set_a31[2] = { +#if NOHCI > 0 + AWIN_A31_USB_CLK_OHCI0_ENABLE | +#endif + AWIN_A31_USB_CLK_USBPHY0_ENABLE | + AWIN_A31_USB_CLK_USBPHY1_ENABLE | + AWIN_A31_USB_CLK_PHY1_ENABLE, +#if NOHCI > 0 + AWIN_A31_USB_CLK_OHCI1_ENABLE | +#endif + AWIN_A31_USB_CLK_USBPHY0_ENABLE | + AWIN_A31_USB_CLK_USBPHY2_ENABLE | + AWIN_A31_USB_CLK_PHY2_ENABLE, +}; int awinusb_match(device_t parent, cfdata_t cf, void *aux) @@ -341,19 +373,35 @@ awinusb_attach(device_t parent, device_t aprint_naive("\n"); aprint_normal("\n"); - /* - * Access to the USB phy is off USB0 so make sure it's on. - */ - awin_reg_set_clear(usbsc->usbsc_bst, aio->aio_ccm_bsh, - AWIN_AHB_GATING0_REG, - AWIN_AHB_GATING0_USB0 | awinusb_ahb_gating[loc->loc_port], 0); - - - /* - * Enable the USB phy for this port. - */ - awin_reg_set_clear(usbsc->usbsc_bst, aio->aio_ccm_bsh, - AWIN_USB_CLK_REG, awinusb_usb_clk_set[loc->loc_port], 0); + if (awin_chip_id() == AWIN_CHIP_ID_A31) { + /* + * Access to the USB phy is off USB0 so make sure it's on. + */ + awin_reg_set_clear(usbsc->usbsc_bst, aio->aio_ccm_bsh, + AWIN_AHB_GATING0_REG, + awinusb_ahb_gating_a31[loc->loc_port], 0); + + /* + * Enable the USB phy for this port. + */ + awin_reg_set_clear(usbsc->usbsc_bst, aio->aio_ccm_bsh, + AWIN_USB_CLK_REG, awinusb_usb_clk_set_a31[loc->loc_port], + 0); + } else { + /* + * Access to the USB phy is off USB0 so make sure it's on. + */ + awin_reg_set_clear(usbsc->usbsc_bst, aio->aio_ccm_bsh, + AWIN_AHB_GATING0_REG, + AWIN_AHB_GATING0_USB0 | awinusb_ahb_gating[loc->loc_port], + 0); + + /* + * Enable the USB phy for this port. + */ + awin_reg_set_clear(usbsc->usbsc_bst, aio->aio_ccm_bsh, + AWIN_USB_CLK_REG, awinusb_usb_clk_set[loc->loc_port], 0); + } /* * Allow USB DMA engine access to the DRAM. @@ -361,11 +409,13 @@ awinusb_attach(device_t parent, device_t awin_reg_set_clear(usbsc->usbsc_bst, aio->aio_core_bsh, loc->loc_offset + AWIN_USB_PMU_IRQ_REG, AWIN_USB_PMU_IRQ_AHB_INCR8 | AWIN_USB_PMU_IRQ_AHB_INCR4 - | AWIN_USB_PMU_IRQ_AHB_INCRX | AWIN_USB_PMU_IRQ_ULPI_BYPASS, - 0); - awin_reg_set_clear(usbsc->usbsc_bst, aio->aio_core_bsh, - AWIN_DRAM_OFFSET + awinusb_dram_hpcr_regs[loc->loc_port], - AWIN_DRAM_HPCR_ACCESS_EN, 0); + | AWIN_USB_PMU_IRQ_AHB_INCRX | AWIN_USB_PMU_IRQ_ULPI_BYPASS, 0); + + if (awin_chip_id() != AWIN_CHIP_ID_A31) { + awin_reg_set_clear(usbsc->usbsc_bst, aio->aio_core_bsh, + AWIN_DRAM_OFFSET + awinusb_dram_hpcr_regs[loc->loc_port], + AWIN_DRAM_HPCR_ACCESS_EN, 0); + } /* initialize the USB phy */ awin_usb_phy_write(usbsc, 0x20, 0x14, 5); Index: src/sys/arch/arm/allwinner/awin_wdt.c diff -u src/sys/arch/arm/allwinner/awin_wdt.c:1.3 src/sys/arch/arm/allwinner/awin_wdt.c:1.4 --- src/sys/arch/arm/allwinner/awin_wdt.c:1.3 Thu Feb 20 21:48:38 2014 +++ src/sys/arch/arm/allwinner/awin_wdt.c Fri Oct 10 07:36:11 2014 @@ -33,7 +33,7 @@ #include <sys/cdefs.h> -__KERNEL_RCSID(1, "$NetBSD: awin_wdt.c,v 1.3 2014/02/20 21:48:38 matt Exp $"); +__KERNEL_RCSID(1, "$NetBSD: awin_wdt.c,v 1.4 2014/10/10 07:36:11 jmcneill Exp $"); #include <sys/param.h> #include <sys/bus.h> @@ -200,9 +200,19 @@ void awin_wdog_reset(void) { cpsid(I32_bit|F32_bit); - bus_space_write_4(&awin_bs_tag, awin_core_bsh, - AWIN_TMR_OFFSET + AWIN_WDOG_MODE_REG, - AWIN_WDOG_MODE_EN | AWIN_WDOG_MODE_RST_EN); + if (awin_chip_id() == AWIN_CHIP_ID_A31) { + bus_space_write_4(&awin_bs_tag, awin_core_bsh, + AWIN_TMR_OFFSET + AWIN_A31_WDOG1_CFG_REG, + __SHIFTIN(AWIN_A31_WDOG_CFG_CONFIG_SYS, + AWIN_A31_WDOG_CFG_CONFIG)); + bus_space_write_4(&awin_bs_tag, awin_core_bsh, + AWIN_TMR_OFFSET + AWIN_A31_WDOG1_MODE_REG, + AWIN_A31_WDOG_MODE_EN); + } else { + bus_space_write_4(&awin_bs_tag, awin_core_bsh, + AWIN_TMR_OFFSET + AWIN_WDOG_MODE_REG, + AWIN_WDOG_MODE_EN | AWIN_WDOG_MODE_RST_EN); + } for (;;) { __asm("wfi"); }