[U-Boot] [PATCH v1] mmc: bfin: Ensure MMR writing is done before next command.

From: Sonic Zhang sonic.zhang@analog.com
- Ensure MMR writing is done before next command. - Invalidate the buffer before starting to read.
Signed-off-by: Sonic Zhang sonic.zhang@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; }

On Saturday 27 April 2013 07:04:10 Sonic Zhang wrote:
From: Sonic Zhang sonic.zhang@analog.com
- Ensure MMR writing is done before next command.
- Invalidate the buffer before starting to read.
this patch was written by Cliff, not yourself. the description really doesn't match reality, and no one has yet to explain what this is doing. i'm fairly certain Cliff, when presented with the bug (iirc, it was "mmc doesn't work at low SCLK") just threw in a crap ton of SSYNCs to slow the driver down and shuffled some code until it worked. no real analysis as to what was actually necessary.
hence, i never pushed this upstream. i still don't think this belongs in mainline. -mike

Hi Mike
On Sat, Apr 27, 2013 at 7:14 PM, Mike Frysinger vapier@gentoo.org wrote:
On Saturday 27 April 2013 07:04:10 Sonic Zhang wrote:
From: Sonic Zhang sonic.zhang@analog.com
- Ensure MMR writing is done before next command.
- Invalidate the buffer before starting to read.
this patch was written by Cliff, not yourself. the description really doesn't match reality, and no one has yet to explain what this is doing. i'm fairly certain Cliff, when presented with the bug (iirc, it was "mmc doesn't work at low SCLK") just threw in a crap ton of SSYNCs to slow the driver down and shuffled some code until it worked. no real analysis as to what was actually necessary.
hence, i never pushed this upstream. i still don't think this belongs in mainline.
Good catch. I can't find the log of this patch in local tree, because you moved the bfin_sdh.c someday. Yes, this patch looks like a workaround. So, ignore it.
Regards,
Sonic
participants (2)
-
Mike Frysinger
-
Sonic Zhang