+// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2012 SAMSUNG Electronics
* Jaehoon Chung <jh80.chung@samsung.com>
* Rajeshawari Shinde <rajeshwari.s@samsung.com>
- *
- * SPDX-License-Identifier: GPL-2.0+
*/
#include <bouncebuf.h>
dwmci_writel(host, DWMCI_BYTCNT, data->blocksize * data->blocks);
}
+static int dwmci_fifo_ready(struct dwmci_host *host, u32 bit, u32 *len)
+{
+ u32 timeout = 20000;
+
+ *len = dwmci_readl(host, DWMCI_STATUS);
+ while (--timeout && (*len & bit)) {
+ udelay(200);
+ *len = dwmci_readl(host, DWMCI_STATUS);
+ }
+
+ if (!timeout) {
+ debug("%s: FIFO underflow timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
{
int ret = 0;
if (data->flags == MMC_DATA_READ &&
(mask & DWMCI_INTMSK_RXDR)) {
while (size) {
- len = dwmci_readl(host, DWMCI_STATUS);
+ ret = dwmci_fifo_ready(host,
+ DWMCI_FIFO_EMPTY,
+ &len);
+ if (ret < 0)
+ break;
+
len = (len >> DWMCI_FIFO_SHIFT) &
DWMCI_FIFO_MASK;
len = min(size, len);
} else if (data->flags == MMC_DATA_WRITE &&
(mask & DWMCI_INTMSK_TXDR)) {
while (size) {
- len = dwmci_readl(host, DWMCI_STATUS);
+ ret = dwmci_fifo_ready(host,
+ DWMCI_FIFO_FULL,
+ &len);
+ if (ret < 0)
+ break;
+
len = fifo_depth - ((len >>
DWMCI_FIFO_SHIFT) &
DWMCI_FIFO_MASK);
} else if (mask & DWMCI_INTMSK_RE) {
debug("%s: Response Error.\n", __func__);
return -EIO;
+ } else if ((cmd->resp_type & MMC_RSP_CRC) &&
+ (mask & DWMCI_INTMSK_RCRC)) {
+ debug("%s: Response CRC Error.\n", __func__);
+ return -EIO;
}