diff options
author | Nicolas Boichat <drinkcat@chromium.org> | 2018-10-08 14:07:34 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-10-14 23:31:10 -0700 |
commit | c0847323192309878855a8e9e85fda91afac5c0d (patch) | |
tree | 99a3d17c0d8582a16940fc4ca86fb1fcc5b4e0c8 | |
parent | 894861f0991192dd9f09087017aa3f76afc93dd9 (diff) | |
download | chrome-ec-c0847323192309878855a8e9e85fda91afac5c0d.tar.gz |
kukui/emmc: Wait 200us between dma_disable and flush SPI TX FIFO
For some unclear reason, SPI+DMA sometimes fails to transmit the
first few bytes after it is activated the third time, that is,
after the transmission is aborted twice (this looks like a
hardware bug).
It does appear that increasing the delay between DMA disabling
and manually resetting ->dr to 0xff from 100us to 200us fixes
the issue, but the reason is unclear.
Also, print transfer try count to the console, to facilitate
debugging.
BRANCH=none
BUG=b:117253718
TEST=Put kukui in a reboot loop, ~1000 sucessful boots without
ever requiring a 4th transfer.
Change-Id: I7e5f6bc4da45d9a70ad18447ffb15afd1b62a7a2
Signed-off-by: Nicolas Boichat <drinkcat@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1267761
Reviewed-by: Yilun Lin <yllin@chromium.org>
-rw-r--r-- | board/kukui/emmc.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/board/kukui/emmc.c b/board/kukui/emmc.c index 36a9256817..af2d4b1701 100644 --- a/board/kukui/emmc.c +++ b/board/kukui/emmc.c @@ -89,13 +89,15 @@ static const struct dma_option dma_rx_option = { /* Setup DMA to transfer bootblock. */ static void bootblock_transfer(void) { + static int transfer_try; + dma_chan_t *txdma = dma_get_channel(STM32_DMAC_SPI_EMMC_TX); dma_prepare_tx(&dma_tx_option, sizeof(bootblock_raw_data), bootblock_raw_data); dma_go(txdma); - CPRINTS("transfer"); + CPRINTS("transfer %d", ++transfer_try); } /* Abort an ongoing transfer. */ @@ -106,8 +108,11 @@ static void bootblock_stop(void) /* * Wait a bit to for DMA to stop writing (we can't really wait for the * buffer to get empty, as the bus may not be clocked anymore). + * + * TODO(b:117253718): For some reason, a delay >=200us is necessary, + * else the SPI/DMA skips bytes when the transfer is resumed. */ - udelay(100); + udelay(200); /* Then flush SPI FIFO, and make sure DAT line stays idle (high). */ STM32_SPI_EMMC_REGS->dr = 0xff; |