From: Sonic Zhang <sonic.zh...@analog.com> - Ensure MMR writing is done before next command. - Invalidate the buffer before starting to read.
Signed-off-by: Sonic Zhang <sonic.zh...@analog.com> --- drivers/mmc/bfin_sdh.c | 30 +++++++++++++++++++++++------- 1 files changed, 23 insertions(+), 7 deletions(-) diff --git a/drivers/mmc/bfin_sdh.c b/drivers/mmc/bfin_sdh.c index 0f98b96..028cb58 100644 --- a/drivers/mmc/bfin_sdh.c +++ b/drivers/mmc/bfin_sdh.c @@ -136,6 +136,9 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data) /* Don't support write yet. */ if (data->flags & MMC_DATA_WRITE) return UNUSABLE_ERR; + blackfin_dcache_flush_invalidate_range(data->dest, + data->dest + data_size); + SSYNC(); #ifndef RSI_BLKSZ data_ctl |= ((ffs(data_size) - 1) << 4); #else @@ -143,21 +146,22 @@ static int sdh_setup_data(struct mmc *mmc, struct mmc_data *data) #endif data_ctl |= DTX_DIR; bfin_write_SDH_DATA_CTL(data_ctl); + SSYNC(); dma_cfg = WDSIZE_32 | PSIZE_32 | RESTART | WNR | DMAEN; bfin_write_SDH_DATA_TIMER(-1); - - blackfin_dcache_flush_invalidate_range(data->dest, - data->dest + data_size); + SSYNC(); /* configure DMA */ bfin_write_DMA_START_ADDR(data->dest); bfin_write_DMA_X_COUNT(data_size / 4); bfin_write_DMA_X_MODIFY(4); bfin_write_DMA_CONFIG(dma_cfg); + SSYNC(); bfin_write_SDH_DATA_LGTH(data_size); + SSYNC(); /* kick off transfer */ bfin_write_SDH_DATA_CTL(bfin_read_SDH_DATA_CTL() | DTX_DMA_E | DTX_E); - + SSYNC(); return 0; } @@ -167,6 +171,7 @@ static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd, { u32 status; int ret = 0; + u16 reg = 0; if (data) { ret = sdh_setup_data(mmc, data); @@ -191,14 +196,18 @@ static int bfin_sdh_request(struct mmc *mmc, struct mmc_cmd *cmd, } while (!(status & (DAT_BLK_END | DAT_END | DAT_TIME_OUT | DAT_CRC_FAIL | RX_OVERRUN))); if (status & DAT_TIME_OUT) { - bfin_write_SDH_STATUS_CLR(DAT_TIMEOUT_STAT); + reg |= DAT_TIMEOUT_STAT; ret |= TIMEOUT; } else if (status & (DAT_CRC_FAIL | RX_OVERRUN)) { - bfin_write_SDH_STATUS_CLR(DAT_CRC_FAIL_STAT | RX_OVERRUN_STAT); + reg |= DAT_CRC_FAIL_STAT | RX_OVERRUN_STAT; ret |= COMM_ERR; } else - bfin_write_SDH_STATUS_CLR(DAT_BLK_END_STAT | DAT_END_STAT); + reg |= DAT_BLK_END_STAT | DAT_END_STAT; + bfin_write_SDH_STATUS_CLR(reg); + bfin_write_DMA_CONFIG(0); + bfin_write_SDH_DATA_CTL(0); + SSYNC(); if (ret) { printf("tranfering data failed\n"); return ret; @@ -218,6 +227,7 @@ static void sdh_set_clk(unsigned long clk) /* setting SD_CLK */ sys_clk = get_sclk(); bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E); + SSYNC(); if (sys_clk % (2 * clk) == 0) clk_div = sys_clk / (2 * clk) - 1; else @@ -230,6 +240,7 @@ static void sdh_set_clk(unsigned long clk) bfin_write_SDH_CLK_CTL(clk_ctl); } else bfin_write_SDH_CLK_CTL(clk_ctl & ~CLK_E); + SSYNC(); } static void bfin_sdh_set_ios(struct mmc *mmc) @@ -247,6 +258,7 @@ static void bfin_sdh_set_ios(struct mmc *mmc) clk_ctl |= WIDE_BUS_4; } bfin_write_SDH_CLK_CTL(clk_ctl); + SSYNC(); sdh_set_clk(mmc->clock); } @@ -262,14 +274,18 @@ static int bfin_sdh_init(struct mmc *mmc) #if defined(__ADSPBF54x__) bfin_write_DMAC1_PERIMUX(bfin_read_DMAC1_PERIMUX() | 0x1); #endif + SSYNC(); bfin_write_SDH_CFG(bfin_read_SDH_CFG() | CLKS_EN); + SSYNC(); /* Disable card detect pin */ bfin_write_SDH_CFG((bfin_read_SDH_CFG() & 0x1F) | 0x60); + SSYNC(); #ifndef RSI_BLKSZ bfin_write_SDH_PWR_CTL(PWR_ON | ROD_CTL); #else bfin_write_SDH_CFG(bfin_read_SDH_CFG() | PWR_ON); #endif + SSYNC(); return 0; } -- 1.7.0.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot