[rtems-libbsd commit] dw_mmc: Properly init/reset DMA

Sebastian Huber sebh at rtems.org
Tue Feb 6 09:03:27 UTC 2018


Module:    rtems-libbsd
Branch:    master
Commit:    bcaa8a28a2a58d9c4fb892eb54edb86650139c5d
Changeset: http://git.rtems.org/rtems-libbsd/commit/?id=bcaa8a28a2a58d9c4fb892eb54edb86650139c5d

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Mon Feb  5 16:45:59 2018 +0100

dw_mmc: Properly init/reset DMA

---

 rtemsbsd/sys/dev/dw_mmc/dw_mmc.c | 39 +++++++++++++++++++++++++++------------
 1 file 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 a65879e..951adea 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);
 



More information about the vc mailing list