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 if "dma" property is set to false, fa...
details: https://anonhg.NetBSD.org/src/rev/394eede89bb2
branches: trunk
changeset: 332171:394eede89bb2
user: jmcneill <jmcneill%NetBSD.org@localhost>
date: Tue Sep 09 20:39:52 2014 +0000
description:
if "dma" property is set to false, fallback to pio mode
diffstat:
sys/arch/arm/allwinner/awin_mmc.c | 104 +++++++++++++++++++++++++++++--------
1 files changed, 80 insertions(+), 24 deletions(-)
diffs (182 lines):
diff -r 16603d543962 -r 394eede89bb2 sys/arch/arm/allwinner/awin_mmc.c
--- a/sys/arch/arm/allwinner/awin_mmc.c Tue Sep 09 20:16:12 2014 +0000
+++ b/sys/arch/arm/allwinner/awin_mmc.c Tue Sep 09 20:39:52 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: awin_mmc.c,v 1.8 2014/09/09 19:23:46 jmcneill Exp $ */
+/* $NetBSD: awin_mmc.c,v 1.9 2014/09/09 20:39:52 jmcneill Exp $ */
/*-
* Copyright (c) 2014 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -29,7 +29,7 @@
#include "locators.h"
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: awin_mmc.c,v 1.8 2014/09/09 19:23:46 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: awin_mmc.c,v 1.9 2014/09/09 20:39:52 jmcneill Exp $");
#include <sys/param.h>
#include <sys/bus.h>
@@ -89,6 +89,8 @@
bus_space_handle_t sc_bsh;
bus_dma_tag_t sc_dmat;
+ bool sc_use_dma;
+
void *sc_ih;
kmutex_t sc_intr_lock;
kcondvar_t sc_intr_cv;
@@ -236,8 +238,11 @@
bus_space_subregion(sc->sc_bst, aio->aio_core_bsh,
loc->loc_offset, loc->loc_size, &sc->sc_bsh);
+ sc->sc_use_dma = true;
+ prop_dictionary_get_bool(cfg, "dma", &sc->sc_use_dma);
+
aprint_naive("\n");
- aprint_normal(": SD/MMC interface\n");
+ aprint_normal(": SD3.0 (%s)\n", sc->sc_use_dma ? "DMA" : "PIO");
awin_mmc_probe_clocks(sc, aio);
@@ -266,9 +271,11 @@
}
}
- if (awin_mmc_idma_setup(sc) != 0) {
- aprint_error_dev(self, "failed to setup DMA\n");
- return;
+ if (sc->sc_use_dma) {
+ if (awin_mmc_idma_setup(sc) != 0) {
+ aprint_error_dev(self, "failed to setup DMA\n");
+ return;
+ }
}
sc->sc_ih = intr_establish(loc->loc_intr, IPL_BIO, IST_LEVEL,
@@ -296,16 +303,18 @@
saa.saa_busname = "sdmmc";
saa.saa_sct = &awin_mmc_chip_functions;
saa.saa_sch = sc;
- saa.saa_dmat = sc->sc_dmat;
saa.saa_clkmin = 400;
saa.saa_clkmax = 50000;
saa.saa_caps = SMC_CAPS_4BIT_MODE|
SMC_CAPS_8BIT_MODE|
SMC_CAPS_SD_HIGHSPEED|
SMC_CAPS_MMC_HIGHSPEED|
- SMC_CAPS_AUTO_STOP|
- SMC_CAPS_DMA|
- SMC_CAPS_MULTI_SEG_DMA;
+ SMC_CAPS_AUTO_STOP;
+ if (sc->sc_use_dma) {
+ saa.saa_dmat = sc->sc_dmat;
+ saa.saa_caps |= SMC_CAPS_DMA|
+ SMC_CAPS_MULTI_SEG_DMA;
+ }
if (sc->sc_has_gpio_detect) {
saa.saa_caps |= SMC_CAPS_POLL_CARD_DET;
}
@@ -410,9 +419,7 @@
static int
awin_mmc_host_maxblklen(sdmmc_chipset_handle_t sch)
{
- struct awin_mmc_softc *sc = sch;
-
- return sc->sc_idma_xferlen;
+ return 8192;
}
static int
@@ -553,6 +560,43 @@
return -1;
}
+
+static int
+awin_mmc_pio_wait(struct awin_mmc_softc *sc, struct sdmmc_command *cmd)
+{
+ int retry = 0xfffff;
+ uint32_t bit = (cmd->c_flags & SCF_CMD_READ) ?
+ AWIN_MMC_STATUS_FIFO_EMPTY : AWIN_MMC_STATUS_FIFO_FULL;
+
+ while (--retry > 0) {
+ uint32_t status = MMC_READ(sc, AWIN_MMC_STATUS);
+ if (!(status & bit))
+ return 0;
+ delay(10);
+ }
+
+ return ETIMEDOUT;
+}
+
+static int
+awin_mmc_pio_transfer(struct awin_mmc_softc *sc, struct sdmmc_command *cmd)
+{
+ uint32_t *datap = (uint32_t *)cmd->c_data;
+ int i;
+
+ for (i = 0; i < (cmd->c_resid >> 2); i++) {
+ if (awin_mmc_pio_wait(sc, cmd))
+ return ETIMEDOUT;
+ if (cmd->c_flags & SCF_CMD_READ) {
+ datap[i] = MMC_READ(sc, AWIN_MMC_FIFO);
+ } else {
+ MMC_WRITE(sc, AWIN_MMC_FIFO, datap[i]);
+ }
+ }
+
+ return 0;
+}
+
static int
awin_mmc_dma_prepare(struct awin_mmc_softc *sc, struct sdmmc_command *cmd)
{
@@ -693,18 +737,25 @@
MMC_WRITE(sc, AWIN_MMC_CMD, cmdval | cmd->c_opcode);
} else {
cmd->c_resid = cmd->c_datalen;
- cmd->c_error = awin_mmc_dma_prepare(sc, cmd);
awin_mmc_led(sc, 0);
- MMC_WRITE(sc, AWIN_MMC_CMD, cmdval | cmd->c_opcode);
- if (cmd->c_error == 0) {
- cmd->c_error = cv_timedwait(&sc->sc_idst_cv,
- &sc->sc_intr_lock, hz*10);
- }
- awin_mmc_dma_complete(sc);
- if (sc->sc_idma_idst & AWIN_MMC_IDST_ERROR) {
- cmd->c_error = EIO;
- } else if (!(sc->sc_idma_idst & AWIN_MMC_IDST_COMPLETE)) {
- cmd->c_error = ETIMEDOUT;
+ if (sc->sc_use_dma) {
+ cmd->c_error = awin_mmc_dma_prepare(sc, cmd);
+ MMC_WRITE(sc, AWIN_MMC_CMD, cmdval | cmd->c_opcode);
+ if (cmd->c_error == 0) {
+ cmd->c_error = cv_timedwait(&sc->sc_idst_cv,
+ &sc->sc_intr_lock, hz*10);
+ }
+ awin_mmc_dma_complete(sc);
+ if (sc->sc_idma_idst & AWIN_MMC_IDST_ERROR) {
+ cmd->c_error = EIO;
+ } else if (!(sc->sc_idma_idst & AWIN_MMC_IDST_COMPLETE)) {
+ cmd->c_error = ETIMEDOUT;
+ }
+ } else {
+ mutex_exit(&sc->sc_intr_lock);
+ MMC_WRITE(sc, AWIN_MMC_CMD, cmdval | cmd->c_opcode);
+ cmd->c_error = awin_mmc_pio_transfer(sc, cmd);
+ mutex_enter(&sc->sc_intr_lock);
}
awin_mmc_led(sc, 1);
if (cmd->c_error) {
@@ -796,6 +847,11 @@
awin_mmc_host_reset(sc);
awin_mmc_update_clock(sc);
}
+
+ if (!sc->sc_use_dma) {
+ MMC_WRITE(sc, AWIN_MMC_GCTRL,
+ MMC_READ(sc, AWIN_MMC_GCTRL) | AWIN_MMC_GCTRL_FIFORESET);
+ }
}
static void
Home |
Main Index |
Thread Index |
Old Index