X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=drivers%2Fmmc%2Fdw_mmc.c;h=074f86c502c0d2aed6eb1c2ffeedfe5730fdbc81;hb=1221ce459d04a428f8880f58581f671b736c3c27;hp=fe2147a226e3c8f946a43c908adbbc306bb17ce9;hpb=5628347f59e1672f381b8113e85e47529770ab47;p=u-boot diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c index fe2147a226..074f86c502 100644 --- a/drivers/mmc/dw_mmc.c +++ b/drivers/mmc/dw_mmc.c @@ -13,7 +13,6 @@ #include #include #include -#include #define PAGE_SIZE 4096 @@ -120,33 +119,37 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) } if (host->fifo_mode && size) { - if (data->flags == MMC_DATA_READ) { - if ((dwmci_readl(host, DWMCI_RINTSTS) & - DWMCI_INTMSK_RXDR)) { + len = 0; + if (data->flags == MMC_DATA_READ && + (mask & DWMCI_INTMSK_RXDR)) { + while (size) { len = dwmci_readl(host, DWMCI_STATUS); len = (len >> DWMCI_FIFO_SHIFT) & DWMCI_FIFO_MASK; + len = min(size, len); for (i = 0; i < len; i++) *buf++ = dwmci_readl(host, DWMCI_DATA); - dwmci_writel(host, DWMCI_RINTSTS, - DWMCI_INTMSK_RXDR); + size = size > len ? (size - len) : 0; } - } else { - if ((dwmci_readl(host, DWMCI_RINTSTS) & - DWMCI_INTMSK_TXDR)) { + dwmci_writel(host, DWMCI_RINTSTS, + DWMCI_INTMSK_RXDR); + } else if (data->flags == MMC_DATA_WRITE && + (mask & DWMCI_INTMSK_TXDR)) { + while (size) { len = dwmci_readl(host, DWMCI_STATUS); len = fifo_depth - ((len >> DWMCI_FIFO_SHIFT) & DWMCI_FIFO_MASK); + len = min(size, len); for (i = 0; i < len; i++) dwmci_writel(host, DWMCI_DATA, *buf++); - dwmci_writel(host, DWMCI_RINTSTS, - DWMCI_INTMSK_TXDR); + size = size > len ? (size - len) : 0; } + dwmci_writel(host, DWMCI_RINTSTS, + DWMCI_INTMSK_TXDR); } - size = size > len ? (size - len) : 0; } /* Data arrived correctly. */ @@ -159,7 +162,7 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data) if (get_timer(start) > timeout) { debug("%s: Timeout waiting for data!\n", __func__); - ret = TIMEOUT; + ret = -ETIMEDOUT; break; } } @@ -195,7 +198,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, ALLOC_CACHE_ALIGN_BUFFER(struct dwmci_idmac, cur_idmac, data ? DIV_ROUND_UP(data->blocks, 8) : 0); int ret = 0, flags = 0, i; - unsigned int timeout = 100000; + unsigned int timeout = 500; u32 retry = 100000; u32 mask, ctrl; ulong start = get_timer(0); @@ -204,7 +207,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, while (dwmci_readl(host, DWMCI_STATUS) & DWMCI_BUSY) { if (get_timer(start) > timeout) { debug("%s: Timeout on data busy\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } } @@ -270,7 +273,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, if (i == retry) { debug("%s: Timeout.\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } if (mask & DWMCI_INTMSK_RTO) { @@ -283,7 +286,7 @@ static int dwmci_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, * CMD8, please keep that in mind. */ debug("%s: Response Timeout.\n", __func__); - return TIMEOUT; + return -ETIMEDOUT; } else if (mask & DWMCI_INTMSK_RE) { debug("%s: Response Error.\n", __func__); return -EIO;