summaryrefslogtreecommitdiffstats
path: root/drivers/mci
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2019-03-04 13:02:12 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2019-03-05 06:46:45 +0100
commit48562aeaa87ec08b961242f18cc37c12884b6382 (patch)
tree193f94dae85706ed4d30b4c0d23e8029afcf88ff /drivers/mci
parent48351bad46b87a7d60c3a2b6f703c3405ef60194 (diff)
downloadbarebox-48562aeaa87ec08b961242f18cc37c12884b6382.tar.gz
barebox-48562aeaa87ec08b961242f18cc37c12884b6382.tar.xz
esdhc-xload: check for PRSSTAT_BREN only after each block
The BREN bit tells us a watermark level sized buffer is ready for read. Instead of testing it before each FIFO read we must only check it once and then read a watermark level sized buffer. This is at least necessary on Layerscape, otherwise timeouts occur while reading the buffer. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/mci')
-rw-r--r--drivers/mci/imx-esdhc-pbl.c25
1 files changed, 16 insertions, 9 deletions
diff --git a/drivers/mci/imx-esdhc-pbl.c b/drivers/mci/imx-esdhc-pbl.c
index 33d78aad05..f77530d310 100644
--- a/drivers/mci/imx-esdhc-pbl.c
+++ b/drivers/mci/imx-esdhc-pbl.c
@@ -84,28 +84,33 @@ static int esdhc_do_data(struct esdhc *esdhc, struct mci_data *data)
u32 databuf;
u32 size;
u32 irqstat;
- u32 timeout;
u32 present;
buffer = data->dest;
- timeout = 1000000;
size = data->blocksize * data->blocks;
irqstat = esdhc_read32(esdhc, SDHCI_INT_STATUS);
while (size) {
- present = esdhc_read32(esdhc, SDHCI_PRESENT_STATE) & PRSSTAT_BREN;
- if (present) {
+ int i;
+ int timeout = 1000000;
+
+ while (1) {
+ present = esdhc_read32(esdhc, SDHCI_PRESENT_STATE) & PRSSTAT_BREN;
+ if (present)
+ break;
+ if (!--timeout) {
+ pr_err("read time out\n");
+ return -ETIMEDOUT;
+ }
+ }
+
+ for (i = 0; i < SECTOR_SIZE / sizeof(uint32_t); i++) {
databuf = esdhc_read32(esdhc, SDHCI_BUFFER);
*((u32 *)buffer) = databuf;
buffer += 4;
size -= 4;
}
-
- if (!timeout--) {
- pr_err("read time out\n");
- return -ETIMEDOUT;
- }
}
return 0;
@@ -205,6 +210,8 @@ static int esdhc_read_blocks(struct esdhc *esdhc, void *dst, size_t len)
IRQSTATEN_DTOE | IRQSTATEN_DCE | IRQSTATEN_DEBE |
IRQSTATEN_DINT);
+ esdhc_write32(esdhc, IMX_SDHCI_WML, 0x0);
+
val = esdhc_read32(esdhc, SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET);
val |= SYSCTL_HCKEN | SYSCTL_IPGEN;
esdhc_write32(esdhc, SDHCI_CLOCK_CONTROL__TIMEOUT_CONTROL__SOFTWARE_RESET, val);