diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2019-03-04 13:02:12 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2019-03-05 06:46:45 +0100 |
commit | 48562aeaa87ec08b961242f18cc37c12884b6382 (patch) | |
tree | 193f94dae85706ed4d30b4c0d23e8029afcf88ff /drivers/mci | |
parent | 48351bad46b87a7d60c3a2b6f703c3405ef60194 (diff) | |
download | barebox-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.c | 25 |
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); |