summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjmcneill <jmcneill@FreeBSD.org>2016-02-27 22:26:05 +0000
committerjmcneill <jmcneill@FreeBSD.org>2016-02-27 22:26:05 +0000
commit0272c813d11a4880c8e723446442093362e2ab45 (patch)
tree514ef918b5e98c30815dd2dac0e2d4810a13cbd3
parent1241a93bc61c027775a2105ffc4c278c1d497f43 (diff)
downloadFreeBSD-src-0272c813d11a4880c8e723446442093362e2ab45.zip
FreeBSD-src-0272c813d11a4880c8e723446442093362e2ab45.tar.gz
Fix PIO mode on A31 and later SoCs.
Newer Allwinner MMC implementations use a different FIFO register offset (0x200 instead of 0x100). Since the FDT uses the same compat string for both cases, base the decision on which FIFO offset to use on the Allwinner SoC family. Reviewed by: Emmanuel Vadot <manu@bidouilliste.com> Approved by: gonzo (mentor) Differential Revision: https://reviews.freebsd.org/D5468
-rw-r--r--sys/arm/allwinner/a10_mmc.c20
-rw-r--r--sys/arm/allwinner/a10_mmc.h3
2 files changed, 20 insertions, 3 deletions
diff --git a/sys/arm/allwinner/a10_mmc.c b/sys/arm/allwinner/a10_mmc.c
index fad58ff..b236c4b 100644
--- a/sys/arm/allwinner/a10_mmc.c
+++ b/sys/arm/allwinner/a10_mmc.c
@@ -86,6 +86,7 @@ struct a10_mmc_softc {
uint32_t a10_intr;
uint32_t a10_intr_wait;
void * a10_intrhand;
+ bus_size_t a10_fifo_reg;
/* Fields required for DMA access. */
bus_addr_t a10_dma_desc_phys;
@@ -170,6 +171,21 @@ a10_mmc_attach(device_t dev)
return (ENXIO);
}
+ /*
+ * Later chips use a different FIFO offset. Unfortunately the FDT
+ * uses the same compatible string for old and new implementations.
+ */
+ switch (allwinner_soc_family()) {
+ case ALLWINNERSOC_SUN4I:
+ case ALLWINNERSOC_SUN5I:
+ case ALLWINNERSOC_SUN7I:
+ sc->a10_fifo_reg = A10_MMC_FIFO;
+ break;
+ default:
+ sc->a10_fifo_reg = A31_MMC_FIFO;
+ break;
+ }
+
/* Activate the module clock. */
switch (allwinner_soc_type()) {
#if defined(SOC_ALLWINNER_A10) || defined(SOC_ALLWINNER_A20)
@@ -513,9 +529,9 @@ a10_mmc_pio_transfer(struct a10_mmc_softc *sc, struct mmc_data *data)
if ((A10_MMC_READ_4(sc, A10_MMC_STAS) & bit))
return (1);
if (write)
- A10_MMC_WRITE_4(sc, A10_MMC_FIFO, buf[i]);
+ A10_MMC_WRITE_4(sc, sc->a10_fifo_reg, buf[i]);
else
- buf[i] = A10_MMC_READ_4(sc, A10_MMC_FIFO);
+ buf[i] = A10_MMC_READ_4(sc, sc->a10_fifo_reg);
sc->a10_resid = i + 1;
}
diff --git a/sys/arm/allwinner/a10_mmc.h b/sys/arm/allwinner/a10_mmc.h
index 4b5d943..02e200c 100644
--- a/sys/arm/allwinner/a10_mmc.h
+++ b/sys/arm/allwinner/a10_mmc.h
@@ -56,7 +56,8 @@
#define A10_MMC_IDIE 0x8C /* IDMAC Interrupt Enable Register */
#define A10_MMC_CHDA 0x90
#define A10_MMC_CBDA 0x94
-#define A10_MMC_FIFO 0x100 /* FIFO Access Address */
+#define A10_MMC_FIFO 0x100 /* FIFO Access Address (A10/A20) */
+#define A31_MMC_FIFO 0x200 /* FIFO Access Address (A31) */
/* A10_MMC_GCTRL */
#define A10_MMC_SOFT_RESET (1U << 0)
OpenPOWER on IntegriCloud