summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZiyuan Xu <xzy.xu@rock-chips.com>2017-05-15 09:07:14 +0300
committerKever Yang <kever.yang@rock-chips.com>2017-07-18 17:05:02 +0300
commit8920f389fed6e5d19867fc589c6258e29a91b28e (patch)
tree0190e5ccb7a1ea8c5d15d31491b0ae4c4f4326c9
parent97b62bc01423f4c11e2aa9ff0791a339c97e4c6c (diff)
downloadu-boot-8920f389fed6e5d19867fc589c6258e29a91b28e.tar.xz
mmc: dw_mmc: reset controller after data error
Per dw_mmc databook, it's recommend that reset the host contoller if some data-related error occurre during tuning progress. Signed-off-by: Ziyuan Xu <xzy.xu@rock-chips.com>
-rw-r--r--drivers/mmc/dw_mmc.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index c05288c8cb..e862eb228e 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -97,7 +97,7 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
{
int ret = 0;
u32 timeout = 240000;
- u32 mask, size, i, len = 0;
+ u32 status, ctrl, mask, size, i, len = 0;
u32 *buf = NULL;
ulong start = get_timer(0);
u32 fifo_depth = (((host->fifoth_val & RX_WMARK_MASK) >>
@@ -114,6 +114,23 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
/* Error during data transfer. */
if (mask & (DWMCI_DATA_ERR | DWMCI_DATA_TOUT)) {
debug("%s: DATA ERROR!\n", __func__);
+
+ dwmci_wait_reset(host, DWMCI_RESET_ALL);
+ dwmci_writel(host, DWMCI_CMD, DWMCI_CMD_PRV_DAT_WAIT |
+ DWMCI_CMD_UPD_CLK | DWMCI_CMD_START);
+
+ do {
+ status = dwmci_readl(host, DWMCI_CMD);
+ if (timeout-- < 0)
+ ret = -ETIMEDOUT;
+ } while (status & DWMCI_CMD_START);
+
+ if (!host->fifo_mode) {
+ ctrl = dwmci_readl(host, DWMCI_BMOD);
+ ctrl |= DWMCI_BMOD_IDMAC_RESET;
+ dwmci_writel(host, DWMCI_BMOD, ctrl);
+ }
+
ret = -EINVAL;
break;
}