summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2018-02-05 16:45:59 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2018-02-06 09:56:35 +0100
commitbcaa8a28a2a58d9c4fb892eb54edb86650139c5d (patch)
treeee35539531d9ab95e9a7b16b84b1ab92142be023
parent138bf250c2b2029ab9bb100c65d8ff43c698cf06 (diff)
downloadrtems-libbsd-bcaa8a28a2a58d9c4fb892eb54edb86650139c5d.tar.bz2
dw_mmc: Properly init/reset DMA
-rw-r--r--rtemsbsd/sys/dev/dw_mmc/dw_mmc.c39
1 files changed, 27 insertions, 12 deletions
diff --git a/rtemsbsd/sys/dev/dw_mmc/dw_mmc.c b/rtemsbsd/sys/dev/dw_mmc/dw_mmc.c
index a65879e7..951adeaf 100644
--- a/rtemsbsd/sys/dev/dw_mmc/dw_mmc.c
+++ b/rtemsbsd/sys/dev/dw_mmc/dw_mmc.c
@@ -177,6 +177,13 @@ dw_mmc_wait_for_interrupt(struct dw_mmc_softc *sc, uint32_t intmask)
BSD_ASSERT(rs == RTEMS_SUCCESSFUL);
}
+static void
+dw_mmc_configure_dma(struct dw_mmc_softc *sc)
+{
+
+ WR4(sc, DW_MMC_BMOD, DW_MMC_BMOD_DE | DW_MMC_BMOD_FB);
+}
+
static int
dw_mmc_init(struct dw_mmc_softc *sc)
{
@@ -184,13 +191,16 @@ dw_mmc_init(struct dw_mmc_softc *sc)
uint32_t fifoth;
int err;
- err = dw_mmc_poll_reset_completion(sc, DW_MMC_CTRL_RESET);
+ err = dw_mmc_poll_reset_completion(sc, DW_MMC_CTRL_DMA_RESET |
+ DW_MMC_CTRL_FIFO_RESET | DW_MMC_CTRL_RESET);
if (err != 0) {
return err;
}
sc->card_clock = UINT32_MAX;
+ dw_mmc_configure_dma(sc);
+
/* Clear interrupt status */
WR4(sc, DW_MMC_RINTSTS, 0xffffffff);
@@ -223,7 +233,10 @@ dw_mmc_init(struct dw_mmc_softc *sc)
static void
dw_mmc_fini(struct dw_mmc_softc *sc)
{
- WR4(sc, DW_MMC_CTRL, DW_MMC_CTRL_FIFO_RESET | DW_MMC_CTRL_RESET);
+ WR4(sc, DW_MMC_CTRL, DW_MMC_CTRL_DMA_RESET | DW_MMC_CTRL_FIFO_RESET |
+ DW_MMC_CTRL_RESET);
+ wmb();
+ WR4(sc, DW_MMC_BMOD, DW_MMC_BMOD_SWR);
}
static struct ofw_compat_data compat_data[] = {
@@ -533,12 +546,19 @@ dw_mmc_fifo_and_dma_reset(struct dw_mmc_softc *sc)
{
uint32_t ctrl_resets = DW_MMC_CTRL_FIFO_RESET | DW_MMC_CTRL_DMA_RESET;
uint32_t ctrl = RD4(sc, DW_MMC_CTRL);
+ int err;
+ ctrl &= ~DW_MMC_CTRL_DMA_ENABLE;
ctrl |= ctrl_resets;
WR4(sc, DW_MMC_CTRL, ctrl);
- return dw_mmc_poll_reset_completion(sc, ctrl_resets);
+ err = dw_mmc_poll_reset_completion(sc, ctrl_resets);
+ if (err != 0)
+ return (err);
+
+ WR4(sc, DW_MMC_BMOD, DW_MMC_BMOD_SWR);
+ return (0);
}
static int
@@ -832,12 +852,7 @@ dw_mmc_dma_setup(struct dw_mmc_softc *sc, struct mmc_data *data)
}
des[i].des0 = DW_MMC_DES0_OWN | DW_MMC_DES0_ER | fs | DW_MMC_DES0_LD;
-
-#ifdef __arm__
- _ARM_Data_synchronization_barrier();
-#else
- /* TODO */
-#endif
+ wmb();
}
@@ -897,11 +912,11 @@ dw_mmc_cmd_do(struct dw_mmc_softc *sc, struct mmc_request *req,
if (use_dma) {
ctrl |= DW_MMC_CTRL_DMA_ENABLE;
- } else {
- ctrl &= ~DW_MMC_CTRL_DMA_ENABLE;
+ WR4(sc, DW_MMC_CTRL, ctrl);
+ wmb();
+ dw_mmc_configure_dma(sc);
}
- WR4(sc, DW_MMC_CTRL, ctrl);
WR4(sc, DW_MMC_BLKSIZ, MIN(count_bytes, MMC_SECTOR_SIZE));
WR4(sc, DW_MMC_BYTCNT, count_bytes);