dw_mmc: Properly init/reset DMA

This commit is contained in:
Sebastian Huber 2018-02-05 16:45:59 +01:00
parent 138bf250c2
commit bcaa8a28a2

View File

@ -177,6 +177,13 @@ dw_mmc_wait_for_interrupt(struct dw_mmc_softc *sc, uint32_t intmask)
BSD_ASSERT(rs == RTEMS_SUCCESSFUL); 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 static int
dw_mmc_init(struct dw_mmc_softc *sc) dw_mmc_init(struct dw_mmc_softc *sc)
{ {
@ -184,13 +191,16 @@ dw_mmc_init(struct dw_mmc_softc *sc)
uint32_t fifoth; uint32_t fifoth;
int err; 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) { if (err != 0) {
return err; return err;
} }
sc->card_clock = UINT32_MAX; sc->card_clock = UINT32_MAX;
dw_mmc_configure_dma(sc);
/* Clear interrupt status */ /* Clear interrupt status */
WR4(sc, DW_MMC_RINTSTS, 0xffffffff); WR4(sc, DW_MMC_RINTSTS, 0xffffffff);
@ -223,7 +233,10 @@ dw_mmc_init(struct dw_mmc_softc *sc)
static void static void
dw_mmc_fini(struct dw_mmc_softc *sc) 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[] = { 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_resets = DW_MMC_CTRL_FIFO_RESET | DW_MMC_CTRL_DMA_RESET;
uint32_t ctrl = RD4(sc, DW_MMC_CTRL); uint32_t ctrl = RD4(sc, DW_MMC_CTRL);
int err;
ctrl &= ~DW_MMC_CTRL_DMA_ENABLE;
ctrl |= ctrl_resets; ctrl |= ctrl_resets;
WR4(sc, DW_MMC_CTRL, ctrl); 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 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; des[i].des0 = DW_MMC_DES0_OWN | DW_MMC_DES0_ER | fs | DW_MMC_DES0_LD;
wmb();
#ifdef __arm__
_ARM_Data_synchronization_barrier();
#else
/* TODO */
#endif
} }
@ -897,11 +912,11 @@ dw_mmc_cmd_do(struct dw_mmc_softc *sc, struct mmc_request *req,
if (use_dma) { if (use_dma) {
ctrl |= DW_MMC_CTRL_DMA_ENABLE; ctrl |= DW_MMC_CTRL_DMA_ENABLE;
} else { WR4(sc, DW_MMC_CTRL, ctrl);
ctrl &= ~DW_MMC_CTRL_DMA_ENABLE; 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_BLKSIZ, MIN(count_bytes, MMC_SECTOR_SIZE));
WR4(sc, DW_MMC_BYTCNT, count_bytes); WR4(sc, DW_MMC_BYTCNT, count_bytes);