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");
 	}

Reply via email to