[U-Boot] [PATCH 1/3] mmc: dw_mmc: change the read/write order under fifo mode
Jacob Chen
jacob2.chen at rock-chips.com
Mon Aug 29 19:26:13 CEST 2016
From: "jacob2.chen" <jacob2.chen at rock-chips.com>
The former implement have a bug.
It will cause wrong data reading sometimes.
Signed-off-by: jacob2.chen <jacob2.chen at rock-chips.com>
---
drivers/mmc/dw_mmc.c | 32 +++++++++++++++++---------------
1 file changed, 17 insertions(+), 15 deletions(-)
diff --git a/drivers/mmc/dw_mmc.c b/drivers/mmc/dw_mmc.c
index afc674d..f072739 100644
--- a/drivers/mmc/dw_mmc.c
+++ b/drivers/mmc/dw_mmc.c
@@ -120,35 +120,37 @@ static int dwmci_data_transfer(struct dwmci_host *host, struct mmc_data *data)
if (host->fifo_mode && size) {
len = 0;
- if (data->flags == MMC_DATA_READ) {
- if ((dwmci_readl(host, DWMCI_RINTSTS) &
- DWMCI_INTMSK_RXDR)) {
+ 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;
+ 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);
+ dwmci_readl(host,
+ DWMCI_DATA);
+ 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);
+ 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. */
--
2.7.4
More information about the U-Boot
mailing list